将结构数组传递给内核导致写入时出现段错误?

时间:2013-11-15 20:45:06

标签: c++ opencl

也许我错过了教程中的内容,因为这让我疯狂。

我想要完成的任务:我想为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。

1 个答案:

答案 0 :(得分:1)

您的问题是您无法为HOST和DEVICE设置单个标头。 你必须像这样分开它们:

//HOST header
struct mystruct{
    cl_ulong a;
    cl_uint b;
};

//DEVICE header
typedef struct{
    ulong a;
    uint b;
} mystruct;

请注意,我还将数据类型更改为标准OpenCL数据类型。您应该使用它们来代替兼容性。