Contrôle de l'ordonnancement avec MPI

From CC Doc
Jump to: navigation, search
This page is a translated version of the page Advanced MPI scheduling and the translation is 100% complete.

Other languages:
English • ‎français

La plupart des utilisateurs devraient soumettre les tâches MPIMessage Passing Interface parallèles à mémoire distribuée selon l'exemple présenté à section Tâche MPIMessage Passing Interface de la page Exécuter des tâches. Il suffit d'utiliser - ntasks ou -n pour spécifier le nombre de processus et de laisser l'ordonnanceur faire la meilleure allocation, compte tenu de l'efficacité de la grappe.

Si par contre vous voulez plus de contrôle sur l'allocation, prenez connaissance de la page Support for Multi-core/Multi-thread Architectures de SchedMD; on y décrit comment plusieurs options de la commande sbatch peuvent agir sur l'ordonnancement des processus.

Dans la foire aux questions Slurm, la réponse à What exactly is considered a CPU? peut aussi s'avérer utile.

Exemples de scénarios

Peu de cœurs, nœuds indéterminés

En plus de spécifier la durée de toute tâche Slurm, il faut aussi indiquer le nombre de processus MPIMessage Passing Interface que Slurm doit démarrer. Le moyen le plus simple de ce faire est d'utiliser --ntasks. Puisque l'allocation par défaut de 256Mo de mémoire est souvent insuffisant, vous devriez aussi spécifier la quantité de mémoire nécessaire. Avec --ntasks, il est impossible de savoir combien de cœurs seront sur chaque nœud; vous voudrez alors utiliser --mem-per-cpu ainsi

--ntasks=15
--mem-per-cpu=3G
srun application.exe

Nous avons ici 15 processus MPIMessage Passing Interface. L'allocation des cœurs pourrait se faire sur 1 nœud, sur 15 nœuds, ou sur tout nombre de nœuds entre 1 et 15.

Nœuds entiers

La plupart des nœuds de Cedar et Graham possèdent 32 cœurs et un minimum de 128Go de mémoire. Pour l'exécution d'une tâche intensive en parallèle qui utiliserait efficacement 32 cœurs (ou un multiple de 32), il faudrait demander des nœuds entiers comme ceci :

--nodes=2
--ntasks-per-node=32
--mem=128000M
srun application.exe

Avec cette requête, la tâche sera probablement exécutée plus rapidement que si --ntasks=64 était demandé.

Quand vous demandez des nœuds entiers, vous devriez utiliser --mem=128000M plutôt que --mem=128G puisqu'une petite portion de la mémoire est réservée au système d'exploitation et qu'une demande pour exactement 128Go fera en sorte que la tâche ne sera pas planifiée pour être exécutée sur les nœuds à plus grande capacité de 128Go. Slurm ne rejettera pas la tâche, mais elle restera en attente beaucoup plus longtemps.

Peu de cœurs, nœud unique

Si pour une raison quelconque nous avons besoin de moins de 32 cœurs, mais qu'ils doivent être dans le même nœud, les instructions suivantes conviennent.

--nodes=1
--ntasks-per-node=15
--mem=45G
srun application.exe

Il faudrait aussi avoir --mem-per-cpu=3G. L'avantage de --mem=45G est que la quantité de mémoire utilisée par chacun des processus est sans importance, en autant que dans l'ensemble les processus utilisent moins de 45Go. Avec --mem-per-cpu=3G, la tâche serait annulée si un des processus exige plus de 3Go.

Tâche intensive en parallèle, nœuds n'étant pas en nombre multiple de 32

Ce ne sont pas toutes les tâches qui sont effectuées de façon optimale sur des cœurs en multiples de 32. Le fait d'indiquer ou non un nombre précis de cœurs peut influer sur le temps d'exécution (ou la bonne utilisation de la ressource) ou le temps d'attente (ou la bonne utilisation du temps qui vous est imparti). Pour de l'aide sur comment évaluer ces facteurs, communiquez avec le soutien technique.

Tâches hybrides : MPIMessage Passing Interface avec OpenMP ou MPIMessage Passing Interface avec fils

Il est important de bien comprendre que le nombre de tâches Slurm demandées représente le nombre de processus qui seront démarrés avec srun. Dans le cas d'une tâche hybride qui utilise à la fois des processus MPIMessage Passing Interface et des fils OpenMP ou Posix, vous voudrez indiquer le nombre de processus MPIMessage Passing Interface avec --ntasks ou -ntasks-per-node et ;le nombre de fils avec --cpus-per-task.

--ntasks=16
--cpus-per-task=4
--mem-per-cpu=3G
srun application.exe

Ici, 64 cœurs sont alloués, mais seulement 16 processus MPIMessage Passing Interface sont et seront initialisés. S'il s'agit en plus d'une application OpenMP, chacun des processus démarrera 4 fils, soit un par cœur. Chaque processus pourra utiliser 12Go. Avec 4 cœurs, les tâches pourraient être allouées sur 2 à 16 nœuds, peu importe lesquels.

--nodes=2
--ntasks-per-node=8
--cpus-per-task=4
--mem=96G
srun application.exe

La taille de cette tâche est identique à celle de la précédente, c'est-à-dire 16 tâches (soit 16 processus MPIMessage Passing Interface) avec chacune 4 fils. La différence ici est que nous obtiendrons exactement 2 nœuds entiers. N'oubliez pas que --mem précise la quantité de mémoire par nœud et que nous l'utilisons de préférence à --mem-per-cpu pour la raison donnée plus haut.

Pourquoi srun plutôt que mpiexec ou mpirun?

mpirun permet la communication entre processus exécutés sur des ordinateurs différents; les ordonnanceurs récents possèdent cette même fonctionnalité. Avec Torque/Moab, il n'est pas nécessaire de fournir à mpirun la liste des nœuds ou le nombre de processus puisque l'ordonnanceur s'en charge. Avec Slurm, c'est l'ordonnanceur qui décide de l'affinité des tâches, ce qui évite d'avoir à préciser des paramètres comme

mpirun --map-by node:pe=4 -n 16  application.exe

Dans les exemples précédents, on comprend que srun application.exe distribue automatiquement les processus aux ressources précises allouées à la tâche.

En termes de niveaux d'abstraction, srun est au-dessus de mpirun; srun peut même faire plus que mpirun. Avec Slurm, srun prend en charge tous les types de calculs; il est aussi plus polyvalent que le pbsdsh de Torque. On pourrait dire de srun que c'est l'outil Slurm universel pour la distribution des tâches en parallèle  une fois les ressources allouées, la nature de l'application importe peu, qu'il s'agisse de MPIMessage Passing Interface, OpenMP, hybride, distribution sérielle, pipeline, multiprogramme ou autre.

Bien entendu, srun est parfaitement adapté à Slurm : il amorce la première étape de la tâche, initialise correctement l;es variables d'environnement SLURM_STEP_ID et SLURM_PROCID et fournit les renseignements de suivi appropriés.

Pour des exemples de quelques différences entre srun et mpiexec, voyez le forum OpenMPI. Dans certains cas, mpiexec offrira une meilleure performance que srun, mais srun diminue le risque de conflit entre les ressources allouées par Slurm et celles utilisées par OpenMPI.

Références

Categorie:SLURM