debuggage

Outils

Plusieurs outils peuvent être utilisés

  1. valgrind (debuggage et profilage)
  2. VTune (profilage pour optimisation)
  3. les outils DDT XXXX denistina peuvent être utilisés.
  4. la version mpidebug de MARS

La documentation suivante décrit l’utilisation de la branche mpidebug de MARS.

Une version de MARS ($HTTPSVNROOT/branches/mpidebug) a été instrumentée pour que le code séquentiel sauve les variables demandées dans des fichiers correspondants à ceux du code MPI: même extension et même domaine spatial. Seules certaines revisions sont disponibles.

Moyennant quelques modifications, le même code peut être adapté pour debugguer OMP ou les reprises.

Mode d’emploi du code MARS en mode debug

sous $UDIR

  1. $HOMEMARS : /home1/caparmor/vgarnier/CODE_MARS_V8/V8.XXdbg/MarsAgrif2 (Vérifier auprès de V.Garnier)

  2. A partir d’une configuration « propre » $UDIR/CONF/CONF-CLEAN (où les routines du $UDIR sont limitées aux routines modifiées par l’utilisateur), créer une nouvelle configuration:

    mkconfdir CONF DEBUG [rank]
    

    dans le makefile : REF_CONFIG est la configuration « propre » (pour ne plus avoir dans $UDIR que les routines qui vont être modifiées lors des développements MPI):

    vi makefile; REF_CONFIG = path_udir/CONF/CONF-CLEAN
    gmake install
    
  3. Récupérer à la main les fichiers parmeters : cp INC/parameters.F90* de CONF-CLEAN dans CONF-DEBUG

  4. Modifier les clés CPP du Makefile.seq et Makefile.mpi pour tous les rangs

  5. Preparer les Makefile.caparmor.seq et Makefile.caparmor.mpi (ajouter les clefs cpp -Dkey_debug, -Dkey_debug_dyn3dy…)

  6. Dans le makefile

    • Si rang : changer les rankX en rank0, rank1 …, et les rank_X en rank_0, rank_1 …

    • Si pas de rang : éliminer les _rankX et rank_X

      make clean && make seq
      gmake clean && gmake mpi
      

sous $RDIR

  1. Après la 1ère compilation, faire les liens mentionnés en fin de compilation. Les fois suivantes, l’exécutable est lancé immédiatement après la compilation.
  2. Préparer dans $RDIR les fichiers para*.txt et output.dat comme pour toute configuration.
  3. Pour les runs MPI avec decoupage 2D, copier dans $RDIR le fichier mpi.txt issu de decoupe.
  4. Dans le fichier mpi/launch_mpi, indiquer le bon nom de fichier de sortie (celui de output.dat suivi de ‘_suffix’) et spécifier le nombre de CPU.
  5. Sous $RDIR/seq, faire le lien ln –s ../mpi/mpidebugprepare . (permet dans le run séquentiel de sortir les résultats découpés de la même manière que dans le run mpi).
  6. Si utilisation de Agrif, faire un lien pour chaque ../mpi/mpidebugprepare_AGRIFchild et copier le fichier AGRIF_FixedGrids.in dans les répertoires seq et mpi.

Pour choisir les pas de temps d’intérêt

Les pas de temps d’intérêt sont les pas de temps pour lesquels on va créer des fichiers:

ncoivXXXXXX

Ce sont ces fichiers qu’il faudra comparer pour déduire à partir de quel moment il y a divergence entre le job séquentiel et le job MPI

  1. sous $UDIR getfile WORK/tooldebugwrite.F90
  2. dans tooldebugwrite.F90, changer l’initialisation des valeurs de debug_nbouc et nbouc_fin (1er et dernier des pas de temps auxquels sont écrits les résultats des variables qu’on vérifie)

Pour afficher de nouvelles variables

  1. à chaque endroit du code où on veut vérifier que la parallélisation MPI n’a pas modifié le calcul d’une variable VAR, ajouter selon le type de variable un

    CALL debugwrite('name_out_file',VAR(:,limin:limax,ljmin:ljmax))
    par exemple:
    CALL debugwrite('xeuv.step2dxy.afterdyn2dxy',xeuv(limin:limax,ljmin:ljmax))
    

    Inscrire ces vérifications dans une clé CPP par type de vérification afin de faciliter l’individualisation des vérifications. Penser à ajouter ces clés dans le Makefile.mpi et le Makefile.seq

Evaluation des résultats

  1. gmake seq ; gmake mpi

  2. les jobs sont lancés automatiquement en fin de compilation et en sortie, pour chaque appel à debugwrite, création d’un fichier de sortie par variable, par CPU et par nbouc. Sous $RDIR /mpi et /seq, déplacer ces fichiers résultats dans des répertoires, qui doivent être rigoureusement identiques pour faciliter la comparaison des fichiers.

  3. la comparaison des répertoires seq et mpi permet de repérer les variables qui donnent des résultats erronés en parallèle:

    diff -r seq/test mpi/test
    
    ou bien
    
    python ./compare_seq_mpi.py seq/dumps mpi/dumps  (voir description ci-dessous)
    
  4. En fin d’étude, envoyer les nouveaux “print” au référent du code MARS pour introduction dans le code de base.

Note

Pour utiliser ce programme pour vérifier les reprises, utiliser la clef cpp -Dkey_debug_restart pour l’un des jobs (sequentiel ou mpi) et préciser debug_nbouc (1 pour le job avec le restart file, X pour job sans restart file) Exemple:

#ifdef key_debug_restart
INTEGER  :: ncall=0,debug_nbouc=1,nbouc_fin=2
#else
INTEGER  :: ncall=0,debug_nbouc=34,nbouc_fin=35
#endif

Mode d’emploi du script python compare_seq_mpi.py (travaux M. Honnorat)

Ce script nécessite le paquet ‘pandas’ pour lire les fichiers tabulés. Il est disponible sous $HOMEMARS/../../branches/mpidebug/DOC/MPI.

Il prend en entrée deux répertoires contenant uniquement les fichiers de dumps pour les runs seq et mpi. Par défaut, ‘seq/test’ et ‘mpi/test’.

Exemple::
python ./compare_seq_mpi.py seq/dumps mpi/dumps

Les répertoires seq/dumps et mpi/dumps ne doivent contenir que des fichiers produits par tooldebugwrite, ils sont produits de la manière suivante

$ cd $UDIR/ACC/ACC-debug
$ make clean && make mpi
$ make clean && make seq
$ cd $RDIR/ACC/ACC-debug
$ (cd seq ; rm -rf test && mkdir -p test && find . -maxdepth 1 -name "debug_*" -exec mv {} test \;)
$ (cd mpi ; rm -rf test && mkdir -p test && find . -maxdepth 1 -name "debug_*" -exec mv {} test \;)

Puis on calcule les différences

$ python ./compare_seq_mpi.py  >& output_seq_mpi.txt

Le script produit une ligne par fichier différent, en indiquant le nombre de différences ainsi que les erreurs L^1, L^2 et L^inf. Comme il se peut qu’il y ait des erreurs de l’ordre de l’epsilon machine, sans gravité, on peut régler le seuil de détection pour l’affichage. Dans la version actuelle, il est fixé à 3e-15 (variable ERR_MIN en début de script).