Gestion des jobs avec SLURM
Sur le cluster du Mésocentre Clermont Auvergne, les ressources gérées par SLURM sont les CPU (ou plus précisément les coeurs logiques), la RAM et les cartes accélératrices (GPU, MIC). Il faut donc quantifier ces ressources lors de la soumission d'un job pour que SLURM puisse les réserver.
Description d'un job
Un job va être décrit typiquement par un script de soumission. Il peut contenir des directives pour décrire les ressources demandées (ligne commençant par #SBATCH). Ces directives correspondent ensuite aux options de la commande sbatch.
Voici un exemple de script (bash) de soumission (réservation d'un CPU quelconque pendant 20 secondes):
#!/bin/bash
#SBATCH --job-name=sleeping
#SBATCH --time=00:20
#SBATCH --ntasks=1
hostname
sleep 10
echo Fin du job.
Voici les options les plus courantes :
--ntasks: spécification du nombre max de tâches du job (avec par défaut 1 CPU par tâche)--cpus-per-task: nombre de cpu demandés par tâche. Pour un job faisant fonctionner un programme multithread sur un seul noeud, on choisira par exemple--ntasks=1 --cpus-per-task=8si l'on souhaite 8 coeurs à affecter aux threads.--hint=nomultithread: option permettant de spécifier que les coeurs logiques supplémentaires présentés pour chaque coeur physique (HyperThreading pour Intel, SMT pour AMD) soient réservés pour le job et pas pour un autre job, assurant ainsi que le job ne sera pas perturbé par le partage de coeur physique.--hint=multithread: le job peut partager les coeurs logiques communs à un même coeur physique, ils ne sont pas réservés pour le job.--tmp=4G: le job a besoin de 4 Go dans l'espace de travail/storage/scratch/disponible sur chaque noeud. Cela permet d'éliminer, dans la sélection des noeuds, des serveurs de calcul qui ne disposeraient pas - au moment du lancement du job - d'assez d'espace de travail pour faire fonctionner le job.--partition: spécification de la partition pour l'allocation de ressources--mem-per-cpu: spécification de la quantité de RAM allouée à chaque CPU--constraint: sélection uniquement de nœuds avec une certaine feature (par exemple--constraint=ivypour des processeurs Ivy Bridge)--time: spécification de la durée maximale du job--output: nom du fichier de sortie (redirection de la sortie standard)--error: nom du fichier d'erreurs (redirection de la sortie d'erreurs)--mail-user: spécification d'une adresse email pour recevoir les notifications par mail--mail-type: spécification des notifications à envoyer (ALL, BEGIN, END, TIME_LIMIT, TIME_LIMIT_90...), en utilisant la virgule comme séparateur.
La page de manuel de la commande sbatch permet d'obtenir la liste complète des options et de leur syntaxe.
Soumission d'un job
La commande pour soumettre un job est sbatch qui prend en argument le nom du script à soumettre, et des options pour spécifier l'allocation de ressources. Les options de la lignes de commande sont prioritaires sur les directives #SBATCH présentes dans le script (cf. supra). La commande sbatch renvoie l'id du job si les ressources demandées sont compatibles avec les ressources existantes (sans présumer de leur disponibilité). La commande squeue permet ensuite de voir la liste des jobs et de suivre l'état d'un job.
[user1@hpc2 ~]$ sbatch monscript.sh
Submitted batch job 606
[user1@hpc2 ~]$ squeue
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
606 normal sleeping user1 R 0:00 1 hpcnode01
602 normal abinit.s user2 R 4:31:47 1 hpcnode01
[user1@hpc2 ~]$ squeue --job 606
JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)
606 normal sleeping user1 R 0:09 1 hpcnode01
La commande squeue --start permet d'avoir une estimation (maximale) de la date de démarrage des jobs en attente.
Un job peut être annulé par le propriétaire avec la commande scancel.
Annulation d'un job
La commande pour annuler un job est scancel qui prend en argument l'identifiant du job.
[user1@hpc2 ~]$ scancel 606
Jobs interactifs
Un job interactif permet d'ouvrir une console interactive sur un nœud de calcul. Cela permet de tester rapidement une ligne de commande, de lancer une compilation complexe, ou de lancer une console interactive python ou R par exemple. A l'instar de la commande sbatch, il est possible de spécifier les ressources du job via les options de la ligne de commande et le job est mis en attente le temps que les ressources demandées soient disponibles.
Pour lancer un job interactif, il faut utiliser la commande srun avec l'option --pty:
[user1@hpc2 ~]$ srun --ntasks=2 --ntasks-per-node=2 --mem=4g --pty bash
srun: job 7043 queued and waiting for resources
srun: job 7043 has been allocated resources
[user1@hpcnode20 ~]$ echo $SLURM_JOB_ID
7043
[user1@hpcnode20 ~]$ echo $SLURM_CPUS_ON_NODE
2
[user1@hpcnode20 ~]$ make -j2
...
[user1@hpcnode20 ~]$ exit
Jobs parallèles
Un job parallèle est un job qui alloue plusieurs CPUs simultanément. Il peut s'agir d'un code multithreadé (un seul processus sur plusieurs cœurs sur un seul nœud) ou d'un code MPI qui va être distribué sur un ou plusieurs nœuds.
Bonnes pratiques
Ne pas lancer de job de production dans votre home
Il est préférable surtout pour les grands jeux de données d'utiliser la variable $SCRATCH plutôt que $HOME
$HOME est approprié pour du stockage permanent de petits fichiers tels que les codes sources, les librairies, les fichiers de configuration ou de scripts, etc.
$SCRATCH est réservé au stockage temporaire de gros fichiers. Il est optimisé pour les opérations de lecture et d'écriture. Il se prête à la parallélisation des calculs.
Limiter le temps d'exécution d'un job
Même si la partition (fast,normal,long,debug,smp) est définie dans le script, l'usage du pragma #SBATCH --time=<upper-bound> permet généralement au job de démarrer plus tôt.
Les jobs longs
Les simulations qui doivent tourner sur plusieurs jours ont un meilleur taux de succès si elles sont décomposés en plusieurs petits jobs utilisant un chaînage de type checkpoint/restart