Skip to main content

Compilateurs et MPI

eXplor-v2 met à disposition des compilateurs et des implémentations MPI via les modules d'environnement. Cette page explique comment choisir un environnement cohérent, compiler un programme C, C++ ou Fortran, puis l'exécuter avec Slurm.

Principe essentiel

Utilisez le même environnement de compilateur et de MPI pour compiler et exécuter un programme parallèle. Mélanger des bibliothèques ou des implémentations MPI incompatibles est une cause fréquente d'échecs à l'exécution.

Concepts essentiels​

TermeSignification
CompilateurOutil qui transforme un code source en exécutable, par exemple C, C++ ou Fortran
MPIInterface de passage de messages pour les programmes parallèles distribués
Wrapper MPICommande de compilation qui appelle le compilateur avec les options MPI nécessaires
Tâche SlurmProcessus attribué et lancé par Slurm
CPU par tâcheNombre de CPU attribués à chaque processus Slurm
OpenMPModèle de parallélisme par threads, souvent utilisé à l'intérieur d'un processus

Les wrappers MPI courants sont :

LangageWrapper MPI courant
Cmpicc
C++mpicxx ou mpic++
Fortranmpifort

Les noms exacts dépendent de l'implémentation MPI chargée.

Préparer un environnement cohérent​

Commencez par rechercher les modules disponibles :

module spider gcc
module spider mpi

Puis construisez un environnement propre :

module purge
module load nom_compilateur
module load nom_mpi
module list

Vérifiez les outils réellement utilisés :

which gcc
which mpicc
which mpifort

mpicc --version
mpifort --version

Pour connaître le compilateur sous-jacent utilisé par un wrapper MPI :

mpicc -show
mpicxx -show
mpifort -show

Selon l'implémentation MPI, l'option peut être --showme :

mpicc --showme
Utilisez les noms de modules fournis par le centre

Les exemples utilisent nom_compilateur et nom_mpi. Utilisez toujours les noms et versions exacts retournés par module avail ou module spider.

Compiler un programme séquentiel​

Programme C​

Fichier bonjour.c :

#include <stdio.h>

int main(void) {
printf("Bonjour depuis eXplor-v2.\n");
return 0;
}

Compilation :

gcc -O3 -Wall -Wextra -o bonjour bonjour.c

Exécution :

./bonjour

Programme C++​

g++ -O3 -Wall -Wextra -std=c++17 -o mon-programme mon-programme.cpp

Programme Fortran​

gfortran -O3 -Wall -o mon-programme mon-programme.f90

Les options d'optimisation doivent être adaptées au compilateur et au programme. Commencez avec des options simples et validez les résultats avant d'utiliser des optimisations agressives.

Compiler un programme MPI​

Les wrappers MPI ajoutent les chemins d'en-têtes et de bibliothèques nécessaires. Préférez-les aux appels directs au compilateur lorsque votre programme utilise MPI.

Programme MPI en C​

Fichier bonjour-mpi.c :

#include <mpi.h>
#include <stdio.h>

int main(int argc, char **argv) {
int rank;
int size;

MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);

printf("Bonjour depuis le rang %d sur %d.\n", rank, size);

MPI_Finalize();
return 0;
}

Compilation :

mpicc -O3 -Wall -Wextra -o bonjour-mpi bonjour-mpi.c

Programme MPI en C++​

mpicxx -O3 -std=c++17 -o mon-programme-mpi mon-programme-mpi.cpp

Programme MPI en Fortran​

mpifort -O3 -o mon-programme-mpi mon-programme-mpi.f90

Exécuter MPI avec Slurm​

Dans une allocation Slurm, utilisez srun pour lancer les processus MPI. Slurm peut ainsi attribuer, contrôler et suivre correctement les tâches.

Exemple en session interactive :

salloc \
--partition=std \
--ntasks=4 \
--cpus-per-task=1 \
--mem=4G \
--time=00:15:00

srun ./bonjour-mpi

Exemple de script batch :

#!/bin/bash
#SBATCH --job-name=bonjour-mpi
#SBATCH --partition=std
#SBATCH --ntasks=4
#SBATCH --cpus-per-task=1
#SBATCH --mem=4G
#SBATCH --time=00:15:00
#SBATCH --output=logs/%x-%j.out
#SBATCH --error=logs/%x-%j.err

set -euo pipefail

mkdir -p logs

module purge
module load nom_compilateur
module load nom_mpi
module list

srun ./bonjour-mpi
Privilégiez srun

Dans un job Slurm, préférez srun à mpirun ou mpiexec, sauf si la documentation spécifique de votre application ou la configuration du centre impose une autre méthode.

Parallélisme MPI, OpenMP et hybride​

MPI​

MPI utilise plusieurs processus, souvent un par tâche Slurm :

#SBATCH --ntasks=8
#SBATCH --cpus-per-task=1

srun ./mon-programme-mpi

OpenMP​

OpenMP utilise plusieurs threads dans un seul processus :

#SBATCH --ntasks=1
#SBATCH --cpus-per-task=8

export OMP_NUM_THREADS="$SLURM_CPUS_PER_TASK"
srun ./mon-programme-openmp

Compilez un programme OpenMP avec l'option adaptée au compilateur. Avec GCC, par exemple :

gcc -O3 -fopenmp -o mon-programme-openmp mon-programme-openmp.c

MPI + OpenMP​

Un programme hybride utilise plusieurs processus MPI, chacun avec plusieurs threads :

#SBATCH --ntasks=4
#SBATCH --cpus-per-task=2

export OMP_NUM_THREADS="$SLURM_CPUS_PER_TASK"
srun ./mon-programme-hybride

Dans cet exemple, le job réserve huit CPU au total : quatre tâches MPI avec deux CPU par tâche.

Bibliothèques et compilation​

Lorsqu'une bibliothèque est fournie par module, chargez son module avant la compilation et l'exécution :

module purge
module load nom_compilateur
module load nom_mpi
module load nom_bibliotheque

Utilisez les options recommandées par le module ou l'outil fourni. pkg-config peut aider à obtenir des options de compilation pour certaines bibliothèques :

pkg-config --cflags nom_bibliotheque
pkg-config --libs nom_bibliotheque

Exemple générique :

gcc -O3 \
$(pkg-config --cflags nom_bibliotheque) \
-o mon-programme mon-programme.c \
$(pkg-config --libs nom_bibliotheque)

Optimisation et débogage​

Commencez par vérifier que le programme produit des résultats corrects avant de chercher à l'optimiser.

Options courantes avec GCC :

ObjectifOptions indicatives
Avertissements-Wall -Wextra
Débogage-g -O0
Optimisation générale-O2 ou -O3
OpenMP-fopenmp
Standard C++ récent-std=c++17
Validez les résultats

Certaines optimisations peuvent modifier le comportement numérique, notamment avec les calculs en virgule flottante. Comparez toujours les résultats avec une référence ou un jeu de tests connu.

Pour un débogage MPI, commencez avec peu de tâches :

srun --ntasks=2 ./bonjour-mpi

Vérifier l'environnement d'exécution​

Avant de lancer une campagne importante, enregistrez les informations de compilation et d'exécution :

module list 2>&1
which mpicc
mpicc -show
which srun
srun --version

Pour identifier les bibliothèques dynamiques d'un exécutable :

ldd ./mon-programme-mpi

Exécutez ldd uniquement sur un exécutable de confiance.

Erreurs fréquentes​

mpi.h: No such file or directory​

Le module MPI n'est probablement pas chargé ou vous utilisez le compilateur direct au lieu de mpicc.

module list
which mpicc

Commande mpicc introuvable​

Recherchez et chargez l'implémentation MPI correspondante :

module spider mpi
module load nom_mpi

Erreur de bibliothèque MPI à l'exécution​

Le programme peut avoir été compilé avec une implémentation MPI différente de celle chargée à l'exécution. Rechargez le même compilateur et le même MPI, ou recompilez le programme dans l'environnement courant.

Nombre de processus inattendu​

Vérifiez les ressources demandées et la commande :

scontrol show job "$SLURM_JOB_ID"
srun --ntasks="$SLURM_NTASKS" ./mon-programme-mpi

Performances faibles​

Vérifiez :

  • si le programme utilise réellement plusieurs tâches ou threads ;
  • le nombre de CPU demandé ;
  • la répartition MPI et OpenMP ;
  • les accès aux fichiers ;
  • la taille du problème ;
  • le temps consacré aux communications MPI.

Augmentez progressivement les ressources et comparez les temps d'exécution plutôt que de supposer qu'un plus grand nombre de CPU sera toujours plus rapide.

Bonnes pratiques​

  • Commencez par module purge.
  • Chargez explicitement le compilateur, MPI et les bibliothèques.
  • Compilez et exécutez avec le même environnement logiciel.
  • Utilisez les wrappers mpicc, mpicxx et mpifort pour les programmes MPI.
  • Préférez srun dans les jobs Slurm.
  • Testez avec peu de tâches avant une grande exécution.
  • Définissez OMP_NUM_THREADS pour les programmes OpenMP.
  • Documentez les modules, compilateurs, options et ressources Slurm utilisés.
  • Conservez les scripts de compilation et de soumission dans votre dépôt de code.

Pages associées​