基本上我有两个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);
我的方法是否正确?
答案 0 :(得分:7)
这取决于您实际填充device
数组的方式。如果您正确初始化,则创建跨越设备的context
是正确的。
不幸的是,你对内核和命令队列有错误的想法。从特定上下文的程序创建内核。另一方面,队列用于与某个设备通信。你想要做的是为每个设备而不是内核创建一个队列:
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
cl_kernel
是从cl_program
中提取的,但只能用于与该程序相关联的设备上,cl_command_queue