最終更新: mikk_ni3_92 2010年05月16日(日) 21:48:24履歴
現在地 >> メニュー >> OpenCL >> OpenCL編02
INDEX:OpenCL編01 <<OpenCL編02 >> OpenCL編03?
次:OpenCL編02_2、OpenCL編02_3
OpenCLのプログラミング手順は次の通り
コンテキストの作成には「clCreateContext()関数」を使う
【例】
■clCreateContext関数
OpenCLの「コンテキスト」は1つ以上作成する。
作成したコンテキストによって、
OpenCLで使うメモリやコマンドキュー、カーネル(GPUの関数)等を制御する。
「コマンドキュー」とはカーネル(GPU上の関数)の実行を制御するためのもの。
例えば
OpenCLではCPU側がこの「コマンドキュー」を作成しておいて、作成したコンテキストで使用する
「各種OpenCLのコマンド」をここに格納しておく仕組みになっている。
「コマンドキュー」は「clCreateCommandQueue()関数」で作成する
【例】
■clCreateCommandQueue関数
※propertiesについて
次:OpenCL編02_2
INDEX:OpenCL編01 <<OpenCL編02 >> OpenCL編03?
次:OpenCL編02_2、OpenCL編02_3
OpenCLでは
イメージとしては、
CPU側で「.clファイル」を読み込んでコンパイルして実行する
ような感じ。(※GLSLやCgのようなシェーダ的な感じ)
- 「○○.cpp」(CPU側)
- 「○○.cl」(GPU側)
イメージとしては、
CPU側で「.clファイル」を読み込んでコンパイルして実行する
ような感じ。(※GLSLやCgのようなシェーダ的な感じ)
OpenCLのプログラミング手順は次の通り
- プラットフォームID
- デバイスIDの取得
- コンテキストの作成
- コマンドキューの作成
- プログラムのセットアップ(「.clファイル」の読み込み、ビルド)
- カーネルの作成
- 各種セットアップ(デバイスメモリ確保、カーネルの引数設定など)
- カーネル(GPU側の関数)の実行
- 生成した各種オブジェクトの破棄
「clGetPlatformIDs()」を使えばプラットフォームIDを取得できる。
NVIDIA GPUでは「oclGetPlatformID()」が簡単(かも)。
【例】
NVIDIA GPUでは「oclGetPlatformID()」が簡単(かも)。
【例】
//--- プラットフォームIDの取得 ---// cl_platform_id cpPlatform = NULL;//プラットフォームID ciErrNum = oclGetPlatformID(&cpPlatform); if (ciErrNum != CL_SUCCESS) { std::cerr << "Can't Get PlatformID\n"; return -1; }▲デフォルトのプラットフォームIDは「0 (=GL_CUCCESS)」。
clGetDeviceIDs()関数を使う。
手順的には、デバイス数(GPUの数)を取得し → IDを取得する。
【例】
手順的には、デバイス数(GPUの数)を取得し → IDを取得する。
【例】
//--- デバイスの取得 ---// cl_uint ciDeviceCount = 0; //デバイス数 cl_device_id *cdDevices = NULL;//デバイスID //デバイス数取得 → デバイスID取得 ciErrNum = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, 0, NULL, &ciDeviceCount); //データ格納用メモリ確保 cdDevices = new cl_device_id[ciDeviceCount]; ciErrNum = clGetDeviceIDs(cpPlatform, CL_DEVICE_TYPE_GPU, ciDeviceCount, cdDevices, NULL); if (ciErrNum != CL_SUCCESS) { std::cerr << "Error @ Getting device Infomation\n"; return -1; } … … //不要になったら破棄 delete [] cdDevices;
コンテキストの作成には「clCreateContext()関数」を使う
【例】
cl_context cxGPUContext;//OpenCLコンテキスト用 … … cl_int ciErrNum = CL_SUCCESS; //エラーチェック用 //--- デバイス関係 ---// cl_uint ciDeviceCount = 0; //デバイス数 cl_device_id *cdDevices = NULL;//デバイスID … … //コンテキストの作成 cxGPUContext = clCreateContext(0, ciDeviceCount, cdDevices, NULL, NULL, &ciErrNum); if (ciErrNum != CL_SUCCESS) { std::cerr << "Can't Create OpenCL Context\n"; return -1; }
■clCreateContext関数
cl_context clCreateContext( cl_context_properties *properties, //プロパテティ → 「NULL」 でいい cl_uint num_devices, //デバイス数 const cl_device_id *devices, //デバイスID void *pfn_notify ( //コールバック関数が必要な時に使用 → とりあえず「NULL」でいい const char *errinfo, const void *private_info, size_t cb, void *user_data), void *user_data, //pfn_notifyに与えるデータ → 「NULL」でいい cl_int *errcode_ret //→エラーコードを拾う時に使う。「NULL」も可能 )
OpenCLの「コンテキスト」は1つ以上作成する。
作成したコンテキストによって、
OpenCLで使うメモリやコマンドキュー、カーネル(GPUの関数)等を制御する。
「コマンドキュー」とはカーネル(GPU上の関数)の実行を制御するためのもの。
例えば
- カーネルを実行する
- メモリデータを転送する(コピーなど)
- CPUとGPU上のメモリを対応付ける(アドレスの対応付け)
- 同期処理
OpenCLではCPU側がこの「コマンドキュー」を作成しておいて、作成したコンテキストで使用する
「各種OpenCLのコマンド」をここに格納しておく仕組みになっている。
「コマンドキュー」は「clCreateCommandQueue()関数」で作成する
【例】
cl_context cxGPUContext;//OpenCLコンテキスト用 cl_command_queue commandQueue;//コマンドキュー … … cl_int ciErrNum = CL_SUCCESS; //エラーチェック用 cl_device_id *cdDevices = NULL;//デバイスID … コンテキストの作成、デバイスIDの取得など … //コマンドキューの作成 commandQueue = clCreateCommandQueue(cxGPUContext, (*cdDevices), 0, &ciErrNum); if (ciErrNum != CL_SUCCESS) { std::cerr << " Error in clCreateCommandQueue call !!!\n"; return -1; }
■clCreateCommandQueue関数
cl_command_queue clCreateCommandQueue(cl_context context,//コンテキスト cl_device_id device,//デバイスID cl_command_queue_properties properties, //コマンドキューのプロパティ(今回は0にして無効化) cl_int *errcode_ret)//エラーコードを拾う時に使用(NULL可)
※propertiesについて
- CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
- CL_QUEUE_PROFILING_ENABLE
次:OpenCL編02_2