2

基本的に、2 つの GPU があり、それぞれでいくつかのカーネルを実行したいと考えています。GPUが同じカーネルで動作し、それぞれがその一部を実行することを望んでいません(これが可能かどうかはわかりません)。念のため、その動作を見たくありません。

両方のデバイスが実行されていることを確認したいだけです。両方のコンテキストとコマンド キューを作成しました。しかし、実行されるカーネルは 1 つだけです。これは、1 つのデバイスしか使用されていないことを意味します。これが私がやった方法です。. .

cl_device_id *device;
cl_kernel *kernels;
...
// creating context.  
context = clCreateContext(0, num_devices, device, NULL, NULL, &error);
...
// creating command queues for all kernels
for(int i = 0; i<num_kenrels; i++)
    cmdQ[i] = clCreateCommandQueue(context, *device, 0, &error);
...
// enqueue kernels 
error = clEnqueueNDRangeKernel(*cmdQ, *kernels, 2, 0, glbsize, 0, 0, NULL, NULL);

私は正しい道を進んでいますか?

4

1 に答える 1

7

実際にdevice配列をどのように埋めたかによって異なります。正しく初期化した場合context、デバイスのスパニングを作成することは正しいです。

残念ながら、あなたはカーネルとコマンド キューについて間違った考えを持っています。カーネルは、特定のコンテキストのプログラムから作成されます。一方、キューは特定のデバイスとの通信に使用されます。やりたいことは、カーネルではなくデバイスごとに 1 つのキューを作成することです。

for (int i = 0; i < num_devices; i++)
    cmdQ[i] = clCreateCommandQueue(context, device[i], 0, &error);

これで、対応するコマンド キューを介して、異なるデバイス上の異なる (または同じ) カーネルをキューに入れることができます。

clEnqueueNDRangeKernel(cmdQ[0], kernels[0], /* ... */);
clEnqueueNDRangeKernel(cmdQ[1], kernels[1], /* ... */);

条件を要約するには:

  • cl_contextは特定のデバイス用に作成され、デバイスcl_platform_idのサブセットのコンテナのようなものです。
  • は、および関連するデバイスcl_program用に作成および構築されます。cl_context
  • acl_kernelは a から抽出cl_programされますが、プログラムのコンテキストに関連付けられたデバイスでのみ使用できます。
  • acl_command_queueは、特定のコンテキストに属する特定のデバイス用に作成されます。
  • メモリ操作とカーネル呼び出しはコマンド キューに入れられ、対応するデバイスで実行されます。
于 2012-07-25T20:39:05.763 に答える