6

Cで次の構造体「データ」を作成しました

typedef struct data
{
  double *dattr;                           
  int d_id;                                
  int bestCent;                            
}Data;

'dattr'は、動的に保たれる上記の構造の配列です。上記の構造のオブジェクトを10個作成する必要があるとします。すなわち

dataNode = (Data *)malloc (sizeof(Data) * 10);

そして、この構造のすべてのオブジェクトについて、次を使用して配列'dattr'用にCのメモリを再割り当てする必要があります。

for(i=0; i<10; i++)
   dataNode[i].dattr = (double *)malloc(sizeof(double) * 3);

OpenCLで同じものを実装するにはどうすればよいですか?構造体オブジェクトにメモリを割り当てたら、配列'dattr'にメモリを割り当てるにはどうすればよいですか?

4

2 に答える 2

6

OpenCLデバイス(GPUなど)でのメモリ割り当ては、clCreateBuffer(またはテクスチャメモリを使用する場合はclCreateImage2D / 3D )を使用してホストスレッドで実行する必要があります。これらの関数を使用すると、ホストデータ(たとえばmallocで作成)をデバイスに自動的にコピーできますが、データ転送のプロファイルを作成できるように、通常はclEnqueueWriteBuffer / clEnqueueMapBuffer(またはテクスチャメモリを使用している場合はclEnqueueWriteImage / clEnqueueMapImage )を明示的に使用することを好みます。次に例を示します。

#define DATA_SIZE 1000

typedef struct data {
    cl_uint id;
    cl_uint x;
    cl_uint y;
} Data;

...

// Allocate data array in host
size_t dataSizeInBytes = DATA_SIZE * sizeof(Data);
DATA * dataArrayHost = (DATA *) malloc(dataSizeInBytes);

// Initialize data
...

// Create data array in device
cl_mem dataArrayDevice = clCreateBuffer(context, CL_MEM_READ_ONLY, dataSizeInBytes, NULL, &status );

// Copy data array to device
status = clEnqueueWriteBuffer(queue, dataArrayDevice, CL_TRUE, 0, dataSizeInBytes, &dataArrayHost, 0, NULL, NULL );

// Make sure to pass dataArrayDevice as kernel parameter
// Run kernel
...

考慮する必要があるのは、OpenCLカーネルを実行する前に、OpenCLカーネルのメモリ要件を知る必要があるということです。そのため、カーネルの実行前(つまりホスト内)に実行された場合、メモリ割り当ては動的になる可能性があります。カーネルを何度も呼び出し、そのたびにカーネルのメモリ要件を調整(割り当て)することを妨げるものは何もありません。

これを考慮して、問題への取り組み方を再考することをお勧めします。まず、配列の構造よりも構造の配列を操作する方が簡単です(ただし、必ずしも効率的である必要はありません)(この場合、配列のサイズは固定されている必要があります)。

これは、OpenCLがどのように機能するかを理解するためのものです。Khronos OpenCLリソースページをご覧ください。OpenCLのチュートリアルと例がたくさんあり、Khronos OpenCLページには、公式のOpenCLリファレンス、manページ、クイックリファレンスカードがあります。

于 2013-01-11T01:45:28.443 に答える
2

動的メモリ割り当てに関心があり、アルゴリズムを少し変更したい場合にFakenが提案したように、ここにいくつかのヒントがあります。

次のコードは、ローカルメモリスペースを動的に割り当て、それを8番目の引数としてOpenCLカーネルに渡します。

  int N; //Number_of_data_points, which will keep on changing as per your requirement  
   size_t localMemSize = ( N* sizeof(int));      
 ...   
 // Dynamically allocate local memory (allocated per workgroup)
 clSetKernelArg(kernel, 8, localMemSize, NULL);
于 2013-01-11T11:49:31.873 に答える