Project

General

Profile

MPI

Cet article donne quelques indications sur les environnements MPI disponibles, la façon de compiler et d'exécuter des programmes MPI sur le cluster.

Avant-propos : MPI ?

Rappelons brièvement que MPI est un "outil" pour faire du calcul parallèle, c'est-à-dire exploiter plusieurs processeurs ou nœuds dans un cluster. MPI une norme, avec différentes implémentations (des librairies), qui seront utilisées par des programmes / logiciels.

  • Si vous êtes développeur, vous pouvez programmer en MPI -- dans ce cas, vous êtes peut-être déjà un expert, ou vous pouvez suivre les formations au développement MPI accessibles au MCIA ou ailleurs
  • Si vous êtes utilisateur d'un logiciel, celui-ci a peut-être la possibilité de "faire" du MPI pour exploiter plus de ressources matérielles -- dans ce cas, merci de consultez la documentation de votre logiciel avant de contacter notre support

Environnements MPI disponibles

Les modules permettent de choisir le "MPI", c'est-à-dire l'implémentation des outils et librairies, et la version précise - Vous pouvez utiliser la commande suivante pour voir tous les modules MPI :

module avail mpi intel/mpi

Les principales versions disponibles :

Module Implémentation Commentaire
mpi/openmpi-x86_64 OpenMPI 4 Version livrée avec le système
mpi/intel-efs/openmpi_gcc_ofi-4.1.6 OpenMPI 4 Version Intel pour Ethernet Fast Fabric - Adaptée pour les noeuds sur réseau RoCE uniquement
intel/mpi/latest Intel OneAPI

Notez que si vous utilisez un logiciel prêt à l'emploi, ou un conteneur, celui-ci sera livré (à coup sûr pour un conteneur, certainement pour un logiciel commercial) avec ses propres librairies MPI. Dans ce cas, vous devrez peut-être prêter attention à la version de MPI fournie et à son paramétrage.

Réseau d'interconnexion et meilleure utilisation possible

Informations sur les communications dans MPI

Sans rentrer dans tous les détails, il faut savoir que les librairies MPI (que ce soit Intel MPI, OpenMPI ou d'autres) ne gèrent pas directement les communications entre les processus. Elles font appel à d'autres librairies, spécialisées dans ces communications, qui elles-mêmes possèdent souvent plusieurs modules pour prendre en charge les différents types de réseaux disponibles.

En général, la librairie MPI va essayer de "deviner" la meilleure façon de communiquer — Mais il est possible, avec des options ou avec des variables d'environnement, de préciser quelle librairie de communication, et quel(s) sous-module(s) on souhaite utiliser.

D'après nos tests sur CALI v3, il semble que les meilleurs résultats pour des communication inter-noeuds (à travers le réseau) soient obtenus avec libfabric (aussi appelée OFI), et ensuite avec son provider (module) psm3 (recommandé) ou verbs quand on est sur le réseau 25 Gb, ou simplement avec le module tcp pour le réseau 10 Gb/s (voir materiel).

  • la commande fi_info liste tous les providers utilisables. Attention, la librairie Intel MPI contient sa propre version de libfabric, avec sa commande fi_info
  • avec des communications de type socket / tcp : les communications passent par les "couches" TCP/IP habituelles du réseau et en particulier du noyau Linux. Cette méthode de communication est la plus simple car très standardisée — cependant, elle n'optimise pas le transfert des données, qui vont être recopiées entre l'espace mémoire du noyau Linux et l'espace mémoire applicatif
  • soit avec des communications de type RDMA (Remote Direct Memory Access), en utilisant le protocole RoCE (RDMA over Convernged Ethernet) du réseau, ce qui est possible avec les providers verbs ou psm3 de libfabric. Nos tests avec un MPI PingPong ont montré des résultats identiques entreverbs ou psm3 (note : le module psm3 est celui fourni par Intel Ethernet Fast Fabric Suite). psm3 devrait être optimisé par Intel pour ce réseau, il est recommandé. Nous vous invitons à faire vos propres tests sur vos codes de calcul.

Rappel : pour indiquer à Slurm que votre job doit être localisé sur des noeuds avec accès au réseau RoCE, utilisez l'option --constraint=net_roce (option pour les commandes srun ou sbatch)

Les variables suivantes sont à mettre dans votre fichier batch avant le lancement du programme.

Configuration pour OpenMPI

Avec OpenMPI v4, positionnez les variables suivantes pour forcer l'utilisation de OFI (libfabric) et activez les meilleurs providers en fonction des noeuds où vous exécutez votre code (psm3 a une priorité supérieure, il sera alors sélectionné automatiquement s'il peut utiliser le réseau) :

export OMPI_MCA_pml=cm
export OMPI_MCA_mtl=ofi
# Sur le réseau 25 Gb / RoCE : 
export OMPI_MCA_mtl_ofi_provider_include=psm3,verbs,tcp,shm
# Pour les autres noeuds : 
export OMPI_MCA_mtl_ofi_provider_include=^psm3,verbs

Configuration pour Intel MPI

Intel MPI utilisera automatiquement libfabric. Il ne reste qu'à éventuellement spécifier le provider utilisé.

Par défaut, psm3 sera sélectionné, donc vous n'avez rien à faire.

Références

Lancer un job MPI sous SLURM

Si vous voulez utiliser plusieurs nœuds de calcul pour faire du calcul distribué, faites par exemple la réservation avec les options suivantes :

#SBATCH --nodes=2             # Nombre (minimum) de nœuds à affecter au job
#SBATCH --ntasks-per-node=1   # Le job est sensé lancer 1 processus par nœud
#SBATCH --cpus-per-task=4     # Nombre de CPU (cœurs) qu'utilisera chaque processus
  • On demande 2 nœuds, chacun aura un processus avec 4 coeurs à sa disposition
  • Bien entendu, cet exemple n'a de sens que si chaque processus est capable d'utiliser 4 cœurs en même temps, donc si un processus est lui même multi-threadé !
  • Vous devez prendre connaissance des limites de chaque partition pour savoir quelles ressources maximales sont disponibles

Ensuite, pour lancer le programme MPI :

# Recommandé par SLURM : 
srun mon_executable_mpi

# Ou en cas de problème, tester : 
mpirun -np $SLURM_NTASKS mon_executable_mpi
  • Avec Intel MPI :
# Recommandé par SLURM : 
export I_MPI_PMI_LIBRARY=/usr/lib64/libpmi2.so.0
srun --mpi=pmi2 mon_executable_mpi

# Ou en cas de problème, tester : 
mpirun -np $SLURM_NTASKS mon_executable_mpi