Turing : exécution d'un code parallèle en batch

La gestion des travaux sur l'ensemble des nœuds est faite par le système LoadLeveler. Pour pouvoir soumettre, il faut commencer par écrire un script de soumission : c'est l'étape qui est abordée ici. Les commandes de soumission et de suivi de job sont détaillées dans la page commandes de contrôle des travaux batch.

Les travaux multi-étapes sont abordé dans cette rubrique et les travaux multi-étapes avec transferts de fichiers avec Ergon sont présentés dans cette page.

Travaux parallèles simples

Voici un exemple de soumission d'un job pour exécuter un code de 2048 processus MPI sur 1024 cœurs (soit 64 nœuds de calcul, avec 16 cœurs chacun) pour une exécution d'une heure maximum. En supposant que le fichier de soumission s'appelle job.ll, la soumission se fait par la commande :

llsubmit job.ll

Le fichier de soumission contient les lignes suivantes :

job.ll
# @ job_name = job_simple
# @ job_type = BLUEGENE
# Fichier sortie standard du travail
# @ output = $(job_name).$(jobid)
# Fichier erreur standard du travail
# @ error = $(output)
# Temps elapsed maximum demande
# @ wall_clock_limit = 1:00:00
# Taille bloc d'execution
# @ bg_size = 64
# @ queue
 
# Optinnal : copy executable and input file to TMPDIR
# Warning: if you need to transfer important volumes
# of data, please use a multi-step job
cp my_code $TMPDIR
cp data.in $TMPDIR
cd $TMPDIR
 
#Run job with 32 processes by compute node (2 processes by core,
# maximum allowed 4 proc/core) for a total of 2048 processes
runjob --ranks-per-node 32 --np 2048 : ./my_code my_args
 
# Copy output file to submission directory
# Warning: if you need to transfer important volumes
# of data, please use a multi-step job
# $LOADL_STEP_INITDIR is the submission directory
cp data.out $LOADL_STEP_INITDIR/

Le script de soumission est séparé en deux parties. La première contient les directives LoadLeveler (lignes commençant par #@ avec ou sans espaces). La deuxième, le script à exécuter.

Attention : si vous avez à copier/déplacer des volumes importants de données, utilisez des jobs multi-étapes ou des jobs multi-étapes avec transferts de fichiers (en cas de transferts avec Ergon).

Directives LoadLeveler

Un travail sur la Blue Gene/Q doit contenir un certain nombre de directives LoadLeveler pour pouvoir être lancé correctement (les valeurs sont indépendantes de la casse majuscules/minuscules hormis les noms de fichiers).

  • Directives obligatoires :
    • # @ job_type = BLUEGENE : le type du job. Seul BLUEGENE est accepté pour tourner sur les noeuds de calcul. SERIAL peut être utilisé pour les phases de pre- ou post-processing sur la frontale ou de transferts de fichiers (voir pages jobs multi-étapes et jobs multi-étapes avec transferts de fichiers) ;
    • # @ bg_size : taille du bloc d'exécution réservée. Cette variable ne peut prendre que certaines valeurs (si autres, le système rejetera la travail) : 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048 ou 4096 (en voir les raisons). Le choix du nombre de processus MPI en dépend directement (voir ici). Attention, cela peut avoir des conséquences importantes sur la comptabilité de vos travaux ;
    • # @ wall_clock_limit : durée maximale d'exécution du code (donnée en temps elapsed ou d'horloge). Elle est donnée soit au format HH:MM:SS, soit directement en secondes ;
    • # @ queue : dernière directive LoadLeveler. Celles qui suivent ne seront pas prises en compte.

  • Directives optionnelles :
    • # @ bg_connectivity : peut prendre différentes valeurs : Torus, Mesh, Either ou un choix pour les 4 premières dimensions du tore 5D (par exemple pour avoir un tore dans les première et quatrième dimensions : Torus Mesh Mesh Torus). La cinquième dimension n'est pas à spécifier car elle est toujours un tore de dimension 2. Il n'est possible d'avoir un vrai tore 5D que pour un bloc d'un midplane au moins (512 nœuds de calcul). Au-delà d'un midplane, il est possible de demander un tore dans les 5 dimensions, mais les temps d'attente peuvent être supérieurs. En-deçà d'un midplane, il n'est pas possible d'obtenir un tore dans toutes les directions (au mieux 2D, dont la 5ème, pour 64 nœuds, 3D pour 128 et 4D pour 256). Le défaut est à Mesh. Demander spécifiquement un tore peut avoir un impact positif non négligeable sur les performances des communications ;
    • # @ job_name : nom du travail (choix libre) ;
    • # @ output : nom du fichier de sortie standard ;
    • # @ error : nom du fichier d'erreur standard. Si vous voulez mettre l'erreur standard dans le même fichier que la sortie standard, il suffit de mettre la directive égale à $(output) ;
    • # @ notification : si mis à la valeur complete, vous recevrez automatiquement un email récapitulatif en fin d'exécution.

Cette liste de directives n'est pas exhaustive; la documentation IBM vous les fournira toutes (certaines ne sont pas adaptées à la machine ou sont interdites à l'IDRIS à cause de leur impact potentiel sur l'exploitation de la machine).

Script

Normalement, le script exécuté ne doit pas contenir de phase séquentielle (hormis des opérations très rapides comme la copie d'un petit fichier ou des changements de répertoire) pour éviter que les cœurs de calcul réservés n'attendent (le temps gaspillé vous est facturé). Dans le cas de phases séquentielles significatives, il est obligatoire de mettre en place des jobs multi-étapes (voir pages jobs multi-étapes et jobs multi-étapes avec transferts de fichiers).

L'exécution d'un code parallèle se fait toujours via un appel à la commande runjob. Il faut toujours préciser le nombre de processus MPI qui doivent être lancés (option --np), valeur à bien choisir. Il faut également préciser le nombre de processus à exécuter par nœud de calcul (option --ranks-per-node, voir ici). Le choix du mapping (option --mapping) peut avoir une influence importante sur les performances des communications MPI (voir ici). La valeur conseillée pour cette dernière est ABCDET (valeur par défaut). Cette option n'est par contre pas obligatoire. Le nom de l'exécutable et la liste de ses arguments peut être donnée à la fin juste après la symbole :.

Les options utiles pour runjob sont données dans cette page.