Using GPUs with Slurm/fr: Difference between revisions

From Alliance Doc
Jump to navigation Jump to search
(Updating to match new version of source page)
(Created page with "== GPU multi-instances sur Narval == La technologie MIG permettant de partitionner un GPU en plusieurs instances est présentement disponible sur Narval comme projet pilote. Pour plus d'information, consultez la page GPU multi-instances.")
 
(200 intermediate revisions by 5 users not shown)
Line 1: Line 1:
<languages />
<languages />
= Introduction =
Pour demander un ou plusieurs GPU pour une tâche, lancez
  --gpus-per-node=[type:]number
À l'intérieur des crochets, vous pouvez indiquer la quantité et le type de GPU. Pour les types, voyez le tableau dans la section <i>GPU disponibles</i> ci-dessous. Voici deux exemples&nbsp;:
  --gpus-per-node=2
  --gpus-per-node=v100:1
Sur la première ligne, on demande deux GPU par nœud, peu importe le type de GPU. Sur la deuxième ligne, on demande 1 GPU par nœud, de type V100.
La forme suivante peut aussi être utilisée
  --gres=gpu[[:type]:number]
Cette forme est cependant moins récente et ne sera probablement plus prise en charge dans les versions de Slurm à venir. Nous vous recommandons  de la remplacer dans vos scripts par <code>--gpus-per-node</code>.
Il y a plusieurs autres directives que vous pouvez utiliser pour demander des GPU, par exemple <code>--gpus</code>, <code>--gpus-per-socket</code>, <code>--gpus-per-task</code>, <code>--mem-per-gpu</code> et <code>--ntasks-per-gpu</code>. Voyez la documentation de Slurm sur [https://slurm.schedmd.com/sbatch.html sbatch].  Notre équipe n'a pas testé toutes les combinaisons; si vous n'obtenez pas le résultat voulu, contactez le [[Technical support/fr|soutien technique]].


Pour l'information générale sur l'ordonnancement des tâches, consultez [[Running jobs/fr|Exécuter des tâches]].
Pour l'information générale sur l'ordonnancement des tâches, consultez [[Running jobs/fr|Exécuter des tâches]].


== Nœuds disponibles ==
= GPU disponibles =
Le tableau suivant décrit les nœuds avec GPUs présentement disponibles avec [[Cedar/fr|Cedar]] et [[Graham/fr|Graham]].
Le tableau suivant liste les GPU qui sont présentement disponibles.


{| class="wikitable"
{| class="wikitable"
|-
|-
! # de nœuds !! Type de nœud !! Cœurs CPU !! Mémoire CPU !! # de GPUs !! Type de GPU !! Topologie du bus PCIe
! rowspan=2|Grappe!! rowspan=2|Qté de nœuds!! rowspan=2|Type de GPU!!colspan=3|Par nœud!! rowspan=2|Modèle de GPU !! rowspan=2|Attribut<br>compute<br>capability(*) !! rowspan=2|Mémoire GPU (GiB)!! rowspan=2|Remarques
|-
|-
| 114  || ''GPU base'', Cedar || 24 || 128Go || 4  || NVIDIA P100-PCIE-12GB || deux GPUs par socket CPU
!                              Cœurs CPU!! Mémoire CPU !! GPU  
|-
|-
| 32 || ''GPU large'', Cedar || 24|| 256Go || 4 || NVIDIA P100-PCIE-16GB || tous les GPUs associés au même socket CPU
| Béluga            || 172 || v100  || 40 || 191000M || 4 || V100-16gb || 70 || 16 || tous les GPU sont associés au même socket CPU et connectés via NVLink et SXM2
|-
|-
| 160 || ''GPU base'', Graham || 32|| 128Go || 2   || NVIDIA P100-PCIE-12GB || un GPU par socket CPU
| rowspan=3|Cedar  || 114 || p100  || 24 || 128000M ||  4 || P100-12gb || 60 || 12 || deux GPU par socket CPU, connectés par PCIe
|-
|                      32  || p100  || 24 || 257000M ||  4 || P100-16gb || 60 || 16 || tous les GPU sont associés au même socket CPU, connectés par PCIe
|-
|                      192 || v100l || 32 || 192000M ||  4 || V100-32gb || 70 || 32 || deux GPU par socket CPU; tous les GPU sont connectés via NVLink et SXM2
|-
| rowspan=5|Graham  || 160 || p100  || 32 || 127518M ||  2 || P100-12gb || 60 || 12 || un GPU par socket CPU, connecté par PCIe
|-
|                      7  || v100  || 28 || 183105M ||  8 || V100(**) || 70 || 16 || voir  [[Graham/fr#Nœuds_GPU_Volta|Nœuds GPU Volta]]
|-
|                      2  || v100(**) || 28 || 183105M ||  8 || V100(***) || 70 || 32 || voir  [[Graham/fr#Nœuds_GPU_Volta|Nœuds GPU Volta]]-
|-
|                      30  || t4    || 44 || 192000M ||  4 || T4-16gb  || 75 || 16 || deux GPU par socket CPU
|-
|                      6  || t4    || 16 || 192000M ||  4 || T4-16gb  || 75 || 16 || &nbsp
|-
| Mist              || 54  || n.a.  || 32 ||  256GiB  ||  4 || V100-32gb || 70 || 32 || voir [https://docs.scinet.utoronto.ca/index.php/Mist#Specifications Mist specifications]
|-  
| Narval            || 159 || a100  || 48 || 510000M ||  4 || A100-40gb || 80 || 40 || deux GPU par socket CPU; tous les GPU sont connectés via NVLink
|-
| Arbutus          ||  colspan=8 | L'ordonnanceur Slurm ne gère pas les ressources infonuagiques. Voir [[Cloud resources/fr|Ressources infonuagiques]] pour l'information sur le matériel disponible.
|}
|}
(*) Le terme <i>Compute Capability</i> est utilisé par NVIDIA pour indiquer les fonctionnalités matérielles spécifiques à un GPU particulier et n'a aucun rapport avec la performance des dispositifs. Cet attribut n'est utile que si vous compilez vos propres programmes GPU. Pour plus d'information, voir [[CUDA/fr#Attribut_.22compute_capability.22|la page CUDA]].
(**) Pour avoir accès à un gabarit pour un nœud V100 de 16Go sur Graham, utilisez les arguments suivants dans la commande sbatch/salloc&nbsp;: <code>--constraint=skylake,v100</code>.
(**) Pour avoir accès à un gabarit pour un nœud V100 de 32Go sur Graham, utilisez les arguments suivants dans la commande sbatch/salloc&nbsp;:  <code>--constraint=cascade,v100</code>.
== Mist ==
[https://docs.scinet.utoronto.ca/index.php/Mist Mist] est une grappe qui comprend des CPU IBM Power9 (et non des Intel x86) et des GPU NVIDIA V100. 
Si vous avez accès à Niagara, vous avez aussi  accès à Mist; voyez les directives sur [https://docs.scinet.utoronto.ca/index.php/Mist#Submitting_jobs le site web de SciNet].
== GPU multi-instances sur Narval ==
La technologie MIG permettant de partitionner un GPU en plusieurs instances est présentement disponible sur Narval comme projet pilote. Pour plus d'information, consultez la page [[Multi-Instance_GPU/fr|GPU multi-instances]].
= Comment indiquer le type de GPU à utiliser =
Certaines grappes possèdent plus d'un type de GPU; c'est le cas de [[Cedar/fr|Cedar]] et [[Graham/fr|Graham]].
</br>
Sur [[Béluga]], [[Cedar/fr|Cedar]] et [[Graham/fr|Graham]] les GPU sont uniquement disponibles sur certains nœuds.
Si le type de GPU n'est pas spécifié, Slurm pourrait acheminer aléatoirement votre tâche vers un nœud équipé avec n'importe quel type de GPU. Dans certains cas, ceci pourrait ne pas être souhaitable. Assurez-vous donc de spécifier le type de GPU.
= Exemples =


== Tâches avec un seul cœur ==
== Tâches avec un seul cœur ==
Line 25: Line 85:
#!/bin/bash
#!/bin/bash
#SBATCH --account=def-someuser
#SBATCH --account=def-someuser
#SBATCH --gres=gpu:1             # Number of GPUs (per node)
#SBATCH --gpus-per-node=1
#SBATCH --mem=4000M              # memory (per node)
#SBATCH --mem=4000M              # mémoire par nœud
#SBATCH --time=0-03:00           # time (DD-HH:MM)
#SBATCH --time=0-03:00
./program
./program                         # pour tester, utilisez nvidia-smi
}}
}}


== Tâches multifils ==
== Tâches multifils ==
Pour une tâche GPU qui nécessite plusieurs CPUs dans un seul nœud,
Pour une tâche GPU qui nécessite plusieurs CPU dans un seul nœud,
{{File
{{File
   |name=gpu_threaded_job.sh
   |name=gpu_threaded_job.sh
Line 39: Line 99:
#!/bin/bash
#!/bin/bash
#SBATCH --account=def-someuser
#SBATCH --account=def-someuser
#SBATCH --gres=gpu:1             # Number of GPU(s) per node
#SBATCH --gpus-per-node=1         # nombre de GPU par nœud
#SBATCH --cpus-per-task=6        # CPU cores/threads
#SBATCH --cpus-per-task=6        # cœurs/fils CPU
#SBATCH --mem=4000M              # memory per node
#SBATCH --mem=4000M              # mémoire par nœud
#SBATCH --time=0-03:00           # time (DD-HH:MM)
#SBATCH --time=0-03:00
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
./program
./program
}}
}}
Pour chaque GPU, les tâches multifils ne devraient pas dépasser
 
*avec Cedar, 6 cœurs;
Pour chaque GPU demandé, nous recommandons
*avec Graham, 16 cœurs.
* sur Béluga, un maximum de 10 cœurs CPU;
* sur Cedar,
** un maximum de 6 cœurs CPU par GPU de type P100 (p100 et p100l)
** un maximum de 8 cœurs CPU par GPU de type V100 (v100l)
* sur Graham, un maximum de 16 cœurs CPU


== Tâches MPI ==
== Tâches MPI ==
Line 57: Line 121:
#!/bin/bash
#!/bin/bash
#SBATCH --account=def-someuser
#SBATCH --account=def-someuser
#SBATCH --gres=gpu:4              # Number of GPUs per node
#SBATCH --gpus=8                  # nombre total de GPU
#SBATCH --nodes=2                # Number of nodes
#SBATCH --ntasks-per-gpu=1        # 8 processus MPI au total
#SBATCH --ntask=48                # Number of MPI process
#SBATCH --cpus-per-task=6         # cœurs CPU par processus MPI
#SBATCH --cpus-per-task=1         # CPU cores per MPI process
#SBATCH --mem-per-cpu=5G          # mémoire hôte par cœur CPU
#SBATCH --mem=120G                # memory per node
#SBATCH --time=0-03:00            # temps de calcul (JJ-HH:MM)
#SBATCH --time=0-03:00            # time (DD-HH:MM)
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
srun ./program
srun --cpus-per-task=$SLURM_CPUS_PER_TASK ./program
}}
}}


== Nœuds entiers  ==
== Nœuds entiers  ==
Si votre application peut utiliser efficacement un nœud entier et ses GPUs 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.  
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 ===
=== Demander un nœud GPU sur Graham ===
{{File
{{File
   |name=graham_gpu_node_job.sh
   |name=graham_gpu_node_job.sh
Line 77: Line 140:
#!/bin/bash
#!/bin/bash
#SBATCH --nodes=1
#SBATCH --nodes=1
#SBATCH --gres=gpu:2
#SBATCH --gpus-per-node=p100:2
#SBATCH --ntasks-per-node=32
#SBATCH --ntasks-per-node=32
#SBATCH --mem=128000M
#SBATCH --mem=127000M
#SBATCH --time=3:00
#SBATCH --time=3:00
#SBATCH --account=def-someuser
#SBATCH --account=def-someuser
Line 85: Line 148:
}}
}}


=== Ordonnancement d'un nœud GPU pour Cedar ===
=== Demander un nœud GPU P100 sur Cedar ===
{{File
{{File
   |name=cedar_gpu_node_job.sh
   |name=cedar_gpu_node_job.sh
Line 92: Line 155:
#!/bin/bash
#!/bin/bash
#SBATCH --nodes=1
#SBATCH --nodes=1
#SBATCH --gres=gpu:4
#SBATCH --gpus-per-node=p100:4
#SBATCH --ntasks-per-node=24
#SBATCH --exclusive
#SBATCH --exclusive
#SBATCH --mem=125G
#SBATCH --mem=125G
Line 100: Line 164:
}}
}}


=== Ordonnancement d'un nœud ''GPU large'' pour Cedar ===
=== Demander un nœud P100-16G sur Cedar ===


Sur la grappe [[Cedar/fr|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.
Sur [[Cedar/fr|Cedar]] se trouve un groupe particulier de nœuds qui ont chacun quatre cartes Tesla P100 16Go, alors que les autres GPU P100 sont de 12Go et les GPU V100 de 32Go.
Les nœuds de type ''GPU large'' utilisent le même connecteur PCI, ce qui fait que la latence dans les communications entre GPUs est plus faible; cependant, la bande passante entre CPUs et GPUs 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.
Les GPU des nœuds P100L 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 qu'avec des nœuds GPU réguliers. De plus, la mémoire vive des nœuds est de 256Go.
Pour utiliser ces nœuds, il faut demander des nœuds entiers et indiquer <code>lgpu</code>. Les tâches avec GPU ont un '''temps d'exécution maximal de 24 heures'''. Il peut arriver que des tâches GPU courtes soient exécutées sur ces nœuds  par [[Job_scheduling_policies/fr#Remplissage_(backfilling)|remplissage (''backfilling'')]] si aucune tâche pour nœud entier n'est en attente.
Pour utiliser ces nœuds, il faut demander des nœuds entiers et indiquer <code>--gres=gpu:p100l:4</code>. Le temps d'exécution maximal pour les tâches sur GPU P100L est de 28 jours.


{{File
{{File
   |name=large_gpu_job.sh
   |name=p100l_gpu_job.sh
   |lang="sh"
   |lang="sh"
   |contents=
   |contents=
#!/bin/bash
#!/bin/bash
#SBATCH --nodes=1  
#SBATCH --nodes=1  
#SBATCH --gres=gpu:lgpu:4  
#SBATCH --gpus-per-node=p100l:4    
#SBATCH --ntasks=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=24    # There are 24 CPU cores on Cedar GPU nodes
#SBATCH --cpus-per-task=24    # il y a 24 cœurs CPU sur les nœuds GPU P100 de Cedar
#SBATCH --mem=0              # demandez toute la mémnoire du nœud
#SBATCH --time=3:00
#SBATCH --time=3:00
#SBATCH --account=def-someuser
#SBATCH --account=def-someuser
Line 123: Line 188:
===Regroupement de tâches pour un seul GPU===
===Regroupement de tâches pour un seul GPU===


<div class="mw-translate-fuzzy">
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/fr|GNU Parallel]]. Voici un exemple simple&nbsp;:
Pour exécuter pendant '''plus de 24 heures''' quatre programmes qui utilisent un seul GPU ou deux programmes qui utilisent deux GPUs, nous recommandons [https://www.gnu.org/software/parallel/ GNU Parallel]. Voici un exemple simple&nbsp;:
<pre>
<pre>
cat params.input | parallel -j4 'CUDA_VISIBLE_DEVICES=$(({%} - 1)) python {} &> {#}.out'
cat params.input | parallel -j4 'CUDA_VISIBLE_DEVICES=$(({%} - 1)) python {} &> {#}.out'
</pre>
</pre>
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.
L'identifiant du GPU est calculé en soustrayant 1 de l'identifiant de la fente (<i>slot</i>), représenté par {%}. L'identifiant de la tâche est représenté par {#}, avec des valeurs partant de 1.
</div>


<div class="mw-translate-fuzzy">
Le fichier <code>params.input</code> devrait contenir les paramètres sur des lignes distinctes, comme suit&nbsp;:
Le fichier params.input devrait contenir les paramètres sur des lignes distinctes, comme suit&nbsp;:
<pre>
<pre>
code1.py
code1.py
Line 140: Line 202:
...
...
</pre>
</pre>
Vous pouvez ainsi soumettre plusieurs programmes. Dans ce cas, GNU Parallel exécutera jusqu'à quatre tâches concurremment et lancera une tâche aussitôt que la précédente sera terminée. Pour éviter que deux programmes se disputent le même GPU, utilisez CUDA_VISIBLE_DEVICES.
Vous pouvez ainsi soumettre plusieurs tâches. Le paramètre <code>-j4</code> 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.
</div>
 
== Profilage des tâches avec GPU ==
 
Sur [[Béluga]] et [[Narval]],
[https://developer.nvidia.com/dcgm DCGM (NVIDIA Data Center GPU Manager)]
doit être désactivé, et ce losrque vous soumettez la tâche.
Selon l'exemple le plus simple de cette page, le paramètre  <code>--export</code>
est utilisé pour configurer la variable d'environnement  <code>DISABLE_DCGM</code>&nbsp;:
 
{{File
  |name=gpu_profiling_job.sh
  |lang="sh"
  |contents=
#!/bin/bash
#SBATCH --account=def-someuser
#SBATCH --export=ALL,DISABLE_DCGM=1
#SBATCH --gpus-per-node=1
#SBATCH --mem=4000M              # mémoire par nœud
#SBATCH --time=0-03:00
 
# attendez que DCGM soit désactivé sur le nœud
while [ ! -z "$(dcgmi -v {{!}} grep 'Hostengine build info:')" ]; do
  sleep 5;
done
 
./profiler arg1 arg2 ...          # modifiez cette ligne (vous pouvez utiliser Nvprof)
}}
Pour plus d'information sur le profilage, voyez [[Debugging and profiling/fr|Débogage et profilage]].
 
[[Category:SLURM]]

Latest revision as of 20:26, 30 July 2024

Other languages:

Introduction

Pour demander un ou plusieurs GPU pour une tâche, lancez

 --gpus-per-node=[type:]number

À l'intérieur des crochets, vous pouvez indiquer la quantité et le type de GPU. Pour les types, voyez le tableau dans la section GPU disponibles ci-dessous. Voici deux exemples :

 --gpus-per-node=2
 --gpus-per-node=v100:1

Sur la première ligne, on demande deux GPU par nœud, peu importe le type de GPU. Sur la deuxième ligne, on demande 1 GPU par nœud, de type V100.

La forme suivante peut aussi être utilisée

 --gres=gpu[[:type]:number]

Cette forme est cependant moins récente et ne sera probablement plus prise en charge dans les versions de Slurm à venir. Nous vous recommandons de la remplacer dans vos scripts par --gpus-per-node.

Il y a plusieurs autres directives que vous pouvez utiliser pour demander des GPU, par exemple --gpus, --gpus-per-socket, --gpus-per-task, --mem-per-gpu et --ntasks-per-gpu. Voyez la documentation de Slurm sur sbatch. Notre équipe n'a pas testé toutes les combinaisons; si vous n'obtenez pas le résultat voulu, contactez le soutien technique.

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

GPU disponibles

Le tableau suivant liste les GPU qui sont présentement disponibles.

Grappe Qté de nœuds Type de GPU Par nœud Modèle de GPU Attribut
compute
capability(*)
Mémoire GPU (GiB) Remarques
Cœurs CPU Mémoire CPU GPU
Béluga 172 v100 40 191000M 4 V100-16gb 70 16 tous les GPU sont associés au même socket CPU et connectés via NVLink et SXM2
Cedar 114 p100 24 128000M 4 P100-12gb 60 12 deux GPU par socket CPU, connectés par PCIe
32 p100 24 257000M 4 P100-16gb 60 16 tous les GPU sont associés au même socket CPU, connectés par PCIe
192 v100l 32 192000M 4 V100-32gb 70 32 deux GPU par socket CPU; tous les GPU sont connectés via NVLink et SXM2
Graham 160 p100 32 127518M 2 P100-12gb 60 12 un GPU par socket CPU, connecté par PCIe
7 v100 28 183105M 8 V100(**) 70 16 voir Nœuds GPU Volta
2 v100(**) 28 183105M 8 V100(***) 70 32 voir Nœuds GPU Volta-
30 t4 44 192000M 4 T4-16gb 75 16 deux GPU par socket CPU
6 t4 16 192000M 4 T4-16gb 75 16 &nbsp
Mist 54 n.a. 32 256GiB 4 V100-32gb 70 32 voir Mist specifications
Narval 159 a100 48 510000M 4 A100-40gb 80 40 deux GPU par socket CPU; tous les GPU sont connectés via NVLink
Arbutus L'ordonnanceur Slurm ne gère pas les ressources infonuagiques. Voir Ressources infonuagiques pour l'information sur le matériel disponible.

(*) Le terme Compute Capability est utilisé par NVIDIA pour indiquer les fonctionnalités matérielles spécifiques à un GPU particulier et n'a aucun rapport avec la performance des dispositifs. Cet attribut n'est utile que si vous compilez vos propres programmes GPU. Pour plus d'information, voir la page CUDA.

(**) Pour avoir accès à un gabarit pour un nœud V100 de 16Go sur Graham, utilisez les arguments suivants dans la commande sbatch/salloc : --constraint=skylake,v100.

(**) Pour avoir accès à un gabarit pour un nœud V100 de 32Go sur Graham, utilisez les arguments suivants dans la commande sbatch/salloc : --constraint=cascade,v100.

Mist

Mist est une grappe qui comprend des CPU IBM Power9 (et non des Intel x86) et des GPU NVIDIA V100. Si vous avez accès à Niagara, vous avez aussi accès à Mist; voyez les directives sur le site web de SciNet.

GPU multi-instances sur Narval

La technologie MIG permettant de partitionner un GPU en plusieurs instances est présentement disponible sur Narval comme projet pilote. Pour plus d'information, consultez la page GPU multi-instances.

Comment indiquer le type de GPU à utiliser

Certaines grappes possèdent plus d'un type de GPU; c'est le cas de Cedar et Graham.
Sur Béluga, Cedar et Graham les GPU sont uniquement disponibles sur certains nœuds.

Si le type de GPU n'est pas spécifié, Slurm pourrait acheminer aléatoirement votre tâche vers un nœud équipé avec n'importe quel type de GPU. Dans certains cas, ceci pourrait ne pas être souhaitable. Assurez-vous donc de spécifier le type de GPU.

Exemples

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 --gpus-per-node=1
#SBATCH --mem=4000M               # mémoire par nœud
#SBATCH --time=0-03:00
./program                         # pour tester, utilisez nvidia-smi


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 --gpus-per-node=1         # nombre de GPU par nœud
#SBATCH --cpus-per-task=6         # cœurs/fils CPU
#SBATCH --mem=4000M               # mémoire par nœud
#SBATCH --time=0-03:00
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
./program


Pour chaque GPU demandé, nous recommandons

  • sur Béluga, un maximum de 10 cœurs CPU;
  • sur Cedar,
    • un maximum de 6 cœurs CPU par GPU de type P100 (p100 et p100l)
    • un maximum de 8 cœurs CPU par GPU de type V100 (v100l)
  • sur Graham, un maximum de 16 cœurs CPU

Tâches MPI

File : gpu_mpi_job.sh

#!/bin/bash
#SBATCH --account=def-someuser
#SBATCH --gpus=8                  # nombre total de GPU
#SBATCH --ntasks-per-gpu=1        # 8 processus MPI au total
#SBATCH --cpus-per-task=6         # cœurs CPU par processus MPI
#SBATCH --mem-per-cpu=5G          # mémoire hôte par cœur CPU
#SBATCH --time=0-03:00            # temps de calcul (JJ-HH:MM)
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
srun --cpus-per-task=$SLURM_CPUS_PER_TASK ./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.

Demander un nœud GPU sur Graham

File : graham_gpu_node_job.sh

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


Demander un nœud GPU P100 sur Cedar

File : cedar_gpu_node_job.sh

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


Demander un nœud P100-16G sur Cedar

Sur Cedar se trouve un groupe particulier de nœuds qui ont chacun quatre cartes Tesla P100 16Go, alors que les autres GPU P100 sont de 12Go et les GPU V100 de 32Go. Les GPU des nœuds P100L 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 qu'avec des nœuds GPU réguliers. De plus, la mémoire vive des nœuds est de 256Go. Pour utiliser ces nœuds, il faut demander des nœuds entiers et indiquer --gres=gpu:p100l:4. Le temps d'exécution maximal pour les tâches sur GPU P100L est de 28 jours.


File : p100l_gpu_job.sh

#!/bin/bash
#SBATCH --nodes=1 
#SBATCH --gpus-per-node=p100l:4     
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=24    # il y a 24 cœurs CPU sur les nœuds GPU P100 de Cedar
#SBATCH --mem=0               # demandez toute la mémnoire du nœud
#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.

Profilage des tâches avec GPU

Sur Béluga et Narval, DCGM (NVIDIA Data Center GPU Manager) doit être désactivé, et ce losrque vous soumettez la tâche. Selon l'exemple le plus simple de cette page, le paramètre --export est utilisé pour configurer la variable d'environnement DISABLE_DCGM :


File : gpu_profiling_job.sh

#!/bin/bash
#SBATCH --account=def-someuser
#SBATCH --export=ALL,DISABLE_DCGM=1
#SBATCH --gpus-per-node=1
#SBATCH --mem=4000M               # mémoire par nœud
#SBATCH --time=0-03:00

# attendez que DCGM soit désactivé sur le nœud
while [ ! -z "$(dcgmi -v | grep 'Hostengine build info:')" ]; do
  sleep 5;
done

./profiler arg1 arg2 ...          # modifiez cette ligne (vous pouvez utiliser Nvprof)


Pour plus d'information sur le profilage, voyez Débogage et profilage.