私は単純な並列化アルゴリズムを使って配列の最小値を探し出しています。私は、インテルのOpenCL 1.2をUbuntu 16.04で実行しています。並列化アルゴリズムでOpenCLの定義されていない動作
次のカーネルは、私は現在、私に間違った答えを与えている実行しようとしていますものです:
__kernel void Find_Min(int arraySize, __global double* scratch_arr, __global double* value_arr, __global double* min_arr){
const int index = get_global_id(0);
int length = (int)sqrt((double)arraySize);
int start = index*length;
double min_val = INFINITY;
for(int i=start; i<start+length && i < arraySize; i++){
if(value_arr[i] < min_val)
min_val = value_arr[i];
}
scratch_arr[index] = min_val;
barrier(CLK_GLOBAL_MEM_FENCE);
if(index == 0){
double totalMin = min_val;
for(int i=1; i<length; i++){
if(scratch_arr[i] < totalMin)
totalMin = scratch_arr[i];
}
min_arr[0] = totalMin;
}
}
プットで{0、-1、-2、-3、ある配列で-4、-5、-6、-7、-8}になると-2が返されます。 。未定義の動作が入ってくるのはここ
は、私は障壁の前にprintf文で次のカーネルを実行すると、私は正しい答えを得る(-8)である:
__kernel void Find_Min(int arraySize, __global double* scratch_arr, __global double* value_arr, __global double* min_arr){
const int index = get_global_id(0);
int length = (int)sqrt((double)arraySize);
int start = index*length;
double min_val = INFINITY;
for(int i=start; i<start+length && i < arraySize; i++){
if(value_arr[i] < min_val)
min_val = value_arr[i];
}
scratch_arr[index] = min_val;
printf("setting scratch[%i] to %f\n", index, min_val);
barrier(CLK_GLOBAL_MEM_FENCE);
if(index == 0){
double totalMin = min_val;
for(int i=1; i<length; i++){
if(scratch_arr[i] < totalMin)
totalMin = scratch_arr[i];
}
min_arr[0] = totalMin;
}
}
私は考えることができる唯一のこと起こっている可能性があるのは、私がbarrierコマンドを間違って使用していることであり、printfが行っていることはカーネルに何らかの形で呼び出しを同期させて最終的な削減ステップの前にすべて完了することです。しかし、printfがなければ、カーネル0は他のカーネルが終了する前に最終的な縮小を実行します。
この問題をデバッグする方法について他に提案やヒントがありますか?
ありがとうございます!