我是opencl的新手,似乎有一些關於屏障功能的東西我不明白。這是我的內核的代碼。這是用* w輸出的標準矩陣向量計算。有1個工作組有64個工作單位,與矢量的維數相同opencl同步
#pragma OPENCL EXTENSION cl_khr_fp64 : enable
__kernel void fmin_stuff(__global double *h, __global double *g, __global double
*w,int n,__global int * gid) {
// Get the index of the current element
int i = get_global_id(0);
int j;
gid[i]=get_local_id(0);
w[i]=-g[i];
barrier(CLK_GLOBAL_MEM_FENCE | CLK_LOCAL_MEM_FENCE);
for (j=0;j<n;j++)
{
if (j<i)
w[i]-=h[i+j*n]*w[j];
barrier(CLK_GLOBAL_MEM_FENCE | CLK_LOCAL_MEM_FENCE);
}
}
問題是代碼隨機失敗。輸出是正確的一段時間。這裏是每次運行的w的初始值。
-0.148351 -0.309007 0.133204 -1.39589 2.88335 -2.72261 2.80155
-0.148351 -0.309007 0.133204 -1.39589 2.88335 -2.72261 2.80155
-0.148351 -0.309007 0.133204 -1.39589 2.88335 -2.72261 2.80155
-0.148351 -0.309007 0.133204 -1.39589 2.88335 -2.72261 2.80155
-0.148351 -0.309007 0.133204 -1.39589 2.88335 -2.72261 2.80155
-0.148351 -0.309007 0.133204 -1.39589 2.88335 -2.72261 2.80155
-0.148351 -0.309007 0.133204 -1.39589 2.88335 -2.34999 2.51524
-0.148351 -0.309007 0.133204 -1.39589 2.88335 -2.72261 2.80155
-0.148351 -0.309007 0.133204 -1.39589 2.88335 -2.72261 2.80155
-0.148351 -0.309007 0.133204 -1.39589 2.88335 -2.72261 2.10141
-0.148351 -0.309007 0.133204 -1.39589 2.88335 -2.72261 2.80155
-0.148351 -0.309007 0.133204 -1.39589 2.88335 -2.68636 2.77369
程序報告內核在每種情況下都成功執行。對於所有運行,向量w中的值最終都是不正確的。任何建議將不勝感激。
這是否是一個簡單的矩陣乘法存在一些混淆。不是這樣。這是代碼試圖完成的地方,其中我只包括w的前5項。
w(1)=-g(1);
w(2)=-g(2);
w(3)=-g(3);
w(4)=-g(4);
w(5)=-g(5);
w(2)-=h(2)*w(1);
w(3)-=h(3)*w(1);
w(4)-=h(4)*w(1);
w(5)-=h(5)*w(1);
w(3)-=h(3+N)*w(2);
w(4)-=h(4+N)*w(2);
w(5)-=h(5+N)*w(2);
w(4)-=h(4+2*N)*w(3);
w(5)-=h(5+2*N)*w(3);
w(5)-=h(5+3*N)*w(4);
此外,內核僅在每次程序運行時調用一次。隨機行爲是由多次運行程序產生的。
該評論讓我看到我做錯了什麼。我將工作組和項目配置爲
size_t global_item_size[3] = {N, 1, 1}; // Process the entire lists
size_t local_item_size[3] = {1,1,1}; // Process in groups of 64
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL,
global_item_size, local_item_size, 0, NULL, NULL);
它應該是什麼時候。
size_t global_item_size[3] = {N, 1, 1}; // Process the entire lists
size_t local_item_size[3] = {N,1,1}; // Process in groups of 64
ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL,
global_item_size, local_item_size, 0, NULL, NULL);
感謝您的幫助。這對我來說很好,但可能對其他人不太感興趣。
採取遠離這一切最重要的是,在OpenCL內核的'barrier'功能只會充當工作組,而不是整個設備的屏障。 GPU上的設備範圍同步是一個積極研究的話題。 – KLee1 2012-04-15 07:56:44