OpenCL-添加到单个全局值

OpenCL-添加到单个全局值,opencl,Opencl,我正在与一个bug作斗争,这个bug与从OpenCL内核添加到单个全局值有关 考虑这个(过于简化的)例子: 我通过clCreateBuffer和clEnqueueWriteBuffer传入一个初始化为零的参数。我假设在添加值之后,让队列完成并读回它,我会得到一个非零值 然后我想这可能是一些奇怪的冲突,所以我试着做一个原子操作: __kernel some_kernel(__global unsigned int *ops) { unsigned int somevalue = ...; // a

我正在与一个bug作斗争,这个bug与从OpenCL内核添加到单个全局值有关

考虑这个(过于简化的)例子:

我通过
clCreateBuffer
clEnqueueWriteBuffer
传入一个初始化为零的参数。我假设在添加值之后,让队列完成并读回它,我会得到一个非零值

然后我想这可能是一些奇怪的冲突,所以我试着做一个原子操作:

__kernel some_kernel(__global unsigned int *ops) {
unsigned int somevalue = ...; // a non-zero value is assigned here
atomic_add(ops, somevalue);
}
唉,没有骰子——将值读回主机指针后,它仍然是零。我已经验证了
somevalue
在内核执行中具有非零值,并且我不知所措

根据请求,创建内存的代码:

unsigned int *cpu_ops = new unsigned int;
*cpu_ops = 0;

cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR;
cl_int error;
cl_mem buffer = clCreateBuffer(context, flags, sizeof(unsigned int), (void*)cpu_ops, &error);
// error code check snipped

error = clEnqueueWriteBuffer(queue, buffer, CL_TRUE, 0, sizeof(unsigned int), (void*)cpu_ops, 0, NULL, NULL);
// error code check snipped

// snip: program setup - it checks out, no errors

cl_kernel some_kernel = clCreateKernel(program, "some_kernel", &error);
// error code check snipped

cl_int error = clSetKernelArg(some_kernel, 0, sizeof(cl_mem), &buffer);
// error code check snipped

//global_work_size and local_work_size set elsewhere
cl_int error = clEnqueueNDRangeKernel(queue, some_kernel, 1, NULL, &global_work_size, &local_work_size, 0, NULL, NULL);
// error code check snipped

clFinish(queue);

cl_int error = clEnqueueReadBuffer(queue, buffer, CL_TRUE, 0, sizeof(unsigned int), (void*)cpu_ops, 0, NULL, NULL);
// error code check snipped

// at this point, cpu_ops still has it's initial value (whatever that value might have been set to)'
我跳过了错误检查代码,因为它不会出错。实际上,我正在使用一系列定制的帮助器函数来发送和接收数据、设置平台和上下文、编译程序等等,因此上面的内容是由适当的帮助器的主体构成的,并更改了参数的名称以使其有意义


我很确定这是我的失误或缺乏理解,但我迫切需要投入。

没关系。我对我的记忆句柄感到困惑——这只是一个愚蠢的错误。代码可能很好。

您能否发布您的代码:创建内存区域、读取和写入内存区域以及运行内核?这绝对不是你发布的代码的问题,而是这里的问题。你开始了。正如我所解释的,我使用了几个helper函数,但它们在其他情况下工作——其他数据是使用它们正确发送、更改和接收的,只有这一个unsigned int*不起作用。
unsigned int *cpu_ops = new unsigned int;
*cpu_ops = 0;

cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR;
cl_int error;
cl_mem buffer = clCreateBuffer(context, flags, sizeof(unsigned int), (void*)cpu_ops, &error);
// error code check snipped

error = clEnqueueWriteBuffer(queue, buffer, CL_TRUE, 0, sizeof(unsigned int), (void*)cpu_ops, 0, NULL, NULL);
// error code check snipped

// snip: program setup - it checks out, no errors

cl_kernel some_kernel = clCreateKernel(program, "some_kernel", &error);
// error code check snipped

cl_int error = clSetKernelArg(some_kernel, 0, sizeof(cl_mem), &buffer);
// error code check snipped

//global_work_size and local_work_size set elsewhere
cl_int error = clEnqueueNDRangeKernel(queue, some_kernel, 1, NULL, &global_work_size, &local_work_size, 0, NULL, NULL);
// error code check snipped

clFinish(queue);

cl_int error = clEnqueueReadBuffer(queue, buffer, CL_TRUE, 0, sizeof(unsigned int), (void*)cpu_ops, 0, NULL, NULL);
// error code check snipped

// at this point, cpu_ops still has it's initial value (whatever that value might have been set to)'