Exemples de scripts pour simulations séquentielles multiples, tâches OpenMP, tâches hybrides

De Wiki de Calcul Québec
Aller à : Navigation, rechercher
Cette page contient des modifications qui ne sont pas marquées pour la traduction.

Autres langues :anglais 100% • ‎français 100%

Voici des exemples de fichiers de soumission de tâches pour différentes situations. On peut copier l'un ou l'autre de ces fichiers dans son répertoire personnel pour le modifier au besoin. Il faudra l'adapter au serveur de toute façon puisque tous les serveurs n'ont pas les mêmes caractéristiques.

Sommaire

Simulations séquentielles multiples

Lorsque l'on veut rouler le même programme sur plusieurs jeux de données différents, il est préférable de regrouper les simulations dans une même tâche Torque. C'est même essentiel sur les serveurs qui ne permettent qu'une seule tâche par nœud (Colosse et Mp2) pour éviter de gaspiller des ressources.

Pour regrouper des simulations efficacement, il faut idéalement que le temps de calcul varie peu d'une simulation à l'autre. Il faut aussi s'assurer d'avoir suffisamment de mémoire sur un nœud pour que toutes les simulations puissent y rouler sans se nuire. Il faut ajuster le nombre de simulations à exécuter en conséquence.

Le principe de fonctionnement est simple : il suffit de lancer plusieurs simulations en arrière-plan grâce à la perluète (le caractère « & »). Ensuite, la commande « wait » permet d'attendre que toutes les simulations arrivent à leur fin avant de terminer le script de soumission. Dans l'exemple ci-dessous, on suppose que le programme « prog » se trouve dans le répertoire « $HOME/rep_programme » et que chaque sous-répertoire contient des fichiers d'entrée différents des autres, de sorte que les huit simulations obtiennent des résultats différents dans le fichier « sortie ». On suppose aussi que tous les modules nécessaires sont déjà chargés.


Fichier : simulations_multiples.sh
#!/bin/bash
#PBS -l walltime=30:00:00
#PBS -l nodes=1:ppn=8
 
SRC=$HOME/rep_programme
cd $SCRATCH/rep1 ; $SRC/prog > sortie &
cd $SCRATCH/rep2 ; $SRC/prog > sortie &
cd $SCRATCH/rep3 ; $SRC/prog > sortie &
cd $SCRATCH/rep4 ; $SRC/prog > sortie &
cd $SCRATCH/rep5 ; $SRC/prog > sortie &
cd $SCRATCH/rep6 ; $SRC/prog > sortie &
cd $SCRATCH/rep7 ; $SRC/prog > sortie &
cd $SCRATCH/rep8 ; $SRC/prog > sortie &
 
wait


Lot de tâches séquentielles

Vous pouvez soumettre un lot de tâche séquentielles avec bqTools sur les serveurs où ce logiciel est installé. Pour les autres machines, voyons maintenant comment faire pour exécuter un programme séquentiel sur un plus grand nombre de jeux de données, qui se trouvent par exemple dans les répertoires « $SCRATCH/repX », où X varie de 0 à 255 et où un maximum de 10 tâches sont exécutées en même temps.

D'abord un exemple avec Moab, à soumettre avec la commande « msub ».

Fichier : lot_taches_sequentielles_moab.sh
#!/bin/bash
#PBS -A abc-123-aa
#PBS -l walltime=30:00:00
#PBS -l nodes=1:ppn=8
#PBS -t [0-255:8]%10
 
SRC=$HOME/rep_programme
LIMITE_SUP=$(($MOAB_JOBARRAYINDEX + 7))
 
for i in $(seq $MOAB_JOBARRAYINDEX $LIMITE_SUP)
do
  cd $SCRATCH/rep$i ; $SRC/prog > sortie &
done
 
wait


Ensuite, le même exemple avec Torque, à soumettre avec la commande « qsub ».

Fichier : lot_taches_sequentielles_torque.sh
#!/bin/bash
#PBS -l walltime=30:00:00
#PBS -l nodes=1:ppn=8
#PBS -t 0-31%10
 
SRC=$HOME/rep_programme
LIMITE_INF=$((8 * $PBS_ARRAYID))
LIMITE_SUP=$(($LIMITE_INF + 7))
 
for i in $(seq $LIMITE_INF $LIMITE_SUP)
do
  cd $SCRATCH/rep$i ; $SRC/prog > sortie &
done
 
wait



Pipeline linéaire avec lots de tâches

Il est possible d'utiliser les lots de tâches pour créer un pipeline linéaire si toutes les tâches requièrent les mêmes ressources. Pour ce faire, avec Moab, créez un script de soumission ressemblant à celui-ci :


Fichier : pipeline_moab.sh
#!/bin/bash
#PBS -A abc-123-aa
#PBS -l walltime=30:00:00
#PBS -l nodes=1:ppn=8
#PBS -t [1-10]%1
#PBS -l flags=CancelOnAnyFailure
 
cd $SCRATCH/repertoire_de_travail
$HOME/mes_scripts/traitement_${MOAB_JOBARRAYINDEX}.sh arguments


Puis soumettez le lot de tâche. L'option %1 s'assurera qu'une seule des tâches s'exécutera en parallèle, puis l'option flags=CancelOnAnyFailure s'assurera que le lot est annulé en entier si l'une des tâches échoue.


Pipeline complexe avec lots de tâches

Il est possible d'utiliser les lots de tâches pour créer un pipeline complexe si toutes les tâches requièrent les mêmes ressources. Pour ce faire, avec Moab, créez un script de soumission ressemblant à celui-ci :


Fichier : pipeline_moab.sh
#!/bin/bash
#PBS -A abc-123-aa
#PBS -l walltime=30:00:00
#PBS -l nodes=1:ppn=8
#PBS -t [1-10]
 
cd $SCRATCH/repertoire_de_travail
$HOME/mes_scripts/traitement_${MOAB_JOBARRAYINDEX}.sh arguments


Puis, définissez les scripts de traitement, traitement_1.sh à traitement_10.sh. Supposons maintenant que votre pipeline est tel que les tâches 1, 2, 3 et 4 peuvent s'exécuter en parallèle, mais que les tâches 5 et 6 doivent s'exécuter après celles-ci, en série, puis que 7, 8, 9 et 10 peuvent s'exécuter en parallèle. Vous pouvez obtenir ce résultat en soumettant vos tâches de la manière suivante :


 
 [nom@serveur $] id=$(msub -h pipeline_moab.sh | tail -n 1)
 [nom@serveur $] mjobctl -m depend=$id[1]:$id[2]:$id[3]:$id[4] $id[5]
 [nom@serveur $] mjobctl -m depend=$id[5] $id[6]
 [nom@serveur $] mjobctl -m depend=$id[6] $id[7]
 [nom@serveur $] mjobctl -m depend=$id[6] $id[8]
 [nom@serveur $] mjobctl -m depend=$id[6] $id[9]
 [nom@serveur $] mjobctl -m depend=$id[6] $id[10]
 [nom@serveur $] mjobctl -u $id
 


La première de ces commandes soumet la tâche à Moab, mais la bloque (option -h), puis capture son identifiant. Les six lignes suivantes définissent les dépendances entre les sous-tâches. La dernière commande débloque l'exécution de la tâche.

Pour faire la même chose avec Torque, créez plutôt un script de soumission ressemblant à celui-ci :

Fichier : pipeline_torque.sh
#!/bin/bash
#PBS -A abc-123-aa
#PBS -l walltime=30:00:00
#PBS -l nodes=1:ppn=8
#PBS -t 1-10
 
cd $SCRATCH/repertoire_de_travail
$HOME/mes_scripts/traitement_${PBS_ARRAYID}.sh arguments


Dans l'exemple ci-dessus, les scripts de traitement, traitement_1.sh à traitement_10.sh, sont identiques à ceux de l'exemple avec Moab. Si on a les mêmes dépendances que ci-dessus, on peut soumettre les tâches ainsi :

 
 [nom@serveur $] jobid=$(qsub -h pipeline_torque.sh | tail -n 1)
 [nom@serveur $] id=$(echo $jobid | sed 's/\[.*//')
 [nom@serveur $] qalter -W depend=afterok:$id[1]:$id[2]:$id[3]:$id[4] $id[5]
 [nom@serveur $] qalter -W depend=afterok:$id[5] $id[6]
 [nom@serveur $] qalter -W depend=afterok:$id[6] $id[7]
 [nom@serveur $] qalter -W depend=afterok:$id[6] $id[8]
 [nom@serveur $] qalter -W depend=afterok:$id[6] $id[9]
 [nom@serveur $] qalter -W depend=afterok:$id[6] $id[10]
 [nom@serveur $] qrls $jobid
 


La première de ces commandes soumet le lot de tâches à Torque, mais le bloque (option -h), puis capture son identifiant. Les six lignes suivantes définissent les dépendances entre les sous-tâches. La dernière commande débloque l'exécution de la tâche.

Tâche OpenMP

Les tâches OpenMP ne s'exécutent que sur un nœud à la fois puisqu'elles ne fonctionnent que sur des ordinateurs à mémoire partagée.

Note : Les paramètres KMP_* ci-dessous ne sont valides qu'avec Intel. Pour plus d'informations, voir la page OpenMP.

Fichier : tache_openmp.sh
#!/bin/bash
#PBS -l walltime=30:00:00
#PBS -l nodes=1:ppn=8
 
# On utilise ici le compilateur d'Intel.
module load compilers/intel/12.0.4 
# On définit des variables d'environnement pour ce compilateur : 
# - on évite de céder les processeurs à la fin des sections parallèles;
export KMP_LIBRARY=turnaround
# - on définit la taille de la pile pour chaque fil d'exécution (valeur
# par défaut de 1m (1 Mo)! Unités acceptées b, k et m pour octet, Ko et Mo);
export KMP_STACKSIZE=1000m
# - on fixe les fils OpenMP sur les cœurs, un à la suite de l'autre.
export KMP_AFFINITY=compact
 
export OMP_NUM_THREADS=8 
SRC=$HOME/rep_programme
cd $SCRATCH/rep
 
$SRC/prog_openmp


Tâche hybride

Voici un exemple d'une tâche utilisant MPI à un processus par nœud et OpenMP sur tous les cœurs de chaque nœud. L'exemple utilise encore une fois le compilateur d'Intel.

Fichier : tache_hybride.sh
#!/bin/bash
#PBS -l walltime=30:00:00
#PBS -l nodes=4:ppn=8
 
# On utilise ici le compilateur d'Intel.
module load compilers/intel/12.0.4
# On utilise une bibliothèque MPI pour ce compilateur.
module load mpi/openmpi/1.4.5_intel
 
# On définit des variables d'environnement pour le compilateur d'Intel, comme dans l'exemple OpenMP : 
export KMP_LIBRARY=turnaround
export KMP_STACKSIZE=1000m
export KMP_AFFINITY=compact
 
export OMP_NUM_THREADS=8
# On indique de ne pas fixer le processus sur un cœur, ce qui désactiverait le parallélisme OpenMP.
export IPATH_NO_CPUAFFINITY=1
SRC=$HOME/rep_programme
cd $SCRATCH/rep
 
mpiexec -n 4 -npernode 1 $SRC/prog_openmp


Documentation additionnelle spécifique aux serveurs

Briarée

Colosse

Cottos

Guillimin

Hadès

Mammouth parallèle II

Mammouth série II

Psi


Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Ressources de Calcul Québec
Outils
Partager