Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to select a GPU with CUDA?

Tags:

cuda

gpu

I have a computer with 2 GPUs; I wrote a CUDA C program and I need to tell it somehow that I want to run it on just 1 out of the 2 graphic cards; what is the command I need to type and how should I use it? I believe somehow that is related to the cudaSetDevice but I can't really find out how to use it.

like image 704
Federico Gentile Avatar asked Jan 23 '15 14:01

Federico Gentile


People also ask

How do I choose a CUDA device?

The canonical way to select a device in the runtime API is using cudaSetDevice . That will configure the runtime to perform lazy context establishment on the nominated device. Prior to CUDA 4.0, this call didn't actually establish a context, it just told the runtime which GPU to try and use.

How do I know if my GPU is CUDA compatible?

To check if your computer has an NVIDA GPU and if it is CUDA enabled: Right click on the Windows desktop. If you see “NVIDIA Control Panel” or “NVIDIA Display” in the pop up dialogue, the computer has an NVIDIA GPU. Click on “NVIDIA Control Panel” or “NVIDIA Display” in the pop up dialogue.


2 Answers

It should be pretty much clear from documentation of cudaSetDevice, but let me provide following code snippet.

bool IsGpuAvailable()
{
    int devicesCount;
    cudaGetDeviceCount(&devicesCount);
    for(int deviceIndex = 0; deviceIndex < devicesCount; ++deviceIndex)
    {
        cudaDeviceProp deviceProperties;
        cudaGetDeviceProperties(&deviceProperties, deviceIndex);
        if (deviceProperties.major >= 2
            && deviceProperties.minor >= 0)
        {
            cudaSetDevice(deviceIndex);
            return true;
        }
    }

    return false;
}

This is how I iterated through all available GPUs (cudaGetDeviceCount) looking for the first one of Compute Capability of at least 2.0. If such device was found, then I used cudaSetDevice so all the CUDA computations were executed on that particular device. Without executing the cudaSetDevice your CUDA app would execute on the first GPU, i.e. the one with deviceIndex == 0 but which particular GPU is that depends on which GPU is in which PCIe slot.

EDIT:

After clarifying your question in comments, it seems to me that it should be suitable for you to choose the device based on its name. If you are unsure about your actual GPU names, then run this code which will print names of all your GPUs into console:

int devicesCount;
cudaGetDeviceCount(&devicesCount);
for(int deviceIndex = 0; deviceIndex < devicesCount; ++deviceIndex)
{
    cudaDeviceProp deviceProperties;
    cudaGetDeviceProperties(&deviceProperties, deviceIndex);
    cout << deviceProperties.name << endl;
}

After that, choose the name of the GPU that you want to use for computations, lets say it is "GTX XYZ". Call the following method from your main method, thanks to it, all the CUDA kernels will be executed on the device with name "GTX XYZ". You should also check the return value - true if device with such name is found, false otherwise:

bool SetGPU()
{
    int devicesCount;
    cudaGetDeviceCount(&devicesCount);
    string desiredDeviceName = "GTX XYZ";
    for(int deviceIndex = 0; deviceIndex < devicesCount; ++deviceIndex)
    {
        cudaDeviceProp deviceProperties;
        cudaGetDeviceProperties(&deviceProperties, deviceIndex);
        if (deviceProperties.name == desiredDeviceName)
        {
            cudaSetDevice(deviceIndex);
            return true;
        }
    }

    return false;
}

Of course you have to change the value of desiredDeviceName variable to desired value.

like image 118
Michal Hosala Avatar answered Nov 15 '22 11:11

Michal Hosala


Searching more carefully in the internet I found this lines of code that select the GPU with more cores among all the devices installed in the Pc.

int num_devices, device;
cudaGetDeviceCount(&num_devices);
if (num_devices > 1) {
  int max_multiprocessors = 0, max_device = 0;
  for (device = 0; device < num_devices; device++) {
          cudaDeviceProp properties;
          cudaGetDeviceProperties(&properties, device);
          if (max_multiprocessors < properties.multiProcessorCount) {
                  max_multiprocessors = properties.multiProcessorCount;
                  max_device = device;
          }
  }
  cudaSetDevice(max_device);
}
like image 30
Federico Gentile Avatar answered Nov 15 '22 11:11

Federico Gentile