就我现在可以调查的问题而言,没有可靠的解决方案。如果您的所有工作都在单个进程中完成,您可以使用返回的条目顺序clGetDeviceIDs
或cl_device
值本身(本质上它们是指针),但如果您尝试在进程之间共享这些标识符,情况会变得更糟。
看到那个人的博客文章,说:
问题是,如果你有两个相同的 GPU,你就无法区分它们。如果您调用clGetDeviceIDs
,它们返回的顺序实际上是未指定的,因此如果第一个进程选择第一个设备,而第二个进程选择第二个设备,它们都可能最终超额订阅同一个 GPU 并使另一个空闲。
但是,他指出 nVidia 和 AMD 提供了他们的自定义扩展,cl_amd_device_topology
并且cl_nv_device_attribute_query
. 您可以检查您的设备是否支持这些扩展,然后按照以下方式使用它们(原作者的代码):
// This cl_ext is provided as part of the AMD APP SDK
#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) {
// Handle error
}
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) {
// Handle error.
}
status = clGetDeviceInfo (devices[i], CL_DEVICE_PCI_BUS_ID_NV,
sizeof(cl_int), &slot_id, NULL);
if (status != CL_SUCCESS) {
// Handle error.
}
std::cout << "Topology = [" << bus_id <<
":"<< slot_id << "]" << std::endl;