OpenCL(pyopencl)まとめ
作成日時: | 2019年7月6日 |
更新日時: | 2020年7月30日 |
AIを開発するためには並列処理が必須と思いGPUで並列処理できないだろうか、ライブラリはないだろうかと調べていたところ、OpenCLという単語を頻繁に見かけたので、これかなと思って調べてみた。
ただし、まだOpenCLでGPUを使った並列処理ができるかどうかは分からない。
おいおい調べてこのブログにまとめるつもり。
※このブログは自分用まとめですがなるべく他の人が分かるように書きます。
マルチコアCPUやGPU、Cellプロセッサ、DSPなどによる異種混在の計算資源(ヘテロジニアス環境、ヘテロジニアス・コンピューティング、英: Heterogeneous)を利用した並列コンピューティングのためのクロスプラットフォームなフレームワークである。
並列コンピューティング=並列処理
GPU、並列コンピューティングとあるので、これを使えば目的を達せられるだろうと自分は考えた。
なんとなく簡単そうなので、pythonからOpenCLを使おうと思った。
PyOpenCLというOpenCLをPythonから使うためのライブラリがあることを知った。
しかし、この本、OpenCLの経験者を対象にしているためかあんまり自分と相性が良くない。自分OpenCL未経験なので・・・
GPUはどんな処理を並列処理で高速化できるか、OpenCLの用語の説明も、もっと概念的な役割みたいな説明が欲しかった。
以下の説明は上のブログの説明の引用を含む。
ホスト … OpenCL APIを呼び出し計算を指示する方。PyOpenCLではopenclの機能を使うpythonコードそのもの。
デバイス … 実際に計算を行う装置
コマンドキュー … ホスト側からOpenCLを通じてデバイス操作(計算を実行する、メモリ操作をする、同期を取る)を行う指示コマンド
カーネル … OpenCLでは、C言語でいうところの関数のような処理単位をカーネル(kernel)と表現します。
しかし、カーネルは並列で実行される前提であり、特定の計算の一部分のみを計算するように記述すべきでしょう。
これはデバイスで並列処理を行う為です。pyopenclを使う場合、ホスト側のpythonと異なりカーネルのコードはOpenCL C言語で書かれる。
コンテキスト … 英語の意味は文脈、話の流れ。各演算装置の使用状況を把握するオブジェクト。
ここまで色々調べたが、GPUはどんな処理を高速化できるのかなどはまだ分からない。
もうちょっと使ってみたり調べたりしてみる。
これの謎が解けないとカーネルコードを読むときにいつも?なので、簡単に解説する。
例えば
#python
for (int i=0; i<100; i++) {
out[i] = i;
}
#python_end
というコードのforを並列化するとき、カーネルコードは
の部分を書くことになる。この時のiはまさにget_global_id(0)で取れる。
つまり並列化したforのどのインデックスについて操作しているかを取得する関数だったのだ。
以下の説明はファイル冒頭でimport numpy as npされていると仮定する。
shapeは作る配列の形状。タプルで指定する。
dtypeはデータ型。
orderはよく分からないが普通は省略される。
ただし、まだOpenCLでGPUを使った並列処理ができるかどうかは分からない。
おいおい調べてこのブログにまとめるつもり。
※このブログは自分用まとめですがなるべく他の人が分かるように書きます。
そもそもOpenCLって何?
(Wikipediaより)マルチコアCPUやGPU、Cellプロセッサ、DSPなどによる異種混在の計算資源(ヘテロジニアス環境、ヘテロジニアス・コンピューティング、英: Heterogeneous)を利用した並列コンピューティングのためのクロスプラットフォームなフレームワークである。
並列コンピューティング=並列処理
GPU、並列コンピューティングとあるので、これを使えば目的を達せられるだろうと自分は考えた。
「Pythonで始めるOpenCL」という本を買った
なんとなく簡単そうなので、pythonからOpenCLを使おうと思った。
PyOpenCLというOpenCLをPythonから使うためのライブラリがあることを知った。
しかし、この本、OpenCLの経験者を対象にしているためかあんまり自分と相性が良くない。自分OpenCL未経験なので・・・
GPUはどんな処理を並列処理で高速化できるか、OpenCLの用語の説明も、もっと概念的な役割みたいな説明が欲しかった。
OpenCL用語解説
このブログの方が本より詳しい用語解説をしてくれている。以下の説明は上のブログの説明の引用を含む。
ホスト … OpenCL APIを呼び出し計算を指示する方。PyOpenCLではopenclの機能を使うpythonコードそのもの。
デバイス … 実際に計算を行う装置
コマンドキュー … ホスト側からOpenCLを通じてデバイス操作(計算を実行する、メモリ操作をする、同期を取る)を行う指示コマンド
カーネル … OpenCLでは、C言語でいうところの関数のような処理単位をカーネル(kernel)と表現します。
しかし、カーネルは並列で実行される前提であり、特定の計算の一部分のみを計算するように記述すべきでしょう。
これはデバイスで並列処理を行う為です。pyopenclを使う場合、ホスト側のpythonと異なりカーネルのコードはOpenCL C言語で書かれる。
コンテキスト … 英語の意味は文脈、話の流れ。各演算装置の使用状況を把握するオブジェクト。
ここまで色々調べたが、GPUはどんな処理を高速化できるのかなどはまだ分からない。
もうちょっと使ってみたり調べたりしてみる。
OpenCLのget_global_id(0)とは
Pythonで始めるOpenCLという本には著者の考えで一番最後に書かれていて、なんだろうと思っていた。これの謎が解けないとカーネルコードを読むときにいつも?なので、簡単に解説する。
例えば
#python
for (int i=0; i<100; i++) {
out[i] = i;
}
#python_end
というコードのforを並列化するとき、カーネルコードは
out[i] = i
の部分を書くことになる。この時のiはまさにget_global_id(0)で取れる。
つまり並列化したforのどのインデックスについて操作しているかを取得する関数だったのだ。
numpy簡単まとめ
pyopenclとnumpyは切っても切り離せない関係なので、よく出てくる関数を紹介しておく。以下の説明はファイル冒頭でimport numpy as npされていると仮定する。
np.empty(shape, dtype = float, order = 'C')
shapeは作る配列の形状。タプルで指定する。
dtypeはデータ型。
orderはよく分からないが普通は省略される。