前回にOpenCLを使用してGPUを使用した並列計算を試してみたが、デバイスの取得やGPU側でのコードの準備、データの準備や転送など、実際の計算よりも前に行う処理が煩雑だった。また、この事前処理が毎回あまり変わらない処理を書く必要があった。そこで、C++クラスとしてラップし定型処理部分を隠蔽して、煩雑な部分をさよならしようと思ったわけだ。
その前にもう一度OpenCLの規格を決めているKhronos Groupを覗いてみると、あるじゃないかC++の公式Bindingsが、もうすでに。C++ Bindings Specification [PDF] OpenCL 1.1 C++ Bindings Header File(cl.hpp)
すでにあるなら、使った方がよいと言うことで、このC++ Bindingsを試してみることにした。計算を行うまでの処理の流れは前回記載しものと同じようになるので、順番に見ていこうと思う。
まずはプラットフォームを取得することから始める。
#define __CL_ENABLE_EXCEPTIONS #if defined(__APPLE__) || defined(__MACOSX) #include <OpenCL/cl.hpp> #else #include <CL/cl.hpp> #endif #include <iostream> int main(int argc, char* argv[]) { try{ std::vector platforms; cl::Platform::get(&platforms); if(platforms.size() == 0){ std::cout << "Any Platforms is NOT FOUNT." << std::endl; return 1; } std::cout << platforms.size() << std::endl; std::string param; platforms.at(0).getInfo(CL_PLATFORM_PROFILE, ¶m); std::cout << param << std::endl; }catch(cl::Error err){ std::cerr << "ERROR: " << err.what() << "(" << err.err() << ")" << std::endl; } return 0; }
まず先頭の「#define __CL_ENABLE_EXCEPTIONS」はC++例外を使用する場合に定義する必要がある。この定義があると、各OpenCLクラス内でエラーがあった場合、「cl::Error」クラスがthrowされる。
次にヘッダーファイルが"opencl.h"から"cl.hpp"に変わる。このヘッダー内で必要なOpenCLのヘッダーファイルを読み込んでいるので、他は特に必要ない。
ここまでで、とりあえずOpenCL C++ Bindingsを使用する準備は整った。
メイン関数の中身を見ていくことにする。OpenCLの例外を有効にしているので、処理部分は「try」で囲み、最後に例外クラスcl::Errorを捕捉している。
プラットフォームの取得はcl::Platformクラスのスタティックメンバ関数getを使用するが、取得したプラットフォームはvectorに格納される。このC++ Bindingsでは配列や文字列を基本的にvectorクラスやstringクラスを使用するようにしているようだ。
取得したプラットフォームの情報を確認する場合はメンバ関数のgetInfoが使用できる。第一引数は列挙型cl_platform_info、第二引数は取得した情報を格納する文字列クラスになる。列挙型cl_platform_infoの一覧はOpenCL 1.1 Specification [PDF]のTable 4.1に記載されている。C++ Bindings Specification [PDF] はOpenCL 1.1 Specification [PDF]の別紙扱いなのか、参照している部分が多い。
ひとまず、プラットフォームについてはここまでで、つぎはコンテキストの取得をしようと思う。
コメント