2016-02-05 63 views
0

我正在使用OpenCL對圖像進行卷積運算(info here)。當我使用大小不是正方形的圖像時(例如rxc),CLK_LOCAL_MEM_FENCE使程序停止並帶有中止陷阱6.OpenCL CLK_LOCAL_MEM_FENCE導致中止陷阱6

我所做的基本上是用合適的值填充本地內存,等待填充本地內存完成,使用屏障(CLK_LOCAL_MEM_FENCE),然後計算值。

看起來像當我使用像我告訴過你關於屏障的圖像(CLK_LOCAL_MEM_FENCE)給出的問題,如果我評論說,一切工作正常(這是奇怪的,因爲沒有同步)。什麼可能會導致這個問題任何想法?

編輯:當高度或寬度或兩者都不是本地項目大小(16 x 16)的倍數時出現問題。全球物品的大小總是16的幾倍,如(512 x 512)。

int c = get_global_id(0); 
int r = get_global_id(1); 

int lc = get_local_id(0); 
int lr = get_local_id(1); 

// this ignores indexes out of the input image. 
if (c >= ImageWidth || r >= ImageHeight) return; 

// fill a local array... 

barrier(CLK_LOCAL_MEM_FENCE); 

if (c < outputImageWidth && r < outputImageHeight) 
{ 
    // LOCAL DATA PROCESSED 
    OutputImage[r* outputImageWidth +c] = someValue; 
} 
+0

我們怎麼沒有密碼猜測?也許你沒有從工作組的所有主題中調用障礙? –

+0

請輸入密碼。您正在循環中使用它,並且當循環大小不是方形時,它將被掛起。 – DarkZeros

+0

@DarkZeros你會看EDIT嗎?我從我的內核添加了一些僞代碼。我不確定它是否取決於我沒有寫在這裏的代碼的實現,但事實是,當我評論這個障礙時,它似乎可以正常工作(它不會停止)。 – Matt

回答

3

的OpenCL要求每個工作組屏障由工作項目的工作組中執行。

在您發佈的代碼中,您有一個提前退出子句來防止超出範圍的訪問。這是在OpenCL 1.X中獲得良好工作組大小的常用技巧,但不幸的是,這會打破上述情況,並且這會導致未定義的行爲(通常是掛起或崩潰)。

爲了避免這種情況,您需要修改內核,方法是刪除早期的退出子句(也可以將適用的超出範圍的工作項(如果適用)),或者通過重構內核,在退出之前,範圍內的工作項目至少會繼續到達障礙。

+0

這正是我所想的。非常感謝您的確認! – Matt

2

您可以更改代碼,以便在不影響行爲來解決這個問題:

int c = get_global_id(0); 
int r = get_global_id(1); 

int lc = get_local_id(0); 
int lr = get_local_id(1); 

// fill a local array... with all the threads 
// ie: for(i=0;i<size;i+=get_local_size(0)) 
//  ... 

barrier(CLK_LOCAL_MEM_FENCE); 

// this ignores indexes out of the input image. 
if (c >= ImageWidth || r >= ImageHeight) return; 

if (c < outputImageWidth && r < outputImageHeight) 
{ 
    // LOCAL DATA PROCESSED 
    OutputImage[r* outputImageWidth +c] = someValue; 
}