OpenCL カーネルは、制限付き (構造体にポインターがないなど) および拡張済み (float4 データ型など) の C99 に似た言語で記述されています。それらは C++ で書かれていません。
ホスト上で C のような構造を初期化してから、それらをコピーします。C のような構造にはメソッドがありません。ホスト上で Visual Studio を使用して C++ OpenCL バインディング (cl.hpp から) を使用すると、次のようになります。
#pragma pack(16)
struct Light {
cl_float4 pos;
cl_float4 dir;
cl_float4 intensity;
cl_int type;
cl_int pad[3];
};
#pragma pack()
const int nlight = 10
Light lights[nlight];
//...code to initialize array of structs
cl::Buffer lights_mem = cl::Buffer(context, CL_MEM_COPY_HOST_PTR, sizeof(Light)*nlight, lights);
kernel1.setArg(0, lights_mem);
これにより、ライトが OpenCL デバイスにコピーされます。カーネルでは、次のようにライトの構造体にアクセスできます。
__kernel void trace(__global Light* lights, ...) {
float4 pos = lights[0].pos
//find a new position (pos_new)
lights[0].pos = pos_new;
カーネルが終了したら、cl::Buffer lights_mem を次のカーネルに渡すことができます。
kernel2.setArg(0, lights_mem);
ただし、読み取り専用または書き込み専用のバッファーを使用すると速度が向上するため、カーネルを読み取り専用と書き込み専用に分けると役立つ場合があります。
pack() プラグマとパディングがまだ必要かどうかはわかりませんが、誰かがもう必要ないと言うたびに問題が発生するため、それらを使用し続けます。