2014/10/13

OpenCLについて理解する

OpenCLの書籍(OpenCL Programming Guide)とOpenCLの仕様書を読んで少しはOpenCLについてわかったので、メモを残しておきます。
詳しくは書籍または仕様書にて確認ください。

  • OpenCLはCPUとGPU,さらにはDSPなどをも並列計算のリソースとして活用できるようにするプラットフォーム
  • OpenCLはISO C99をベースにしたOpenCL C言語を使用
  • OpenCLはベンダーに依存しないオープンな規格
  • データ単位またはタスク単位での並列プログラミングモデルをサポート
  • 組み込みデバイス用のプラットフォームも提供

OpenCL プラットフォーム
OpenCLプラットフォームは一つ以上のOpenCLデバイスから構成されます。
OpenCLデバイスはひとつ以上のCompute Unitに分けられ、さらにCompute Unitは複数のProcessing Elementに分けられます。
実際の計算はProcessing Elementが行います。


OpenCLのプラットフォーム(OpenCL 仕様書より)
ホストPC上には複数のプラットフォーム(AMDのOpenCLランタイム、nVidiaのOpenCLランタイムなど)が同居できます。

OpenCLカーネルとOpenCLプログラム
OpenCLカーネルは、Processing Element上で実行可能なコードを持つオブジェクトです。
OpenCLプログラムは、OpenCLカーネルの集まりです。

ワークグループとワークアイテム
画像データなどを並列処理する場合、計算元のデータはいくつかのグループに分けられます。
一つのワークグループには一つ以上のワークアイテムが所属します。
ワークアイテム=Processing element、ワークグループ=Compute Unitとなります。

メモリの管理
ホスト(デスクトップPC,ノートPC、その他)にメモリが積まれているように、OpenCLデバイスにもメモリが積まれています。OpenCLデバイス上のメモリは、4つの使われ方をします。

  • グローバルメモリ  すべてのワークアイテムから読み書き可能なメモリ領域です。同期コマンドを使用しない限りは、メモリの一貫性は保証されません。
  • コンスタントメモリ グローバルメモリに置かれる読み取り専用の領域です。ここにはカーネルが実行するコードが置かれます。

  • ローカルメモリ 各ワークグループに割り当てられたメモリ領域です。同一ワークグループに所属するワークアイテムからは自由に読み書きできますが、他のワークグループからはアクセスすることができません。
  • プライベートメモリ 各ワークアイテムに割り当てられたメモリです。他のワークアイテムからはアクセスできません。
メモリ(OpenCL 仕様書より)

コマンドキュー
OpenCLはメモリの転送、プログラムの実行などのコマンドをキューに貯めこんで処理していくコマンドキュー方式で動作しています。プログラマが明示的に同期コマンドを発行しない場合は、前のコマンドが完了していなくても次のコマンドの実行が開始されます。


プログラムの実行方法(かなり大雑把)
  1. ホストプログラム上でOpenCLデバイスを検索します。
  2. OpenCLデバイスを選び、コンテキストを作成します。
  3. コンテキストを使ってOpenCL コマンドキュー、OpenCLカーネル、OpenCLプログラム、OpenCLメモリオブジェクトを作成します。
  4. コマンドキューにカーネル、メモリ、プログラムを放り込んでOpenCLデバイスに転送し、処理を実行させます。
  5. 終わったらホストプログラムから結果を読み込みます。

以上、OpenCLの簡単なメモでした。

OpenCLの環境を整える(Win7 64bit)

OpenCV 3.0 alphaをインストールし、サンプルプログラムを実行しようとしたところ、"opencl runtimeがありません"と言ったメッセージが出て実行できませんでした。

OpenCLは並列計算用のライブラリで、CPUやGPUを計算リソースとして使うことができます。
OpenCLはベンダーに依存しない言語仕様なので、AMDやInterl、nVidiaがそれぞれの製品用のOpenCLランタイムを提供しています。

私のPCにはPhenom II x6とRadeon HD 5450が積まれているので、AMDからOpenCL用のランタイム(AMD-APP-SDK-v2.9-1.599.381-GA-Full-windows-64.exe)をダウンロードしてインストールしました。
AMD App SDK

インストール後はOpenCVのサンプルプログラムも無事動くようになりました。

OpenCLについて調べてみると、Pythonからも使えるようになるpyopenclというライブラリがあることが分かりました。

というわけで早速インストールしてみます。

参考ページ:PyOpenCL

(インストール前に、各ベンダーから提供されているOpenCLのランタイムが動作することを確認してください。たいていはsampleフォルダなどにビルド済みのものがあると思います。)
  1. まずはpython 3.3の32bit版をインストールします。
  2. http://www.lfd.uci.edu/~gohlke/pythonlibs/ から以下のパッケージをダウンロードしてインストールします。pytonの各バージョン・各プラットフォーム用のパッケージがあるので、pythonのものとバージョンをあわせます(今回はpy3.3、32bit用)。
      • pillow
      • pytools
      • mako
      • numpy-MKL
      • pytools
      • pyopencl
インストール作業は以上で完了です。

pythonを起動し、pyopenclが動くか見てみましょう。

import pyopencl as cl
cl.create_some_context()


コンピュータに複数のOpenCLデバイスがある場合は、複数デバイスが表示され、どれかを選ぶようメッセージが出ます。

>>> cl.create_some_context()
Choose device(s):
[0]
[1]
Choice, comma-separated [0]:

エラーメッセージがでなければpythonからOpenCLを扱う準備が整ったことになります。