我是一名从事 OpenCL 工作的新人。当我尝试编译内核时遇到了一些奇怪的麻烦。
在 Nvidia 平台上,无论源代码中的什么代码,它总是显示 cl_success 并且日志只有“\n”;在Intel平台上,不管源码里是什么代码,clBuildProgram返回CL_INVALID_BINARY,clGetProgramBuildInfo和CL_PROGRAM_BUILD_STATUS返回CL_ERROR,看日志没发现错误:
fcl build 1 succeeded.\n fcl build 2 succeeded.\n bcl build succeeded.\n.
由于这是我的第一段复杂的内核代码,我知道它有很多错误。但是,这看起来不像是代码错误。为什么编译器会显示一些相互矛盾的信息?
这是我的代码: 代码很长,我只发布可能与之相关的部分。 “...”表示跳过了某些内容。如果需要,请询问其余部分。 绘制过程.ccp
#include <stdlib.h>
#include "Console.h"
#include "Renderer.h"
#include "Object.h"
#include "TertiaryArithmeticAlgorithms.h"
#define CL_USE_DEPRECATED_OPENCL_2_0_APIS
#if defined(__APPLE__) || defined(__MACOSX)
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.h>
#endif
#include "Camera.h"
cl_command_queue CommandQueue;
cl_mem BufIdx[8];
cl_kernel Rasterization;
bool Initialization()
{
ConWrite("======== OpenCL Initializing ========\n");
//
cl_platform_id ThePlatformID=NULL;
cl_uint NumPlatforms;
cl_int status;
if(CL_INVALID_VALUE==clGetPlatformIDs(NULL,NULL,&NumPlatforms))
{
ConWrite("ERROR: Fail to Get the Number of Available Items in Platform List! The Number of Available Items in Platform List Equal to 0 and Platform List is NULL OR Both Platform List and the Exact Number of Items in Platform List are NULL.\n");
ConWrite("=== OpenCL Initialization Failed! ===\n");
return 1;
}
else
{
ConWrite("The Number of Items in Platform List is ");
ConWrite(&NumPlatforms);
ConWrite(".\n");
}
//
cl_platform_id *PlatformList;
if(NumPlatforms>0)
{
PlatformList=(cl_platform_id*)malloc(NumPlatforms*sizeof(cl_platform_id));
if(CL_INVALID_VALUE==clGetPlatformIDs(NumPlatforms,PlatformList,NULL))
{
ConWrite("ERROR: Fail to Get the Platform List! The Number of Available Items in Platform List Equal to 0 and Platform List is NULL OR Both Platform List and the Exact Number of Items in Platform List are NULL.\n");
ConWrite("=== OpenCL Initialization Failed! ===\n");
return 1;
}
else
{
ConWrite("Platform List Obtained.\n");
}
}
else
{
ConWrite("ERROR: The Number of Available Items in Platform List is not Greater than 0!\n");
ConWrite("=== OpenCL Initialization Failed! ===\n");
return 1;
}
...
cl_program VertexProgram=clCreateProgramWithSource(Context,1,Cartography,NULL,NULL);
status=clBuildProgram(VertexProgram,LengthOfDevices/sizeof(cl_device_id*),DeviceList,NULL,NULL,NULL);
if(CL_SUCCESS==status)
{
ConWrite("CODE: CL_SUCCESS. OpenCL Program Built.\n");
}
else
{
switch(status)
{
case CL_INVALID_PROGRAM:
ConWrite("CODE: CL_INVALID_PROGRAM. ERROR: The Program is an Invalid Program Object!\n");
break;
case CL_INVALID_VALUE:
ConWrite("CODE: CL_INVALID_VALUE. ERROR: Device List is Unavailable and the Number of Devices is Greater Than Zero, OR Device List is NOT NULL and the Number of Devices is Zero, OR the Pointer to Notify is NULL But User Data is NOT NULL!\n");
break;
case CL_INVALID_DEVICE:
ConWrite("CODE: CL_INVALID_DEVICE. ERROR: OpenCL Devices listed in the Device List are NOT in the List of Devices Associated with the Program!\n");
break;
case CL_INVALID_BINARY:
ConWrite("CODE: CL_INVALID_BINARY. ERROR: The Program was Created with Binary and Devices Listed in the Device List do NOT Have a Valid Binary Program!\n");
break;
case CL_INVALID_BUILD_OPTIONS:
ConWrite("CODE: CL_INVALID_BUILD_OPTIONS. ERROR: The Build Options Specified by Options are Invalid!\n");
break;
case CL_INVALID_OPERATION:
ConWrite("CODE: CL_INVALID_OPERATION. ERROR: The Build of the Program Executable for Any of the Devices Listed in the Device List by a Previous Call to the Function for the Program has NOT Completed!\n");
break;
//case CL_COMPILER_NOT_AVAILABLE: if program is created with clCreateProgramWithSource and a compiler is not available i.e. CL_DEVICE_COMPILER_AVAILABLE specified in the table of OpenCL Device Queries for clGetDeviceInfo is set to CL_FALSE.
//case CL_BUILD_PROGRAM_FAILURE: if there is a failure to build the program executable. This error will be returned if clBuildProgram does not return until the build has completed.
//case CL_INVALID_OPERATION: if there are kernel objects attached to program.
//case CL_OUT_OF_HOST_MEMORY: if there is a failure to allocate resources required by the OpenCL implementation on the host.
}
}
cl_build_status *BudStat;
size_t StatusSize;
clGetProgramBuildInfo(VertexProgram,DeviceList[0],CL_PROGRAM_BUILD_STATUS,0,NULL,&StatusSize);
BudStat=(cl_build_status*)malloc(StatusSize);
clGetProgramBuildInfo(VertexProgram,DeviceList[0],CL_PROGRAM_BUILD_STATUS,StatusSize,BudStat,NULL);
switch (*BudStat)
{
case CL_BUILD_NONE:
ConWrite("CODE: CL_BUILD_NONE.\n");
break;
case CL_BUILD_ERROR:
ConWrite("CODE: CL_BUILD_ERROR.\n");
break;
case CL_BUILD_SUCCESS:
ConWrite("CODE: CL_BUILD_SUCCESS.\n");
break;
case CL_BUILD_IN_PROGRESS:
ConWrite("CODE: CL_BUILD_IN_PROGRESS.\n");
default:
break;
}
char *Log;
size_t LogSize;
status=clGetProgramBuildInfo(VertexProgram,DeviceList[0],CL_PROGRAM_BUILD_LOG,0,NULL,&LogSize);
if(status==CL_SUCCESS)
{
ConWrite("CODE: CL_SUCCESS. OpenCL Program Build Infomation Obtained.\n");
}
else
{
switch(status)
{
case CL_INVALID_DEVICE:
ConWrite("CODE: CL_INVALID_DEVICE. ERROR: The Device is NOT in the List of Devices Associated with the Program.\n");
break;
case CL_INVALID_VALUE:
ConWrite("CODE: CL_INVALID_VALUE. ERROR: The Parameter Name is Invalid, OR the Size in Bytes Specified by Parameter's Value Size is Less Than Size of Return Type and Parameter Value is NOT NULL.\n");
break;
case CL_INVALID_PROGRAM:
ConWrite("CODE: CL_INVALID_PROGRAM. ERROR: The Program is an Invalid Program Object.\n");
break;
}
}
Log=(char*)malloc(LogSize+1);
Log[LogSize]='0';
clGetProgramBuildInfo(VertexProgram,DeviceList[0],CL_PROGRAM_BUILD_LOG,LogSize+1,Log,NULL);
ConWrite(Log);
Rasterization=clCreateKernel(VertexProgram,"VertexRenderer",NULL);
...
这是我的内核: 渲染器.h
#ifndef _1174_Renderer
#define _1174_Renderer
//------------------------------
const char *Cartography[]=
{
"#define COUNTER IdxVert\n",
"__kernel void VertexRenderer(",
"global float4 CamPos,", //X coordinate, Y coordinate, Z coordinate, SectorID
"global float4 CamAng,", //Horizontal Angle, Vertical Angle, Inclined Angle, Sight Angle
"global float4 CamNorV1,", //W represents horizontal resolution.
"global float4 CamNorV2,", //W represents vertical resolution.
"global float4 CamNorV3,", //W represents diagonal resolution.
"global float4 *Vertex,", //
"global uint IdxVert,",
"global uchar2 *ScrPos)\n", //
"{",
" half4 CpToV[COUNTER];", //CpToV.w is useless.
" int GID=(int)get_global_id(0);",
" mem_fence(CLK_GLOBAL_MEM_FENCE);",
" CpToV[GID].xyz=Vertex[GID].xyz-CamPos.xyz;",
" half Distance[COUNTER];",
" mem_fence(CLK_GLOBAL_MEM_FENCE);",
" Distance[GID]=tan(acos((CamNorV1.x*CpToV[GID].x+CamNorV1.y*CpToV[GID].y+CamNorV1.z*CpToV[GID].z)*rsqrt(CamNorV1.x*CamNorV1.x+CamNorV1.y*CamNorV1.y+CamNorV1.z*CamNorV1.z)*rsqrt(CpToV[GID].x*CpToV[GID].x+CpToV[GID].y*CpToV[GID].y+CpToV[GID].z*CpToV[GID].z)))/tan(CamAng.w)*CamNorV3.w;",
" half Scale[COUNTER];",
" mem_fence(CLK_GLOBAL_MEM_FENCE);",
" Scale[GID]=(CamNorV1.x*CpToV[GID].x+CamNorV1.y*CpToV[GID].y+CamNorV1.z*CpToV[GID].z)/(CamNorV1.x*CamNorV1.x+CamNorV1.y*CamNorV1.y+CamNorV1.z*CamNorV1.z);",
" half4 MapVect[COUNTER];",
" mem_fence(CLK_GLOBAL_MEM_FENCE);",
" MapVect[GID].xyz=CpToV[GID].xyz-Scale*CamNorV1.xyz;",
" half Theta1[COUNTER];",
" half Theta2[COUNTER];",
" mem_fence(CLK_GLOBAL_MEM_FENCE);",
" Theta1[GID]=acos((CamNorV2.x*MapVect[GID].x+CamNorV2.y*MapVect[GID].y+CamNorV2.z*MapVect[GID].z)*rsqrt(CamNorV2.x*CamNorV2.x+CamNorV2.y*CamNorV2.y+CamNorV2.z*CamNorV2.z)*rsqrt(MapVect[GID].x*MapVect[GID].x+MapVect[GID].y*MapVect[GID].y+MapVect[GID].z*MapVect[GID].z));",
" Theta2[GID]=acos((CamNorV3.x*MapVect[GID].x+CamNorV3.y*MapVect[GID].y+CamNorV3.z*MapVect[GID].z)*rsqrt(CamNorV3.x*CamNorV3.x+CamNorV3.y*CamNorV3.y+CamNorV3.z*CamNorV3.z)*rsqrt(MapVect[GID].x*MapVect[GID].x+MapVect[GID].y*MapVect[GID].y+MapVect[GID].z*MapVect[GID].z));",
" half Theta[COUNTER];",
" constant half Pi=(half)3.1415926f;",
" mem_fence(CLK_GLOBAL_MEM_FENCE);",
" (Theta1[GID]<=Pi/2)?(Theta[GID]=Theta2[GID]):(Theta[GID]=2*Pi-Theta2[GID]);",
" mem_fence(CLK_GLOBAL_MEM_FENCE);",
" ScrPos[GID].x=(uchar)cos(Theta[GID])*Distance[GID]+CamNorV1.w;",
" ScrPos[GID].y=(uchar)sin(Theta[GID])*Distance[GID]+CamNorV2.w;",
"}"
"#define COUNTER Dlt\n",
"__kernel void Polarization(",
"global float4 *NmVect,",
"global float4 *AllVert,",
"global ushort4 *DltIdx,", //W represents the index of planar vectors of primarch.
"global uint Dlt)\n",
"{",
" int GID=(int)get_global_id(0);",
" half4 SPToCam[COUNTER];",
" mem_fence(CLK_GLOBAL_MEM_FENCE);",
" SPToCam[GID].xyz=CamPos.xyz-AllVert[DltIdx[GID].x].xyz;",
" half m[COUNTER];",
" mem_fence(CLK_GLOBAL_MEM_FENCE);",
" m[GID]=SPToCam[GID].x*NmVect[DltIdx[GID].w].x+SPToCam[GID].y*NmVect[DltIdx[GID].w].y+SPToCam[GID].z*NmVect[DltIdx[GID].w].z;",
" bool Polar[COUNTER];",
" mem_fence(CLK_GLOBAL_MEM_FENCE);",
" (m>0)?(Polar=true):(Polar=false);",
" mem_fence(CLK_GLOBAL_MEM_FENCE);",
" ",
"}",
"__kernel void Hierarchization(",
"global ",
")\n",
"{",
" for(uint i=0;i<NumOfObj;i++){",
" for(uint k=0;k<NumOfLvInObj[IdxOfObj[i]];k++){",
" for(uint j=0;j<NumOfVtxInLv[k+IdxOfLv[IdxOfObj[i]]]-1;j++){",
" uint m=0;",
" (k==0)?():()",
" "
};
//------------------------------
#endif
不需要太在意内核。都错了……
还有我的硬件: 我的桌面:
我的笔记本电脑:
另一个问题:当我在桌面上运行程序时,只能检测到Nvidia平台。 OpenCL 也可以在 CPU 上运行,不是吗?为什么检测不到Intel平台?
最佳答案
不过,我不确定 clCreateProgramWithSource 中的第二个参数看起来很奇怪:
cl_program VertexProgram=clCreateProgramWithSource(Context,1,Cartography,NULL,NULL);
它应该是你源代码中的一些行,所以我建议尝试
cl_program VertexProgram=clCreateProgramWithSource(Context,sizeof(Cartography)/sizeof(Cartography[0]),Cartography,NULL,NULL);
关于c++ - OpenCL 编译器异常情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32709799/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在学习Rails,并阅读了关于乐观锁的内容。我已将类型为integer的lock_version列添加到我的articles表中。但现在每当我第一次尝试更新记录时,我都会收到StaleObjectError异常。这是我的迁移:classAddLockVersionToArticle当我尝试通过Rails控制台更新文章时:article=Article.first=>#我这样做:article.title="newtitle"article.save我明白了:(0.3ms)begintransaction(0.3ms)UPDATE"articles"SET"title"='dwdwd
在Cooper的书BeginningRuby中,第166页有一个我无法重现的示例。classSongincludeComparableattr_accessor:lengthdef(other)@lengthother.lengthenddefinitialize(song_name,length)@song_name=song_name@length=lengthendenda=Song.new('Rockaroundtheclock',143)b=Song.new('BohemianRhapsody',544)c=Song.new('MinuteWaltz',60)a.betwee
我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案
我最近决定从我的系统中卸载RVM。在thispage提出的一些论点说服我:实际上,我的决定是,我根本不想担心Ruby的多个版本。我只想使用1.9.2-p290版本而不用担心其他任何事情。但是,当我在我的Mac上运行ruby--version时,它告诉我我的版本是1.8.7。我四处寻找如何简单地从我的Mac上卸载这个Ruby,但奇怪的是我没有找到任何东西。似乎唯一想卸载Ruby的人运行linux,而使用Mac的每个人都推荐RVM。如何从我的Mac上卸载Ruby1.8.7?我想升级到1.9.2-p290版本,并且我希望我的系统上只有一个版本。 最佳答案
我不知道为什么,但是当我设置这个设置时它无法编译设置:static_cache_control,[:public,:max_age=>300]这是我得到的syntaxerror,unexpectedtASSOC,expecting']'(SyntaxError)set:static_cache_control,[:public,:max_age=>300]^我只想将“过期”header设置为css、javaascript和图像文件。谢谢。 最佳答案 我猜您使用的是Ruby1.8.7。Sinatra文档中显示的语法似乎是在Ruby1.
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手