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 commandefi_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 providersverbs
oupsm3
de libfabric. Nos tests avec un MPI PingPong ont montré des résultats identiques entreverbs
oupsm3
(note : le modulepsm3
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.
Si vous avez des problèmes ou pour tester différents providers
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 :
- Avec OpenMPI, nous recommandons de passer par
srun
, méthode préconisée par Slurm :
# 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