Commit bee62f2c authored by Sören Wacker's avatar Sören Wacker
Browse files

Use the GPU type names Slurm accepts and keep module PyTorch off RTX Pro 6000...

Use the GPU type names Slurm accepts and keep module PyTorch off RTX Pro 6000 nodes where it crashes
parent ab0daf3a
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -144,7 +144,7 @@ Load modules in your SLURM batch script:
#!/bin/bash
#SBATCH --account=<your-account>
#SBATCH --partition=all
#SBATCH --gres=gpu:1
#SBATCH --gres=gpu:nvidia_l40:1

module purge
module load 2025/gpu
@@ -153,6 +153,10 @@ module load py-torch/2.5.1
srun python train.py
```

{{% alert title="Module PyTorch does not run on RTX Pro 6000 GPUs" color="warning" %}}
The `py-torch` modules contain GPU code for the A40 and L40 only. On an RTX Pro 6000 node `torch.cuda.is_available()` still returns `True`, but the first GPU operation fails with `CUDA error: no kernel image is available for execution on the device`. Request an A40 (`gpu:nvidia_a40:1`) or L40 (`gpu:nvidia_l40:1`) for jobs that use these modules.
{{% /alert %}}

{{% alert title="Always use module purge" color="info" %}}
Start batch scripts with `module purge` to ensure a clean environment.
{{% /alert %}}
+10 −3
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ if torch.cuda.is_available():
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=4
#SBATCH --mem=8G
#SBATCH --gres=gpu:1
#SBATCH --gres=gpu:nvidia_l40:1
#SBATCH --output=gpu_%j.out

module purge
@@ -59,10 +59,17 @@ cat gpu_301.out
To request a specific GPU type:

```bash
#SBATCH --gres=gpu:l40:1      # NVIDIA L40
#SBATCH --gres=gpu:a40:1      # NVIDIA A40
#SBATCH --gres=gpu:nvidia_l40:1            # NVIDIA L40
#SBATCH --gres=gpu:nvidia_a40:1            # NVIDIA A40
#SBATCH --gres=gpu:nvidia_rtx_pro_6000:1   # NVIDIA RTX Pro 6000
```

The type must be written exactly as Slurm names it (`sinfo -o "%n %G"` lists it per node); short forms such as `gpu:l40:1` are rejected.

{{% alert title="Module PyTorch does not run on RTX Pro 6000 GPUs" color="warning" %}}
The `py-torch` modules contain GPU code for the A40 and L40 only. On an RTX Pro 6000 node `torch.cuda.is_available()` still returns `True`, but the first GPU operation fails with `CUDA error: no kernel image is available for execution on the device`. Request an A40 or L40 for jobs that use these modules, as `gpu_job.sh` above does.
{{% /alert %}}

## Next steps

- Use [Containers](/tutorials/apptainer/) for custom GPU environments
+20 −26
Original line number Diff line number Diff line
@@ -77,11 +77,11 @@ Let's walk through creating and submitting a batch job step by step.

### Step 1: Create a Python script

First, create a simple script to run. This one just prints some information. Use the editor you are comfortable with: `nano` is the simplest, and the [Vim tutorial](/tutorials/vim/) covers `vim`.
First, create a simple script to run. This one just prints some information. `vim` is the editor installed on DAIC; if you have not used it before, the [Vim tutorial](/tutorials/vim/) explains how to insert text, save, and quit.

```shell-session
$ cd /tudelft.net/staff-umbrella/<project>
$ nano hello.py
$ vim hello.py
```

```python
@@ -98,7 +98,7 @@ print(f"CPUs allocated: {os.environ.get('SLURM_CPUS_PER_TASK', 'unknown')}")
Now create the Slurm script that will run your Python code:

```shell-session
$ nano hello_job.sh
$ vim hello_job.sh
```

```bash
@@ -252,11 +252,12 @@ Request GPUs with the `--gres` (generic resources) option:
```bash
#SBATCH --gres=gpu:1    # One GPU (any type)
#SBATCH --gres=gpu:2    # Two GPUs
#SBATCH --gres=gpu:l40:1   # Specifically an L40 GPU
#SBATCH --gres=gpu:a40:2   # Two A40 GPUs
#SBATCH --gres=gpu:nvidia_l40:1            # Specifically an L40 GPU
#SBATCH --gres=gpu:nvidia_a40:2            # Two A40 GPUs
#SBATCH --gres=gpu:nvidia_rtx_pro_6000:1   # An RTX Pro 6000 GPU
```

Available GPU types on DAIC include L40, A40, and RTX Pro 6000. Request specific types only if your code requires it - being flexible gets you through the queue faster.
The type must be written exactly as Slurm names it; a short form such as `gpu:l40:1` is rejected with "Requested node configuration is not available". `sinfo -o "%n %G"` lists the GPU type of every node. Request specific types only if your code requires it - being flexible gets you through the queue faster.

## Running GPU jobs

@@ -305,7 +306,7 @@ print("Training complete!")
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=4
#SBATCH --mem=16G
#SBATCH --gres=gpu:1
#SBATCH --gres=gpu:nvidia_l40:1
#SBATCH --output=train_%j.out

# Clean environment and load required modules
@@ -339,6 +340,10 @@ module load py-torch/2.5.1 # Load PyTorch, which train.py imports

The job script above loads all three in one `module load` line. Without `py-torch`, `import torch` fails with `ModuleNotFoundError`. If you manage your own packages instead (for example with `uv`), see [Python environments](/tutorials/python/).

{{% alert title="Module PyTorch does not run on RTX Pro 6000 GPUs" color="warning" %}}
The `py-torch` modules contain GPU code for the A40 and L40 only. On an RTX Pro 6000 node `torch.cuda.is_available()` still returns `True`, but the first GPU operation fails with `CUDA error: no kernel image is available for execution on the device`. This is why the job script requests `gpu:nvidia_l40:1` rather than `gpu:1`. A PyTorch you install yourself from PyPI runs on all DAIC GPU types.
{{% /alert %}}

Why use modules?

- **Version control**: Run `module load python/3.11` today, `python/3.12` tomorrow
@@ -386,13 +391,7 @@ The `tail -f` command shows output in real-time as your job runs.
Modify the basic job to request a GPU. Add `nvidia-smi` to verify the GPU is available.

{{% alert title="Check your work" color="info" %}}
Your output should include `nvidia-smi` output showing a GPU:
```
+-----------------------------------------------------------------------------+
| NVIDIA-SMI ...    Driver Version: ...    CUDA Version: ...                  |
|-------------------------------+----------------------+----------------------+
| GPU  Name        ...
```
Your output should include the `nvidia-smi` status table, which names the GPU (for example `NVIDIA L40` or `NVIDIA RTX PRO 6000 Blackwell Server Edition`) and shows its memory.
If the command fails or lists no devices, check that you requested a GPU with `--gres=gpu:1`.
{{% /alert %}}

@@ -403,7 +402,7 @@ Before submitting a long batch job, test your code interactively:
### Request an interactive session

```shell-session
$ salloc --account=<your-account> --partition=all --time=1:00:00 --cpus-per-task=4 --mem=8G --gres=gpu:1
$ salloc --account=<your-account> --partition=all --time=1:00:00 --cpus-per-task=4 --mem=8G --gres=gpu:nvidia_l40:1
salloc: Pending job allocation 12351
salloc: job 12351 queued and waiting for resources
salloc: job 12351 has been allocated resources
@@ -418,18 +417,13 @@ You now have resources reserved. But you're still on the login node - you need `
$ srun hostname
gpu15.ethernet.tudhpc

$ srun nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.15    Driver Version: 550.54.15    CUDA Version: 12.4     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  NVIDIA L40          On   | 00000000:41:00.0 Off |                    0 |
| N/A   30C    P8    22W / 300W |      0MiB / 46068MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
$ srun nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv
name, memory.total [MiB], driver_version
NVIDIA L40, 46068 MiB, 610.43.02
```

Plain `srun nvidia-smi` prints the full status table, including current utilisation and memory use.

Modules loaded in this shell are passed on to the commands `srun` starts, so load the software first:

```shell-session
@@ -749,7 +743,7 @@ Common causes:
1. Forgot `--gres=gpu:1` in your script
2. Running on login node instead of through `srun`
3. A CPU-only PyTorch build is installed in your environment
4. The PyTorch build needs a newer CUDA version than the node's driver supports (see [CUDA version mismatch](/tutorials/python/#cuda-version-mismatch))
4. The PyTorch build does not support the GPU model or the driver (see [GPU and CUDA compatibility](/tutorials/python/#gpu-and-cuda-compatibility))

## Best practices