0

こんにちは、この構造体のような openCL オブジェクトを作成できるかどうか疑問に思っていました

struct Product
{

    int n_id;
    char n_name;

    Item(id, name){n_id = id; n_name = name;}
} item;

この情報をカーネルに渡して、構造体を別の構造体から再利用できるようにしたいと考えていました。

カーネル経由でアイテムを追加したい

kernel addItem(int name, char name)
{
    Item it(id,name);
    Items.add(it);
}

私の質問は、この情報を渡す方法と、作成したオブジェクトを別のカーネルから再利用可能にする方法です。

乾杯

4

1 に答える 1

2

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() プラグマとパディングがまだ必要かどうかはわかりませんが、誰かがもう必要ないと言うたびに問題が発生するため、それらを使用し続けます。

于 2013-03-22T07:45:54.317 に答える