据我现在所了解的,目前没有可靠的解决方案。如果您所有的工作都是在单个进程中完成的,您可以使用
clGetDeviceIDs
返回的条目顺序或
cl_device
值本身(实际上它们是指针),但是如果您尝试在进程之间共享这些标识符,则情况会变得更糟。
请参见该人的博客文章,其中说:
问题在于,如果您有两个相同的GPU,则无法区分它们。如果调用clGetDeviceIDs
,则返回它们的顺序实际上是未指定的,因此,如果第一个进程选择第一个设备,而第二个进程选择第二个设备,则它们都可能过度订阅同一GPU并使另一个GPU处于空闲状态。
然而,他指出nVidia和AMD提供了他们的自定义扩展,cl_amd_device_topology
和cl_nv_device_attribute_query
。您可以检查您的设备是否支持这些扩展,并像原作者的代码一样使用它们:
#include <CL/cl_ext.h>
cl_device_topology_amd topology;
status = clGetDeviceInfo (devices[i], CL_DEVICE_TOPOLOGY_AMD,
sizeof(cl_device_topology_amd), &topology, NULL);
if(status != CL_SUCCESS) {
}
if (topology.raw.type == CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD) {
std::cout << "INFO: Topology: " << "PCI[ B#" << (int)topology.pcie.bus
<< ", D#" << (int)topology.pcie.device << ", F#"
<< (int)topology.pcie.function << " ]" << std::endl;
}
或者(由我编写的代码,改编自上面链接的帖子):
#define CL_DEVICE_PCI_BUS_ID_NV 0x4008
#define CL_DEVICE_PCI_SLOT_ID_NV 0x4009
cl_int bus_id;
cl_int slot_id;
status = clGetDeviceInfo (devices[i], CL_DEVICE_PCI_BUS_ID_NV,
sizeof(cl_int), &bus_id, NULL);
if (status != CL_SUCCESS) {
}
status = clGetDeviceInfo (devices[i], CL_DEVICE_PCI_BUS_ID_NV,
sizeof(cl_int), &slot_id, NULL);
if (status != CL_SUCCESS) {
}
std::cout << "Topology = [" << bus_id <<
":"<< slot_id << "]" << std::endl;