Jean Zay : exécution de travaux multi-étapes et en cascade

Utilisation de la notion d'étape avec Slurm

Certains utilisateurs ont développé des chaînes de traitement complexes (flux de données), qui consistent à enchaîner des travaux dont les caractéristiques peuvent être différentes (nombre de cœurs, temps de calcul et mémoire nécessaires). Les fichiers de sortie d'un travail sont souvent utilisés comme fichiers d'entrée du travail suivant, ce qui ajoute des relations d'interdépendance entre les travaux. Slurm permet de gérer cette problématique d'une façon simple et efficace : chaque étape est définie dans un fichier à exécuter auquel sont associées des ressources propres (nombre de cœurs, mémoire, temps). Un travail multi-étapes consistera à définir autant d'étapes que de travaux à exécuter, ainsi que les relations d'interdépendance entre ces étapes : de cette façon, à chaque étape, les ressources réservées correspondent exactement aux ressources utilisées.

Enchaînement des travaux

Pour soumettre un job multi-étape sur Jean Zay, il faut :

  • Créer un script Bash qui soumet plusieurs travaux Slurm (un job par étape) : à la soumission de chacune des étapes du calcul, on récupère le JOB_ID correspondant pour le transmettre lors de la soumission de l'étape suivante : le JOB_ID du travail est le quatrième champ dans le retour de la commande sbatch (commande cut).
    Dans l'exemple suivant, quatre étapes sont soumises, chaque étape (sauf la première) dépend de l'étape précédente et ne s’exécutera que si celle-ci s'est bien terminée (--dependency=afterok).

    multi_steps.bash
    #!/bin/bash
    JID_JOB1=`sbatch job1.slurm | cut -d " " -f 4`
    JID_JOB2=`sbatch --dependency=afterok:$JID_JOB1 job2.slurm | cut -d " " -f 4`
    JID_JOB3=`sbatch --dependency=afterok:$JID_JOB2 job3.slurm | cut -d " " -f 4`
    sbatch --dependency=afterok:$JID_JOB3 job4.slurm

    Attention : ce script n'est pas un travail Slurm, c'est un script bash à lancer de la façon suivante :

    $ chmod +x multi_steps.bash
    $ ./multi_steps.bash


  • Écrire toutes les étapes (jobN.slurm) comme étant des travaux indépendants : chaque étape soumise via la commande sbatch est un travail Slurm classique, comme ceux décrits dans la documentation disponible dans les rubriques Exécution/Contrôle d'un code CPU ou Exécution/Contrôle d'un code GPU. De cette façon, vous pouvez spécifier indépendamment la partition, la QoS, le temps CPU et le nombre de nœuds nécessaires pour chaque étape.

Attention :

  • S'agissant de travaux indépendants, la variable $JOBSCRATCH sera valorisée différemment dans chaque étape. Les fichiers devant être partagés entre deux étapes ne devront donc pas être enregistrés dans cet espace JOBSCRATCH mais dans le répertoire semi-temporaire SCRATCH, ou encore un répertoire permanent comme le WORK, mais avec une moins bonne bande passante : voir toutes les caractéristiques des Espaces Disques.
  • En cas d'échec d'un des travaux de l'enchaînement, les travaux suivants restent par défaut en attente avec la raison “DependencyNeverSatisfied” mais ne pourront jamais s'exécuter. Vous devez alors les supprimer en utilisant la commande scancel. Si vous souhaitez que ces travaux soient automatiquement annulés en cas d'échec, vous devez préciser l'option –kill-on-invalid-dep=yes lors de leurs soumissions.
    Dans l'exemple suivant, cette option est utilisée pour exécuter un travail (job2.slurm) uniquement si le précédent (job1.slurm) a échoué (–dependency=afternotok:$JID_JOB1) et éviter qu'il reste en attente si le job précédent s'est bien terminé (–kill-on-invalid-dep=yes). De plus, le dernier travail (job3.slurm) sera exécuté si l'un des deux précédents (job1.slurm ou job2.slurm) s'est bien terminé (–dependency=afterok:$JID_JOB1?afterok:$JIB_JOB2) :

    multi_steps.bash
    #!/bin/bash
    JID_JOB1=`sbatch job1.slurm | cut -d " " -f 4`
    JID_JOB2=`sbatch --dependency=afternotok:$JID_JOB1 --kill-on-invalid-dep=yes job2.slurm | cut -d " " -f 4`
    sbatch --dependency=afterok:$JID_JOB1?afterok:$JIB_JOB2 job3.slurm

Exemples de travaux chaînés utilisant le STORE

Extraction de données depuis le STORE avant un calcul

  • Script de soumission extract_data.slurm pour la phase de préparation des données :
extract_data.slurm
#SBATCH --job-name=Extraction # nom du travail
#SBATCH --partition=archive   # on utilise la partition "archive" ou "prepost" qui a accès au STORE
#SBATCH --ntasks=1            # on a un travail séquentiel
#SBATCH --hint=nomultithread  # 1 processus MPI par coeur physique (pas d'hyperthreading)
#SBATCH --time 02:00:00       # temps d execution maximum demande (HH:MM:SS)
#SBATCH --output=%x_%j.out    # fichier de sortie et d'erreur (%x = nom du travail, %j = numéro du travail)
# Si vous disposez de plusieurs projets ou de plusieurs types d'heures,
# vous devez spécifier la comptabilité à utiliser même si les heures ne
# seront pas décomptées pour les partitions "archive" et "prepost".
##SBATCH --account=...
 
# Extraction de données depuis le STORE vers le SCRATCH
cd $SCRATCH/mon_calcul
tar -xvf $STORE/monarchive.tar
  • Script de soumission compute.slurm pour la phase de calcul :
compute.slurm
#SBATCH --job-name=Calcul     # nom du travail
# Directives Slurm à compléter en fonction de votre calcul
 
# Calcul utilisant les données préalablement extraites du STORE vers le SCRATCH
cd $SCRATCH/mon_calcul
srun ...
  • Chaînage des travaux :
multi_steps.bash
#!/bin/bash
JOB_ID_EXTRACT_DATA=`sbatch extract_data.slurm | cut -d " " -f 4`
# On n'exécute le calcul que si l'extraction des données s'est faite avec succès
sbatch --dependency=afterok:$JOB_ID_EXTRACT_DATA compute.slurm

Archivage de données vers le STORE après un calcul

  • Script de soumission compute.slurm pour la phase de calcul :
compute.slurm
#SBATCH --job-name=Calcul     # nom du travail
# Directives Slurm à compléter en fonction de votre calcul
 
# Calcul produisant des données à archiver à long terme
cd $SCRATCH/mon_calcul
srun ...
  • Script de soumission archive_data.slurm pour la phase d'archivage des données :
archive_data.slurm
#SBATCH --job-name=Archivage  # nom du travail
#SBATCH --partition=archive   # on utilise la partition "archive" ou "prepost" qui a accès au STORE
#SBATCH --ntasks=1            # on a un travail séquentiel
#SBATCH --hint=nomultithread  # 1 processus MPI par coeur physique (pas d'hyperthreading)
#SBATCH --time 02:00:00       # temps d execution maximum demande (HH:MM:SS)
#SBATCH --output=%x_%j.out    # fichier de sortie et d'erreur (%x = nom du travail, %j = numéro du travail)
# Si vous disposez de plusieurs projets ou de plusieurs types d'heures,
# vous devez spécifier la comptabilité à utiliser même si les heures ne
# seront pas décomptées pour les partitions "archive" et "prepost".
##SBATCH --account=...
 
# Archivage de données depuis le SCRATCH vers le STORE
cd $SCRATCH/mon_calcul
tar -cvf $STORE/monarchive.tar resultats*.h5
  • Chaînage des travaux :
multi_steps.bash
#!/bin/bash
JOB_ID_COMPUTE=`sbatch compute.slurm | cut -d " " -f 4`
# On n'exécute l'archivage que si le calcul s'est terminé avec succès
sbatch --dependency=afterok:$JOB_ID_COMPUTE archive_data.slurm