Anteru's blog
  • Consulting
  • Research
    • Assisted environment probe placement
    • Assisted texture assignment
    • Edge-Friend: Fast and Deterministic Catmull-Clark Subdivision Surfaces
    • Error Metrics for Smart Image Refinement
    • High-Quality Shadows for Streaming Terrain Rendering
    • Hybrid Sample-based Surface Rendering
    • Interactive rendering of Giga-Particle Fluid Simulations
    • Quantitative Analysis of Voxel Raytracing Acceleration Structures
    • Real-time Hybrid Hair Rendering
    • Real-Time Procedural Generation with GPU Work Graphs
    • Scalable rendering for very large meshes
    • Spatiotemporal Variance-Guided Filtering for Motion Blur
    • Subpixel Reconstruction Antialiasing
    • Tiled light trees
    • Towards Practical Meshlet Compression
  • About
  • Archive

Associating OpenCL device ids with GPUs

August 01, 2014
  • Opencl
  • Programming
approximately 4 minutes to read

What’s more fun than one GPU? Two of them, of course. However, if you are using OpenCL from multiple processes, things get a bit hairy once you have multiple GPUs in a machine. A typical example would be MPI: With MPI, you’ll want to spawn one process per GPU. The problem you’re going to run into is how to assign GPUs, or rather, OpenCL devices, to processes.

The issue is that if you have two identical GPUs, you can’t distinguish between them. If you call clGetDeviceIds, the order in which they are returned is actually unspecified, so if the first process picks the first device and the second takes the second device, they both may wind up oversubscribing the same GPU and leaving the other one idle.

What we need is to get a persistent, unique identifier for each device which remains stable between processes, so we can match an OpenCL device id to a physical GPU. There’s no such thing in standard OpenCL, but luckily for us, there are some severely under-documented, vendor specific extensions which can help us.

AMD

Updated 2021-02-11: Replaced cl_amd_device_topology by cl_amd_device_attribute_query, added OpenCL SDK link.

On AMD, you want to use the cl_amd_device_attribute_query extension. This extension works on both Linux and Windows and can be used to query the PCIe bus, which is unique for each GPU. Let’s take a look how this works:

// This cl_ext is provided as part of the AMD OpenCL SDK. See below for how
// to get hold of this
#include <CL/cl_ext.h>

cl_device_topology_amd topology;
status = clGetDeviceInfo (devices[i], CL_DEVICE_TOPOLOGY_AMD,
    sizeof(cl_device_topology_amd), &topology, NULL);

if(status != CL_SUCCESS) {
    // Handle error
}

if (topology.raw.type == CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD) {
    std::cout << "INFO: Topology: " << "PCI[ B#" << (int)topology.pcie.bus
        << ", D#" << (int)topology.pcie.device << ", F#"
        << (int)topology.pcie.function << " ]" << std::endl;
}

This will give you a unique id for each GPU in your machine. You can also find this information in the AMD APP OpenCL programming guide, in the appendix. You can find the extension header in the AMD OpenCL SDK light package.

NVIDIA

For NVIDIA, the approach is very similar. The cl_nv_device_attribute_query extension supports two undocumented tokens for clGetDeviceInfo, CL_DEVICE_PCI_BUS_ID_NV (0x4008) and CL_DEVICE_PCI_SLOT_ID_NV (0x4009), which return the same information. Testing indicates that the return value is an integer. Unfortunately, I couldn’t find any documentation about this, but trust me, this works :)

Combined approach

The combined approach is to query the device vendor first, and then try to obtain the information. I combine it into an opaque 64-bit number which I associate with a device (on AMD, I merge the device and bus, on NVIDIA, the slot and bus.) I’m curious to hear how this is supposed to work for multiple Intel Xeon Phi, if you know, please drop me a line or comment!

Acknowledgements

Thanks to Herve & Marcus for their help! Undocumented functions are sure fun ;)

Previous post
Next post

Recent posts

  • Data formats: Why CSV and JSON aren't the best
    Posted on 2024-12-29
  • Replacing cron with systemd-timers
    Posted on 2024-04-21
  • Open Source Maintenance
    Posted on 2024-04-02
  • Angular, Caddy, Gunicorn and Django
    Posted on 2023-10-21
  • Effective meetings
    Posted on 2022-09-12
  • Older posts

Find me on the web

  • GitHub
  • GPU database
  • Projects

Follow me

Anteru NIV_Anteru
Contents © 2005-2025
Anteru
Imprint/Impressum
Privacy policy/Datenschutz
Made with Liara
Last updated February 11, 2021