IMPORTANT : fonctionnement du cluster
Vous ne devez pas exécuter votre code / logiciel directement sur la machine de connexion login-hpc.
Vous devez travailler sur une machine (=nœud) de calcul. Pour cela, vous devez d’abord demander à utiliser une ou plusieurs machines via un ordonnanceur nommé Slurm.
Votre demande peut-être résumée dans un fichier. Vous devez ensuite lancer la commande sbatch nom_de_votre_fichier sur login-hpc pour demander une allocation de machine qui exécutera votre code.
Pour les exécutions de courte durée, se référer à la partie sur le mode interactif.
Les sections ci-dessous vous expliquent tout en détail.
Paramétrer sa réservation de ressources
Les réservations sur le cluster se font via le scheduler Slurm, qui met les jobs soumis en file d’attente jusqu’à l’allocation des ressources.
Important : lors de la soumission d’un job, les informations suivantes sont nécessaires :
- account= le nom du groupe projet qui vous a été attribué par le comité scientifique (reçu par e-mail)
- partition= la file sur laquelle votre job sera envoyé. Par défaut, si aucune partition n’est spécifiée, le job est envoyé sur cpucourt. Veillez à choisir la bonne partition en fonction des besoins de votre job (temps, ressources). Voir la description des partitions ici.
- time= temps (aussi appelé walltime) au bout duquel votre job sera arrêté par Slurm (avec time=jj-hh:mm:ss). Le walltime de votre job doit être inférieur ou égal au walltime maximum défini pour la partition sur laquelle vous soumettez votre job (voir les limites ici).
- les ressources que vous souhaitez réserver (par défaut, 1 coeur). Vous pouvez notamment utiliser :
- -n ou –ntasks= pour le nombre de tâches à exécuter. Par défaut, Slurm alloue un coeur par tâche. Si votre job est séquentiel (aucune parallélisation), définir uniquement ntasks égal à 1. Donner une valeur supérieure à 1 pour les jobs MPI.
- -N ou –nodes= pour le nombre de noeuds. S’il n’est pas spécifié, l’allocation se basera sur les autres options de ressources. Si vous ne spécifiez que le nombre de noeuds, avec la file cpucourt (qui n’est pas exclusive) cela réservera par défaut 1 coeur par noeud réservé.
- cpus-per-task= à utiliser pour les jobs OpenMP. Cette option spécifie le nombre de threads voulus (à associer avec ntasks=1). Slurm alloue un coeur par cpu.
- ntasks-per-node= nombre de tâches à effectuer sur un même noeud.
- ntasks-per-socket= nombre de tâches à effectuer sur un même processeur. Pour rappel, les noeuds des files cpucourt et cpulong disposent de 2 processeurs de 20 coeurs chacun.
- constraint=intel ou amd selon le type de processeur que vous voulez utiliser (plus de détails sur cette page)
Attention : même si votre job n’a pas terminé son exécution une fois le walltime atteint, votre job sera automatiquement arrêté. Il vous est donc fortement recommandé de bien estimer le temps d’exécution de votre job et d’introduire des points de reprise dans votre code.
Soumettre un job
Dans un script
Pour lancer le job : sbatch nom_de_votre_fichier
La liste complète des options lors de la soumission d’un job est à retrouver ici.
Exemple de script nommé « myJob » qui permet d’exécuter 5 tâches (ici une tâche prendra 1 coeur). Les ressources seront réservées pendant 2 heures maximum et le job sera envoyé sur la file des jobs courts (cpucourt).
#!/bin/bash
#SBATCH --job-name=myJob
#SBATCH --output=output.txt
#SBATCH --ntasks=5
#SBATCH --time=0-02:00:00 #SBATCH --account=nom_de_votre_projet
#SBATCH --partition=cpucourt
#SBATCH --mail-user=...@univ-cotedazur.fr
#SBATCH --mail-type=BEGIN,END,FAIL
module purge
module load ...
mes commandes pour exécuter le job ...
Bien que facultatives, les commandes mail-user et mail-type vous permettent de recevoir par e-mail des notifications sur l’état de votre job.
Les modules permettent de modifier de manière dynamique les variables d’environnement nécessaires à l’exécution de votre code (essentiellement PATH, LD_LIBRARY_PATH ou encore MAN_PATH), en fonction du module que vous chargez. Pour plus d’informations sur l’utilisation des modules, cliquez ici. La liste complète des modules installés sur le cluster est consultable ici.
Jobs OpenMP
Avec OpenMP, la parallélisation ne peut se faire qu’entre les différents threads d’un seul et même nœud. Il est donc recommandé de définir ntasks à 1 afin que l’exécution du code ne soit lancée qu’une seule fois. Le nombre de threads voulus est à définir avec cpus-per-tasks, qui correspond au nombre de cœurs qui seront alloués au job sur ce nœud. Voici un exemple :
#!/bin/bash
#SBATCH --job-name=myJob #SBATCH --nodes=1 #SBATCH --ntasks=1
#SBATCH --cpus-per-task=12
#SBATCH --time=0-02:00:00 #SBATCH --account=projectname
#SBATCH --partition=cpucourt
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
Jobs MPI
Jobs Python
Voir cette page pour créer votre environnement Miniconda.
GPU
Pour les jobs utilisant le GPU, il faut obligatoirement rajouter les deux options ci-dessous, gres étant le nombre de cartes GPU à réserver par nœud (entre 1 et 4).
#SBATCH --gres=gpu:1
#SBATCH --partition=gpu
Attention, dans certains codes utilisant la notation cuda:0 vous devez absolument remplacer cette notation par cuda:$CUDA_VISIBLE_DEVICES afin que votre job tourne bien sur la ou les cartes graphiques attribuées.
Si vous souhaitez préciser le type carte GPU (A100 ou V100), voir cette page.
Pour définir le nombre de cœurs utilisables par carte GPU, vous pouvez rajouter l’option suivante :
#SBATCH
--cpus-per-gpu=
Pour utiliser plus de 4 GPUs dans un même job, vous devez renseigner les options nodes et tasks-per-node. Exemple d’en-tête de job qui utilisera au total 6 GPUs (3 GPUs sur 2 nœuds) :
#!/bin/bash #SBATCH --job-name=gpujob #SBATCH --time=09:00:00 #SBATCH --ntasks=2 #SBATCH --nodes=2 #SBATCH --tasks-per-node=1 #SBATCH --account=projectname #SBATCH --partition=gpu #SBATCH --gres=gpu:3
En mode interactif
Le mode interactif est une alternative au mode « j’envoie mon script avec sbatch et je le laisse tourner ».
Ce mode vous permet de lancer un shell interactif sur un nœud de calcul afin que vous puissiez directement travailler dessus. Il est particulièrement adapté aux cas suivants :
- vous voulez lancer des exécutions qui durent peu de temps
- vous voulez compiler un code
- vous voulez désarchiver un fichier
- vous utilisez un logiciel avec lequel il vous est nécessaire d’interagir en temps réel
Ce mode est idéal pour toute exécution de serveur type Jupyter.
Pour lancer un shell interactif bash pendant 1h sur la partition cpucourt :
srun -A mon_account_Slurm -p cpucourt -t 01:00:00 --pty bash -i
Dans cet exemple, il n’y a pas d’option -N ou -n donc un seul cœur sera réservé.
Pour un job sur GPU, il faut indiquer le nombre de cartes GPU voulues (ici 1) :
srun -A mon_account_Slurm -p gpu --gres=gpu:1 -t 01:00:00 --pty bash -i
Jupyter
Sur le noeud de visualisation
Réserver des nœuds en mode exclusif
Le mode par défaut sur Azzurra est le mode partagé. Ce qui signifie que lorsque vous réservez un certain nombre de coeurs sur un ou plusieurs noeuds, d’autres jobs que le vôtre peuvent tourner sur les coeurs restants de ce(s) noeud(s).
En mode exclusif, vous réservez tous les cœurs d’un ou plusieurs nœuds. Aucun autre job ne tournera en même temps que le vôtre sur le(s) nœud(s) réservé(s). Cependant, même si votre job n’utilise pas tous les cœurs d’un même nœud, Slurm considèrera que vous avez consommé le temps écoulé pour le job fois le nombre total de cœurs réservés.
Ajoutez cette option pour passer en mode exclusif:
#SBATCH --exclusive (dans un script) ou --exclusive (en ligne de commande)
Dépendances entre jobs
Si vous avez besoin d’envoyer une série de jobs, mais qu’ils doivent s’exécuter les uns après les autres, vous pouvez inclure des dépendances.
Dans l’exemple ci-dessous, on envoie un premier job, et lorsque celui-ci est terminé, un nouveau job pourra débuter. L’exemple montre un cas avec un job initial puis 5 jobs dépendants les uns des autres. Vous pouvez évidemment l’adapter à vos besoins. Pensez à remplacer code.sh par le programme que vous voulez lancer et adapter les options slurm (account, partition, etc.).
#!/bin/sh id=$(sbatch --parsable --account=your_account --partition=cpucourt --job-name=job-initial --ntasks=1 --output=outjob.txt code.sh) echo "job 1 has jobid $id" for n in {1..5}; do id=$(sbatch --parsable --account=your_account --partition=cpucourt --depend=afterany:$id --job-name=iteration-$n --ntasks=1 --output=output-iter-$n.slurmout code.sh); echo "job $n has jobid $id" done