2013-10-28 30 views
0

我正在打击与从OpenCL内核添加到单个全局值相关的错误。OpenCL - 添加到单个全局值

考虑这个(简单化)例如:

__kernel some_kernel(__global unsigned int *ops) { 
unsigned int somevalue = ...; // a non-zero value is assigned here 
*ops += somevalue; 
} 

我通过在通过clCreateBufferclEnqueueWriteBuffer初始化为零的参数。我认为在添加值之后,让队列完成并读取它,我会得到一个非零值。

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

__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)' 

我已经跳过了错误检查代码,因为它不报错了。实际上,我使用了一堆自定义帮助函数来发送和接收数据,设置平台和上下文,编译程序等等,所以上面的代码是由相应帮助器的主体构建的,参数名称已更改为合理。

我相当肯定,这是我的缺点或缺乏理解,但绝望地需要在这方面的投入。

+0

你可以发布你的代码:创建内存区域,读写内存区域,运行内核? 这绝对不是你发布的代码片段的问题,而是一个问题。 – DarkZeros

+0

你走了。正如我已经解释的那样,我使用了一些辅助函数,但是它们的工作原理 - 其他数据是使用它们发送,更改和正确接收的,只是这一个unsigned int *不会起作用。 –

回答

0

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