通过 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.

的输出而设计的