2013-10-28 31 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

沒關係。我對我的記憶手柄感到困惑 - 只是一個愚蠢的錯誤。代碼可能很好。