「OpenCLのC++ Bindingsを使ってみる - その1」、「OpenCLのC++ Bindingsを使ってみる - その2」に引き続き、今回はOpenCLの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[]) { cl_int error = CL_SUCCESS; try{ std::vector platforms; cl::Platform::get(&platforms); if(platforms.size() == 0){ std::cout << "Any Platforms is NOT FOUNT." << std::endl; return 1; } cl_context_properties properties[] = {CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0}; cl::Context context(CL_DEVICE_TYPE_GPU, properties); std::vector devices = context.getInfo(); char* addVector = { "__kernel void\n\ addVector(__global const float *input1,\n\ __global const float *input2,\n\ __global float *output)\n\ {\n\ int index = get_global_id(0);\n\ output[index] = sin(input1[index]) * sin(input2[index]);\n\ output[index] = cos(output[index]);\n\ output[index] = pow(output[index], output[index]);\n\ }\n"}; cl::Program::Sources source(1,std::make_pair(addVector, strlen(addVector))); cl::Program program = cl::Program(context, source); program.build(devices); cl::Kernel kernel(program, "addVector", &error); }catch(cl::Error err){ std::cerr << "ERROR: " << err.what() << "(" << err.err() << ")" << std::endl; } return 0; }
太字に下部分が今回追加したコードになる。
まず、プログラムにするソースである文字列addVectorを用意する。これは、「OpenCLで実際に計算してみる」で使用したものを流用した。この文字列addVectorからcl::Program::Source型のsourceを用意する。このcl::Program::SourceはC++ Bindings Specification [PDF] によると、
typedef VECTOR_CLASS<std::pair<const char*, ::size_t> > Sources
と定義されているようで、実態はソース文字列とサイズのペアのstd::vectorのようだ。つまり、要素数1、addVectorとaddVectorのサイズのペアのstd::vectorということになる。
次にこのソースからプログラムをビルドする必要がある。まずはコンテキストとソースからプログラムのインスタンスを生成する。
cl::Program program = cl::Program(context, source);
の部分がこれにあたる。続いて、
program.build(devices);
とし使用するデバイス向けにビルドする。
これで、カーネルを生成する準備が整ったので、
cl::Kernel kernel(program, "addVector", &error);
プログラムと名前とエラーコード保存用の変数からカーネルを生成している。メイン関数先頭でcl_int errorを用意しているのはここで使用するためである。
次回はメモリオブジェクトを用意しようと思う。
コメント