Ada : exécution d'un travail mixte MPI/OpenMP en batch

Les travaux sont gérés sur l'ensemble des nœuds par le logiciel LoadLeveler. Ils sont répartis dans des classes principalement en fonction du temps Elapsed, du nombre de cœurs et de la mémoire demandés. Vous pouvez consulter ici la structure des classes sur Ada.

Attention : depuis le 4 mars 2014, nous avons positionné par défaut la variable MP_USE_BULK_XFER à yes pour activer le RDMA. Cette fonctionnalité permet d'accroître les performances des communications collectives ainsi que le recouvrement calcul/communication. Cependant, quelques codes peuvent voir leurs performances baisser lorsque cette variable est positionnée à yes : vous pouvez désactiver le RDMA pour votre code en valorisant la variable à no juste avant l'exécution de votre binaire (export MP_USE_BULK_XFER=no ou setenv MP_USE_BULK_XFER no).

Pour soumettre un travail mixte MPI + threads (OpenMP ou pthreads) en batch, il faut :

  • Créer un script de soumission. Voici un exemple, enregistré dans le fichier mixte.ll, qui définit un travail d'1h30mn Elapsed maximum, dont l'exécution se déroulera sur 8 processus MPI demandant chacun 4 tâches OpenMP ou pthreads :
mixte.ll
# Nom arbitraire du travail LoadLeveler
# @ job_name = Mixte
# Fichier de sortie standard du travail
# @ output   = $(job_name).$(jobid)
# Fichier de sortie d'erreur du travail
# @ error= $(job_name).$(jobid)
# Type de travail
# @ job_type = parallel
# Nombre de processus MPI demandes
# @ total_tasks = 8
# Nombre de tâches OpenMP/pthreads par processus MPI
# @ parallel_threads = 4
# Temps du job hh:mm:ss (1h30mn ici)
# @ wall_clock_limit = 1:30:00
# @ queue
# Pour avoir l'echo des commandes
set -x
# Repertoire temporaire de travail
cd $TMPDIR
# La variable LOADL_STEP_INITDIR est automatiquement positionnee par
# LoadLeveler au repertoire dans lequel on tape la commande llsubmit
cp $LOADL_STEP_INITDIR/a.out .
# La memoire STACK max. (defaut 4Mo) utilisee (ici 16 Mo) par
# les variables privees de chaque thread.
export KMP_STACKSIZE=16m
# Il est aussi possible d'utiliser OMP_STACKSIZE
# export OMP_STACKSIZE=16M
# Execution d'un programme parallèle mixte (MPI + threads).
poe ./a.out
  • Soumettre ce script par la commande llsubmit :
$ llsubmit  mixte.ll

Remarques :

  • Dans cet exemple, on suppose que l'exécutable a.out se situe dans le répertoire de soumission, c'est-à-dire le répertoire dans lequel on entre la commande llsubmit (la variable LOADL_STEP_INITDIR est automatiquement valorisée par LoadLeveler).
  • Le fichier de sortie du calcul Mixte.numero_job sera également créé dans le répertoire de soumission; l'éditer ou le modifier pendant le déroulement du travail peut bloquer celui-ci.
  • Le mot-clef parallel_threads indique au gestionnaire de travaux le nombre threads par processus MPI souhaité. ATTENTION : le nombre de processus MPI (total_tasks) et le nombre de threads par processus MPI (parallel_threads) à indiquer sont tels que le nombre total de cœurs réservés (total_tasks * parallel_threads) soit inférieur ou égal à 2048.
  • Mémoire : La valeur par défaut est de 3.5 Go par cœur réservé (donc par thread). Si vous demandez plus de 64 cœurs
    (total_tasks * parallel_threads > 64) alors vous ne pouvez pas dépasser cette limite. Sinon, la valeur maximale que vous pouvez demander est de 7.0 Go par cœur réservé via le mot-clef as_limit. Notez que vous devez spécifier une limite par processus MPI correspondant à (parallel_threads * 7.0 Go). Par exemple, si chaque processus MPI génère 4 threads : # @ as_limit = 28.0gb
  • Les variables privées OpenMP sont stockées dans des zones dites STACK associées à chaque thread. Chacune d'elle est limitée par défaut à 4Mo. Pour dépasser cette limite et aller par exemple jusqu'à 16Mo par thread, il faut utiliser la variable d'environnement KMP_STACKSIZE=16m ou OMP_STACKSIZE=16M. Notez que la valeur de OMP_STACKSIZE est automatiquement ajustée sur la valeur de KMP_STACKSIZE lorsque cette dernière est positionnée.
  • Le mot-clef # @ environment permet de définir des variables d'environnement au niveau LoadLeveler ; ne pas l'utiliser pour certaines variables spécifiques d'OpenMP ou du multi-threading (comme OMP_NUM_THREADS) car elles sont définies automatiquement et valorisées par LoadLeveler au début de l'exécution du travail.
  • Si votre travail comporte des commandes séquentielles relativement longues (pré ou post-traitement, transferts ou archivages de gros fichiers,…), l'utilisation de travaux multisteps peut se justifier.

Pour une étude plus approfondie, vous pouvez consulter :