Personal tools
You are here: Home Calcul Technique Documentation calculateur ATOS BULL Myria Gestion des signaux envoyés par Slurm

Gestion des signaux envoyés par Slurm

Document Actions
Il est possible de paramétrer Slurm pour envoyer un signal au calcul quelques secondes ou minutes avant la limite de temps (TimeLimit). Ce signal est interceptable et peut permettre, par exemple, d'envoyer l'ordre de génération d'un fichier de reprise ou de soumettre un nouveau calcul.

Les signaux sous Linux

A la base, les signaux sont utilisés pas le noyau Linux pour avertir les processus d'évènements (instruction illégale, adressage mémoire invalide, etc.). Certains signaux sont interceptables par le processus destinataire afin d'exécuter une action associée. D'autres signaux tuent le processus destinataire.

Les signaux peuvent également être utilisés entre processus pour communiquer.

Exemple de signal classique : un au clavier sur un processus en tache de fond lui envoie un signal SIGTERM.

Une série de signaux sont définie au niveau du système pour une utilisation par les utilisateurs. Ce sont les signaux SIGUSR1 et SIGUSR2.
La commande permettant d'envoyer un signal à un processus est la commande "kill".


Gestion des signaux sous Slurm

Par défaut, quand la limite de temps d'un calcul est atteinte, Slurm envoie un signal SIGTERM à tous les processus pour les tuer et terminer le calcul. Les processus ont alors environ 30s pour se terminer. Au delà de ce temps, s'il reste des processus, ils reçoivent un signal SIGKILL. Le signal SIGTERM est un signal interceptable, contrairement au signal SIGKILL qui correspond à une mort assurée et immédiate.

En complément, il est possible de demander à Slurm d'envoyer un signal choisi, un certain temps avant d'atteindre la limite de temps. Le processus peut alors l'intercepter et effectuer des tâches de génération de fichiers de reprises, de nettoyage des données ou de re-soumission de calculs.


Exemple d'utilisation

Le script suivant est en plusieurs blocks :

  • bloc des commandes SLURM (lignes #SBATCH)
  • bloc de déclaration de la fonction et de l'association avec le signal
  • bloc du code avec un & sur la commande srun
  • bloc de fin du script avec un wait puis la recopie des fichiers


#!/bin/bash

#SBATCH --mem-per-cpu=3000
#SBATCH -n 1
#SBATCH -t 0:5:00
#SBATCH -p debug
# asks SLURM to send the SIGUSR1 signal 120 seconds before end of the time limit
#SBATCH --signal=B:SIGUSR1@120


## Handle function ##
# Function executed 120s before the end of the time limit
sig_handler_USR1()
{
        echo "   function sig_handler_USR1 called"
        # do whatever cleanup you want here
           echo "   Signal trapped -  `date`"
           # Do what you want :
           #    save data ...
           #    cleanup ...
           #    requeue job ...
           #    send signal to MPI job ...
        exit 2
}

## Handle function association ##
# associate the function "sig_handler_USR1" with the USR1 signal
trap 'sig_handler_USR1' SIGUSR1


## Job script ##
cd $LOCAL_WORK_DIR
srun sleep 40000 &


# Let's wait for signals or end of all background commands
wait

# This is the place to move your data files to your home-dir as a normal job
mkdir $SLURM_SUBMIT_DIR/$SLURM_JOB_ID
mv *.log *.dat $SLURM_SUBMIT_DIR/$SLURM_JOB_ID

exit 0

Informations avancées

Paramètre "--signal"

Format : --signal=[B:]signal[@durée]

  • Si aucune durée n'est indiquée, un signal sera envoyé 60s avant la fin de la limite de temps.
  • Si le "B" n'est pas spécifié, alors le signal est envoyé à tous les processus SAUF au script de lancement. S'il est spécifié, le signal est envoyé au script de lancement uniquement.
  • Les signaux peuvent être spécifiés par leur numéro ou leur nom (ex : 10 ou SIGUSR1). Pour connaitre la liste des signaux disponibles sur Myria, à partir d'une frontale, tapez la commande "man 7 signal".
Vous pouvez préférer que le signal soit émis vers votre code C ou Fortran afin de lui faire effectuer une action précise (ex : génération d'un fichier de reprise) plutôt que par le script de soumission.


Commande trap

La commande "trap" permet d'associer une commande ou une fonction à un signal : en cas de réception de ce signal par le script de soumission, son exécution est stoppée pour exécuter la commande ou fonction associée.
Dans l'exemple ci-dessus, la commande "trap 'sig_handler_USR1' SIGUSR1" définie l'exécution de la fonction "sig_handler_USR1" en cas de réception du signal SIGUSR1 par le script de soumission.

Le nom du signal peut être modifié ou spécifié par une valeur numérique (ex : SIGUSR1 correspond aux signaux 10, 30 et 16).
La fonction peut être remplacée par une commande.

Il est possible de déclarer plusieurs interceptions de signaux différents dans un même script en rajoutant d'autres lignes "trap".


Commande wait

La fin d'un script de soumission déclenche la fin du calcul et l'envoie de signaux SIGKILL vers ceux-ci.
La commande "wait", comme son nom l'indique, attend que les processus fils (commande(s) srun ... &) soient terminées pour continuer d'exécuter les lignes suivantes.
Si les commandes "srun" ne sont pas exécutées en tâche de fond, le script bash ne sera pas en mesure d'intercepter les signaux.

Si le calcul contient plusieurs steps (commandes "srun") à tourner successivement, il faut alterner des commandes "srun ... &" et "wait" afin d'attendre le fin de la commande précédente.


Signal SIGTERM

Comme indiqué plus haut, Slurm envoie un signal SIGTERM quand la limite de temps est atteinte. Il est tout à fait possible de rajouter une interception de ce signal également. Dans ce cas, il suffit de rajouter une ligne "trap" sur le signal et de l'associer à une fonction.

Si vous avez également utilisé l'option "--signal", à la fin de la fonction associée, repassez en mode "wait" pour attendre la fin du calcul, car si le script de soumission se termine, cela tue ses fils (commandes srun). Cela correspond à remplacer la commande "exit 2" de l'exemple par la commande "wait"


Commande scancel

La commande "scancel" a un comportement similaire à la commande "kill" : elle ne "tue" pas, elle envoie un signal à un calcul...
Le signal envoyé par défaut est une succession de 3 signaux : SIGCONT puis SIGTERM et environ 30s plus tard SIGKILL.

Il est possible d'envoyer un autre signal via la commande "scancel", en utilisant le paramètre "--signal". Afin que le signal soit envoyé uniquement au script de soumission, il faut rajouter l'option "-b" ou "--batch".
exemple : scancel --batch --signal=SIGUSR1 num_job


Code de sortie

Si vous définissez un code de sortie différent dans la fonction sig_handler_USR1 (ex : exit 2) , du code de sortie et fin de script (ex : exit 0), vous conserverez une trace du mode de sortie de votre calcul :

  • 0 -> fin de script normale,
  • 2-> fin de script normale grâce au signal 120s avant la limite de temps

Pour retrouver les codes de sortie d'un précédent calcul, utilisez la commande "sacct -j job_id".
La colonne "ExitCode" utilise le format Code_d_erreur:Signal_reçu. Le script de soumission correspond à la ligne "batch".


Références


Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: