同时在不同的GPU上执行不同的内核

Nik*_*ike 2 opencl

基本上我有两个GPU,我想在每个GPU上执行一些内核.我不希望GPU在同一个内核上工作,每个人都做一部分(我不知道这是否可行),以防万一我甚至不想看到这种行为.

我只是想确保两个设备都在运行.我已经为它们创建了上下文和命令队列.但是我看到只有一个内核被执行,这意味着只使用了一个设备.这就是我做到的...

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);
Run Code Online (Sandbox Code Playgroud)

我会走正确的路吗?

mat*_*ias 7

这取决于你实际填充device数组的方式.如果您正确初始化它,创建context跨设备是正确的.

不幸的是,你对内核和命令队列有错误的想法.一个内核是由特定上下文程序创建的.甲队列在另一方面,使用具有特定设备通信.你想要做的是为每个设备而不是内核创建一个队列:

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

现在,您可以通过相应的命令队列将不同(或相同)内核排入不同设备:

clEnqueueNDRangeKernel(cmdQ[0], kernels[0], /* ... */);
clEnqueueNDRangeKernel(cmdQ[1], kernels[1], /* ... */);
Run Code Online (Sandbox Code Playgroud)

总结条款:

  • A cl_context是为特定的东西创建的,cl_platform_id就像是设备子集的容器,
  • a cl_program是为a cl_context及其相关设备创建和构建的
  • a cl_kernel是从a 中提取的,cl_program但只能在与程序上下文关联的设备上使用,
  • a cl_command_queue是为属于某个上下文的特定设备创建的,
  • 内存操作和内核调用在命令队列中排队并在相应的设备上执行.