はじめに
OpenCL
を用いた演習をしていて,タイトルにある通り, エラーに悩まされていましたが,不意に解決しました.
使用教材はC#によるOpenCL並列プログラミングという本です.
環境
Visual Studio 2019
概要
入力された画像に対して, カーネルプログラムで書いたラプラシアンフィルタ
を適用するプログラムです.
以下のようなエラー文が出力されていました.
System.Runtime.InteropServices.COMException (0x8007007A): システム コールに渡されるデータ領域が小さすぎます。 (HRESULT からの例外: 0x8007007A)
本の通りにタイピングしたつもりだったのですが...
色々調べてみてもBufferの確保の話だとか,UTF-8関連の話だとか様々でした.
他にもコンソールアプリケーションとあまり関係なさそうなものまでヒットしてわけわかめでした.
コード
カーネルプログラムは以下のようになっていました.
__kernel void
clCode(__global const unsigned char in[],
__global unsigned char out[],
__const int width)
{
int yx[3][3]; // 二次元配列
size_t x=get_global_id(0);
size_t y=get_global_id(1);
int stride=4*width;
for(int dY=0; dY<3; dY++)
for(int dX=0; dX<3; dX++)
yx[dY][dX]=(y+dY)*stride+(x+dX)*4;
for(int rgb=0; rgb<3;rgb++)
{
int data=(int)(
-in[yx[0][0]+rgb] -in[yx[0][1]+rgb] -in[yx[0][2]+rgb]
-in[yx[1][0]+rgb] +in[yx[1][1]+rgb]*8 -in[yx[1][2]+rgb]
-in[yx[2][0]+rgb] -in[yx[2][1]+rgb] -in[yx[2][2]+rgb]
);
out[yx[1][1]+rgb]=convert_uchar_sat(data);
}
}
他のカーネルプログラムは問題なく実行できていたため,おそらくカーネルが悪いのだろうという結論になり5時間くらい長考していました...()
結論
5時間調べ物をしていてふとした瞬間に
「UTF-8? bufferのメモリ? コメントアウトいる?」
みたいな思考になり,// 二次元配列
を消してみました.
するとあら不思議.頑なに動かなかったプログラムが動くではないですか.
ちなみに英語でコメントした場合問題なく動いたので,どうやら'UTF-8'の日本語入力でコメントを打つとうまくいかないみたいです.
カーネルプログラムは以下のようになりました.
__kernel void
clCode(__global const unsigned char in[],
__global unsigned char out[],
__const int width)
{
int yx[3][3];
size_t x=get_global_id(0);
size_t y=get_global_id(1);
int stride=4*width;
for(int dY=0; dY<3; dY++)
for(int dX=0; dX<3; dX++)
yx[dY][dX]=(y+dY)*stride+(x+dX)*4;
for(int rgb=0; rgb<3;rgb++)
{
int data=(int)(
-in[yx[0][0]+rgb] -in[yx[0][1]+rgb] -in[yx[0][2]+rgb]
-in[yx[1][0]+rgb] +in[yx[1][1]+rgb]*8 -in[yx[1][2]+rgb]
-in[yx[2][0]+rgb] -in[yx[2][1]+rgb] -in[yx[2][2]+rgb]
);
out[yx[1][1]+rgb]=convert_uchar_sat(data);
}
}
コメントアウトが消えただけですね.
日本語の影響で使用するメモリサイズに対して確保したメモリの大きさが足りなくなったような感じなのですかね?
検証は重ねていませんが,カーネルプログラムでは日本語入力に気をつけようって話でした.
それでは