关于C#:如何在内核中传递数组,做一些事情然后返回它 – OpenCL

How to pass array in kernel, do something and then return it - OpenCL

我正在尝试将数组传递给 OpenCL 内核,然后对其进行处理并将其传递回主机。我在本教程中修改了代码。

这只是用于确定 OpenCL 实际工作方式的内核。我希望这只会从array1的第一个元素中减去2并将其存储到array2的第一个元素中:

1
2
3
__kernel void test(global int* array1, global int* array2) {
    array2[0] = array1[0] - 2;
}

在 main 我有两个数组,一个(host1)有一些数字,第二个(host2)初始化为零。
比创建我使用的内存缓冲区:

1
2
memobj = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, MEM_SIZE * sizeof(int), &host1, &ret);
memobj2 = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, MEM_SIZE * sizeof(int), &host2, &ret);

构建程序后我设置了参数:

1
2
ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), &host1);
ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), &host2);

然后在执行后我尝试取回那个数组。

1
ret = clEnqueueReadBuffer(command_queue, memobj2, CL_TRUE, 0, MEM_SIZE * sizeof(int), host2, 0, NULL, NULL);

在这里,如果我将 memobj2 更改为 memobj,则 host2 将包含 host1 的值,否则保持不变。我想这不是返回数组的方式。

我被困在这一点上。


您对 clSetKernelArg() 的调用无效 - 您应该传递 OpenCL 缓冲区,而不是主机指针。例如:

1
2
ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), &memobj);
ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), &memobj2);

正如已经指出的,您应该检查每个 OpenCL 运行时 API 调用的返回码。这会很快将您指向错误。