0

私はOpenCLを使用したヘテロジニアス コンピューティングに従っていますが、ハングしたままです。

画像を float の配列として enqueueWriteBuffer に渡します。この場合、画像には色の値がないと思います。{0,0,0,1,0,2,1,0,1,1,1,2...} のように単純に {col,row,col,row,col,row} です。

しかし、彼らが enqueueReadBuffer を実行するとき、彼らが期待するサイズは H W であり、私が行ったように配列を実行する場合、配列のサイズは H W*2 になります。

// SETUP BUFFERS
Buffer d_ip = Buffer(context, CL_MEM_READ_ONLY, W*H*sizeof(float));
Buffer d_op = Buffer(context, CL_MEM_WRITE_ONLY, W*H*sizeof(float));
queue.enqueueWriteBuffer(d_ip, CL_TRUE, 0, W*H*sizeof(float), img); //img, what is img? the book just says it is my image.

// SETUP RANGES
NDRange globalws(W, H);
NDRange localws(16, 16);

// QUEUE AND READ
queue.enqueueNDRangeKernel(rotn_kernel, NullRange, globalws, localws);
queue.enqueueReadBuffer(d_op, CL_TRUE, 0, W*H*sizeof(float), img);

// X AND Y INSIDE THE KERNEL
const int x = get_global_id(0);
const int y = get_global_id(1);

すべての新しいピクセル座標がカーネルで計算される場合、適切なサイズの空の float 配列を渡すだけではいけません ( W H * 2ではないことはわかりませんが、明らかにW H です)。しかし、これを (500x300 の画像で) ハードコーディングしようとしたところ、スタックが爆発してしまいました。

4

2 に答える 2

1

OpenCL コードを記述するときは、データが 1D、2D、3D のいずれであるかに関係なく、常に各カーネルを 3D データ セットの読み取りとして扱います。

 __kernel void TestKernel(__global float *Data){
      k = get_global_id(0); //also z
      j = get_global_id(1); //also y
      i = get_global_id(2); //also x

      //Convert 3D to 1D
      int linear_coord = i + get_global_size(0)*j + get_global_size(0)*get_global_size(1)*k;

      //do stuff
 }

clEnqueueNDKernelRange(...) を実行するときは、ディメンションを次のように設定します。

 int X = 500;
 int Y = 300;
 int Z = 1;

 size_t GlobalDim = {Z, Y, X};

これにより、すべてのカーネルがすべての次元で簡単に機能します。

あなたのコードは何も呼び出していませんclSetKernelArg。これらを追加しましたか? OpenCL 関数でエラーが発生していますか? 一歩下がって、C++ クラスの代わりに OpenCL C コードを使用することをお勧めします。

于 2013-07-24T17:59:51.743 に答える
1

W*H*2おそらくあなたが思っているようにデータを保存していないので、サイズではありません。W通常、この性質のデータは、データの最初の行が最初のエントリに格納され、 2 番目の行が 2 番目のエントリに格納されるというように格納されますW。これは size の配列になりますW*HXしたがって、行、列の何かに関する情報をY取得するには、インデックスの要素を取得する必要があります(W * X) + Y

于 2013-07-24T17:50:39.037 に答える