通过 UUID 设置 CUDA 设备
Set CUDA device by UUID
有什么方法可以通过UUID设置程序CUDA设备吗?
因为我使用多实例 GPU (MIG) 从逻辑上拆分 GPU,并且不同的虚拟 GPU 具有不同的 UUID。
在 CUDA 中,select 使用设备的方法是通过 cudaSetDevice()
和 this requires 整数参数。
但是,UUID 是 device property structure 的一部分,因此您可以检索它们(例如使用 cudaGetDeviceProperties()
类似于 deviceQuery
示例代码中的演示)然后 select 基于设备 index/ordinal 和设备 UUID 之间的映射的设备。
这是一个例子:
$ cat t1872.cu
#include <iostream>
#include <iomanip>
#include <cstddef>
#include <vector>
#include <tuple>
bool uuid_equal(cudaUUID_t a, cudaUUID_t b){
bool retval = true;
for (int i = 0; i < sizeof(a.bytes); i++)
if (a.bytes[i] != b.bytes[i]) retval = false;
return retval;
}
void uuid_print(cudaUUID_t a){
std::cout << "GPU";
std::vector<std::tuple<int, int> > r = {{0,4}, {4,6}, {6,8}, {8,10}, {10,16}};
for (auto t : r){
std::cout << "-";
for (int i = std::get<0>(t); i < std::get<1>(t); i++)
std::cout << std::hex << std::setfill('0') << std::setw(2) << (unsigned)(unsigned char)a.bytes[i];
}
std::cout << std::endl;
}
int main(){
int num_dev;
cudaGetDeviceCount(&num_dev);
cudaUUID_t desired_UUID = {(char)0x26U, (char)0x7cU, (char)0xe6U, (char)0x89U, (char)0xf4U, (char)0xf6U, (char)0x87U, (char)0x17U, (char)0x51U, (char)0x5eU, (char)0x84U, (char)0xaaU, (char)0xe8U, (char)0x93U, (char)0xd3U, (char)0x12U};
int desired_index = -1;
for (int i = 0; i < num_dev; i++){
cudaDeviceProp p;
cudaGetDeviceProperties(&p,i);
if (uuid_equal(p.uuid, desired_UUID)){desired_index = i;}
std::cout << "dev: " << i << " UUID: ";
uuid_print(p.uuid);
}
if (desired_index < 0) std::cout << "Desired UUID not found! " << std::endl;
else {cudaSetDevice(desired_index); std::cout << "set device to: " << desired_index << std::endl;}
}
$ nvcc -o t1872 t1872.cu -std=c++11
$ compute-sanitizer ./t1872
========= COMPUTE-SANITIZER
dev: 0 UUID: GPU-267ce689-f4f6-8717-515e-84aae893d312
dev: 1 UUID: GPU-909fbaf6-cabf-faae-137a-b75aeaa0fa31
dev: 2 UUID: GPU-d05dc1d5-d090-6176-7236-6a42d73b311d
dev: 3 UUID: GPU-49fa3a59-ba1b-eb51-dc8b-9a0254300a38
set device to: 0
========= ERROR SUMMARY: 0 errors
$
请注意 cudaUUIT_t
只是一个包含 16 char
的数组。我的 UUID 打印例程只是为了匹配 nvidia-smi -a
.
的输出而设计的
有什么方法可以通过UUID设置程序CUDA设备吗? 因为我使用多实例 GPU (MIG) 从逻辑上拆分 GPU,并且不同的虚拟 GPU 具有不同的 UUID。
在 CUDA 中,select 使用设备的方法是通过 cudaSetDevice()
和 this requires 整数参数。
但是,UUID 是 device property structure 的一部分,因此您可以检索它们(例如使用 cudaGetDeviceProperties()
类似于 deviceQuery
示例代码中的演示)然后 select 基于设备 index/ordinal 和设备 UUID 之间的映射的设备。
这是一个例子:
$ cat t1872.cu
#include <iostream>
#include <iomanip>
#include <cstddef>
#include <vector>
#include <tuple>
bool uuid_equal(cudaUUID_t a, cudaUUID_t b){
bool retval = true;
for (int i = 0; i < sizeof(a.bytes); i++)
if (a.bytes[i] != b.bytes[i]) retval = false;
return retval;
}
void uuid_print(cudaUUID_t a){
std::cout << "GPU";
std::vector<std::tuple<int, int> > r = {{0,4}, {4,6}, {6,8}, {8,10}, {10,16}};
for (auto t : r){
std::cout << "-";
for (int i = std::get<0>(t); i < std::get<1>(t); i++)
std::cout << std::hex << std::setfill('0') << std::setw(2) << (unsigned)(unsigned char)a.bytes[i];
}
std::cout << std::endl;
}
int main(){
int num_dev;
cudaGetDeviceCount(&num_dev);
cudaUUID_t desired_UUID = {(char)0x26U, (char)0x7cU, (char)0xe6U, (char)0x89U, (char)0xf4U, (char)0xf6U, (char)0x87U, (char)0x17U, (char)0x51U, (char)0x5eU, (char)0x84U, (char)0xaaU, (char)0xe8U, (char)0x93U, (char)0xd3U, (char)0x12U};
int desired_index = -1;
for (int i = 0; i < num_dev; i++){
cudaDeviceProp p;
cudaGetDeviceProperties(&p,i);
if (uuid_equal(p.uuid, desired_UUID)){desired_index = i;}
std::cout << "dev: " << i << " UUID: ";
uuid_print(p.uuid);
}
if (desired_index < 0) std::cout << "Desired UUID not found! " << std::endl;
else {cudaSetDevice(desired_index); std::cout << "set device to: " << desired_index << std::endl;}
}
$ nvcc -o t1872 t1872.cu -std=c++11
$ compute-sanitizer ./t1872
========= COMPUTE-SANITIZER
dev: 0 UUID: GPU-267ce689-f4f6-8717-515e-84aae893d312
dev: 1 UUID: GPU-909fbaf6-cabf-faae-137a-b75aeaa0fa31
dev: 2 UUID: GPU-d05dc1d5-d090-6176-7236-6a42d73b311d
dev: 3 UUID: GPU-49fa3a59-ba1b-eb51-dc8b-9a0254300a38
set device to: 0
========= ERROR SUMMARY: 0 errors
$
请注意 cudaUUIT_t
只是一个包含 16 char
的数组。我的 UUID 打印例程只是为了匹配 nvidia-smi -a
.