Philippe Marion e93420b26b mv jobs_longs_checkpoint checkpoint | 7 jaren geleden | |
---|---|---|
.. | ||
README-checkpoint.md | 7 jaren geleden | |
checkpoint-dmtcp1.oar | 7 jaren geleden | |
checkpoint-dmtcp2.oar | 7 jaren geleden | |
checkpoint-user1.oar | 7 jaren geleden | |
compteur.c | 7 jaren geleden | |
compteur.m | 7 jaren geleden | |
compteur.py | 7 jaren geleden | |
compteur10mn.c | 7 jaren geleden | |
simpleCompteur10mn.c | 7 jaren geleden | |
simpleCompteur4mn.c | 7 jaren geleden |
Project: admin PCS author: Ph. M. date: 2016-10-18, update 2017-11-12 title: Checkpoint
L'objectif de cette fiche est de présenter quelles sont les méthodes qui peuvent «assurer» l'exécution de très longs travaux sur la plateforme de calcul. Si un programme n'a pas «nativement» un procédé d'avancement en son sein, tout arrêt brutal implique une reprise à partir de zéro. Pour éviter cela, il n'y a parfois pas d'autres solutions que d'effectuer un checkpoint. Soit l'utilisateur le met en place dans son programme, c'est l'idéal, mais la mise en œuvre peut être complexe. Soit on utilise un programme externe qui le fait, c'est précisément le second objectif de cette fiche : présenter DMTCP (Distributed MultiThreaded CheckPointing). En lançant ses travaux conjointement avec DMTCP , un utilisateur peut générer un ou plusieurs "checkpoint" de son job en cours d'exécution. Les checkpoints sont soit décidés au lancement par une instruction périodique, soit déclenchés par l'envoi/réception d'un signal. Les principes ainsi que la mise en œuvre n'est pas trivial. Avant d'utiliser cette méthode, il est donc essentiel de s'assurer que l'on en a réellement besoin et surtout, qu'il n'existe une solution plus simple, mieux adaptée.
!!! info "DMTCP: De quoi s'agit-il ? principe de base"
Au lieu de lancer directement un programme:
- ./mon_programme.exe
On le lance à travers une commande :
- dmtcp_launch ./mon_programme.exe [-interval 600] ( option qui prévoit un checkpoint automatique toutes les 600s)
Cette dernière commande, « 2 en 1 », lance le _coordinateur dmtcp_ et le programme `mon_programme.exe.`
- Qu'on ait prévu des checkpoints cycliques, où bien que l'on déclenche (par un _signal_) un checkpoint, tout arrêt du job pourra être relancé grâce au script `dmtcp_restart_script.sh` qui est généré à chaque checkpoint
!!! info "les cibles"
1. les programmes «trop gourmands» en ressources pour entrer dans le cadre de la [politique de réservation](https://www-calculco.univ-littoral.fr/utilisation/politique-de-reservation) (nov 2017 : max 1600 heures cœurs, sur au plus 80 cœurs)
2. le programme peut être exécuté dans la queue «longue» de calculco, mais aucun n'avancemnt contextextuel n'a lieu pendant sont exécution: s'il y a un problème ( ex. électrique) au bout de 200h, on doit le relancer de zéro.
3. nécessité d'effectuer un checkpoint ( pour n'importe quelle bonne ou mauvaise raison!)
!!! tip "à la maison ?"
Relativement facile à installer, cette méthode peut être très intéressante pour ceux qui font des calculs à la maison:
- coupure de courant annoncée,
- besoin momentanné du PC pour faire autre chose que des calculs (et les calculs en cours l'on transformé en brouette!),
Quelques exemples d'arrêt et reprise de jobs où la méthode dmtcp
est parfaitement inutile, d'une manière générale la plupart des programmes font des calculs en parallèle ( et non un calcul parallèle!) :
gestion manuelle : Si nativement le programme «gère» son avancé. ex: traitement massif : « tant qu'il y a du grain à moudre dans "IN", traiter et placer les résulats dans "OUT"» :
le même programme lancé de très nombreuses fois avec des paramètres différents
: La solution pour ce type travaux est de soumettre un job de type array dans la queue besteffort
avec l'option idempotent
: tous les jobs du array qui auraient été stoppés - par exemple en raison d'une affluence d'une série de jobs de priorité supérieure ( default queue)- reprennent automatiquement , dès que suffisamment de ressources (cœurs) sont libérés.
Arrêt électrique (hors sujet? pour info) : En cas de coupure électrique, les nœuds de calcul sont mis en état d'hibernation. Une reprise des calculs au rétablissement du courant peut réussir sous certaines conditions (nombreuses!). Evidemment, un calcul 100% local au nœud a une meilleure chance de reprendre avec réussite.
Pour l'ensemble des tests, un simple programme compteur.c
#include "stdio.h"
int main( int argc, char *argv[] )
{
int i;
int max=60 /* ~10 minutes */
for (i=0; i<max; i++)
{
printf("i = %d\n", i);
fflush(stdout);
sleep(10);
}
}
programme similaire en python:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time
i=1
max=60
while i < max:
print "i = %d" % i
time.sleep(10)
i = i + 1
Dans le terminal n°1
gcc compteur.c # compilation du prog. ci-dessus
dmtcp_launch ./a.out # «2 en 1» : equivalent à
dmtcp_launch ./a.out
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
...
Dans un autre terminal (n°2)
dmtcp_command -c # déclenchement d'un checkpoint
# liste des fichiers générés:
ls -1
ckpt_a.out_16a8547747dd5-40000-6cc6fe8f28ea7.dmtcp
dmtcp_restart_script_16a8547747dd5-40000-6cc6fac26313c.sh
dmtcp_restart_script.sh -> dmtcp_restart_script_16a8547747dd5-40000-6cc6fac26313c.sh
!!! tip "lien dmtcp_restart_script.sh"
Le checkpoint déclenche la création de plusieurs fichiers:
- `ckpt_a.out_16a8547747dd5-40000-6cc6fe8f28ea7.dmtcp` (le checkpoint proprement dit: taille à surveiller?)
- `dmtcp_restart_script_16a8547747dd5-40000-6cc6fac26313c.sh`
- `dmtcp_restart_script.sh` : le script à relancer ( lien vers le script ci-dessus)
retour au terminal n°1 : CTRL+C ( pour arrêter brutalement le programme)
gcc compteur.c # compilation du prog. ci-dessus
dmtcp_launch ./a.out # «2 en 1» : equivalent à
dmtcp_launch ./a.out
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
^C
reprise du programme (toujours terminal n°1):
./dmtcp_restart_script.sh
[22084] mtcp_restart.c:377 restore_brk:
error: new/current break (0x55555577f000) != saved break (0x555b22ea8000)
i = 5 # <= malgré la petit erreur (ci-dessus) le programme reprend bien au «checkpoint» CTRL+C (à i=5)
i = 6
i = 7
i = 8
i = 9
i = 10
...
Et ainsi de suite
# dmtcp lancé cette fois avec l'option -i 20 (un checkpoint toutes les 20 s)
dmtcp_launch -i 20 ./a.out
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
^C --> CTRL+ C au bout de ~ 50 seconde : arrêt du programme
./dmtcp_restart_script.sh
[24741] mtcp_restart.c:377 restore_brk:
error: new/current break (0x55555577f000) != saved break (0x5576fe402000)
i = 4 --> It works !
i = 5
i = 6
terminal n°1 : on lance le coordinateur
dmtcp_coordinator
?
#----------------> de l'aide?: affiche les commandes disponible du coordinateur
COMMANDS:
l : List connected nodes
s : Print status message
c : Checkpoint all nodes
i : Print current checkpoint interval
(To change checkpoint interval, use dmtcp_command)
k : Kill all nodes
q : Kill all nodes and quit
? : Show this message
terminal n°2 :
dmtcp_launch ./a.out
Tests (terminal 1): succession de touches l
,c
(checkpoint), k
(kill, qui exige donc une reprise avec ./dmtcp_restart.sh dans le terminam n°2), l
..., q
(kill le coordinateur et les processue gérés -donc le prog dans le terminal n°2-)
#lancement
dmtcp_launch -i 20 ./compteur.py
i=1
...
i=12
# arrêt
^C -> les insultes sont copieuses
# reprise
i= 11 -> but it works!
i=1;
max=60;
while i < max
fprintf(" i = %d \n",i);
i = i + 1;
pause(10);
end
dmtcp_launch matlab -nodesktop -nodisplay -nosplash -nojvm -r 'compteur'
...TODO ( il y a un bug sur matlab , qui est pourtant censé fonctionner)
man dmtcp_coordinator
, man dmtcp_launch
... pour connaître les options
nombreuses options peuvent être fixées autrement que par les commandes avec les variables d'environnements:
DMTCP_CHECKPOINT_DIR
DMTCP_TMPDIR
DMTCP_CHECKPOINT_INTERVAL
DMTCP_SIGCKPT
DMTCP_HOST
DMTCP_PORT
Remarques:
host
est un des premiers soucis rencontrés lors des premiers tests: host (193.49...) ou localhost
(127.0.0.1)port
par défaut est 7779En cas de problèmes, lancer préalablement à tout test la commande dmtcp_coordinator
: elle affiche clairement les variables par défaut (host, port etc), au lieu de lancer dmtcp_launch ./a.out
(commande «2 en 1» qui vérifie que le coordinateur est lancé et le lance si ce n'est pas le cas).
!!! info "problématiques propre à calculco"
Toutes les difficultés viennent du fait qu'un calcul sur la plateforme est lancé par le _gestionnaire de tâches OAR_ . batch . Un jeu de signaux Unix entre OAR, le programme et le script de lancement OAR doit être mis en place pour que la magie opère...
- comment lancer le (dmtcp,programme) via _OAR_?
- comment capter (automatiquement) le signal _d'OAR_ (`oarsub --signal ?`,
- comment, avec l'option _OAR_ `idempotent`, relancer le script dmtcp_restart.sh
- peut-on relancer les jobs sur un autre nœud?
Voici trois exemples qui apportent quelques éléments de réponse:
walltime
:5mn)-t idempotent
et --checkpoint
extrait de la fonction sig_handler
de compteur10mn.c
:
void sig_handler(int signal)
{
switch (signal)
{
case SIGINT:
// code exécuté si on reçoit SIGINt (CTRL+C);
printf("SIGINT recu (programme C)\n");
printf("valeur du compteur enregistre: %d\n", compteur);
// fichier de sauvegarde du "contexte" ( l'indice = nb de secondes!
fp = fopen("context_compteur.txt", "wb");
if(fp == NULL) {
printf("error creating file");
}
else {
fwrite( &compteur , sizeof(int) , 1 , fp);
fclose(fp);
}
break;
...
!!! summary "sources"
- [script OAR: checkpoint-user1.oar](https://gogs.univ-littoral.fr/PoleCalcul/tutoriaux_calculco/jobs_longs_checkpoint/checkpoint-user1.oar)
- [programme: compteur10mn.c](https://gogs.univ-littoral.fr/PoleCalcul/tutoriaux_calculco/jobs_longs_checkpoint/compteur10mn.c)
Même idée que précédemment mais le programme utilisateur ne «sait pas» gérer son contexte : DMTCP le fait pour lui.
walltime
:5mn)dmtcp_launch -i [x seconde] ./PROG
qui provoque un checkpoint toutes les x secondes
( doit évidemment être inférieur au walltime
du job).!!! note "intérêt?"
Peut-être intéressant pour des programmes vraiment longs :
- par sécurité (ex : coupure électrique)
- besoin d'évaluer la pertinence de continuer l'exécution ( ou pas : -> `oardel JOBID`)
- limiter en ressources la requête OAR ( nombre heures.cœurs )
!!! summary "sources"
- [script OAR: checkpoint-user1.oar](https://gogs.univ-littoral.fr/PoleCalcul/tutoriaux_calculco/jobs_longs_checkpoint/checkpoint-dmtcp1.oar)
- [programme: simpleCompteur4mn.c](https://gogs.univ-littoral.fr/PoleCalcul/tutoriaux_calculco/jobs_longs_checkpoint/compteur10mn.c)
!!! quote "extrait OAR.ckpt-dmtcp1.out"
```
- Debut du jobs ou restart ?
- -> Debut du jobs
- i = 0
- i = 1
- i = 2
- ...
- i = 185
- i = 186 # WALLTIME atteint: le job est tué.
- loading lmod environment
- loading easybuild environment
- Debut du jobs ou restart ?
- -> reprise du job # relance (a la main ): il y a un ckpt, on ne repart pas de zéro
- i = 170
- i = 171
- ...
- i = 239
- i = 240
- ---post treatement---
- fin effective du programme, suppression des checkpoints
```
walltime
:6mn)-t idempotent
et --checkpoint
dmtcp_launch ./PROG
(sans checkpoint)!!! summary "sources"
- [script OAR: checkpoint-dmtcp2.oar](https://gogs.univ-littoral.fr/PoleCalcul/tutoriaux_calculco/jobs_longs_checkpoint/checkpoint-dmtcp2.oar)
- [programme: simpleCompteur10mn.c](https://gogs.univ-littoral.fr/PoleCalcul/tutoriaux_calculco/jobs_longs_checkpoint/compteur10mn.c)
Remarque: il est possible (et peut-être intéressant) de combiner l'exemple 2 et 3 ( traiter les signaux avec un démarrage qui prévoit un checkpoint via dmtcp, option [-i x secondes]
!!! warning "Précautions à prendre, soucis à prévoir, dans tous les cas (ex 1 à 3) "
- surveiller ses jobs (**MONITORING**). En cas de boucle infinie (`oardel JOBID` !)
- la taille des checkpoint est-elle raisonnable ?
- «multiuser» sur le même noeud? Non décrit dans ce tutorial, la socket standard du port du coordinateur DMTCP est 7779. Un deuxième utilisateur ( et les suivants ) ne pourra pas utiliser dmtcp sur le même nœud sans changer ce port par défaut. La solution est de lancer dmtcp avec l'option `-p 0` ( tirage aléatoire d'un n° de port )... mais il faudra gérer en plus gérer dans les scripts la récupération du numéro de port, les variables d'environnements du port et de l'hôte. On peut s'inspirer par exemple d'un des [scripts du projet dmtcp](https://github.com/dmtcp/dmtcp/blob/master/plugin/batch-queue/job_examples/slurm_launch.job)
Quelques références du monde «checkpointing» (hormis ce document!)
Berkeley Lab Checkpoint/Restart (BLCR) : Nombreuses références sur le web, mais il semble que le projet se soit arrêter à la
peut après la fin de la version 2.6 du noyau Linux
Checkpoint/Restore In Userspace(CRIU) : À explorer?
quelques références web: :
- [github.com/dmtcp/dmtcp](https://github.com/dmtcp/dmtcp)
- [dmtcp.sourceforge.net/dmtcp-mug-17.pdf](http://dmtcp.sourceforge.net/dmtcp-mug-17.pdf)
- [wiki (forge Grenoble)](http://servforge.legi.grenoble-inp.fr/projects/soft-trokata/wiki/SoftWare/SignalCheckpoint/OAR)
- [message list oar](mailman.13.1505124010.6427.oar-users@lists.gforge.inria.fr)
- [cvw.cac.cornell.edu/Checkpoint/dmtcpcount](https://cvw.cac.cornell.edu/Checkpoint/dmtcpcount)
- [thèse de Blaise Omer Yenke tel.archives-ouvertes.fr/tel-00685856](https://tel.archives-ouvertes.fr/tel-00685856)
- [research.cs.wisc.edu/htcondor/CondorWeek2011/presentations/cooperman-dmtcp.pdf](http://research.cs.wisc.edu/htcondor/CondorWeek2011/presentations/cooperman-dmtcp.pdf)
- [www.ccs.neu.edu/course/cs5600f15/dmtcp/md_src_QUICK-START.html](http://www.ccs.neu.edu/course/cs5600f15/dmtcp/md_src_QUICK-START.html)
- [www.youtube.com/watch?v=UeIsZTjVPAI](https://www.youtube.com/watch?v=UeIsZTjVPAI)
la release 2.5.1 (stable)sourceforge.net/projects/dmtcp/files/2.5.1 se compile facilement sur une debian
tar xfz dmtcp-2.5.1.tar.gz
cd dmtcp-2.5.1
./configure
make
make install