LoginSignup
2
1

More than 3 years have passed since last update.

OpenCLでアウトオブオーダー実行しようとしたらCL_INVALID_VALUEが返ってきた

Posted at

経緯

並列処理に関心があり、その入門として、慣れ親しんだ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

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1