コンソール・アプリケーションの雛型
OpenCL C++ Bindingsを使ったホスト側コードが必要とするヘッダは
#include <CL/cl.hpp>
これだけです。が、vectorとstringを使っていますから、CL/cl.hppの#includeに先立って、
#include <vector> #include <string>
が必要となりますが、__NO_STD_VECTOR, __NO_STD_STRING を#defineしておけばstd::vector,std::stringの簡略版であるcl::vector, cl::stringが使われます。また、__CL_ENABLE_EXCEPTIONSを#defineしておくと各APIのエラー時にcl::Errorがthrowされます。
そんなわけでコンソール・アプリケーションの雛型は、
#include <vector> // または #define __NO_STD_VECTOR
#include <string> // または #define __NO_STD_STRING
#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
// その他必要なヘッダの#include...
int main() try {
...
} catch ( const cl::Error& ex ) {
...
}
となりますか。
それではOpenCL C++ Bindingsに登場するクラスとサンプルコードを順を追って説明しましょう。
Platoform, Context, Device
OpenCLは複数かつ各種の計算デバイスをひとつのホストから利用するヘテロジニアスな形態をサポートします。そのため、複数のデバイスおよびそれぞれのデバイスに対応した複数のPlatform(プラットフォーム)が共存することになります。利用可能なPlatformを列挙します:
// Platformを列挙する vector<cl::Platoform> platforms; cl::Platform::get(&platforms); assert( !platforms.empty() ); // 最初のPlatform cl::Platform platform = platforms[0];
僕の環境で利用可能なPlatformはATI Stream がサポートするものひとつだけなので platforms.size() == 1 となります。
得られたPlatformからContext(コンテキスト)を作ります。Contextは計算デバイスを利用する環境を司り、後述するDevice,CommandQueue,Program等の生成に関与します。
// Contextを生成
cl_context_properties props[] = {
CL_CONTEXT_PLATFORM,
reinterpret_cast<cl_context_properties>(platform()),
0 };
cl::Context context(CL_DEVICE_TYPE_GPU, props);
ContextがサポートするDevice(デバイス)を手に入れておきましょう。
// デバイスを入手 vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>(); assert( !devices.empty() ); cl::Device device = devices[0];
CommandQueue
一般にホストはDeviceの持つリソース、たとえばビデオ・カード内のGPUやメモリに直接アクセスする手段を持たず、ビデオ・カードに対応したドライバを介して制御します。このときホストとデバイス間の仲介を行うのがCommandQueue(コマンド・キュー)です。Deviceへの命令やDevice上のメモリの読み書きなど、すべてCommandQueueを介して行います。
// CommandQueueの生成 cl::CommandQueue queue(context,device);
