0
我正在打擊與從OpenCL內核添加到單個全局值相關的錯誤。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)'
我已經跳過了錯誤檢查代碼,因爲它不報錯了。實際上,我使用了一堆自定義幫助函數來發送和接收數據,設置平臺和上下文,編譯程序等等,所以上面的代碼是由相應幫助器的主體構建的,參數名稱已更改爲合理。
我相當肯定,這是我的缺點或缺乏理解,但絕望地需要在這方面的投入。
你可以發佈你的代碼:創建內存區域,讀寫內存區域,運行內核? 這絕對不是你發佈的代碼片段的問題,而是一個問題。 – DarkZeros
你走了。正如我已經解釋的那樣,我使用了一些輔助函數,但是它們的工作原理 - 其他數據是使用它們發送,更改和正確接收的,只是這一個unsigned int *不會起作用。 –