OpenCL:结构内结构发送到设备端的内部功能
OpenCL: Struct within struct sending to internal function on device side
有一个关于 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)
代码将在设备端 运行。还有其他方法吗?因为我没有发送对函数的引用,它是按值传递的吗?这难道不应该比通过引用传递函数参数慢吗?
所以问题(来自评论)是 __private
和 __global
地址 space 之间的混淆,可能 compiler/runtime 不是很有帮助在告知指针的组合。
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
地址 space 中某物的指针 [换句话说,所有 CL 线程具有相同的地址],void [=15= 的参数] OwnStruct* g)
在默认 __private
地址 space 中声明一个指向 OwnStruct
的参数 [换句话说,在该线程的堆栈上]。
正确的做法是通过声明函数 PrintOwnStruct(__global OwnStruct* g)
为指向 __global
的两个指针维护地址 space。
我很确定某些 OpenCL 编译器会为此给出错误,但显然不是这个。我希望真正的语法错误,例如在代码中添加 %-&6
实际上会给你一个根本没有 运行 的内核,所以当你调用 clCreateKernel
或 clBuildProgram
,你会得到一个错误 - 可以通过 clGetProgramBuildInfo
显示。但是,如果编译器没有检测到不同的地址 space,那么它就是编译器的 bug/feature。
[事实上,如果你的编译器是基于 Clang 的,你可能想看看这个错误:
https://llvm.org/bugs/show_bug.cgi?id=19957 - 谷歌搜索半小时给出了某种结果! :)]
在较新的 CL2.0 中,默认地址-space 是 generic
,这允许使用 "any" 地址 space。
有一个关于 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)
代码将在设备端 运行。还有其他方法吗?因为我没有发送对函数的引用,它是按值传递的吗?这难道不应该比通过引用传递函数参数慢吗?
所以问题(来自评论)是 __private
和 __global
地址 space 之间的混淆,可能 compiler/runtime 不是很有帮助在告知指针的组合。
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
地址 space 中某物的指针 [换句话说,所有 CL 线程具有相同的地址],void [=15= 的参数] OwnStruct* g)
在默认 __private
地址 space 中声明一个指向 OwnStruct
的参数 [换句话说,在该线程的堆栈上]。
正确的做法是通过声明函数 PrintOwnStruct(__global OwnStruct* g)
为指向 __global
的两个指针维护地址 space。
我很确定某些 OpenCL 编译器会为此给出错误,但显然不是这个。我希望真正的语法错误,例如在代码中添加 %-&6
实际上会给你一个根本没有 运行 的内核,所以当你调用 clCreateKernel
或 clBuildProgram
,你会得到一个错误 - 可以通过 clGetProgramBuildInfo
显示。但是,如果编译器没有检测到不同的地址 space,那么它就是编译器的 bug/feature。
[事实上,如果你的编译器是基于 Clang 的,你可能想看看这个错误: https://llvm.org/bugs/show_bug.cgi?id=19957 - 谷歌搜索半小时给出了某种结果! :)]
在较新的 CL2.0 中,默认地址-space 是 generic
,这允许使用 "any" 地址 space。