OpenCL实例化本地内存数组:内核

时间:2016-04-30 00:19:44

标签: c++ opencl

我尝试为内核创​​建2个本地数组。我的目标是将全局输入缓冲区复制到第一个数组(arr1),并实例化第二个数组(arr2),以便可以在以后访问和设置其元素。

我的内核看起来像这样:

__kernel void do_things (__global uchar* in, __global uchar* out, 
uint numIterations, __local uchar* arr1, __local uchar* arr2)
{
  size_t work_size = get_global_size(0) * get_global_size(1);

  event_t event;
  async_work_group_copy(arr1, in, work_size, event);
  wait_group_events(1, &event);

  int cIndex = (get_global_id(0) * get_global_size(1)) + get_global_id(1);
  arr2[cIndex] = 0;

  //Do other stuff later
}

在我调用它的C ++代码中,我设置了这样的内核参数:

//Create input and output buffers
cl_mem inputBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY |
    CL_MEM_COPY_HOST_PTR, myInputVector.size(), (void*) 
    myInputVector.data(), NULL);
cl_mem outputBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY,
    myInputVector.size(), NULL, NULL);

//Set kernel arguments.
clSetKernelArg(kernel, 0, sizeof(cl_mem), (void*)&inputBuffer));
clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&outputBuffer));
clSetKernelArg(kernel, 2, sizeof(cl_uint), &iterations));
clSetKernelArg(kernel, 3, sizeof(inputBuffer), NULL));
clSetKernelArg(kernel, 4, sizeof(inputBuffer), NULL));

myInputVector是一个充满uchars的向量。

然后,我用2D工作大小排队,行* cols大。 myInputVector的大小为rows * cols。

//Execute the kernel
size_t global_work_size[2] = { rows, cols }; //2d work size
status = clEnqueueNDRangeKernel(commandQueue, kernel, 2, NULL,
    global_work_size, NULL, 0, NULL, NULL);

问题是,我在运行内核时遇到了崩溃问题。具体来说,内核中的这一行:

arr2[cIndex] = 0;

负责崩溃(省略它会使它不再崩溃)。错误如下:

*** glibc detected *** ./MyProgram: free(): invalid pointer: 0x0000000001a28fb0 ***

我想要的就是能够与arr1一起访问arr2。 arr2应与arr1的大小相同。如果是这样,为什么我会收到这个奇怪的错误?为什么这是一个无效的指针?

1 个答案:

答案 0 :(得分:0)

问题是您只为本地缓冲区分配sizeof(cl_mem)。而cl_mem只是某种指针类型的typedef(因此取决于你的系统,4到8个字节)。

在你的内核中发生的事情是,你访问的内容超出了你分配的本地缓冲区的大小,GPU会启动内存故障。

clSetKernelArg(kernel, 3, myInputVector.size(), NULL);
clSetKernelArg(kernel, 4, myInputVector.size(), NULL);

应该解决你的问题。另请注意,您提供的大小是以字节为单位的大小,因此您需要乘以向量元素类型的sizeof(代码中不清楚)。