Torque+Maui

Le gestionnaire de travaux du cluster Avakas est Torque (conjointement au scheduler MAUI) alias PBS.

Introduction

On peut trouver une introduction au gestionnaire de travaux Torque dans le paragraphe 7 du document: Bright Cluster Management 5.2 User's Manual (1664)

commandes de gestion des jobs

  • Lancer un job décrit dans le script <jobscript>
    qsub <jobscript>
    
  • consulter la liste des jobs soumis:
    qstat
    
  • supprimer un job:
    qdel <jobid>
    
  • Obtenir des informations sur un job soumis:
    module load maui
    checkjob <jobid>
    

Exemple de script pour un job sequentiel

#!/bin/sh

#############################
# les directives PBS vont ici:

# Your job name (displayed by the queue)
#PBS -N helloWorld

# Specify the working directory
#PBS -d .

# walltime (hh:mm::ss)
#PBS -l walltime=00:10:00

# Specify the number of nodes(nodes=) and the number of cores per nodes(ppn=) to be used
#PBS -l nodes=1:ppn=1

# fin des directives PBS
#############################

# modules cleaning
module purge
module add torque

# useful informations to print
echo "#############################" 
echo "User:" $USER
echo "Date:" `date`
echo "Host:" `hostname`
echo "Directory:" `pwd`
echo "PBS_JOBID:" $PBS_JOBID
echo "PBS_O_WORKDIR:" $PBS_O_WORKDIR
echo "PBS_NODEFILE: " `cat $PBS_NODEFILE | uniq`
echo "#############################" 

#############################

# What you actually want to launch
echo "Hello World" 
sleep 1m # fake to work

# all done
echo "Job finished" 

Une fois le script lancé, par exemple avec

qsub simulation.sh

(en supposant que le script ci-dessus soit enregistré dans un fichier simulation.sh), un nom de job s'affichera à l'écran. Tous les affichages écran dûs au script simulation.sh seront stockés dans des fichiers de la forme nomdujob.eIDduJob (pour stderr) et nomdujob.oIDduJob (pour stdout) dans le dossier défini par #PBS -d ., c'est à dire, dans le cas présent, le répertoire courant (".") lors de la soumission du job par qsub.

Par exemple, pour le script donné en exemple, en supposant que l'ID du job soit 3088, à la fin du job, il y aura deux fichiers : helloWorld.e3088 et helloWorld.o3088.

NB: afin d'être correctement lues et prises en compte par Torque, les directives PBS (#PBS) doivent impérativement se situer au début du fichier script, avant toute directive de type shell. Dans le cas contraire elles seront ignorées (les détails sont fournis dans la documentation Torque de qsub).

Demander des ressources

Afin de permettre un fonctionnement normal du gestionnaire de travaux, vous êtes obligés de spécifier les ressources dont vous avez besoin pour votre calcul. Dans le cas où vous omettez de les spécifier, une valeur par défaut est prise.

Les ressources importantes:
  • walltime: le nombre d'heures pendant lequel votre calcul est autorisé a tourner. Au delà, le système l'arrêtera (i.e.: le tuera sauvagement). Valeur par défaut: 1 heure. Si vous demandez un walltime supérieur à 120 heures, vous serez dirigé automatiquement dans la file d’attente longq qui présente certaines restrictions. La durée maximale d'un job est fixée à 30 jours (voir Configuration Scheduler)
  • nombre de processeurs: votre calcul aura à disposition le nombre de processeurs désigné. Vous pouvez demander un certain nombre de nœuds (défaut: 1) ainsi qu'un certain nombre de processeurs par nœuds (défaut: 1)
  • cputime: il s'agit de la durée CPU cumulée sur tous les processeurs du job (grosso modo walltime * nb cœurs). Il n'est pas nécessaire de spécifiée cette durée, mais vous ne pouvez pas dépasser 5760 heures (~ 48 cœurs sur 5 jours, voir Configuration Scheduler)

Exemples

Il est utile d'ajouter des options à un qsub uniquement si ces options ne sont pas déjà spécifiées dans le script de job <script> en lui même.

  • job séquentiel de 2 heures
    qsub -l walltime=2:00:00 <script>
    
  • job openmp 4 cœurs (sur un seul nœud) de 1 jour
    qsub -l walltime=24:00:00 -l nodes=1:ppn=4 <script>
    
  • job parallèle de 300 cœurs (répartis au hasard)
    qsub -l select=300:ncpus=1 <script>
    
  • job parallèle de 120 cœurs avec 10 nœuds complets:
    qsub -l nodes=10:ppn=12 <script>
    

Interroger le système de batchs

Connaître les ressources disponibles

On peut utiliser la commande:

module load maui
showbf

Cette commande fournit le nombre de cœurs disponibles pour plusieurs durées. showbf -h donne une liste des options disponibles.

Evaluer la date de départ d'un job

La commande:

module load maui
showstart <JOBID>

donne des informations utiles sur la date de départ (prévisible) d'un job, ainsi qu'une estimation de sa date de terminaison.

Avoir des informations sur les jobs (actifs, en attente ou bloqués)

module load maui
showq
showq -h pour plus de détails

lancer des jobs interactifs

On peut avoir besoin d'accéder à une ressource de calcul pour y exécuter des commandes interactivement (cycle développement<->compilation) ou lancer des logiciels qui nécessitent l'intervention de l'utilisateur (debugger, etc...).

Pour avoir une connexion sur un nœud de calcul, il suffit d'ajouter l'option -I à la commande qsub. On se passe alors de script et un shell est ouvert sur la ressource dès qu'elle est allouée. Les entrées-sorties de ce shell sont connectées sur le terminal qui exécute qsub.

Exemple:

qsub -I

Pour obtenir un déport de la session x11 (pouvoir lancer des applications graphiques, quoi...):

qsub -I -X -V

Dans ce cas, un cœur sera alloué pour une heure, ce qui équivalent à :


qsub -I -X -V -l nodes=1:ppn=1,walltime=01:00:00

Lancer des jobs MPI

La configuration particulière du cluster impose de prendre certaines précautions selon la version de MPI qu'on veut utiliser.

Pour un simple test, OpenMPI sera le plus simple à mettre en œuvre:

#!/bin/sh

#PBS -l nodes=2:ppn=12

#PBS -N OPENMPI

module purge
module add torque  
module add openmpi/gcc 

myapp=<chemin-vers-application>

# pour éviter certains warnings:
export IPATH_NO_CPUAFFINITY=1

mpirun $myapp 

Pour des instructions spécifiques, voir Jobs MPI

Partitionnement du cluster

Le Cluster Avakas est principalement composé de deux types de serveurs de calcul (voir Environnement matériel):
  • les nœuds de calcul classiques (aussi appelés c6100): node001 à node264
  • les nœuds dits bigmem: bigmem01 à bigmem04
  • Les nœuds visu: visu01, visu02, visu05 et visu06
La partition par défaut est la partition c6100. Pour lancer un job Torque sur la partition bigmem, il y a plusieurs façons de procéder:
  • demander des ressources sur la partition c6100:
    # demande de 4 cœurs sur 1 nœud "c6100" 
    #PBS -l nodes=1:ppn=4:c6100
    
  • demander des ressources ayant "l'étiquette" bigmem:
    # demande de 4 cœurs sur 1 nœud "bigmem" 
    #PBS -l nodes=1:ppn=4:bigmem
    
  • demander directement à tourner sur la partition bigmem
    # partition "bigmem" 
    #PBS -W x=PARTITION:bigmem
    

Se connecter quand même aux nœuds pendant un job

La connexion directe sur les nœuds de calcul est interdite dans le cluster Avakas. Le seul moyen d'accéder aux ressources est de soumettre un job.

Cependant, il peut être souhaitable de disposer d'une connexion aux nœuds de calcul dont on a obtenu la réservation à travers une soumission de job.

Un outil permettant cette utilisation est disponible dans le module "torque-ssh2job". Le script du job devra faire appel à l'utilitaire "jobsshd" qui lance un serveur sshd pour chaque nœud alloué au job.

L'utilisateur peut ensuite utiliser la commande ssh2job pour accéder aux ressources réservées.

Exemple de script batch lançant sur 2 nœuds des serveurs sshd:

#! /bin/bash
#PBS -l nodes=2:ppn=12

module load torque torque-ssh2job

# launch sshd on every allocated node
jobsshd

# wait until hit walltime limit
while true; do
    sleep 3600
done

Après soumission de ce script, on peut déterminer la liste des nœuds alloués au job par la commande "qstat -n":

master.cm.cluster:
                                                                         Req'd  Req'd   Elap
Job ID               Username Queue    Jobname          SessID NDS   TSK Memory Time  S Time
-------------------- -------- -------- ---------------- ------ ----- --- ------ ----- - -----
1184.master.cm.c     dummy    d_i      test-ssh2job.qsu  26762     1   1    --  01:00 R 00:00
   node264

rmq: la liste des noeuds peut aussi être obtenue dans le script de soumission via la variable d'environnement "$PBS_NODEFILE". Il est ainsi possible de l'ecrire dans un fichier qui pourra par exemple servir d'argument à des appels à mpirun.

Pour se connecter au nœud 264 au travers du job 1184, l'utilisateur pourra exécuter après chargement du module "torque-ssh2job" la commande "ssh2job -n node264 -j 1184"

Prologues et épilogues

Torque permet l'exécution de scripts dits prologue et épilogue autour d'un job.

Il existe plusieurs genres de ces scripts, pour la plupart réservés aux administrateurs du système. Cependant l'utilisateur peut en spécifier des personnels pour au moment de la soumission de son job (voir la documentation Torque ici):

qsub -l prologue=<path_to_prologue_script> epilogue=<path_to_epilogue_script> <jobscript>

On notera que ces jobs doivent être relativement courts (~ moins de 5 minutes) et qu'ils ne sont exécutés que sur le premier des nœuds alloués au job. On peut récupérer les informations du job dans les scripts par les arguments de la ligne de commande.

L'intérêt de cette fonctionnalité est de permettre l'exécution d'un script hors du job proprement dit. Ca signifie entre autres que l'épilogue sera exécuté même quand le job est en erreur, a été supprimé ou est parti en timelimit.

On peut notamment utiliser ce mécanisme pour récupérer les résultats locaux d'un job en cas d'erreur, faire du nettoyage spécifique en fin de job, etc...

Synchroniser un répertoire local avec un répertoire réseau lors d'un job

Les solutions d'épilogue ou de ssh2job peuvent être insuffisantes ou inadaptées. On peut alors utiliser un script pour synchroniser régulièrement des répertoires locaux avec une espace partagé: jobrsync

Utilisation "avancée"

Tableau de jobs

Il est possible avec une commande qsub, de lancer un grand nombre de jobs en une seule fois, en utilisant l'argument -t. On peut spécifier le nombre de jobs via une liste d'indexes, exemple :

qsub -t 1-3
qsub -t 1,3,4,5-10
ou, dans un script PBS, par :
#PBS -t 1-3,10-20

Un identifiant de la forme xxxx[yyyy] est attribué à chaque job, avec yyyy pris parmi les indexes spécifiés par -t, et tout les jobs seront sous un même identifiant global xxxx[].
Par exmple, si on utilise -t 1,5,7, les JOBIDs résultants seront :
13932[1].master.cm.cluster
13932[5].master.cm.cluster
13932[7].master.cm.cluster

pour voir l'état des jobs groupés, on utlise la commande qstat, comme suit,
$ qstat -t 13932[]
Job id                    Name             User            Time Use S Queue
------------------------- ---------------- --------------- -------- - -----
13939[1].master            myjob_in_out-1   dummy                 0 Q d_i            
13939[5].master            myjob_in_out-5   dummy                 0 Q d_i            
13939[7].master            myjob_in_out-7   dummy                 0 Q d_i

ou individuellement (job par job) par la commande qstat 13939[1].

$ qstat 13939[1]
Job id                    Name             User            Time Use S Queue
------------------------- ---------------- --------------- -------- - -----
13939[1].master            myjob_in_out-1   dummy                 0 Q d_i

Lancer un job avec le même exécutable et plusieurs fichiers d'entrée/sortie.

Les variables PBS_ARRAYID et PBS_JOBID peuvent être utilisées dans les scripts.
Si vous avez par exemple plusieurs fichiers de données/entrée et vous voulez les traiter par un même exécutable, vous pouvez utiliser dans ce cas un tableau de job.
voici un exemple :
Supposons que vous avez 3 fichiers de données :

data1.in 
data5.in
data7.in  

et pour chaque fichier de données data<k>.in correspond un fichier de sortie de type data<k>.out, le script suivant permet de créer un tableau de job :

!/bin/sh

## fichiers d'entrée et sortie de soumission

#PBS -o $HOME/Mpi_test/Test_Hello/test_array.out

#PBS -e $HOME/Mpi_test/Test_Hello/test_array.err

#PBS -l nodes=1:ppn=3
#PBS -t 1,5,7

# Informations sur le job
echo "Job Id:" $PBS_JOBID
echo "List of nodes allocated for job (PBS_NODEFILE): " `cat $PBS_NODEFILE | uniq`

### Modules cleaning ###

module purge

###  Load modules needed ###

module add torque

cd $HOME/Mpi_test/Test_Hello

myapp=./hello_in_out

$myapp  data${PBS_ARRAYID}.in  data${PBS_ARRAYID}.out

Lancer un job avec plusieurs exécutables dans un script.

Le but de ce script est de pouvoir lancer plusieurs exécutables en tâches de fond. Le job se termine quand soit il atteinte sa durée soit toutes les tâches sont terminées. Il permet d'optimiser le nombre de jobs à soumettre.
Voici un exemple. Il peut s'améliorer pour des programmeurs en SHELL plus avertis.
Supposons que vous avez deux programmes à lancer :

#!/bin/bash
#PBS -e job.err
#PBS -o job.log

./prog1&
p1=`echo $!`

./prog2&
p2=`echo $!`

## Le test sur p et p1, assure que la commande grep n'envoi pas une chaine de caractère identique au numéro du processus p1
##
while true ; do
        p=`ps x | grep "$p1"|grep -v grep |awk '{print $1}'`
        if [ "$p" != "$p1" ]
        then
                break
        fi
done

while true ; do
        p=`ps x | grep "$p2"|grep -v grep |awk '{print $1}'`
        if [ "$p" != "$p2" ]
        then
                break
        fi
done