wiki:SoftWare/SignalCheckpoint/OAR

Version 3 (modified by g7moreau, 12 years ago) (diff)

Asynchrone case

SoftWare/SignalCheckpoint / OAR - utilisation avec le scheduleur OAR

OAR est un gestionnaire de batch. C'est celui que nous utilisons au LEGI. Il est développé sur Grenoble : http://oar.imag.fr/

Sur cette page ne sont décrit que les spécificité de l'utilisation de la bibliothèque SignalCheckpoint avec le scheduleur OAR.

L'objectif est de lancer un code avec l'option de relance automatique en fin de traitement tant que le calcul n'est pas finit (idempotent). On lance un calcul de 24h et 10min avant la fin, OAR envoie le signal SIGUSR2 au code pour lui demander de s'arrêter.

A noter que les scripts de soumission sont écrit en bash mais devrait fonctionner à l'identique sous ksh. Il faut cependant oublier le {csh (et le tcsh) qui ne gère pas les signaux correctement.

Cas simple - sans post-traitement

Le script de soumission configure l'environnement du calcul en chargeant quelques modules puis en exécutant un pré-traitement.

Comme il n'y a pas de post-traitement à réaliser, le plus simple est de passer la main au programme de calcul via la directive du shell exec. Ainsi, le script de soumission s'arrête très rapidement et OAR enverra ces signaux directement au code de calcul. A lui de les gérer.

On remarque donc sur cet exemple que le script de soumission n'a donc pas à gérer les signaux. L'optimisation via exec permet en plus de récupérer un peu de mémoire vive pour le code !

#!/bin/bash

#OAR -n MYCODE
#OAR -t idempotent
#OAR --checkpoint 600
#OAR -l /core=1,walltime=24:00:00

# Load environment
. /etc/profile

module load intel/2011.7


# Pretreatment possible here


# Start / give the hand to the code
exec ./mycode

Cas asynchrone - avec post-traitement

Il y a de nombreux cas ou le script de soumission doit reprendre la main après l'exécution du code de calcul. Cependant, il faut savoir que le shell ne gère les signaux qu'entre deux instructions, ou lors d'instruction bloquante interne au shell (par exemple wait).

L'exemple suivant par exemple ne fonctionne pas car le script exécutera le code dans trap qu'une fois le code mycode finit, donc en pratique jamais car le code dure plus de 24h. Au final, au bout de 24, OAR fera un kill violent du code...

#!/bin/bash

#OAR -n MYCODE
#OAR -t idempotent
#OAR --checkpoint 600
#OAR -l /core=1,walltime=24:00:00

# Signal child retransmit
trap 'kill -USR2 $(jobs -p)' USR2


# Load environment
. /etc/profile

module load intel/2011.7


# Pretreatment possible here


# Start / give the hand to the code
./mycode


# Post-treatment possible here

Une solution est de lancer le code en asynchrone afin que le script de soumission reprenne le plus vite possible la main. Cependant, il doit quand même attendre la fin du code avant de faire l'étape de post-traitement. Voici une solution fonctionnelle à ces impératifs

#!/bin/bash

#OAR -n MYCODE
#OAR -t idempotent
#OAR --checkpoint 600
#OAR -l /core=1,walltime=24:00:00

# Signal child retransmit
trap 'kill -USR2 $(jobs -p)' USR2


# Load environment
. /etc/profile

module load intel/2011.7


# Pretreatment possible here


# Launch the code and take back the hand (asynchrone)
./mycode &

# Wait for the end of the code
while [ $(jobs -p | wc -l) -gt 0 ]
do
   wait
done

# Post-treatment possible here

La boucle while est très importante car le code peux finir suite à la réception d'un signal mais aussi naturellement lorsqu'il a enfin finit son traitement global. Les deux cas doivent être géré. Or la commande interne wait attends la fin du calcul ou la réception d'un signal.

Une fois le signal reçu, la commande trap retransmet le signal au code, et le script de soumission repars dans la boucle while afin d'attendre la fin réelle du code. Sans cette boucle, il passerait de suite sur la phase de post-traitement et se terminerait en laissant OAR tuer sauvagement le code dans sa phase terminale...