#経緯
並列処理に関心があり、その入門として、慣れ親しんだC言語で扱える並列処理フレームワークの1つであるOpenCLを触っていましす。書籍を読みながらOpenCLの処理の流れを学んでいる中で、書籍に載っているC言語プログラムの1つをコンパイルして実行すると、
$ gcc -o taskParallel taskParallel.c -framework opencl
$ ./taskParallel
0.00 -2.00 0.00 -2.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00
$ ./taskParallel
0.00 8589934592.00 0.00 8589934592.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00
このように出力の値が乱れてしまいました。(なにこれ怖いんですけど…)
正常に実行できた場合の出力は以下の通りです。
$ ./taskParallel
2.00 -4.00 33.00 0.25
6.00 0.00 77.00 0.50
10.00 4.00 121.00 0.75
14.00 8.00 165.00 1.00
##実行環境
MacBook Air (13-inch, Early 2015)
プロセッサ名: Intel Core i5
プロセッサ速度: 1.6 GHz
コアの総数: 2
メモリ: 8 GB
#retをprintfしてデバッグしてみると…
今回読んでいる本にははっきりとは載ってない方法ですが、エラーコードを返すcl_int
型の変数ret
をprintfしてデバッグしてみると、
command_queue = clCreateCommandQueue(context, device_id, CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE, &ret);
printf("ret = %d\n", ret);//-30
このように、ret
に-30が。OpenCLのヘッダファイルの1つであるcl.h
をのぞいてみると、どうやらCL_INVALID_VALUE
というエラーだそうですね。「プロパティ(コマンドキュー内のコマンドを、アウトオブオーダー実行させるためのプロパティCL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
)の値が有効じゃないよ」と言いたいらしい。
ちなみに、このcommand_queue
を引数に持つ関数では、ret
に-36(CL_INVALID_COMMAND_QUEUE
)が返ってくる。「コマンドキューが有効じゃないよ」と言いたいらしい。そりゃ出力の値が狂いまくるわけですね。
##結論
:clCreateCommandQueue
の第3引数を0にすれば正常に実行できる。
##どうしてできないのか気になる
渡しているプロパティの名称は正しいのになんで「有効じゃない」と言われるのでしょうか?確かに、結果が出せればいいなら、そうすればいいのだろうけど、「なんで動かんねん」ということが頭に残るわけです。
#解決するためのヒントを探す
Google先生に「CL_INVALID_VALUE」「CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE」と打ち込むと、OpenCLのドキュメントサイトの他に、以下のサイトが出てきました。
https://stackoverflow.com/questions/16821293/opencl-command-queue-cl-queue-out-of-order-exec-mode-enable-not-working-macos
アウトオブオーダー実行をサポートしている実行環境が少ない、という意見が見られますね。
どうやらデバイス等の実行環境で対応しているプロパティが変わってくる模様。(当たり前だ、という人もいるでしょうが、初心者なので多めにみてください)
##デバイス情報を見てみる
http://tkokamo.hateblo.jp/entry/2019/04/06/132534
こちらの記事を参考にして、OpenCLのデバイス情報取得をば。(コード自体はNvidiaの方が作成されたC++のコードっぽいですね)
CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
に対応していれば、
CL_DEVICE_QUEUE_PROPERTIES: CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
と表示されるみたい。実際に、このプログラムを実行してみると、
$ ./clDeviceQuery
clDeviceQuery Starting...
1 OpenCL Platforms found
CL_PLATFORM_NAME: Apple
CL_PLATFORM_VERSION: OpenCL 1.2 (Oct 25 2019 05:16:10)
OpenCL Device Info:
2 devices found supporting OpenCL on: Apple
----------------------------------
Device Intel(R) Core(TM) i5-5250U CPU @ 1.60GHz
---------------------------------
CL_DEVICE_NAME: Intel(R) Core(TM) i5-5250U CPU @ 1.60GHz
CL_DEVICE_VENDOR: Intel
CL_DRIVER_VERSION: 1.1
CL_DEVICE_TYPE: CL_DEVICE_TYPE_CPU
CL_DEVICE_MAX_COMPUTE_UNITS: 4
CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: 3
CL_DEVICE_MAX_WORK_ITEM_SIZES: 1024 / 1 / 1
CL_DEVICE_MAX_WORK_GROUP_SIZE: 1024
CL_DEVICE_MAX_CLOCK_FREQUENCY: 1600 MHz
CL_DEVICE_ADDRESS_BITS: 64
CL_DEVICE_MAX_MEM_ALLOC_SIZE: 2048 MByte
CL_DEVICE_GLOBAL_MEM_SIZE: 8192 MByte
CL_DEVICE_ERROR_CORRECTION_SUPPORT: no
CL_DEVICE_LOCAL_MEM_TYPE: global
CL_DEVICE_LOCAL_MEM_SIZE: 32 KByte
CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: 64 KByte
CL_DEVICE_QUEUE_PROPERTIES: CL_QUEUE_PROFILING_ENABLE
CL_DEVICE_IMAGE_SUPPORT: 1
CL_DEVICE_MAX_READ_IMAGE_ARGS: 128
CL_DEVICE_MAX_WRITE_IMAGE_ARGS: 8
CL_DEVICE_IMAGE <dim> 2D_MAX_WIDTH 8192
2D_MAX_HEIGHT 8192
3D_MAX_WIDTH 2048
3D_MAX_HEIGHT 2048
3D_MAX_DEPTH 2048
CL_DEVICE_PREFERRED_VECTOR_WIDTH_<t> CHAR 16, SHORT 8, INT 4, FLOAT 2, DOUBLE 4
----------------------------------
Device Intel(R) Iris(TM) Graphics 6100
---------------------------------
CL_DEVICE_NAME: Intel(R) Iris(TM) Graphics 6100
CL_DEVICE_VENDOR: Intel Inc.
CL_DRIVER_VERSION: 1.2(Dec 1 2019 20:38:22)
CL_DEVICE_TYPE: CL_DEVICE_TYPE_GPU
CL_DEVICE_MAX_COMPUTE_UNITS: 48
CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: 3
CL_DEVICE_MAX_WORK_ITEM_SIZES: 256 / 256 / 256
CL_DEVICE_MAX_WORK_GROUP_SIZE: 256
CL_DEVICE_MAX_CLOCK_FREQUENCY: 950 MHz
CL_DEVICE_ADDRESS_BITS: 64
CL_DEVICE_MAX_MEM_ALLOC_SIZE: 384 MByte
CL_DEVICE_GLOBAL_MEM_SIZE: 1536 MByte
CL_DEVICE_ERROR_CORRECTION_SUPPORT: no
CL_DEVICE_LOCAL_MEM_TYPE: local
CL_DEVICE_LOCAL_MEM_SIZE: 64 KByte
CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: 64 KByte
CL_DEVICE_QUEUE_PROPERTIES: CL_QUEUE_PROFILING_ENABLE
CL_DEVICE_IMAGE_SUPPORT: 1
CL_DEVICE_MAX_READ_IMAGE_ARGS: 128
CL_DEVICE_MAX_WRITE_IMAGE_ARGS: 8
CL_DEVICE_IMAGE <dim> 2D_MAX_WIDTH 16384
2D_MAX_HEIGHT 16384
3D_MAX_WIDTH 2048
3D_MAX_HEIGHT 2048
3D_MAX_DEPTH 2048
CL_DEVICE_PREFERRED_VECTOR_WIDTH_<t> CHAR 1, SHORT 1, INT 1, FLOAT 1, DOUBLE 1
clDeviceQuery, Platform Name = Apple, Platform Version = OpenCL 1.2 (Oct 25 2019 05:16:10), NumDevs = 2, Device = Intel(R) Core(TM) i5-5250U CPU @ 1.60GHz, Device = Intel(R) Iris(TM) Graphics 6100
System Info:
Local Time/Date = 15:51:23, 01/27/2020
^C
このように詳細情報が得られます。
どうやらこのMacBook AirはCL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
プロパティに対応していないようですね。残念。
(最後のところで進まなくなりましたが、欲しい情報は得られたのでヨシ!)
#考察
アウトオブオーダー実行ができなかったのは、デバイスが対応していないから、と考えられる。
#感想
-どのような環境であればアウトオブオーダー実行ができる(CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
プロパティが使える)のか気になった。
-どうしてデバイス情報を取得するプログラムが最後まで実行されなかったのか気になった。(C++の勉強不足でよくわかってない)
-Qiitaの記事を書くのは初めてだったけど、書き方はこんな風で良かったのかな。
#参考文献
OpenCLの学習に用いている書籍です。最初に実行したプログラムはこちらの書籍に掲載されています。
[改訂新版 OpenCL入門 1.2対応 マルチコアCPU・GPUのための並列プログラミング]
https://book.impress.co.jp/books/3172