π Magus02 Knowledge Base β HPC User β MPI Usage
MPI (Message Passing Interface) is the standard for distributed-memory parallel programming β running a program as multiple independent processes that communicate by passing messages, potentially across many compute nodes.
What is MPI?
MPI programs spawn multiple processes (as opposed to OpenMP's threads), each with its own separate memory space. Processes coordinate by explicitly sending and receiving messages. This allows MPI programs to scale across dozens or hundreds of nodes, making it the dominant model for large-scale HPC workloads.
On Magus02:
- Two MPI libraries are available: Open MPI and Intel MPI
- Never load both at the same time β they conflict
- MPI is always loaded via the module system
β οΈ Critical: Load exactly one MPI module. Loading both mpi/openmpi and mpi/intelmpi simultaneously will cause conflicts and unpredictable failures. Use module purge at the start of every jobscript.
Loading MPI Modules
Open MPI
$ module purge $ module load gcc/11.2.0 $ module load mpi/openmpi
Intel MPI
$ module purge $ module load intel/oneapi $ module load mpi/intelmpi
Compiling MPI Code
MPI provides compiler wrappers that automatically include the correct headers and libraries. Always use these wrappers instead of calling gcc or icc directly.
Open MPI Compiler Wrappers
| Language | Wrapper | Example |
|---|---|---|
| C | mpicc |
mpicc -O2 myprog.c -o myprog
|
| C++ | mpicxx |
mpicxx -O2 myprog.cpp -o myprog
|
| Fortran | mpifort |
mpifort -O2 myprog.f90 -o myprog
|
Intel MPI Compiler Wrappers
Intel MPI ships two sets of wrappers β one for GCC and one for Intel compilers. Use the right set for your code.
| Underlying Compiler | C | C++ | Fortran |
|---|---|---|---|
| GCC-based | mpicc |
mpicxx |
mpifort
|
| Intel-based | mpiicc |
mpiicpc |
mpiifort
|
Example with Intel compilers:
$ module purge $ module load intel/oneapi mpi/intelmpi $ mpiicc -O2 myprog.c -o myprog # C with Intel compiler $ mpiicpc -O2 myprog.cpp -o myprog # C++ with Intel compiler $ mpiifort -O2 myprog.f90 -o myprog # Fortran with Intel compiler
On most systems, environment variables are also available:
$ $MPICC myprog.c -O2 -o myprog $ $MPICXX myprog.cpp -O2 -o myprog $ $MPIFC myprog.f90 -O2 -o myprog
Running MPI Programs
Basic Launch
# General form: $ mpirun -n <num_processes> [options] ./my_program [program_args] # Example: run with 256 MPI processes: $ mpirun -n 256 ./my_mpi_program input.dat
Note: mpirun and mpiexec are synonymous in Open MPI. In Intel MPI it is mpiexec.hydra and mpirun.
Key mpirun Options
Open MPI
| Option | Description |
|---|---|
-n <N> or -np <N> |
Total number of MPI processes |
-npernode <N> |
Number of processes per node |
-npersocket <N> |
Number of processes per socket |
-wdir <dir> |
Change working directory before execution |
-x VAR |
Export environment variable to remote processes |
-output-filename <name> |
Redirect output to files named <name>.<rank> |
--help |
List all available options |
Intel MPI
| Option | Description |
|---|---|
-n <N> |
Total number of MPI processes |
-ppn <N> |
Processes per node (set I_MPI_JOB_RESPECT_PROCESS_PLACEMENT=off if needed)
|
-wdir <dir> |
Change working directory |
-outfile-pattern <name> |
Redirect stdout to file |
-g |
Enable debug symbols |
-O2 / -O3 |
Optimization level |
Complete Slurm Jobscript β MPI
#!/bin/bash #SBATCH --job-name=mpi_vasp #SBATCH --partition=medium #SBATCH --nodes=4 #SBATCH --ntasks-per-node=64 #SBATCH --mem=512G #SBATCH --time=7-00:00:00 #SBATCH --output=vasp_%j.out #SBATCH --error=vasp_%j.err #SBATCH --mail-type=END,FAIL #SBATCH [email protected] module purge module load intel/oneapi module load mpi/intelmpi module load mkl # Run with total tasks = nodes Γ ntasks-per-node = 256: mpirun -n $SLURM_NTASKS ./vasp_std
Process Binding
Binding MPI processes to specific CPU cores improves performance by ensuring each process stays close to its local memory (NUMA-awareness). Both Open MPI and Intel MPI support binding.
β οΈ Multi-job binding conflict: MPI binding is on by default in most implementations. If you run more than one MPI job on the same hardware simultaneously (e.g. in a non-exclusive allocation), all jobs assume they are the only job and bind themselves to the same cores β resulting in 1/N performance while other cores sit idle.
Open MPI β Binding Options
# Bind one process per core: $ mpirun -n 64 --bind-to core ./my_mpi_program # Bind one process per socket: $ mpirun -n 8 --bind-to socket ./my_mpi_program # Report binding (for verification): $ mpirun -n 64 --bind-to core --report-bindings ./my_mpi_program 2>&1 | head -20
Intel MPI β Binding Options
# Bind to cores: $ export I_MPI_PIN=1 $ export I_MPI_PIN_DOMAIN=core $ mpirun -n 64 ./my_mpi_program # Check binding: $ export I_MPI_DEBUG=4 $ mpirun -n 4 ./my_mpi_program
References
- NUMA Architecture β Memory Locality
- Batch Scheduler β MPI Jobscript
- OpenMP Usage β Hybrid Jobs
- Compilers on Magus02
- Open MPI mpiexec man page
- Intel MPI Reference
β Back to Knowledge Base Β· Maintained by HPC Administration Β· wiki.snu.edu.in