Jobs sur noeuds GPU

Les noeuds GPU sur le clusters Bigfoot de GRICAD

Pour les simulations nécessitant des cartes GPU pour s’exécuter, plusieurs noeuds vous sont accessibles :

  • noeuds de 4 GPUs NVIDIA Tesla V100 NVLink
  • noeuds avec 2 NVIDIA A100
  • noeuds avec 4 AMD MI210/XGMI
  • noeuds Virgo accessibles la nuit avec des GPU T4.

Utilisation

Le cluster “Bigfoot” est dédié aux calculs nécessitant l’usage de noeuds délivrant de la puissance de calcul par le biais de co-processeurs, actuellement des GPGPU. L’accès se fait de manière classique, depuis les bastions SSH de Gricad, vers la frontale bigfoot:

login@trinity:~$ ssh bigfoot
Linux bigfoot 4.19.0-18-amd64 #1 SMP Debian 4.19.208-1 (2021-09-29) x86_64
                       Welcome to Bigfoot cluster! 

                             :            :
                            .'            :
                        _.-"              :
                    _.-"                  '.
    ..__...____...-"                       :
   : \_\                                    :
   :    .--"                                 :
   `.__/  .-" _                               :
      /  /  ," ,-                            .'
     (_)(`,(_,'L_,_____       ____....__   _.'
      "' "             """""""          """   

GPU, GPU, GPU, ... ;-)

            Type 'chandler' to get cluster status  
          Type 'recap.py' to get cluster properties

Sample OAR submissions: 
  # Get a A100 GPU and all associated cpu and memory resources:
  oarsub -l /nodes=1/gpu=1 --project test -p "gpumodel='A100'" "nvidia-smi -L"
  # Get a MIG partition of an A100 on a devel node, to make some tests
  oarsub -l /nodes=1/gpu=1/migdevice=1 --project test -t devel "nvidia-smi -L"

Last login: Mon Jan 10 17:37:43 2022 from 129.88.178.43
login@bigfoot:~$ 

La commande chandler permet d’avoir un aperçu des ressources disponibles et de leur état instantané.

Plusieurs modèles de GPU sont disponibles. La commande recap.py donne des informations à jour sur la configuration matérielle des différents noeuds, en particulier le modèle et le nombre de GPU disponible à l’intérieur des noeuds:

login@bigfoot:~$ recap.py 
 ================================================================================
|   node  | cpumodel       | gpumodel  | gpus | cpus | cores| mem | mem/gpu |MIG|
 ================================================================================
|bigfoot1 | intel Gold 6130| V100      |   4  |   2  |   32 | 192 |   96  |  NO |
|    [ + 1  more node(s) ]                                                      |
|bigfoot3 | intel Gold 6130| V100      |   4  |   2  |   32 | 192 |   96  |  NO |
|bigfoot4 | intelGold 5218R| V100      |   4  |   2  |   40 | 192 |   96  |  NO |
|    [ + 1  more node(s) ]                                                      |
|bigfoot6 | intelGold 5218R| V100      |   4  |   2  |   40 | 192 |   96  |  NO |
|bigfoot7 | amd   EPYC 7452| A100      |   2  |   2  |   64 | 192 |   96  | YES |
|bigfoot8 | intelGold 5218R| V100      |   4  |   2  |   40 | 192 |   48  |  NO |
|bigfoot9 | amd   EPYC 7452| A100      |   2  |   2  |   64 | 192 |   96  |  NO |
|    [ + 2  more node(s) ]                                                      |
|bigfoot12| amd   EPYC 7452| A100      |   2  |   2  |   64 | 192 |   96  |  NO |
|bigfoot13| intelSilver 4130| MI210     |   4  |   2  |   24 | 256 |   64  |  NO |
|bigfoot14| intelSilver 4130| MI210     |   4  |   2  |   24 | 256 |   64  |  NO |
|virgo1   | intel      vcpu| T4        |   1  |   1  |    2 |   4 |    4  |  NO |
|    [ + 33 more node(s) ]                                                      |
|virgo35  | intel      vcpu| T4        |   1  |   1  |    2 |   4 |    4  |  NO |
 ================================================================================
 # of GPUS: 10 A100, 28 V100, 8 MI210, 35 T4

login@bigfoot:~$ 

Les noeuds, hors noeuds Virgo T4, sont interconnectés via le même réseau à faible latence Omnipath que le cluster Dahu.

Les noeuds Virgo sont des noeuds utilisés pour l’enseignement en journée (un noeud reste disponible pour des tests) mais qui peuvent être utilisés pour des jobs la nuit.

Les espaces de stockage habituels sont disponibles depuis la frontale et tous les noeuds:

  • /home : un espace dédié au cluster Bigfoot, pour bien distinguer les environnements
  • /bettik : espace de travail capacitif à haute performance, partagé avec les clusters Dahu et Luke
  • /silenus : scratch temporaire à ultra haute performance (SSD/NVMe), partagé avec le cluster Dahu
  • Mantis : espace de stockage de type cloud géré sous iRods

Environnement logiciel

Les environnements classiques NIX et GUIX sont disponibles et partagés avec les clusters Dahu et Luke, ainsi que le répertoire d’applications spécifique /applis.

Pour installer les librairies couramment utilisées dans le calcul sur GPU, vous pouvez utiliser les environnements conda prédéfinis.

Pour utiliser les GPUs NVIDIA, il faudra également sourcer le toolkit CUDA adéquat. Vous pouvez utiliser le script suivant en passant le nom du cluster et la version du toolkit souhaitée. Exemple pour le toolkit version 11.7:

user@bigfoot:~$ source /applis/environments/cuda_env.sh 11.7

Pour lister les toolkits disponibles sur un cluster utilisez le script cuda_env.sh.

user@bigfoot:~$ source /applis/environments/cuda_env.sh -l

Lancement des jobs

Pour lancer un job, nous utilisons le gestionnaire de ressources OAR (dont les commandes essentielles sont décrites dans cette page.), et plus particulièrement la commande oarsub.

La particularité sur le cluster Bigfoot, est que l’unité de ressource à demander est généralement une gpu. Les autres ressources des noeuds de calcul (cpu-core et mémoire) ont été réparties et associées aux gpu en fonction de la configuration matérielle des noeuds qui est hétérogène.

Il est conseillé (mais pas obligatoire) de préciser le modèle de GPU que vous souhaitez obtenir sur vos noeuds de calcul, en exploitant la propriété OAR gpumodel.

L’exemple suivant donne les options minimales permettant de soumettre un job nécessitant une seule gpu sur un noeud qui dispose de GPU Nvidia A100:

oarsub -l /nodes=1/gpu=1 -p "gpumodel='A100'" ...

OAR allouera également au prorata, un certain nombre de coeurs de calcul généralistes (cpu-cores) et un certain volume de mémoire.

Cet autre exemple de job obtiendra 2 GPU Nvidia A100 sur le même noeud, ainsi que les ressources cpu et mémoire associées:

oarsub -l /nodes=1/gpu=2 -p "gpumodel='A100'" ...

OAR alloue les unités GPU en fonction de la propriété gpudevice. Pour connaître quelles sont les unités allouées, il faut utiliser, une fois sur le noeud (en interactif) la commande oarprint :

user@bigfoot2:~$ oarprint gpudevice
1
0

Cette même commande vous permet aussi de connaitre les cpu-cores associées aux gpudevice:

user@bigfoot8:~$ oarprint -P gpudevice,cpuset core
0 3
1 12
1 18
0 9
0 1
1 17
1 14
0 5
1 10
1 16
0 8
0 4
0 6
1 15
0 7
1 11
0 2
1 13
0 0
1 19

Ici, on a obtenu 20 coeurs de calcul et 2 GPU, chaque GPU étant associée à 10 coeurs dont on a listé le rang au sein du noeud de calcul.

Pour connaitre le montant de mémoire centrale alloué, on peut interroger le cgroup du job de la manière suivante:

user@bigfoot8:~$ cat /dev/oar_cgroups_links/memory/`cat /proc/self/cpuset`/memory.limit_in_bytes
100693262336

Ce montant de mémoire varie en fonction du nombre de GPU obtenues sur le noeud et en fonction des caractéristiques du noeud. La propriete mem_per_gpu (en Go) permet de connaitre la configuration des noeuds et de mettre des contraintes à la soumission des jobs sur la quantité de mémoire centrale nécessaire au job. Par exemple:

oarsub -l /nodes=1/gpu=2 -p "gpumodel='A100' and mem_per_gpu > 64"...

Pour les GPU Nvidia, la commande nvidia-smi permet d’obtenir des informations sur les GPU accessibles. Elle permet d’ailleurs de voir que OAR ne permettera d’accéder qu’aux GPU qui ont été allouées:

user@bigfoot:~$ oarsub -l /nodes=1/gpu=2 -p "gpumodel='V100'" --project test -I
[ADMISSION RULE] Set default walltime to 7200.
[ADMISSION RULE] Modify resource description with type constraints
OAR_JOB_ID=293
Interactive mode: waiting...
Starting...
Connect to OAR job 293 via the node bigfoot8
user@bigfoot8:~$ nvidia-smi -L
GPU 0: Tesla V100-SXM2-32GB (UUID: GPU-263f55be-a11c-81be-8af6-e948471cb954)
GPU 1: Tesla V100-SXM2-32GB (UUID: GPU-9e4e2b6c-19ea-73ef-7026-00619f988787)
bzizou@bigfoot8:~$ logout
Connection to bigfoot8 closed.
Disconnected from OAR job 293.
user@bigfoot:~$ oarsub -l /nodes=1/gpu=1 -p "gpumodel='A100'" --project test -I
[ADMISSION RULE] Set default walltime to 7200.
[ADMISSION RULE] Modify resource description with type constraints
OAR_JOB_ID=294
Interactive mode: waiting...
Starting...
Connect to OAR job 294 via the node bigfoot12
user@bigfoot12:~$ nvidia-smi -L
GPU 0: NVIDIA A100-PCIE-40GB (UUID: GPU-45d882aa-be45-3db7-bd3a-06da9fcaf3b1)
user@bigfoot12:~$ logout

Limitations

Le walltime maximum est de 48h. Cela est necessaire afin de permettre un turnover raisonnable pour un partage équitable des ressources. C’est aussi nécessaire pour faciliter les opérations de maintenance et de mise à jour de la machine. Si vos jobs nécessitent un temps d’éxécution plus long, vous devez alors mettre en place ou utiliser des fonctionnalités de checkpoint au sein de vos applications (c’est à dire que vos applications doivent pouvoir sauver leur état dans des fichiers afin de pouvoir redémarrer plus tard sur un cet état en chargeant ces fichiers).

Soumettre un job à l’aide d’un script de soumission

La soumission d’un job CPU à l’aide d’un script est expliquée sur cette page.

La soumission d’un job GPU se déroule de la même manière, à l’exception du contenu du dump.sh, dont voici le contenu :

#!/bin/bash

#OAR -n Hello_World
#OAR -l /nodes=1/gpu=1,walltime=00:01:30
#OAR -p gpumodel='A100'
#OAR --stdout hello_world.out
#OAR --stderr hello_world.err
#OAR --project test

cd /bettik/bouttier/
/bin/hostname >> dumb.txt

Dans cet exemple, nous demandons un job sur GPU A100.

#OAR -p gpumodel='A100'

Contrairement à la soumission interactive, dans un script de soumission, -p gpumodel='A100' ne s’écrit pas en guillemets.

Noeuds GPU AMD

Les GPU AMD s’exploitent via les couches “amdgpu” et “rocm”.

Pour joindre ces noeuds spécifiques, il faut ajouter le type de job amd, par exemple:

user@bigfoot:~$ oarsub -t amd -l /nodes=1/gpu=2 --project test -I

ou encore, en mode directives dans un script:

#!/bin/bash                                                                                                                  

#OAR -n Hello_World
#OAR -l /nodes=1/gpu=1,walltime=00:01:30
#OAR -p gpumodel='MI210'
#OAR -t amd
#OAR --stdout hello_world.out
#OAR --stderr hello_world.err
#OAR --project test

Au niveau de l’environnement, nous vous conseillons le shell NIX suivant, fournissant les utilitaires rocm, opencl et openmpi incluant les drivers pour exploiter les liens XGMI. Vous pouvez copier/coller intégralement cette section dans un job interactif sur votre noeud:

source /applis/site/nix.sh
NIX_PATH="nixpkgs=channel:nixos-23.05" nix-shell -p nur.repos.gricad.openmpi4 -p nur.repos.gricad.ucx -p rocm-smi -p clinfo -p rocm-opencl-runtime -p rocm-opencl-icd

Ou lancer votre programme en passif en le préfixant par le nix-shell de la façon suivante dans un script:

source /applis/site/nix.sh
export NIX_PATH="nixpkgs=channel:nixos-23.05" 
nix-shell --command <./votre_programme> -p nur.repos.gricad.openmpi4 -p nur.repos.gricad.ucx -p rocm-smi -p clinfo -p rocm-opencl-runtime -p rocm-opencl-icd

Voici un exemple plus complet, vous permettant de configurer OpenCL localement, en interactif:

$ source /applis/site/nix.sh
$ NIX_PATH="nixpkgs=channel:nixos-23.05" nix-shell -p nur.repos.gricad.openmpi4 -p nur.repos.gricad.ucx -p rocm-smi -p clinfo -p rocm-opencl-runtime -p rocm-opencl-icd
[nix-shell:~]$ mkdir -p ~/.local/etc/OpenCL/vendors
[nix-shell:~]$ echo `nix eval --raw nixpkgs.rocm-opencl-runtime.outPath`/lib/libamdocl64.so > ~/.local/etc/OpenCL/vendors/amdocl64.icd
[nix-shell:~]$ export OCL_ICD_VENDORS=~/.local/etc/OpenCL/vendors/amdocl64.icd
[nix-shell:~]$ clinfo                                                                                                                                                                                                                                      
Number of platforms                               1                                                                          
  Platform Name                                   AMD Accelerated Parallel Processing

  [...]

Les commandes suivantes vous permettent d’avoir des informations sur les GPUS AMD:

[nix-shell:~]$ rocminfo
rocm-smi  --showhw
rocm-smi --showtopo
rocm-smi --shownodesbw

Exemple de compilation et runtime avec le code IDEFIX:

#Test of IDEFIX application developped with KOKKOS (https://kokkos.org/) 
#The Kokkos C++ EcoSystem is a solution for writing modern C++ applications, a programming model for performance and portability. 

#Compilation of IDEFIX code in a nix shell :

user@bigfoot:~$ cd idefix-bench/benchmark
user@bigfoot:~/idefix-bench/benchmark$ NIX_PATH="nixpkgs=channel:nixpkgs-unstable"
user@bigfoot:~/idefix-bench/benchmark$ . ./sourceMeFirst.sh
user@bigfoot:~/idefix-bench/benchmark$ nix-shell -p nur.repos.gricad.openmpi4 -p nur.repos.gricad.ucx -p rocm-smi -p hip -p cmake

#The cmake options to compile for AMD HIP:  "-DKokkos_ENABLE_HIP=ON -DKokkos_ARCH_VEGA90A=ON"  (for AMD Mi200/Mi250X)
#The HIP C°° compiler command is "hipcc".

user@bigfoot:~/idefix-bench/benchmark$ cmake $IDEFIX_DIR -DKokkos_ENABLE_HIP=ON -DKokkos_ARCH_VEGA90A=ON -DCMAKE_CXX_COMPILER=hipcc
user@bigfoot:~/idefix-bench/benchmark$ make

user@bigfoot:~/idefix-bench/benchmark$ oarsub -I -lnodes=1 --project admin -t amd 
user@bigfoot14:~/idefix-bench/benchmark$ . /applis/site/nix.sh
user@bigfoot14:~/idefix-bench/benchmark$ mpirun  -np 2 --mca btl '^openib' -x UCX_TLS=sm,self,rocm_copy,rocm_ipc --mca pml ucx -x UCX_RNDV_THRESH=128 --mca osc ucx ./idefix

Mode devel: le bac-à-sable

Le mode de soumission particulier -t devel est disponible pour faciliter la mise au point des jobs. Il est limité à des jobs de 2 heures maximum, et alloue des ressources sur des noeuds dédié à ce mode. Cela permet d’avoir des ressources de type bac-à-sable beaucoup plus disponibles que les ressources de production.

Mais attention, ce bac-à-sable fonctionne sur des GPU plus petites, qui sont en fait des partitions de GPU Nvidia A100. Chaque GPU Nvidia A100 du mode devel est en fait une sous-gpu, que l’on appellera mig par abus de language (MIG=Multi Instance GPU). Aussi la sélection des ressources diffère un peu, et il faudra préciser le nombre de migdevice que l’on veut. En général on n’en demandera qu’un seul car cela n’a pas vraiment de sens de travailler sur plusieurs:

oarsub -l /nodes=1/gpu=1/migdevice=1,walltime=00:10:00 -t devel ...

Noeuds virtuels “Virgo”: T4 GPU pour calculs opportunistes

Le cluster bigfoot héberge également des noeuds “virtuels” auxquels sont associés des petites GPU Nvidia T4. Ces GPU sont utilisées la journée par des étudiants au cours de leurs formations. Elles sont mises à disposition par le projet Fall.

La nuit, à partir de minuit, les machines virtuelles sont allumées en allouant un GPU physique. Les noeuds virgo deviennent actifs dans le cluster Bigfoot, offrant ainsi des ressources Nvidia T4 aux jobs en attente de ce gpumodel. Les machines virtuelles sont éteintes à 6h du matin. Les jobs doivent donc être suffisamment courts (walltime inférieur à 6h) afin d’être autorisés sur ces ressources.

oarsub -l /nodes=1/gpu=1,walltime=04:00:00 -p "gpumodel='T4'" ...