cudagpugpgpunvidia

How does CUDA assign device IDs to GPUs?


When a computer has multiple CUDA-capable GPUs, each GPU is assigned a device ID. By default, CUDA kernels execute on device ID 0. You can use cudaSetDevice(int device) to select a different device.

Let's say I have two GPUs in my machine: a GTX 480 and a GTX 670. How does CUDA decide which GPU is device ID 0 and which GPU is device ID 1?


Ideas for how CUDA might assign device IDs (just brainstorming):


Motivation: I'm working on some HPC algorithms, and I'm benchmarking and autotuning them for several GPUs. My processor has enough PCIe lanes to drive cudaMemcpys to 3 GPUs at full bandwidth. So, instead of constantly swapping GPUs in and out of my machine, I'm planning to just keep 3 GPUs in my computer. I'd like to be able to predict what will happen when I add or replace some GPUs in the computer.


Solution

  • CUDA picks the fastest device as device 0. So when you swap GPUs in and out the ordering might change completely. It might be better to pick GPUs based on their PCI bus id using:

    cudaError_t cudaDeviceGetByPCIBusId ( int* device, char* pciBusId )
       Returns a handle to a compute device.
    
    cudaError_t cudaDeviceGetPCIBusId ( char* pciBusId, int  len, int  device )
       Returns a PCI Bus Id string for the device.
    

    or CUDA Driver API cuDeviceGetByPCIBusId cuDeviceGetPCIBusId.

    But IMO the most reliable way to know which device is which would be to use NVML or nvidia-smi to get each device's unique identifier (UUID) using nvmlDeviceGetUUID and then match it do CUDA device with pciBusId using nvmlDeviceGetPciInfo.