Ordonnancement Slurm des tâches exécutées avec GPU

From Alliance Doc
Revision as of 21:25, 1 April 2020 by Diane27 (talk | contribs)
Jump to navigation Jump to search
Other languages:

Pour l'information générale sur l'ordonnancement des tâches, consultez Exécuter des tâches.

Nœuds disponibles

Le tableau suivant décrit les nœuds avec GPU présentement disponibles avec Béluga, Cedar, Graham et Hélios.

# de nœuds Type de nœud Cœurs CPU Mémoire CPU # de GPU Type de GPU Topologie du bus PCIe
172 GPU base, Béluga 40 191000M 4 NVIDIA V100-SXM2-16Go tous les GPU associés au même socket CPU
114 GPU base, Cedar 24 128000M 4 NVIDIA P100-PCIE-12Go deux GPU par socket CPU
32 GPU large, Cedar 24 257000M 4 NVIDIA P100-PCIE-16Go tous les GPU associés au même socket CPU
160 GPU base, Graham 32 127518M 2 NVIDIA P100-PCIE-12Go un GPU par socket CPU
7 GPU base, Graham 28 183105M 8 NVIDIA V100-PCIE-16Go quatre GPU socket CPU
36 GPU base, Graham 16 196608M 4 NVIDIA Tesla T4-16Go deux GPU par socket CPU
15 K20, Hélios 20 110000M 8 NVIDIA K20-5Go quatre GPU par socket CPU
6 K80, Hélios 24 257000M 16 NVIDIA K80-12Go huit GPU par socket CPU

Comment indiquer le type de GPU à utiliser

Plusieurs types de GPU sont disponibles sur la plupart des grappes. Pour indiquer le type de GPU à utiliser, ajoutez l'option appropriée, selon la grappe.

Cedar

Pour demander un P100 de 12G :

 #SBATCH --gres=gpu:p100:1

Pour demander un P100 de 16G :

 #SBATCH --gres=gpu:p100l:1

Par défaut, toutes les tâches sur GPU exigeant <= 125Go seront exécutées sur des P100 de 12Go.

 #SBATCH --gres=gpu:v100l:1

Unless specified, all GPU jobs requesting <= 125G of memory will run on 12G P100s

Graham

Pour demander un P100 :

 #SBATCH --gres=gpu:p100:1

Pour demander un V100 :

 #SBATCH --gres=gpu:v100:1

Pour demander un T4 :

 #SBATCH --gres=gpu:t4:1

Par défaut, toutes les tâches sur GPU seront exécutées sur des P100.

Béluga

Comme il n'y a qu'un type de GPU, aucune option n'est nécessaire.

Hélios

Pour demander un K20 :

 #SBATCH --gres=gpu:k20:1

Pour demander un K80 :

 #SBATCH --gres=gpu:k80:1

Tâches avec un seul cœur

Pour une tâche qui nécessite un seul cœur CPU et un GPU,

File : gpu_serial_job.sh

#!/bin/bash
#SBATCH --account=def-someuser
#SBATCH --gres=gpu:1              # Number of GPUs (per node)
#SBATCH --mem=4000M               # memory (per node)
#SBATCH --time=0-03:00            # time (DD-HH:MM)
./program


Tâches multifils

Pour une tâche GPU qui nécessite plusieurs CPU dans un seul nœud,

File : gpu_threaded_job.sh

#!/bin/bash
#SBATCH --account=def-someuser
#SBATCH --gres=gpu:1              # Number of GPU(s) per node
#SBATCH --cpus-per-task=6         # CPU cores/threads
#SBATCH --mem=4000M               # memory per node
#SBATCH --time=0-03:00            # time (DD-HH:MM)
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
./program


Pour chaque GPU, les tâches multifils ne devraient pas dépasser

  • avec Béluga, 10 cœurs;
  • avec Cedar, 6 cœurs;
  • avec Graham, 16 cœurs.

Tâches MPI

File : gpu_mpi_job.sh

#!/bin/bash
#SBATCH --account=def-someuser
#SBATCH --gres=gpu:4              # Number of GPUs per node
#SBATCH --nodes=2                 # Number of nodes
#SBATCH --ntasks=48               # Number of MPI process
#SBATCH --cpus-per-task=1         # CPU cores per MPI process
#SBATCH --mem=120G                # memory per node
#SBATCH --time=0-03:00            # time (DD-HH:MM)
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
srun ./program


Nœuds entiers

Si votre application peut utiliser efficacement un nœud entier et ses GPU associés, vous pouvez probablement réduire le temps d'attente si vous demandez un nœud entier. Utilisez les scripts suivants comme modèle.

Ordonnancement d'un nœud GPU pour Graham

File : graham_gpu_node_job.sh

#!/bin/bash
#SBATCH --nodes=1
#SBATCH --gres=gpu:2
#SBATCH --ntasks-per-node=32
#SBATCH --mem=127000M
#SBATCH --time=3:00
#SBATCH --account=def-someuser
nvidia-smi


Ordonnancement d'un nœud GPU pour Cedar

File : cedar_gpu_node_job.sh

#!/bin/bash
#SBATCH --nodes=1
#SBATCH --gres=gpu:4
#SBATCH --ntasks-per-node=24
#SBATCH --exclusive
#SBATCH --mem=125G
#SBATCH --time=3:00
#SBATCH --account=def-someuser
nvidia-smi


Ordonnancement d'un nœud GPU large pour Cedar

Sur Cedar se trouvent des nœuds de type GPU large qui ont chacun quatre cartes Tesla P100 16Go, alors que les autres nœuds sont de 12Go. Les nœuds de type GPU large utilisent le même connecteur PCI, ce qui fait que la latence dans les communications entre GPU est plus faible; cependant, la bande passante entre CPU et GPU est plus basse que dans le cas des nœuds GPU réguliers. De plus, la mémoire vive des nœuds est de 256Go plutôt que de 128Go. Pour utiliser ces nœuds, il faut demander des nœuds entiers et indiquer lgpu. Le temps d'exécution maximal pour ces tâches est passé de 24 haures à 28 jours.

File : large_gpu_job.sh

#!/bin/bash
#SBATCH --nodes=1 
#SBATCH --gres=gpu:lgpu:4   
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=24    # There are 24 CPU cores on Cedar GPU nodes
#SBATCH --mem=0               # Request the full memory of the node
#SBATCH --time=3:00
#SBATCH --account=def-someuser
hostname
nvidia-smi


Regroupement de tâches pour un seul GPU

Pour exécuter pendant plus de 24 heures quatre programmes qui utilisent un seul GPU ou deux programmes qui utilisent deux GPU, nous recommandons GNU Parallel. Voici un exemple simple :

cat params.input | parallel -j4 'CUDA_VISIBLE_DEVICES=$(({%} - 1)) python {} &> {#}.out'

L'identifiant du GPU est calculé en soustrayant 1 de l'identifiant de la fente (slot), représenté par {%}. L'identifiant de la tâche est représenté par {#}, avec des valeurs partant de 1.

Le fichier params.input devrait contenir les paramètres sur des lignes distinctes, comme suit :

code1.py
code2.py
code3.py
code4.py
...

Vous pouvez ainsi soumettre plusieurs tâches. Le paramètre -j4 fait en sorte que GNU Parallel exécutera quatre tâches concurremment en lançant une tâche aussitôt que la précédente est terminée. Pour éviter que deux tâches se disputent le même GPU, utilisez CUDA_VISIBLE_DEVICES.