各バッファの長さがわかっていて、それらすべてが等しい場合。それでは、次のように書き直してはどうでしょうか。
ホスト側:
//Use one struct to organize the data
struct MyStruct{
cl_int values[10];
// ...
};
//Create one only cl::Buffer of N elements of type MyStruct
cl::Buffer mybuff = cl::Buffer(context, CL_MEM_READ_ONLY, in_size * sizeof(MyStruct));
//Run the kernel
デバイス側:
//Use one struct to organize the data
typedef struct{
int values[10];
// ...
}MyStruct;
__global void pix_reduce
(MyStruct out*, MyStruct* in)
{
// ...
}
長さ「10」を X に定義し、その定義をコード (ホストおよび CPU 側) に入れることもできます。別の適切なオプションは、連続したメモリの 1 つの BIG 配列であり、分離の長さをカーネルに渡します。
注: ポインターの使用をやめるのが難しいことはわかっていますが、メモリ ゾーンが異なるため、その代償を払う必要があります。信じてください、私は非常に複雑な動的な長さの構造体を作成しましたが、少し考えて書き直すだけで機能し、コードは非常に整然としています。
編集:動的に変更できる別のソリューション
ホスト側:
//Data organized as jagged array
std::vector<std::vector<cl_int> > my_data;
//It is supposed to be filled my_Data
//....
//Create one only cl::Buffer of NxM elements of type int
cl::Buffer mybuff = cl::Buffer(context, CL_MEM_READ_ONLY, my_data.size() * my_data[0].size() * sizeof(cl_int));
cl::Buffer mybuff_out = cl::Buffer(context, CL_MEM_WRITE_ONLY, my_data.size() * my_data[0].size() * sizeof(cl_int));
// Copy the jagged array
for(int i=0; i<my_data.size(); i++)
queue.enqueueWriteBuffer(mybuff, CL_FALSE, i * my_data[0].size() * sizeof(cl_int), my_data[0].size() * sizeof(cl_int), &my_data[i][0]);
//Set kernel
kernel.SetArgs(0, mybuff);
kernel.SetArgs(1, mybuff_out);
kernel.SetArgs(2, (cl_int)my_data[0].size());
//Run the kernel
queue.EnqueueNDRangeKernel(...);
デバイス側:
__kernel void pix_reduce
(_global const int * in, _global int * out, const int size)
{
unsigned int id = get_global_id(0);
for(int i=0; i<size; i++){
out[id*size+i] = out[id*size+i]; //Or any other operation using size as the separation between chunks
}
}