Skip to content

Longs jobs, arrêt et reprise des calculs : idempotent, checkpoint, DMTCP.

Avant-propos

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 de tels procédés ne sont pas triviaux. 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.

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 [-i 600] ./mon_programme.exe (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

les cibles

  1. les programmes «trop gourmands» en ressources pour entrer dans le cadre de la politique de réservation (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!)

à 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’ont transformé en brouette!),
  • consulter les parties installation et usage et de cette fiche.

Quelques exemples d’arrêt et reprise de jobs où la méthode dmtcp peut être inutile:

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.
Note: si les jobs de ce array sont susceptibles d’être long, le checkpoint est indispensable. En effet, plus ils sont longs, plus la probabilité d’être killé avant terme est grande, ils risquent donc d’être indéfiniment relancé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.

Distributed MultiThreaded CheckPointing (DMTCP) : Usage

Pour les plus pressés, voici les éléments à mettre en œuvre sur la plateforme de calcul.

Les autres peuvent consulter les étapes pas-à-pas installation et usage dmtcp de cette fiche pour tester dmtcp sur leur poste de travail

Sur la plateforme calculco

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:

exemple 1 : checkpoint utilisateur ( sans dmtcp )

  • le programme (timer de 10 mn) est trop long pour être exécuté dans le temps imparti (walltime :5mn)
  • OAR est lancé avec les options -t idempotentet --checkpoint
  • c’est le programme utilisateur qui prévoit de capter le signal checkpoint d’OAR pour effectuer lui-même la sauvegarde de son contexte:

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;
    ...

exemple 2 : checkpoint cyclique via dmtcp (sans contrôle des signaux)

Même idée que précédemment mais le programme utilisateur ne «sait pas» gérer son contexte : DMTCP le fait pour lui.

  • le programme (timer de 10 mn) est trop long pour être exécuté dans le temps imparti (walltime :5mn)
  • OAR est lancé sans option particulière : il n’y a pas de redémarrage automatique
  • Le programme est lancé via dmtcp dmtcp_launch -i [x seconde] ./PROG qui provoque un checkpoint toutes les x secondes ( doit évidemment être inférieur au walltime du job).
  • Le script doit être relancé à la main pour poursuivre l’exécution du programme.

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 )

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

```

exemple 3 : checkpoint via dmtcp avec contrôle des signaux

  • le programme (timer de 10 mn) est trop long pour être exécuté dans le temps imparti (walltime :6mn)
  • OAR est lancé avec les options -t idempotentet --checkpoint
  • Le programme est lancé via dmtcp dmtcp_launch ./PROG (sans checkpoint)
  • Le checkpoint du programme est assuré par une gestion correct des signaux. Le script OAR capte le signal de checkpointing du SCHEDULER OAR et transmet un signal au coordinateur dmtcp afin qu’il déclenche un checkpoint du timer.
  • l’option idempotent d’OAR permet de relancer automatique le script jusqu’au terme du programme.

autres exemples : OpenMP ? Cilk++ …

DMTCP est capable d’effectuer des checkpoints de programmes plus complexes (multi-threads etc.), d’autres exemples sont disponibles dans le dépot git tutoriaux_calculco (sous répertoire «checkpoint»).

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]

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

tests sur poste de travail personnel (debian, stretch) : usages basiques

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

ex1: checkpoint manuel

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

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

ex2: checkpoint à intervalles réguliers

# 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

ex3: checkpoint manuel, gestion du coordinateur

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-)

ex4: python ?

#lancement
dmtcp_launch  -i 20 ./compteur.py
i=1
...
i=12
# arrêt 
^C       -> les insultes sont copieuses
# reprise
i= 11    -> but it works!

ex5 Matlab ?

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)

variable d’environnements, réseau, debuggage

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:

  • le host est un des premiers soucis rencontrés lors des premiers tests: host (193.49…) ou localhost (127.0.0.1)
  • le port par défaut est 7779

En 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).

Note installation

  • pas de package sur Dabian Stretch ( contrairement à jessie … probablement backport ?)
  • le package des backports trouve ne fonctionne pas
  • soucis en compilant le «master» de github (v.3.0) (oct 2017)
  • 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 

sources, notes, à explorer?

Quelques références:

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)