Soumettre une tâche
Comment soumettre une tâche?
Écrire un script PBS
La soumission de tâches sur le serveur de calcul Mingan se fait par l’intermédiaire d’un script PBS. Ce script se résume à un ensemble de commandes bash avec en entête des directives PBS (commençant par #PBS
). Ces directives définissent les propriétés de la tâche à exécuter et sont transmises directement à l’ordonnanceur (Torque + Maui). Cette ordonnanceur est responsable de l’exécution et de la distribution des tâches sur les différents nœuds du serveur. Il veille ainsi à la répartition des ressources et du temps de calcul entre les utilisateurs de Mingan.
Exemple de script PBS
#!/bin/bash
#PBS -l walltime=30:00:00
#PBS -l nodes=1:ppn=40
#PBS -j oe
#PBS -r n
#PBS -N bar
module load opt-python
cd $PBS_O_WORKDIR
python ./foo.py
Détails
#!/bin/bash
- Spécifie l’interpréteur à utiliser.
#PBS -l walltime=30:00:00
- C'est le critère de répartition des tâches parmi les différentes queues. Voir la Description_des_queues_pbs pour plus de détails.
- c’est le temps réservé à l’exécution de la tâche, en heures, minutes et secondes (Heur:Min:Sec). Après ce temps, la tâche est automatiquement annulée qu’elle soit terminée ou non.
#PBS -l nodes=1:ppn=40
- Spécifie le nombre de nœuds (
nodes
) et de processeurs par noeud (ppn
) qui seront assignés à la tâche. Mingan dispose de 40 processeurs par nœud, ainsi la variableppn
ne peut pas excéder ce nombre.
#PBS -j oe
- Permet de fusionner la sortie standard et la sortie d'erreur dans un même fichier. Si cette option n'est pas spécifiée, il est possible de rediriger la sortie d'erreur en ajoutant la directive
#PBS -e chemin/sortie.err
ou la sortie standard avec la directive#PBS -o chemin/sortie.out
#PBS -r n
- Empêche le serveur de redémarrer la tâche en cas de panne du serveur de calcul Mingan.
#PBS -N bar
- Permet de nommer la tâche:
bar
.
module load opt-python
- Permet de charger le langage python (2.7) dans l’environnement d’exécution de la tâche. Il est important que l’utilisateur veille à ce que les dépendances (librairies ou langages) nécessaires à l’exécution de son programme soient chargées dans l’environnement. Pour plus d’informations consultez la page des Modules
cd $PBS_O_WORKDIR
- Permet de se déplacer dans le répertoire où le script de soumission à été lancé.
python ./test.py
- Exécute le script python.
Soumettre la tâche
qsub script_a_lancer.sh
Après la soumission de cette commande, l’ordonnanceur renvoie l’identifiant unique de la tâche.
Comment interagir avec la tâche soumise?
Arreter une tâche
qdel tache_id
On peut récupérer l’identifiant unique de la tâche (tache_id
) grâce aux commandes showq -u NomUtilisateur
ou qstat -u NomUtilisateur
.
Obtenir de l’information sur la tâche soumise
Après soumission de la tâche par la commande qsub
, il est possible d’afficher l’état des différentes tâches soumises par l’exécution des commandes qstat
et showq
. showq
présente l’avantage de séparer les tâches soumises en fonction de leurs états (bloqués, éligible ou en cours d’exécution).
Exemples de commande:
showq -r
- permet de lister les tâches en cours d’exécution. Il fournit l’identifiant unique, le noeud alloué à la tâche (p.ex: compute-0-1), l’heure d’exécution et le temps d’exécution restant.
show -u NomUtilisateur
- permet de lister seulement les tâches de l’utilisateur spécifié.
Ganglia
Si vous êtes sur le campus de l’UQAR, on peut également regarder le comportement des tâches en cours d’exécution par l’intermédiaire de Ganglia disponible à cette adresse: http://minganadm.uqar.ca/ganglia/. Cet outil permet de visualiser l’allocation des ressources (CPUs et mémoire) sur chacun des noeuds.
Se connecter au noeud
Il est possible de se connecter au noeud où la tâche est en cours d'exécution. Dans un premier temps, on identifie le noeud où la tâche est exécuté en utilisant showq -r -u NomUtilisateur
. Puis, on se connecte par ssh: ssh NomDuNoeud
, par exemple ssh compute-0-1
Autres exemples de scripts PBS
Tâches séquentielles multiples
Si l'on veut lancer un même programme unique sur plusieurs répertoires ou fichiers de données l'approche séquentielle multiple est à privilégier.
#!/bin/bash
# Directives PBS
#PBS -l walltime=30:00:00
#PBS -l nodes=1:ppn=8
# Chemin d'accès
SRC=$HOME/rep_programme
DATA=/share/work/utilisateur
# Commandes
cd $DATA/rep1 ; $SRC/prog > sortie &
cd $DATA/rep2 ; $SRC/prog > sortie &
cd $DATA/rep3 ; $SRC/prog > sortie &
cd $DATA/rep4 ; $SRC/prog > sortie &
cd $DATA/rep5 ; $SRC/prog > sortie &
cd $DATA/rep6 ; $SRC/prog > sortie &
cd $DATA/rep7 ; $SRC/prog > sortie &
cd $DATA/rep8 ; $SRC/prog > sortie &
wait
Ce script permet d'exécuter un programme unique (prog
) en arrière plan (grâce à la perluète &) sur 8 répertoires de données rep1
à rep8
. La commande wait
permet d'attendre que tous les programmes arrivent à leur fin avant de terminer le script de soumission.
Il est important de vérifier que le nombre d'exécution du programme ne dépasse pas la quantité de processeur demandé (#PBS -l nodes=1:ppn=8
) et que la mémoire requise par l'ensemble des programmes n'excèdent pas la mémoire disponible sur le noeud (80 Go). Sans cela, les programmes se nuiront mutuellement et diminueront les performances du noeud.
Lot de tâches séquentielles (vecteur de tâches)
Soumettre un lot de tâches
Parfois, le nombre de tâche à exécuter est trop important pour que chaque tâche soit écrite à la main (voir Tâches séquentielles multiples). On privilégie dans ce contexte l'approche par lot de tâches séquentielles.
#!/bin/bash
# Directives PBS
#PBS -l walltime=30:00:00
#PBS -l nodes=1:ppn=40
#PBS -t 0-31%10
# Chemin d'accès
SRC=$HOME/rep_programme
DATA=/share/work/utilisateur
LIMITE_INF=$((40 * $PBS_ARRAYID))
LIMITE_SUP=$(($LIMITE_INF + 39))
# Commandes
for i in $(seq $LIMITE_INF $LIMITE_SUP)
do
cd $DATA/rep$i ; $SRC/prog > sortie &
done
wait
Ce script permet d’exécuter le programme prog
en arrière-plan (grâce à la perluète &) sur 1280 répertoires de données (32 tâches * 40 exécutions du programme). Chaque tâche membre du lot exécutera le même programme sur 40 répertoires de données différents.
Le script est soumis comme un lot de tâches grâce à la directive #PBS -t 0-31%10
. Chaque tâche membre du lot possédera un identifiant (position dans un vecteur) variant de 0 à 31. En précisant %10
, l’ordonnanceur ne pourra pas lancer plus de 10 tâches du lot en même temps. On récupère la position dans le vecteur de tâche grâce à la variable d’environnement $PBS_ARRAYID
. L'exécution s'opère à l'intérieur de la boucle for i in $(seq $LIMITE_INF $LIMITE_SUP)
ou i
varie entre $LIMITE_INF
et $LIMITE_SUP
. $LIMITE_INF
correspond au nombre de programmes à exécuter (nombre de processeurs) multiplié par la position dans le vecteur de tâches. Ainsi, si la position dans le vecteur de tâches est de 0, le programme s'exécutera sur les répertoires rep0 à rep39 et si la position est de 1, le programme traitera les répertoires rep40 à rep79.
IMPORTANT: Les ressources demandées par la directive #PBS -l nodes=1:ppn=40
doivent correspondre aux ressources nécéssaires à la réalisation d'une tâche à l'intérieur du lot.
Manipuler un lot de tâches
Les tâches s'afficheront dans la liste de la manière suivante: LotTacheID[PosVecteur]
Pour arrêter un lot de tâche, on peut utiliser la commande qdel LotTacheID[]
Lancement d’un programme avec MPI
Ce script permet de lancer un programme compilé en MPI (lancé avec mpirun). Pour cet exemple, on a utilisé les modules d’environnement gcc/4.9.2 et openmpi/1.8.3-gcc-4.9.2. La version de openmpi fournie par ce dernier module a été compilée pour interagir automatiquement avec l’ordonnanceur Torque. Ainsi, on n’a pas à fournir d’informations à mpirun outre le nom du programme à lancer. C’est Torque qui fourni l’information directement à mpirun. Pour plus d’informations consultez la page des Modules.
#!/bin/sh
#Directives PBS
#PBS -l walltime=20:00:00
#PBS -l nodes=3:ppn=21
#PBS -j oe
#PBS -N ww3_shel
# Chargement des modules nécessaires à la tâche
module load gcc/4.9.2
module load openmpi/1.8.3-gcc-4.9.2
module load dot
#Se deplacer dans le repertoire a partir duquel ce script a ete lance
cd $PBS_O_WORKDIR
#Exécuter le programme
mpirun ./ww3_shel
Lancement de tâches en cascade
Quand des simulations prennent du temps, il peut être intéressant d'écrire un petit programme qui lance les simulations l'une à la suite de l'autre. En PBS, on peut utiliser l'option "qsub -W depend=..." pour créer des dépendances entre les tâches à soumettre.
qsub -W depend=afterok:<Job-ID> <QSUB SCRIPT>
- Ici, le script <QSUB SCRIPT> sera soumis après que la tâche, <Job-ID> aura été complétée avec succès .
Les différentes options qui existent pour "depend=..." sont:
- afterok
- <Job-ID> La prochaine tâche est exécutée si la tâche <Job-ID> se termine sans erreur ou est complétée avec succès.
- afternotok:<Job-ID> La prochaine tâche est exécutée si la tâche <Job-ID> se termine avec une erreur
- afterany:<Job-ID> La prochaine tâche est exécutée si la tâche <Job-ID> se termine avec ou sans erreur
Une méthode pour simplifier ce processus est d'écrire une séquence de script de lancement de tâche job1.pbs, job2.pbs, job3.pbs etc et de les soumettre comme ceci:
<source lang="bash">
- !/bin/bash
FIRST=$(qsub job1.pbs) echo $FIRST SECOND=$(qsub -W depend=afterany:$FIRST job2.pbs) echo $SECOND THIRD=$(qsub -W depend=afterany:$SECOND job3.pbs) echo $THIRD
La tâche <$FIRST> sera placée dans la queue dexécution pendant que les autres tâches <$SECOND> et <$THIRD> seront placées dans la queue mais en attente avec un Hold ("H). Quand <$FIRST> sera complétée, <$SECOND> rejoindra la queue dexécution active, pendant que <$THIRD> sera encore en attente.
Attention: si on liste les dépendances comme "afterok"/"afternotok" et que la tâche se termine avec /sans erreurs, la tâche suivant sera tuée vue que la dépendance n'aura pas été validée.