技術

clCreateImageがおかしい

CUDAで作ったあれをOpenCLに移植した。
作業はMacで行った。

移植した最初のバージョンは、CUDAのときより2倍以上遅かった。
CUDAの場合は、参照するだけのデータはテクスチャリファレンスを使うようにしてたけど、OpenCL版では読み取り専用に設定したグローバルメモリを使ったせいだと思う。
新しくないGPUだから、できるだけテクスチャアクセスにしないとキャッシュが効かないのだ。

この差を解消するために、CUDAで言うところのテクスチャリファレンスに相当すると思われるImage2Dを使うようにしようと思ったけど、どうもclCreateImageの動きがおかしい。
特におかしなflagは渡してないのに、CL_INVALID_VALUEエラーが発生する。
width, heightを128とか小さめにしたらエラーが出ない。
CL_DEVICE_IMAGE2D_MAX_WIDTH, CL_DEVICE_IMAGE2D_MAX_HEIGHTはそれぞれ4096になってるのに。

具体的には以下のような引数で実行している。(C++ Wrapperを使っている)

cl::Image2D hoge(ctx, CL_MEM_READ_ONLY, cl::ImageFormat(CL_RGBA, CL_UNORM_INT8), 1024, 1024);

これをWrapperを通さずに直接clCreateImageをしても同じ。
しかしOpenCL 1.2ではdepricatedになってるclCreateImage2Dを使うと大丈夫っぽい。
大丈夫というのは、ホストコードでエラーが出ないってだけで、カーネルから正しく読めるかは確認してない。
正しく読めたとしても、こんな微妙な環境では後で痛い目にあいそうだからやりたくない。

あとデバイス側はOpenCL C 1.0どまりなんだけど、1.0で対応してないはずのimage1d_tをカーネルの中で使ってもコンパイルやビルドでエラーにならならずに実行出来てしまう。
でも実際は正しい値は読み取れないので正しい結果にはならない。(アラインメントがズレてる感じ)
エラーにならずに中途半端に実行出来てしまうのはヤバいと思う。
コンパイルやビルド段階ではエラーにならなくても、最低限カーネルの実行時にはエラーになってほしい。

色々調べてる中で思ったんだけど、OpenCLって環境依存・バージョン依存の問題が多い印象がある。
CUDAのほうはNVIDIA以外の環境を切り捨ててるので環境依存の問題は少なくて当たり前なんだけど、それにしてもOpenCLは。という感じ。
しかも本格利用してるユーザーがそんなに多くないうえに、環境やバージョンで情報が散り散りになってしまってて、調べるのがめんどくさい感じ。
Khronosのサイトはリファレンスとしては十分だけど、微妙な問題が起きたときは一般的にリファレンスは役にたたないわけで、そういうときはユーザの多さと情報のまとまり具合が大事だと思う。

Mac(Geforce 9400M)+CUDAが不安定だから、一端UbuntuでCUDAやろうと思って、でもMac(Geforce 9400M)+OpenCLが安定してるならそっちのほうがいいなぁと思ってまた戻ってきてたんだけど、これではちょっときびしい。
MacでGPGPU(Open”G”Lを利用したものを除く)をやろうってのがあまり良い選択肢ではないのかもしれない。
新しいマシンならそうでもないのかもしれないけど。

Mac(Geforce 9400M)+CUDAについては、不安定といってもたまにcuInitに失敗したりメモリが確保出来なかったりするだけで、そういう場合はきちんとエラーになるし、実行出来たときは中途半端な結果にはならなかったので、今回のOpenCLの場合より精神衛生上まだマシだった。
新しいGPUドライバを用意出来る環境なら、安定して動くだろうという思いもあったし。
実際、新しいGPUドライバを用意してUbuntuで構築した環境(自作機)では安定している。が、この環境ならOpenCLの方も安定するのかもしれない。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です



※画像をクリックして別の画像を表示

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください