我正在解决与从OpenCL内核添加单个全局值相关的错误。
考虑这个(过于简化的)例子:
__kernel some_kernel(__global unsigned int *ops) {
unsigned int somevalue = ...; // a non-zero value is assigned here
*ops += somevalue;
}
我通过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)'
我已跳过错误检查代码,因为它没有错误输出。我实际上使用了一堆自定义辅助函数来发送和接收数据,设置平台和上下文,编译程序等等,所以上面是由适当的帮助器的主体构成的,参数的名称改为有道理。
我很确定这对我来说是一个漏洞或缺乏理解,但迫切需要输入。
答案 0 :(得分:0)
没关系。我对我的内存句柄感到困惑 - 只是一个愚蠢的错误。代码可能很好。