在OpenCL中,我可以将内核参数设置如下吗?
cl_uint a = 0;
kernel.setArg(0, sizeof(a), &a);
我想从内核函数读取和写入一个值,而不仅仅是写入。
答案 0 :(得分:4)
以这种方式设置内核参数只能用于内核的输入。您要读取的任何输出(在后续内核或主机程序中)都必须写入缓冲区或映像。在您的情况下,这意味着您需要创建单元素缓冲区并将缓冲区传递给内核。
考虑这一点的一种方法是,当您使用参数& a调用setArg时,OpenCL内核使用a的值,而不是 location 一个。如果内核要写入内核参数零,那么你的宿主程序就无法恢复写入的值。
答案 1 :(得分:2)
您的代码会创建类型为unsigned int
的参数,而不是指向unsigned int
的指针。
clSetKernelArg
使用指向参数值的指针,而不是值本身。
如果要传递指针参数,则必须使用clCreateBuffer
创建一个缓冲区(即使它只是一个值),并使用生成的clSetKernelArg
调用cl_mem
。
以下代码在 __ global 内存中为1 cl_uint
创建一个缓冲区,并将my_value
的值复制到该内存中。运行内核后,它会将(可能已修改的)值复制回my_value
。
cl_uint my_value = 0;
const unsigned int count = 1;
// Allocate buffer
cl_mem hDeviceMem = clCreateBuffer(hContext, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, count * sizeof(cl_uint), &my_value, &nError);
// Set pointer to buffer as argument
clSetKernelArg(hKernel, 0, sizeof(cl_mem), &hDeviceMem);
// Run kernel
clEnqueueNDRangeKernel(...);
// Copy values back
clEnqueueReadBuffer(hCmdQueue, hDeviceMem, CL_TRUE, 0, count * sizeof(cl_uint), &my_value, 0, NULL, NULL);
你的内核应该是这样的:
__kernel void myKernel(__global unsigned int* value)
{
// read/write to *value here
}
答案 2 :(得分:0)
这应该与将1长度向量作为参数发送相同。您可能必须在内核定义中使用__global uint aParam。