Parcourir la source

checkpoint de array en besteffort

Philippe Marion il y a 4 ans
Parent
commit
56f0c56e8d

+ 27 - 0
checkpoint/besteffort-array/0README

@@ -0,0 +1,27 @@
+À partir de la version 2.5.4 d'OAR, il est possible de lancer un
+signal de checkpoint au jobs en besteffort qui sont sur le point
+d'être tués par des jobs d'une queue prioritaire (avant la v. 2.5.4 le
+meurtre était forcément sans préavis!)
+
+IMPORTANT : les scripts ci-dessous sont «fixés» sur orval06 car ce
+nœud était libre lors de la mise au point de ces programmes
+test. Merci de ne pas lancer ces tests avant de vérifier (monitoring)
+que le noeud orval06 est libre (au besoin, modifier le noeud dans les
+scripts
+
+1) make : compile les fichiers C (compteur capable de recevoir le
+   signal de checkpoint SIGUSR2) et fortran
+
+2) oarsub -S ./orval06-a-tuer.oar pour lancer le «tableau de jobs»
+compteurs de minutes (autant de jobs que de ligne dans input.txt )
+
+3) qques minutes plus tard, lancer :
+
+oarsub -S ./killer-orval06.oar ( quelques produit matriciel openMP
+ dans la queue prioritaire )
+
+- tout compteur tué aura préalablement effectué un checkpoint
+
+- après la fin job «tueur» ( multiplication matricielle, assez court),
+  les ressources sont libérées et les jobs précédemment tués sont
+  relancés (mais à partir du checkpoint)

+ 21 - 0
checkpoint/besteffort-array/Makefile

@@ -0,0 +1,21 @@
+#################################################
+#
+#################################################
+FC=gfortran
+CC=gcc
+FFLAGS=-fopenmp -O3
+
+all :  timing compte
+
+timing : 
+	 $(FC) $(FFLAGS)  matmul-omp.f90 -o timingopenmp 
+
+compte : 
+	 $(CC) compteur-arg.c -o compte
+
+clean:
+	rm -f timingopenmp compte *~ 
+
+allclean:
+	rm -f timingopenmp compte *~ context_compteu* compteur.*.err compteur.*.out openmp-timing-*.??? done.context_comp*
+

+ 118 - 0
checkpoint/besteffort-array/compteur-arg.c

@@ -0,0 +1,118 @@
+#include <stdio.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>  // bool
+#include <unistd.h>  //sleep
+
+/*
+
+ - compteur avec arg  nb de minutes / affichage toutes les 10S
+     usage : ./compte 4   ( pour 4 minute) 
+ - capture du signal  SIGUSR2 12 pour checkpoint:  kill -s 12 LE_PID pour tester 
+ - le checkpoint consiste à sauvegarder le compteur dans le fichier context_compteur_$ARG.txt
+      - relancer le  programme avec le même $ARG reprend à partir de context_compteur_$ARG.txt la valeur contenu dans 
+      - lorsque décompte est fini alors que le fichier context_compteur_$ARG.txt existe,
+        ce dernier est déplacé en done.context_compteur_$ARG.txt 
+      - si ce dernier n'existait pas, le fichier done.context_compteur_$ARG.txt est tout de même crée 
+ */
+
+#define SIZE 1
+#define NUMELEM 5
+
+#define SIGNAL_CHECKPOINT SIGUSR2
+
+/*compteur  variable globale ( main et signal ) */
+int compteur;
+bool checkpt;
+//findice_ckpt
+FILE * fp;
+// nom fichier sauvegarde contexte
+char nomFich[256];
+char doneFich[256];
+
+// fonction capture du signal
+void sig_handler(int signal)
+{
+  printf("signal checkpoint  recu \n");
+  checkpt=true;  
+}
+
+
+int main( int argc, char *argv[] )
+{
+  //int i ;
+
+  if(argc<=1) {
+    printf("merci de passer le nombre de minutes en argument, arret du programme...\n");
+    exit(1);
+  } // sinon, on continue:
+
+
+  checkpt=false;
+  signal(SIGNAL_CHECKPOINT, sig_handler);
+  
+  // nom du fichier de contexte (déjà existant ou à créér) en cas de checkpoint
+  
+  snprintf(nomFich, sizeof nomFich, "context_compteur_%s.txt", argv[1]);  
+  fp = fopen( nomFich, "rb");
+
+  /* avant de lancer le compteur on vérifie s'il n'y a pas un checkpoint
+   (existance du fichier)  context_compteur_$PARAMETRE.txt
+   si oui, initialisation de compteur à sa valeur du dernier checpoint*/
+  
+  if (fp){
+    fread( &compteur , sizeof(int) , 1 , fp);
+    printf("valeur compteur au precedent checkpoint = %d s\n", compteur*10);
+    fclose(fp);
+  }else{
+    compteur=0;
+  }
+
+  // ---- le Compteur proprement dit ---------
+  //( approximatif ce n'est pas un chrono!)
+  int max= atoi(argv[1])*6 ; /* max exprimé en minute (environ: ce n'est pas un chrono!)*/
+  printf("--- compteur de %d minutes ----\n",max/6);  
+  
+  //  while ((compteur < max) && ( checkpt==false ))
+  while ((compteur < max + 1) && ( !checkpt ))  
+    {
+      printf("compteur = %03d0s\n", compteur);
+      // force l'écriture sur la sortie
+      fflush(stdout);
+      sleep(10);
+      compteur++;
+    }
+  // checkpoint:
+  // si la boucle a été interrompue par réception du signal(kill -s 12 le_PID)
+  if(checkpt){
+    printf("valeur du compteur enregistre: %d\n", compteur*10);
+    //fp = fopen("context_compteur.txt", "wb");
+    fp = fopen(nomFich, "wb");
+    if(fp == NULL) {
+        printf("error creating file");
+    }
+    else {
+      fwrite( &compteur , sizeof(int) , 1 , fp);
+      fclose(fp);
+    }
+  }
+    // checkpoint tjrs négatif
+  else {
+    // on est est arrivé au bout, s'il y a un fichier de checkpoint
+    // on le supprime( ou le déplace)
+    snprintf(doneFich, sizeof nomFich, "done.%s", nomFich);
+    if (fp){
+      rename(nomFich, doneFich);
+      // ou bien:
+      //remove(nomFich);
+    }
+    // facultatif: on crée le fichier done.context_compteur_$LePARAM.txt
+    // (facilite post traitement oar)
+    else{
+      fp = fopen(doneFich,"w");
+      fclose(fp);
+    }
+  }
+  return 0;
+}

+ 9 - 0
checkpoint/besteffort-array/input.txt

@@ -0,0 +1,9 @@
+3
+5
+6
+4
+9
+10
+7
+2
+8

+ 19 - 0
checkpoint/besteffort-array/killer-orval06.oar

@@ -0,0 +1,19 @@
+#!/bin/bash
+
+#OAR -l /core=12,walltime=0:15
+#OAR -O openmp-timing-%jobid%.out
+#OAR -E openmp-timing-%jobid%.err
+# à éditer ( vérifier monitoring pour sélectionner un noeud )
+#OAR -p network_address = 'orval06'
+echo "Debut du job ${OAR_JOB_ID}"
+#echo "compilation du programme "
+#make
+
+for i in 4 8 16
+do
+    export OMP_NUM_THREADS=$i
+    echo "Nombre de threads : ${i}"
+    ./timingopenmp
+done
+exit $?
+

+ 56 - 0
checkpoint/besteffort-array/matmul-omp.f90

@@ -0,0 +1,56 @@
+!gfortran -fopenmp -O3 timings.f90
+
+program timings1
+
+    use omp_lib
+
+    implicit none
+    integer, parameter :: ntests = 20
+    integer :: n, nthreads
+    real(kind=8), allocatable, dimension(:,:) :: a,b,c
+    real(kind=8) :: t1, t2, elapsed_time
+    integer(kind=8) :: tclock1, tclock2, clock_rate
+    integer :: i,j,k,itest
+
+    ! Specify number of threads to use:
+    !!$ print *, "Using OpenMP, how many threads? "
+    !!$ read *, nthreads
+    !!nthreads=8
+    !!$ call omp_set_num_threads(nthreads)
+    !omp_get_num_threads()
+    n=1200
+    !print *, "Will multiply n by n matrices, input n: "
+    !read *, n
+
+    allocate(a(n,n), b(n,n), c(n,n))
+
+    ! fill a and b with 1's just for demo purposes:
+    a = 1.d0
+    b = 1.d0
+
+    call system_clock(tclock1)  ! start wall timer
+
+    call cpu_time(t1)   ! start cpu timer
+    do itest=1,ntests
+        !$omp parallel do private(i,k)
+        do j = 1,n
+            do i = 1,n
+                c(i,j) = 0.d0
+                do k=1,n
+                    c(i,j) = c(i,j) + a(i,k)*b(k,j)
+                    enddo
+                enddo
+            enddo
+        enddo
+
+    call cpu_time(t2)   ! end cpu timer
+    print 10, ntests, t2-t1
+ 10 format("Performed ",i4, " matrix multiplies: CPU time = ",f12.8, " seconds")
+
+    
+    call system_clock(tclock2, clock_rate)
+    elapsed_time = float(tclock2 - tclock1) / float(clock_rate)
+    print 11, elapsed_time
+ 11 format("Elapsed time = ",f12.8, " seconds")
+
+end program timings1

+ 31 - 0
checkpoint/besteffort-array/orval06-a-tuer.oar

@@ -0,0 +1,31 @@
+#!/bin/bash
+
+
+#OAR -l /core=1,walltime=20:00
+#OAR -n compte-besteffort
+#OAR -q besteffort
+#OAR -t idempotent
+#OAR --checkpoint 60
+#OAR --signal 12 
+#OAR --array-param-file input.txt
+#OAR -O compteur.%jobid%.out
+#OAR -E compteur.%jobid%.err
+# à éditer ( vérifier monitoring pour sélectionner un noeud )
+#OAR -p network_address = 'orval06' 
+##OAR --notify mail:philipe.marion@univ-littoral.fr
+
+
+# lancement du programme 
+./compte $@ &
+# récupération du PID du programme
+PROGPID=$!
+# au besoin, capture et retransmission du signal SIGUSR2 (12) 
+trap "kill -s 12 $PROGPID ; SCRIPT_CHECKPOINTED='YES' " 12
+wait $PROGPID
+
+# important: si on a quitté le «wait» via un signal de checkpoint,
+# sortir du script OAR avec un code «autre» que 0 (arbitrairement
+# 99) afin que le job soit automatiquement relancé (idempotent)
+[ -n "$SCRIPT_CHECKPOINTED" ] && exit 99
+
+exit $?