Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to match OpenCL devices with a specific GPU given PCI vendor, device and bus IDs in a multi-GPU system?

Tags:

gpu

opencl

pci

I would like to be able to match OpenCL devices with GPUs in the system on multi-GPU systems identified by PCI IDs.

For example, if I have a system with multiple GPUs, possibly from different vendors, I can list the devices by enumerating the PCI bus. This gives me PCI vendor, device and bus IDs. If I choose one of these (GPU) PCI devices to use for OpenCL computation based on some selection criteria, how do I match it to the OpenCL device?

I can enumerate GPU devices in OpenCL using clGetDeviceIDs() but there is no obvious way to match OpenCL devices to PCI devices. The OpenCL function clGetDeviceInfo() provides access to the PCI vendor ID and device name but not PCI device or bus IDs. I could try to match the PCI device name with the OpenCL device name but it's possible that you have more than one of the same type of device and the names are not always the same anyway.

Why is this necessary? Say I know that program X is running CUDA or something else on GPU A. I want to avoid also using GPU A for an OpenCL operation so I choose GPU B. I then need to figure out which OpenCL device is GPU A and which is GPU B. PCI IDs seem to be the only consistent and cross platform way of identifying GPU devices.

BTW, the CUDA API does give you PCI, bus and slot IDs (CU_DEVICE_ATTRIBUTE_PCI_BUS_ID, CU_DEVICE_ATTRIBUTE_PCI_DEVICE_ID) but CUDA only works with NVidia devices.

Ideally I need a solution using either C or C++.

like image 519
jcoffland Avatar asked Sep 01 '11 21:09

jcoffland


2 Answers

The way to do it is to use two vendor-specific extensions. For AMD, you have to use CL_DEVICE_TOPOLOGY_AMD which works on Windows and Linux and will return the PCIe bus id, which is unique for a GPU. On NVIDIA, query the device for CL_DEVICE_PCI_BUS_ID_NV. See also: https://anteru.net/2014/08/01/2483/

like image 162
Anteru Avatar answered Sep 30 '22 04:09

Anteru


Unfortunately the answer you're looking for is not pretty due to the abstracted nature of openCL.

The only way I have found to reliably do it is to assign a demanding workload to the platform + device ID in openCL, and then monitor the process usage via tools such as AMD's ADL and Nvidia's NVML. Even mature applications like cgminer have issues with this and often mix up openCL workloads with card metrics, so much so that they assign configuration variables to correct it manually ("gpu-map").

I wish there was a better answer for now because it would be great to know, through openCL, which device is behind the endpoint! This may change in the future, as AMD is working to add this layer to openCL as arsenm pointed out.

like image 26
tweak2 Avatar answered Sep 30 '22 05:09

tweak2