現在この問題を調査できる限り、信頼できる解決策はありません。すべての作業が 1 つのプロセス内で行われる場合は、clGetDeviceIDs
またはcl_device
値自体 (本質的にはポインター) によって返されるエントリの順序を使用できますが、それらの識別子をプロセス間で共有しようとすると、事態はさらに悪化します。
その男のブログ投稿を参照してください。
問題は、2 つの同一の GPU がある場合、それらを区別できないことです。を呼び出した場合clGetDeviceIDs
、それらが返される順序は実際には指定されていないため、最初のプロセスが最初のデバイスを選択し、2 番目のプロセスが 2 番目のデバイスを取得すると、両方が同じ 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;