Using GPU accelerators¶
Our clusters provide NVIDIA GPUs for general-purpose computing (GPGPU). Hyperion and Atlas EDR have different GPU types and different ways of requesting them through SLURM.
Hyperion¶
Available GPUs¶
| GPU | Nodes | GPUs/node | Memory | Interconnect | Constraint |
|---|---|---|---|---|---|
| NVIDIA A100 SXM4 | hyperion-[253,282-284] | 8 | 80 GB | NVLink | a100-sxm4 |
| NVIDIA A100 PCIe | hyperion-[252,254,257] | 8 | 80 GB | PCIe Gen4 | a100-pcie |
| NVIDIA RTX 3090 | hyperion-[030,052,074,096,118,140,162,182] | 2 | 24 GB | PCIe Gen4 | rtx3090 |
| NVIDIA RTX A6000 | hyperion-263 | 1 | 48 GB | PCIe Gen4 | a6000 |
| GPU | Nodes | GPUs/node | Memory | Interconnect | Constraint |
|---|---|---|---|---|---|
| NVIDIA A100 SXM4 | hyperion-[255,256] | 8 | 80 GB | NVLink | a100-sxm4 |
| NVIDIA A30 | hyperion-[260-261] | 2 | 24 GB | PCIE Gen4 | a30 |
| NVIDIA RTX PRO 6000 | hyperion-304 | 1 | 96 GB | PCIE Gen4 | pro6000 |
| NVIDIA RTX 3090 | hyperion-305 | 7 | 24 GB | PCIE Gen4 | rtx3090 |
| NVIDIA RTX 4090 | hyperion-306 | 1 | 24 GB | PCIE Gen4 | rtx4090 |
Requesting GPUs¶
On Hyperion, use --gres=gpu:N to request N GPUs and --constraint to select the GPU type:
#!/bin/bash
#SBATCH --job-name=gpu_job
#SBATCH --qos=regular
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=8
#SBATCH --gres=gpu:1
#SBATCH --mem=32gb
#SBATCH --time=04:00:00
#SBATCH --output=%x.%j.out
#SBATCH --error=%x.%j.err
module load CUDA/12.4.0
srun ./my_gpu_program
To select a specific GPU type, add --constraint:
# 2 RTX 3090 GPUs
#SBATCH --gres=gpu:2
#SBATCH --constraint=rtx3090
# 8 A100 SXM4 GPUs (NVLink)
#SBATCH --gres=gpu:8
#SBATCH --constraint=a100-sxm4
# 8 A100 PCIe GPUs
#SBATCH --gres=gpu:8
#SBATCH --constraint=a100-pcie
# Any type of A100 (SXM4 or PCIe)
#SBATCH --gres=gpu:8
#SBATCH --constraint=a100
If no --constraint is specified, SLURM will assign any available GPU that satisfies the request.
GPU and CPU microarchitecture¶
GPU nodes have different CPU architectures:
| GPU type | CPU architecture |
|---|---|
| RTX 3090 | Cascadelake |
| RTX 3090 | Zen 3 |
| RTX 4090 | Zen 3 |
| RTX A6000 | Icelake |
| A100 (all) | Icelake |
| RTX PRO 6000 | Zen 3 |
Requesting a specific GPU type implicitly selects the CPU architecture. If you need a specific architecture but do not care about the GPU model:
#SBATCH --gres=gpu:1
#SBATCH --constraint=gpu-icelake
A100 SXM4 nodes: usage policy¶
The A100 SXM4 nodes use NVIDIA's HGX platform with NVLink interconnects between all 8 GPUs within each node (up to 300 GB/s bidirectional, compared to ~32 GB/s over PCIe). These nodes are intended for workloads that benefit from fast multi-GPU communication, such as distributed deep learning training.
Minimum 4 GPUs per node
Jobs requesting fewer than 4 GPUs cannot be submitted to A100 SXM4 nodes on the general partition. This ensures the NVLink-connected GPUs remain available for workloads that truly benefit from them.
preemption-gpu partition¶
When A100 SXM4 nodes have idle GPUs, you can use them for smaller jobs (fewer than 4 GPUs) through the preemption-gpu partition. These jobs will be canceled and requeued if a larger job (4+ GPUs) on the general partition needs the resources.
#SBATCH --partition=preemption-gpu
#SBATCH --gres=gpu:2
| QoS | Priority | Max walltime | Max resources |
|---|---|---|---|
| preemption-gpu | 200 | 8 days | 3 GPUs, 1 node |
Warning
Do not specify QoS values from the general partition when submitting to preemption-gpu. Use the partition's default QoS.
How preemption works:
- A job submitted to
preemption-gpustarts immediately if resources are available, or queues normally if not. - When a
generalpartition job requesting 4+ A100 SXM4 GPUs arrives and resources are occupied bypreemption-gpujobs, those jobs are canceled and requeued. - If resources are occupied by other
generalpartition jobs, the new job queues normally.
Design preemption-safe jobs
If you use the preemption-gpu partition, make sure your code can resume from checkpoints. Your job may be killed and restarted at any time.
Atlas EDR¶
Available GPUs¶
| GPU | Nodes | GPUs/node | SLURM request |
|---|---|---|---|
| NVIDIA RTX 3090 24 GB | atlas-[328-331] | 2 | --gres=gpu:rtx3090:2 |
| NVIDIA Tesla P40 24 GB | atlas-[249-256] | 2 | --gres=gpu:p40:2 |
| NVIDIA Tesla P40 24 GB | atlas-[257-280] | 1 | --gres=gpu:p40:1 |
Requesting GPUs¶
On Atlas EDR, the GPU type is specified directly in the --gres flag (there is no --constraint mechanism):
#!/bin/bash
#SBATCH --job-name=gpu_job
#SBATCH --qos=regular
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=4
#SBATCH --gres=gpu:p40:1
#SBATCH --mem=32gb
#SBATCH --time=04:00:00
#SBATCH --output=%x.%j.out
#SBATCH --error=%x.%j.err
module load CUDA/11.7.0
srun ./my_gpu_program
CUDA compatibility¶
Not all GPUs on Atlas EDR support all CUDA versions:
| GPU | Minimum CUDA | Minimum toolchain |
|---|---|---|
| NVIDIA RTX 3090 | 11.0 | fosscuda/2020b or newer |
| NVIDIA Tesla P40 | 8.0 | Any CUDA-enabled toolchain |
Warning
If your code or the software you are using was compiled with CUDA < 11.0, it will not work on RTX 3090 GPUs. Make sure to use CUDA 11.0 or newer (or a toolchain version 2020b or newer) when targeting these GPUs.
Verifying GPU access¶
After your job starts, verify that your application can see the allocated GPUs:
nvidia-smi
SLURM sets the CUDA_VISIBLE_DEVICES environment variable automatically to expose only the GPUs allocated to your job. From Python:
python -c "import torch; print(torch.cuda.device_count(), 'GPUs available')"
See also¶
-
PyTorch distributed training
PyTorch distributed, NCCL, torchrun.
-
GPU computing stack
NCCL, GPU topology, bandwidth benchmarks, environment variables.
-
Compilers: GPU compilation
Compiling GPU code with NVHPC.
-
Containers (Apptainer)
Running GPU applications in containers.
-
Python
Setting up conda environments for deep learning.