Docker GPU Discovery and Mounting
This page explains how GPUs are discovered using containerized environments, as well as how these devices are exposed to the grading pipeline.
GPU Discovery
Like other host resources, resource discovery is performed in DockerDaemonDispatcher
, when each of the daemon hosts
are created. However, since Docker does not have information regarding the installed GPUs on the host, we need to use
other means to obtain the list of GPUs on a system.
lspci
First of all, we need to obtain a list of all GPUs present on the host system. Since /sys
is exposed in Docker
containers, we can use lspci
to obtain the list of PCI devices on the host system. lspci
also has a
machine-parsable format which helps the Grader to determine GPUs in all PCI devices.
We use lspci -Dvmm
, which has the following effect (see lspci(8)):
-D
: Displays the full PCI domain/bus (will be used to locate the card/render device of each GPU)-v
: Enables verbose output-mm
: Outputs the PCI device data in a machine-readable format
After obtaining the output of lspci
, we filter all devices which have a class of VGA compatible controller
, and
we will have a list of all GPUs on the system.
DRI Card and Rendering Devices
In addition to the PCI bus number, the card and render device number is required for AMD/Intel GPUs to be used in
containers. This will also be obtained using the discovery phase, and will be retrieved by listing all symlinks under
/dev/dri/by-path
. Each device will be listed in the form of pci-${pciBus}-{card,render}
, and each device can be
mapped to the DRI devices by replacing ${pciBus}
with the full PCI bus of the device.
In addition, we also resolve the symlink to the actual device name under /dev/dri
.
NVIDIA GPUs
Additionally, we also need to know the device IDs of each NVIDIA GPU as seen from the NVIDIA kernel module, as Docker’s Container Toolkit uses internal GPU IDs to determine which GPU to mount into the system.
From some sources, it appears that GPU IDs are enumerated via the PCI major bus, so the order of devices outputted
by lspci
is sufficient for mapping each GPU device to the index of the device as understood by NVIDIA tools.
GPU Allocation
GPUs are allocated using the current DockerDaemonDispatcher
logic.
Mounting to a Container
Once a GPU has been allocated to a runner, DockerPipelineStage
will be responsible for mounting the devices to the
containers.
NVIDIA
NVIDIA GPUs will use Docker’s device request functionality to mount the GPU into the container. The device ID of the NVIDIA GPU will be used here.
AMD/Intel
Other GPUs will use Docker’s device functionality to mount the GPU into the container. The /dev/dri
path of the
GPU will be used here, and will be mounted to the same path in the container. The container will be given read/write
access to the GPU (it is unknown whether mknod
permission is required).