あなたの問題の原因に可能な提案:
arg
整数は、完全なループの間に同じメモリアドレスを持っています。 CLカーネルに渡すときには、(値のコピーではなく)アドレスを渡すので、値はすべてのインスタンスごとに毎回変わります。
これは、すべてのグリッド配列の値が、最後の値を除いてゼロではなく、同じ、最後の値に等しいことを示唆しています。
合計を計算するときに、なぜこれが機能しますか? 私の推測では、grid
配列内に個々の値を格納していないということです(カーネルが終了してデータが読み込まれた後に保持する必要があります)。代わりに、値が追加されてgrid[0]
に割り当てられ、grid[0]
の値はそれ以上idx
に依存しません。
確かに、これはやや曖昧であり、いくつかの当て推量を必要とするが、ここであなたが試すことができるものです。
for (int i = 0; i < size; i++) {
int *arg = malloc(sizeof(*arg));
*arg = i;
clSetKernelArg(kernel_id, 1, arg, sizeof(*arg));
clEnqueueTask(command_queue, kernel_id, 0, NULL, NULL);
}
(何らかの理由で、あなたの例ではclSetKernelArg
にsize
引数を持っていません。理由はわかりません。) 明らかに通常は、arg
をサイズsize
の配列として割り当てます。繰り返しするたびにmallocするのではなく、この例を工夫しておきましょう。
これがうまくいくと、あなたは何かを見ることができます。free
arg
これはかなりのメモリリークです。そしてループ内でarg
を解放することはできません。
私はうまく動作する 'clEnqueueNDRangeKernel'を使ってしまいました。この場合、なぜタスクの並列処理が機能しなかったのかまだ分かりません。 'clEnqueueTask'は、Intelによって実装されたOpenCLで廃止予定とマークされていますが、問題とは関係ありません。 – Lev