也许我错过了教程中的内容,因为这让我疯狂。
我想要完成的任务:我想为OpenCL设备创建一个结构数组,以用作工作区。主机不需要以任何方式查看它或与之交互,它只是作为内核工作的“划痕”空间。
这就是我所拥有的:
主程序和OpenCL内核都可以访问头文件中的struct声明:
typedef struct {
uint64_t a;
uint32_t b;
} result_list;
初始化暂存空间缓冲区“outputBuffer”以保存MAX_SIZE元素:
cl_mem outputBuffer;
outputBuffer = clCreateBuffer(this->context,
CL_MEM_READ_WRITE,
sizeof(result_list) * MAX_SIZE,
NULL,
&status);
我从不打电话给clEnqueueWriteBuffer
,因为主持人并不关心内存是什么。它只是意味着成为内核的工作空间。我将其保留为未初始化但已分配。
将其设置为内核使用的参数:
status = clSetKernelArg(myKernel,
1,
sizeof(cl_mem),
&this->outputBuffer);
内核(简化为删除非问题部分):
__kernel void kernelFunc(__global const uint32_t *input, __global result_list *outputBuffer) {
if (get_global_id(0) >= MAX_SIZE) { return; }
// Make a few local variables and play with them
outputBuffer[0].a = 1234; // Memory access violation here
// Code never reaches here
}
我做错了什么?
我安装了AMD的CodeXL,对这些调试问题没什么帮助。它给我的最多的是“线程试图读取或写入它无法访问的虚拟地址。”
编辑:好像它真的不喜欢typedef。我没有使用结构,而是将其简化为typedef uint64_t result_list
并拒绝编译,称“类型'ulong'的值不能分配给'result_list'类型的实体”,即使result_list - > uint64_t - > unsigned long。
答案 0 :(得分:1)
您的问题是您无法为HOST和DEVICE设置单个标头。 你必须像这样分开它们:
//HOST header
struct mystruct{
cl_ulong a;
cl_uint b;
};
//DEVICE header
typedef struct{
ulong a;
uint b;
} mystruct;
请注意,我还将数据类型更改为标准OpenCL数据类型。您应该使用它们来代替兼容性。