Python OpenCL入門: PythonでGPGPUの世界へ
価格: ¥0
本書が想定する読者は、C/C++で半年程度の開発経験(学校、職場問わず)のあるPython開発者です。
numpyについても数ヶ月以上の使用経験があることを想定します。
※誤植、改善点、追加内容等がある場合は随時更新していきます。Amazonの「コンテンツと端末の管理」ページで本の自動更新機能を有効にしてください。5月24日更新、誤植・表現等の改善を行う予定です。
目的
OpenCLのPythonバインディングライブラリ、PyOpenCL(Python OpenCL)を紹介します。
構成
第一部:PyOpenCLの紹介
PyOpenCLにはOpenCLを忠実にバインディングしたランタイムAPIと、numpyに類似した配列/数値計算/アルゴリズムライブラリの2つが存在します。この第一部は後者の紹介をしますが、高速な並列処理計算をしたい読者は第一部をとばして第二部から読むことを推奨します。筆者が検証した限り、PyOpenCLの配列/数値計算/アルゴリズムライブラリはPyOpenCLランタイムライブラリで実装したアルゴリズムに比べて著しく遅いため読者にとって有用ではないと考えます。第一部は参考目的としてお読みください。
第二部:OpenCLアーキテクチャ
OpenCLのアーキテクチャを、ソフトウェアとハードウェアの両面から解説します。
第三部:PyOpenCLランタイム
PyOpenCLのランタイムライブラリとOpenCL-C言語について解説します。
第四部:FFT、BitonicSort、RadixSort等
内容
Pythonを用いてOpenCLの基本的な概念及び基本API(JOCLとC99規格準拠のカーネルプログラミング言語)の解説をしますが、データ並列プログラミングで頻繁に使われるコードパターンも合わせて解説します。
解説する範囲は以下の4つのパターンです。
・還元パターン(Reduction、基数整列アルゴリズムを用いて解説)
・行列転置(Transposition、FFTアルゴリズムを用いて解説)
・バンクコンフリクト対策(ヒストグラム計算を用いて解説)
・ソーティングネットワーク(バイトニックアルゴリズムを用いて解説)
高速フーリエ変換は2次元アルゴリズムも含めた解説をしています。2次元に適用するため行列の転置も合わせて解説します。
※2次元画像の高域フィルターの実装例については「Java OpenCL入門」を参照ください。
GPGPUを使った基数整列(Radix Sort)は整列アルゴリズムの中でも最速とされており幅広く活用されているアルゴリズムです。Prefix-Sumの算出のために、Reductionパターンを解説します。
ヒストグラムの計算ではキャッシュ(SLM)を使うために、データ構造をスレッドセーフにするための設計手法を解説します。
バイトニック整列(Bitonic Sort)はRadix Sort程ではありませんが、GPUを使うことで高速整列を行えます。ソーティングネットワークの基本的なアルゴリズムを提示します。
OpenCL関数やコマンドのリファレンス(PyOpenCLではなくOpenCL 1.2)もありますので、開発時の参考として使用もできます。
必要知識と対象読者
本書の読者はC/C++でコーディングをしたことがあるPythonエンジニア(業務で使う主言語はCでなくともよい)と想定します。
原則として数学の知識は不要ですが、例外として高速フーリエ変換の章では工学部・理学部2〜3年次程度の数学知識を前提とします。ビット演算を頻繁に使うため、ビット演算の知識も必須です。
開発環境
(低価格またはゼロコストで)身近なIntelの内蔵GPUを使ってGPGPUを学べるようにするため、本書ではIntel Core I5の内蔵HD Graphicsを検証に使います。
IntelのCore i3, i5, i7に附属してくる内蔵iGPU(HD Graphics/Iris Pro)を使ったGPGPUのプログラミングを通じて、OpenCLに慣れて頂きます。
外付・内臓を含めたGPU製品でIntelは約7割の市場シェアを持ち、非サーバーCPUのほぼ全てにiGPUが付属しています。現行システムに外付GPU(dGPU)を導入できないPython開発者がIntelのiGPUの使用を検討するきっかけになるものと考えます。
OSは「Max OS X 10.11.4」を使います。
検証環境には以下2つのソフトウェアがインストールされているものとします。
* PyCharm Community Edition 2016
* Python 3.5
目次
I. 第一部: PyOpenCL
1. PyOpenCL
2. 検証環境
3. Python環境設定
4. OpenCL開発環境
5. APIとアーキテクチャ
5.1. プラットフォームAPI
5.2. ランタイムAPI
5.3. カーネルプログラミング言語
6. PyOpenCL
6.1. 基本実装
7. メモリーモデル
7.1. デバイスメモリへのコピー
7.1.1. デバイスメモリ複製のユーティリティ関数
8. Arrayクラス
8.1. Arrayクラス
8.1.1. Arrayの属性
8.1.2. Arrayのメソッド
8.2. Arrayファクトリー
8.3. PyOpenCLデータ型
8.3.1. スカラー型
8.3.2. ベクトル型
8.3.3. 複素数
9. 組み込み数値計算ライブラリ
9.1. pyopencl.clmathライブラリ
10. カスタムカーネル(組み込み)
11. MapReduceアルゴリズム
12. PrefixSumアルゴリズム
II. 第二部: OpenCLアーキテクチャ
III. 第三部: PyOpenCLランタイム
IV. 第四部: PyOpenCL実装
18. ヒストグラム
18.1. アルゴリズムのパラメータ
18.2. 共有ローカルメモリ
18.3. ストライドとメモリアクセス
18.4. ストライドとBank Conflict
18.5. Stride型のアルゴリズム
18.6. バンクコンフリクトの緩和対策の実装例
18.7. アトミック型のアルゴリズム
19. 高速フーリエ変換(Fast Fourier Transform)
19.1. 使用する数学のまとめ
19.2. フーリエ変換(Fourier Transform)の定義
19.3. 離散フーリエ変換(Discrete Fourier Transform)
19.4. 高速フーリエ変換(Fast Fourier Transform)
19.4.1. Cooley-Tukey型アルゴリズム
19.4.2. Bit Reversal
19.5. 実装例(CPU)
19.6. 実装例(GPU)
20. 2次元高速フーリエ変換
20.1. 実装例(GPGPU)
20.2. 2次元カーネルの実装
20.2.1. 全体の流れ
20.3. GPGPUへの修正点(メモリストライド・Bank Conflict対策)
21. Bitonic Sort(バイトニックソート)
21.1. バイトニック配列の構築
21.2. バイトニックマージ
21.3. バイトニックソートのOpenCL実装例
21.4. カーネルの実装(bitonic split)
21.5. カーネルの実装(bitonic merge)
22. 基数配列
22.1. ヒストグラム
22.2. Bucket Scan
22.3. Reduction(還元)
22.3.1. 結合性
22.3.2. 交換性
22.4. Prefix Sumへの適用
22.5. up-sweep(掃き上げ)
22.5.1. down-sweep(掃き下げ)
22.6. 並び替え(Rank)
22.7. 実装例(CPU)
22.8. 実装例(GPU)
付録
A. OpenCL対応デバイス一覧表
B. OpenCL 1.2 API Reference
C. OpenCLエラーコード