【发布时间】:2011-10-10 21:33:55
【问题描述】:
好的,所以我已将其隔离为一个非常具体的问题。
我的印象是您可以在数组缓冲区中传递 OpenCL 任何类型的数据;整数、字符、您自己的自定义结构,只要它们只是数据并且不包含指向 GPU 无法检索的堆对象的指针。
现在,我已经尝试过了,我认为它适用于大量整数数组,但不适用于我的结构数组。具体来说,
cl_mem log_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE,
num_elements * sizeof(int), NULL, NULL);
int* error_codes_in = (int*)malloc(num_elements * sizeof(int));
for (i = 0; i < num_elements; i++) {
error_codes_in[i] = i;
}
error = clEnqueueWriteBuffer(command_queue, log_buffer, CL_TRUE,
0, num_elements * sizeof(int), error_codes_in, 0, NULL, NULL);
这很好用,我在 GPU 上获得了一组数字,并且可以并行地成功操作它们。
但是,当我使用自己的自定义结构时:
typedef struct {
float position[2];
float velocity[2];
float radius;
float resultant_force[2];
} ocl_element_2d_t;
(也在内核中定义,as)
const char* kernel_string =
"typedef struct { float position[2]; float velocity[2]; float radius; float resultant_force[2]; } ocl_element_2d_t;"...
我使用相同/非常相似的代码写入我的结构数组的 GPU 版本:
cl_mem gpu_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE,
num_elements * sizeof(ocl_element_2d_t), NULL, NULL);
error = clEnqueueWriteBuffer(command_queue, (cl_mem)gpu_buffer, CL_TRUE,
0, num_elements * sizeof(ocl_element_2d_t), host_buffer, 0, NULL, NULL);
我在 GPU 中得到空白值,并且偶尔为结构内的所有浮点值生成垃圾(350 中的三个或四个值)。两个返回值都是CL_SUCCESS。
关于我哪里出错了有什么建议吗?我唯一的想法是 GPU 编译器在内存中生成了一个具有不同间隙的结构,并且由于复制方法忽略了项目的内部结构并只是复制了一个连续的 RAM 块,因此最终会出现不匹配和可能的异相项目。我的操作系统是否可能是 i7(四核)上的 64 位(OS X Lion),而我的 GPU 运行的是 32 位,这就是问题所在?它是 ATI Radeon HD 5750,不支持双精度,并声称拥有 128 位总线(可能相关,也可能不相关,我不知道这东西的确切含义。)
有没有正确的方法来做到这一点?对于结构中的不同属性,我是否必须使用所有 FORTRAN 并拥有 7 个不同的数组,每个数组都有自己的内核参数?
【问题讨论】:
-
我看不到你实际上在哪里传递你的结构。你传入大小,否则它不会被使用。
-
@0A0D 抱歉,这些只是 sn-ps。我将缓冲区添加为内核参数并成功执行内核;我知道那部分正在工作,因为我可以得到整数。如果您愿意,我可以发布更多代码,但是帖子已经变得很长了...编辑:哦,您的意思是主机数据不是吗?这是最后一个 sn-p 中
clEnqueueWriteBuffer的host_buffer参数。 -
你应该发布相关的代码来证明你的问题。
-
失败的操作是将结构数组复制到 GPU 内存空间的代码 - 已经提供了所有设置以及库调用本身。我不相信任何其他代码是相关的。
-
这就是我不明白的......它在哪里将结构复制到主机缓冲区?