基本上我有两个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)
我会走正确的路吗?
这取决于你实际填充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)
总结条款:
cl_context是为特定的东西创建的,cl_platform_id就像是设备子集的容器,cl_program是为a cl_context及其相关设备创建和构建的cl_kernel是从a 中提取的,cl_program但只能在与程序上下文关联的设备上使用,cl_command_queue是为属于某个上下文的特定设备创建的,