メインコンテンツに移動

OpenCLの使い方

  • 参考文献: AppleのOpenCLのページ ここが全て
  • 計算をするデバイスが,多次元に配列しているものとする.
  • 各デバイスで,あるOpenCL関数を実行する.
    • OpenCL関数では,自分がデバイス配列のどこであるか,を知ることができる.
    • そこで,通常 do-enddo の中に書いてある作業を行う関数を作成しておけば,デバイス配列がdoループを並列に行うことになる.
  • デバイスで実行するOpenCLプログラムと,普通のパソコンで実行するプログラム(ホストプログラム)は,全く別物である.
    • ホストプログラムは,普通に ic++ とかでコンパイルすればよい.
    • デバイスで実行するOpenCLプログラムは,「ホストプログラム」を実行したとき,そのパソコンが装備している「計算デバイス」にマッチするようにその場でコンパイルされ,実行される.(これをJust-in-Time(JIT)コンパイルと呼ぶそうだ)
      • 具体的には,ホストプログラムの文字列変数の中に,OpenCLプログラムを記入する:(■は改行を表すものとする)
              std::string prog="void vec_add(__global double *A,__global double *B){■int index=get_global_id(0);■A[index]=B[index];}";
              ↑ これがホストプログラムの文字変数 prog                  ↑こちらがOpenCL関数
        という感じである. もちろん,こんなことは並みの神経ではできない.そこで,例えば, デバイスで実行するプログラムのファイル名をハードコーディングしておき,実行時にそのファイルの内容を,文字列変数progに読み込むようにプログラムすることになる.
      • 上記のようにプログラムすると,「デバイスで実行するプログラム」のデバッグが困難である.なぜならば,「デバイスで実行するプログラム」のコンパイルエラーは,毎度,本物のプログラムを実行しなければならないためである.
      • この問題に対応するために,GPU対応マシンでは「OpenCLオフラインコンパイラ」がインストールされている.これは,Intel CPUを対象として, OpenCL関数が実行できるか,コンパイルするものである.
        • まずは, GPUマシンにsshでログインする:
               ssh pc3200e
        • OpenCL関数が kernel.cl ファイルに書いてあったとすると,
               ioc  -input=kernel.cl
          とコマンドを打てば,まるで普通のコンパイラのように,コンパイルを行いエラーを表示したりする.
  • デバイスのメモリーと,ホストパソコンのメモリーは,別物である.なぜならば,デバイスのメモリーはグラフィックカードに,パソコンのメモリーは,マザーボードに,はんだ付けされているからである.
    • それではプログラムが書けないので,OpenCLでは次の段取りでデータのやり取りを行う.