Un cluster est un ensemble de machines qui se compose d’une frontale, ou plusieurs frontales, et de noeuds de calcul. Une frontale est la machine sur laquelle l’utilisateur se connecte en ssh, tandis que les noeuds sont les machines sur lesquelles l’utilisateur fait tourner ses programmes.
Tous les programmes que l’utilisateur lance se font depuis une frontale en utilisant un gestionnaire de ressources chargé de trouver et d’allouer les ressources requises parmi les noeuds.
Le gestionnaire de ressources utilisé est OAR.
Un job est ce que l’utilisateur soumet au gestionnaire de ressources pour éxécuter un programme. Il est composé d’une description des ressources nécessaires à l’exécution du programme et les commandes permettant cette exécution, généralement fournies dans un script.
Parmi les ressources requises par le gestionnaire de ressources pour la soumission d’un job, on a le nombre de noeuds, de coeurs par noeud, et le temps de calcul maximal. Si l’utilisateur omet ces informations, le gestionnaire applique des valeurs par défaut. Les défauts sont 1 noeud, 1 coeur et 2h maximum.
Un job a un cycle de vie, il est :
La commande pour soumettre un job est oarsub. Cette commande a de nombreuses options que l’on peut trouver en utilisant l’option --help
.
[cgirpi@froggy2 ~]$ oarsub --help
Usage: /usr/lib/oar/oarsub [options] [-I|-C|<script>]
Submit a job the OAR batch scheduler
Options are:
-I, --interactive Request an interactive job. Open a login shell
on the first node of the reservation instead of
running a script.
-C, --connect=<job id> Connect to a running job
-l, --resource=<list> Set the requested resources for the job.
The different parameters are resource properties
registered in OAR database, and `walltime' which
specifies the duration before the job must be
automatically terminated if still running.
Walltime format is [hour:mn:sec|hour:mn|hour].
Ex: host=4/cpu=1,walltime=2:00:00
--array <number> Specify an array job with 'number' subjobs
--array-param-file <file> Specify an array job on which each subjob will
receive one line of the file as parameter
-S, --scanscript Batch mode only: asks oarsub to scan the given
script for OAR directives (#OAR -l ...)
-q, --queue=<queue> Set the queue to submit the job to
-p, --property="<list>" Add constraints to properties for the job.
(format is a WHERE clause from the SQL syntax)
-r, --reservation=<date> Request a job start time reservation,
instead of a submission. The date format is
"YYYY-MM-DD HH:MM:SS".
--checkpoint=<delay> Enable the checkpointing for the job. A signal
is sent DELAY seconds before the walltime on
the first processus of the job
--signal=<#sig> Specify the signal to use when checkpointing
Use signal numbers, default is 12 (SIGUSR2)
-t, --type=<type> Specify a specific type (deploy, besteffort,
cosystem, checkpoint, timesharing)
-d, --directory=<dir> Specify the directory where to launch the
command (default is current directory)
--project=<txt> Specify a name of a project the job belongs to
-n, --name=<txt> Specify an arbitrary name for the job
-a, --anterior=<job id> Anterior job that must be terminated to start
this new one
--notify=<txt> Specify a notification method
(mail or command to execute). Ex:
--notify "mail:name@domain.com"
--notify "exec:/path/to/script args"
--resubmit=<job id> Resubmit the given job as a new one
-k, --use-job-key Activate the job-key mechanism.
-i, --import-job-key-from-file=<file>
Import the job-key to use from a files instead
of generating a new one.
--import-job-key-inline=<txt>
Import the job-key to use inline instead of
generating a new one.
-e --export-job-key-to-file=<file>
Export the job key to a file. Warning: the
file will be overwritten if it already exists.
(the %jobid% pattern is automatically replaced)
-O --stdout=<file> Specify the file that will store the standart
output stream of the job.
(the %jobid% pattern is automatically replaced)
-E --stderr=<file> Specify the file that will store the standart
error stream of the job.
(the %jobid% pattern is automatically replaced)
--hold Set the job state into Hold instead of Waiting,
so that it is not scheduled (you must run
"oarresume" to turn it into the Waiting state)
-s, --stagein=<dir|tgz> Set the stagein directory or archive
--stagein-md5sum=<md5sum> Set the stagein file md5sum
-D, --dumper Print result in DUMPER format
-X, --xml Print result in XML format
-Y, --yaml Print result in YAML format
-J, --json Print result in JSON format
-h, --help Print this help message
-V, --version Print OAR version number
La forme la plus basique d’utilisation est celle où on précise uniquement le projet et la commande à lancer : oarsub --project <your-project> <command>
Par exemple, ci-dessous un exemple de soumission de la commande /bin/hostname
:
[cgirpi@froggy1 ~]$ oarsub --project cecipex /bin/hostname
[ADMISSION RULE] Set default walltime to 1800.
[ADMISSION RULE] Modify resource description with type constraints
[COMPUTE TYPE] Setting compute=YES
[ADMISSION RULE] Antifragmentation activated
[ADMISSION RULE] You requested 0 cores
[ADMISSION RULE] No antifrag for small jobs
OAR_JOB_ID=15576103
Chaque job est identifié de façon unique par son identifiant de job (OAR_JOB_ID
). Dans l’exemple, cet identifiant a pour valeur 15576103.
Attention, la commande que vous passez en argument de oarsub, et que vous voulez exécuter sur le noeud, doit avoir les droits d’exécution. et être accessible depuis les noeuds. En particuier si le chemin d’accès n’est pas dans la variable d’environnement PATH, il faut alors passer en argument la commande avec son chemin complet.
Avec la soumission de commande précédente, nous n’avons demandé aucune ressource spécifique. Ainsi, en message de retour, le gestionnaire de ressources OAR nous a alloué le walltime par défaut (1800 secondes) et nous indique qu’aucun coeur de calcul n’a été demandé.
Walltime et fin de job Si votre job se termine normalement (ou plante !) avant le temps indiqué par le walltime, tout va bien, les ressources sont libérées aussitôt. En revanche, s’il est encore en cours d’exécution à la fin du walltime, il sera tué. Assurez-vous donc de spécifier un walltime suffisant pour qu’il puisse se terminer dans le temps imparti, mais pas trop grand afin qu’il ne patiente pas inutilement dans la file d’attente du gestionnaire de ressources.
Pour réservé des ressources explicitement, il faut utiliser l’option -l
de la commande oarsub. Par exemple :
bouttier@froggy1 $ oarsub --project test -l /nodes=4/core=1,walltime=1:00:00 /bin/hostname
[ADMISSION RULE] Modify resource description with type constraints
[COMPUTE TYPE] Setting compute=YES
[ADMISSION RULE] Antifragmentation activated
[ADMISSION RULE] You requested 4 cores
[ADMISSION RULE] No antifrag for small jobs
OAR_JOB_ID=15676746
Avec cette commande, nous avons demandé 1 coeur sur 4 noeuds, soit un total de 4 coeurs, pour une durée maximale (walltime
) d’une heure.
Comme nous l’avons vu auparavant, chaque job est identifié à l’aide d’un numéro unique pour chaque cluster contenu dans la variable d’environnement $OAR_JOB_ID
, ici 15676746. Par défaut, comme le job s’exécute sur des ressources non accessibles directeemnt, nous n’avons pas accès aux sorties standard et erreur dans lesquelles nos commandes peuvent renvoyer des informations. En réalité, ces sorties sont recopiés dans deux fichiers propres à chaque job, nommés respectivement OAR.$OAR_JOB_ID.stdout
et OAR.$OAR_JOB_ID.stderr
. Ces fichiers sont créés par OAR
la où vous avez soumis votre job.
Les mots-clés les plus couramment utilisés sont décrits dans ce tableau :
Mots-clés | Signification |
---|---|
nodes | Nb de noeuds demandés |
core | Nb de coeurs demandés |
cpu | Nb de cpu demandés |
walltime | Temps maximal d’exécution demandé |
Voici plusieurs exemples de réservations de ressources :
oarsub -l /nodes=10,walltime=00:05:00 --project test /bin/hostname
Ici, nous réservons 10 noeuds complets pour 5 minutes dee temps d’exécution maximal.
oarsub -l /core=54,walltime=00:00:30 --project test /bin/hostname
Dans ce cas, 54 coeurs sont réservés, que le gestionnaire va choisir en fonction des disponibilités de la machine (sur un nombre indéfini de noeuds au moment de la soumission), le tout pour 30 secondes de temps d’exécution.
oarsub -l /nodes=3/cpu=1, walltime=2:00:00 --project test /bin/hostname
Enfin, ici, nous demandons 3 noeuds avec 1 cpu sur chacun (les autres cpu de ces noeuds soeront donc dédiés à d’autres jobs), pour 2 heures de temps d’exécution maximal.
La mémoire vive La mémoire vive qui vous est allouée est celle correspondant aux coeurs que vous avez réservés. Ainsi, si vous réservez 1 noeud entier, vous avez accès à la totalité de la mémoire vive (RAM) du noeud. En revanche, si vous demandez n
coeurs, vous aurez accès à `RAM_du_noeud*(n/nb_total_de_coeurs_sur_le_noeud)
Une pratique courante pour bien appréhender la calcul sur un cluster est de soumettre un job interactif. En bref, voous demandez des ressources, et le gestionnaire de ressources va vous connecter sur l’une d’entre elle (un noeud sur lequel elle vous a alloué un coeur) à partir duquel vous pourrez lancer vos commandes/scripts/programmes en interactif. A la fin du walltime, votre session est automatiquement tuée. Si vous la quittez avant, le gestionnaire libérera vos ressources.
La soumission en interactif se fait à l’aide de l’option -I
de la commande oarsub
. Par exemple :
bouttier@froggy1 $ oarsub -I -l /nodes=1,walltime=1:00:00 --project admin
[ADMISSION RULE] Modify resource description with type constraints
[COMPUTE TYPE] Setting compute=YES
[ADMISSION RULE] Antifragmentation activated
[ADMISSION RULE] You requested 16 cores
[ADMISSION RULE] Disabling antifrag optimization as you are already using /node property
OAR_JOB_ID=15676747
Interactive mode : waiting...
Starting...
Connect to OAR job 15676747 via the node frog80
bouttier@frog80 $
Nous pouvons faire ici plusieurs remarques :
oarsub
sur la frontale (froggy1
dans la premier prompt)-I
a été bien rajoutée/bin/hostname
)frog80
Nous voyons qu’ici, avec le deuxième prompt, nous sommes connecté sur le noeud frog80
à partir duquel nous pourrons manipuler les fichiers, lancer des commandes, des scripts en interactif. Pour quitter le job, il suffit de quitter le noeud via la commande exit
.
La soumission interactive est utile pour prendre en main le cluster, faire des tests. En revanche, pour lancer automatiquement un ensemble de commande (préparation de fichier, préparation de l’environnement logiciel, exécution du programme principal, récupération des fichiers de sorties et nettoyage), il est très peu recommandé.
Dans ce cas d’utilisation, nous allons soumettre un job via un script de soumission. Ce script de soumission peut-être écrit dans différents langages interprétés, le plus souvent bash
et python
.
Le script de soumission va contenir l’ensemble des instructions dont vous avez besoins pour effectuer votre expérience ainsi que des directives OAR qui indiqueront aux gestionnnaires de ressources tout ce dont vous avez besoin. Ces directives sont signalées par la chaîne de caractères #OAR
en début d’une ligne. Attention, #OAR
n’est pas un commentaire de votre script de soumission.
Le script de soumission sera ensuite passé en paramètre à la commande oarsub
à l’aide de l’option -S
. Il faudra préalablement l’avoir rendu exécutable à l’aide de la commande chmod +x
.
Comme mille mots valent bien une image, passons à un exemple concret. Voici un script de soumission complètement inutile mais qui illustrera tous les mécanismes que nous avons besoin de présenter ici. Nous l’appellerons donc logiquement dumb.sh
dont voici le contenu :
#!/bin/bash
#OAR -n Hello_World
#OAR -l /nodes=2/core=1,walltime=00:01:30
#OAR --stdout hello_world.out
#OAR --stderr hello_world.err
#OAR --project test
cd /bettik/bouttier/
/bin/hostname >> dumb.txt
On peut distinguer deux grandes parties dans ce script :
#OAR
Pour ces dernières, ce script, qui ne va fonctionner que sur les clusters luke
et dahu
, va :
/bin/hostname
dans le fichier dumb.txt
.
Pour qu’il fonctionne sur froggy
, il faudrait travailler dans le dossier /scratch
en lieu et place du dossier /bettik
.Pour les directives OAR
,nous remarquons ici quelques options connues de oarsub
. Regardons ligne par ligne ce que nous demandons au gestionnaire de ressources :
#OAR -n Hello_World
Ici, nous nommons notre job hello_world
.
#OAR -l /core=1,walltime=00:01:30
Nous demandons 1 coeur pour 1 minutes 30 secondes maximum.
#OAR --stdout hello_world.out
Le fichier de sortie standard s’appellera hello_world.out
.
#OAR --stderr hello_world.err
Le fichier d’erreur standard s’appellera hello_world.err
.
#OAR --project test
Nous indiquons que nous appartenons au projet test.
En réalité, ces directives reprennent les options que nous passons en temps normal à la commande oarsub
. Il est à noter que toutes les options décrites ici peuvent être utilisées en ligne de commande avec oarsub
Ici, les fichiers de sorties standard et erreur sont nommés indépendamment de l’identifiant de job. Cela peut être dangereux, parce que si soumettez plusieurs fois le script, cahque job écrira dans ce fichier et nous perdrons potentiellement les informations relatives à chaque job.
Avant de soumettre le script, il faut d’abord le rendre exécutable :
chmod +x dumb.sh
Maintenant, nous pouvons soumettre le script :
oarsub -S ./dumb.sh
Une fois les ressources demandées disponibles, la série de commandes décrite dans le script s’exécutera.
Pour connaître l’état et les caractéristiques d’un job soumis, il faut utiliser la commande oarstat
. Exécutée toute seule, cette commande renverra l’état des jobs soumis par l’ensemble des utilisateurs sur le cluster. Pour des raisons de lisibilités, nous allons la restreindre à un seul utilisateur à l’aide de l’option -u
suivie du login :
bouttier@f-dahu:~$ oarstat -u bouttier
Job id S User Duration System message
--------- - -------- ---------- ------------------------------------------------
4936641 W bouttier 0:00:00 R=1,W=0:1:30,J=B,N=Hello_World,P=admin,T=heterogeneous
Le résultat donne l’ensemble des jobs soumis par cet utilisateur. Nous voyons qu’il n’en a qu’un. Nous voyons son identifiant, son état (ici, W pour waiting, il est en attente de lancement), combien s’est écoulé depuis le début de son exécution (ici 0 puisqu’il est encore en attente) et ses caractéristiques (ressources demandées, walltime, nom, projet, type).
Pour connaître les informations détaillées d’un job, une fois muni de son identifiant, nous pouvons exécuter la commande suivante :
bouttier@f-dahu:~$ oarstat -f -j 4936641
Job_Id: 4936641
job_array_id = 4936641
job_array_index = 1
name = Hello_World
project = admin
owner = bouttier
state = Terminated
wanted_resources = -l "{type = 'default'}/core=1,walltime=0:1:30"
types = heterogeneous
dependencies =
assigned_resources = 1067
assigned_hostnames = dahu66
queue = default
command = dumb.sh
exit_code = 32512 (127,0,0)
launchingDirectory = /home/bouttier
stdout_file = hello_world.out
stderr_file = hello_world.err
jobType = PASSIVE
properties = ((((hasgpu='NO') AND compute = 'YES') AND sequential='YES') AND desktop_computing = 'NO') AND drain='NO'
reservation = None
walltime = 0:1:30
submissionTime = 2019-11-01 16:17:58
startTime = 2019-11-01 16:18:09
stopTime = 2019-11-01 16:18:11
cpuset_name = bouttier_4936641
initial_request = oarsub -S dumb.sh; #OAR -n Hello_Worl; #OAR -l /core=1,walltime=00:01:3; #OAR --stdout hello_world.ou; #OAR --stderr hello_world.er; #OAR --project admi
message = R=1,W=0:1:30,J=B,N=Hello_World,P=admin,T=heterogeneous (Karma=0.000,quota_ok)
scheduledStart = no prediction
resubmit_job_id = 0
events =
2019-11-01 16:18:12> SWITCH_INTO_TERMINATE_STATE:[bipbip 4936641] Ask to change the job state
Ici, la ligne state = Terminated
nous indique qu’il est maintenant terminé.
Si vous avez lancé un job et que vous vous êtes apercu qu’il est inutile qu’il se poursuive (calcul inutile, erreur dans le script de soumission, etc.) vous pouvez supprimer votre soumission à l’aide de la commande oardel
:
bouttier@f-dahu:~$ oarsub -S dumb.sh
[PARALLEL] Small jobs (< 32 cores) restricted to tagged nodes
[ADMISSION RULE] Modify resource description with type constraints
OAR_JOB_ID=4936645
bouttier@f-dahu:~$ oardel 4936645
Deleting the job = 4936645 ...REGISTERED.
The job(s) [ 4936645 ] will be deleted in the near future.
Sur un cluster OAR, vous pouvez voir une valeur de karma lorsque vous soumettez un travail interactif, ou lorsque vous demandez le statut d’un job (oarstat -j $JOB_ID
) ou lorsque vous vérifiez vos données comptables. Il s’agit d’une valeur utilisée pour assurer le partage équitable des ressources que nous utilisons sur chaque cluster de GRICAD. Le partage équitable signifie que le système essaie de permettre l’utilisation des ressources avec équité entre les utilisateurs. Plus votre karma est faible, plus vous avez de chances que vos travaux commencent avant ceux d’un utilisateur qui a une valeur karma plus élevée. Le karma est fonction du temps de calcul que vous avez demandé et effectivement consommé dans le passé (pendant une fenêtre coulissante, généralement une semaine ou deux selon la plateforme). Mais notez que le karma (et l’algorithme de partage équitable) n’est utilisé que lorsque le système est plein d’emplois. La plupart du temps, la programmation est de type FIFO avec remplissage.