在OpenCL中有一个关于结构处理的问题,我在这里找不到。我收集了结构中使用的所有数据,结构本身由几个结构组成。我想做以下事情:
typedef struct tag_OwnStruct
{
float a;
float b;
float c;
int d;
float e;
int f;
}OwnStruct;
typedef struct tag_DataStruct
{
OwnStruct g;
//+ Alot of other structs... not written for simplicity
}DataStruct;
void PrintOwnStruct(OwnStruct* g)
{
printf("Current lane id : %f\n",g->a);
}
__kernel void Test(__global DataStruct *data)
{
PrintOwnStruct(&data->g);
}
所以我希望,从我从主机端发送到设备的给定数据,将引用发送到它内部的结构。这不会以某种方式起作用,我也不知道为什么。我在普通的C代码中尝试过相同的东西并且它有效..
如果我将PrintOwnStruct更改为:
void PrintOwnStruct(OwnStruct g)
{
printf("Current lane id : %f\n",g.a);
}
并将函数调用为:PrintOwnStruct(data->g)
代码将在设备端运行。有没有其他方法可以做到这一点?由于我没有发送对函数的引用,它是否通过值传递?并且不应该比通过引用传递函数参数慢吗?
答案 0 :(得分:1)
因此问题出现(来自注释)是__private
和__global
地址空间之间的混淆,并且可能编译器/运行时在通知指针混合方面不是很有帮助。
void PrintOwnStruct(OwnStruct* g)
{
printf("Current lane id : %f\n",g->a);
}
__kernel void Test(__global DataStruct *data)
{
PrintOwnStruct(&data->g);
}
__global DataStruct *data
是指向__global
地址空间中某些内容的指针[换句话说,所有CL线程具有相同的地址],void PrintOwnStruct
OwnStruct* g)
的参数声明一个在默认OwnStruct
地址空间中指向__private
的参数[换言之,在此线程的堆栈中]。
正确的做法是通过声明函数__global
来维护指向PrintOwnStruct(__global OwnStruct* g)
的两个指针的地址空间。
我很确定某些OpenCL编译器会为此提供错误,但显然不是这个错误。我希望真正的语法错误,例如将%-&6
添加到代码中实际上会为您提供一个根本无法运行的内核,因此当您调用clCreateKernel
或clBuildProgram
时,您将收到错误 - 可由clGetProgramBuildInfo
显示。但是如果编译器没有检测到不同的地址空间,那么它就是编译器的错误/特征。
[事实上,如果您的编译器基于Clang,您可能需要查看此错误: https://llvm.org/bugs/show_bug.cgi?id=19957 - 半小时的谷歌搜索给出了某种结果! :)]
在较新的CL2.0中,默认地址空间为generic
,允许"任何"地址空间。