0

条件に基づいて、opencl カーネルの出力配列にいくつかの値を入力したいと考えています。したがって、配列に値が入力されるたびに、配列のインデックスをインクリメントしたいと考えています。条件を満たす必要があるため、出力配列インデックスは不明です。出力配列インデックスを引数として使用しています。

__kernel void match(__global float* input, __global float* output, int pos)
{ 
     if(condition)
     {
          output[pos] = input[get_global_id(0)];
          atomic_inc(&pos); // this is where the problem lies
     }
}

また、posを配列として与えようとしました

__kernel void match(__global float* input, __global float* output, __global int* pos)
{ 
     if(condition)
     {
          output[pos[0]] = input[get_global_id(0)];
          atomic_inc(pos[0]); // this is where the problem lies
     }
}

どちらの場合も、clBuildProgram はエラー コード -11 を返しました。値pos ++をインクリメントすると機能しましたが、配列の位置の最終値は返されませんでした。

誰が私が間違っているのか説明できますか?

4

2 に答える 2

2

質問を理解しているかどうかわかりませんが、試してみましょう:

各要素にinputスレッドが割り当てられていますか? もしそうなら、あなたが1D配列を使用していると仮定して(巨大な仮定)カーネルでinput使用して索引付けされ、同様のグローバル作業サイズで呼び出されますindex[get_global_id(0)]clEnqueuNDRangeKernel()size_t Global_Work_Size[1] = {input_size}

を使用して最初の例と同様のカーネルを呼び出すと、すべてのスレッドにint posの定数が設定されるため、質問を解釈していると機能しません。pos

カーネル インデックスが簡単な方法でマップされない場合は、インデックスをオンザフライで計算するか、または にマップinputされるインデックスのルックアップ テーブル (LUT) である別の配列を入力する必要がありますoutput

最後に、clGetProgramBuildInfoを使用して、エラーの正確な内容を確認できます。 私が別のスレッドで行った書き込みを参照してください

于 2013-08-21T21:23:58.210 に答える
0

atomic_inc を使用してインクリメントする変数の値を直接使用することはできません。そうしないと、競合状態が発生します。atomic_incのドキュメントには、インクリメントの前に古い値が返されることが記載されており、各スレッドがこの方法で使用すると、それぞれが一意の値を取得します。したがって、それを使用する正しい方法は次のとおりです。

int localPos = atomic_inc(&pos);
output[localPos] = input[get_global_id(0)];

「pos」はグローバルでもローカルでもかまいませんが、使用するにはグローバルにする必要があるようです。

于 2013-08-23T00:24:53.830 に答える