Skip to content

Commit 5ef7fef

Browse files
authored
Document how to use MPItrampoline (#838)
1 parent 7c4b0bf commit 5ef7fef

1 file changed

Lines changed: 153 additions & 1 deletion

File tree

docs/src/configuration.md

Lines changed: 153 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,29 @@ By default, MPI.jl will download and link against the following MPI implementati
66

77
This is suitable for most single-node use cases, but for larger systems, such as HPC
88
clusters or multi-GPU machines, you will probably want to configure against a
9-
system-provided MPI implementation in order to exploit features such as fast network
9+
specialized MPI implementation in order to exploit features such as fast network
1010
interfaces and CUDA-aware or ROCm-aware MPI interfaces.
1111

12+
There are three ways to point Julia to an MPI implementation:
13+
- *jll binaries* (preferred). A jll binary is a package that is built
14+
via [BinaryBuilder](https://docs.binarybuilder.org/stable/) and can
15+
be downloaded for all architectures. Almost all external libraries
16+
(such as CUDA, HDF5, libpng, OpenSSL, ...) are provided as jll
17+
binaries because they are quick and easy to download and work out of
18+
the box.
19+
- *system binaries* (for experts only). A system binary is a shared
20+
library that you need to configure and build yourself. This is
21+
tricky even for experts. The problem is not just build the shared
22+
library, in addition one has to be careful to ensure that the shared
23+
library is ABI compatible with all other package you are using.
24+
(More details on this below.)
25+
26+
If you want to use an MPI implementation on your system, then you can
27+
either use it as *system binary* (this is for experts only), or you
28+
can use MPItrampoline as *jll binary*, and point MPItrampoline to the
29+
other MPI library. This is preferred since it automatically ensures
30+
ABI compatibility.
31+
1232
The MPIPreferences.jl package allows the user to choose which MPI implementation to use in MPI.jl. It uses
1333
[Preferences.jl](https://github.com/JuliaPackaging/Preferences.jl) to configure the MPI backend for each
1434
project separately. This provides a single source of truth that can be used for JLL packages (Julia packages
@@ -23,8 +43,137 @@ julia --project -e 'using Pkg; Pkg.add("MPIPreferences")'
2343
See [Migration from MPI.jl v0.19 or earlier](@ref) for more information on
2444
how to migrate your configuration from earlier MPI.jl versions.
2545

46+
47+
48+
## [Using a jll MPI backend](@id using_jll_mpi)
49+
50+
This is the recommended way to use MPI.jl. By default, MPI.jl will use
51+
`MPICH_jll` as jll MPI backend.
52+
53+
You can select from four different jll MPI binaries:
54+
- [`MPICH_jll`](http://www.mpich.org/)), the default
55+
- [`OpenMPI_jll`](https://www.open-mpi.org/), an alternative to MPICH
56+
- [`MPItrampoline_jll`](https://github.com/eschnett/MPItrampoline), a
57+
forwarding MPI implementation that uses another MPI implementation
58+
- [`MicrosoftMPI_jll`](https://docs.microsoft.com/en-us/message-passing-interface/microsoft-mpi)
59+
for Windows
60+
61+
For example, to switch to OpenMPI, you would first use MPIPreferenes.jl to switch:
62+
63+
```sh
64+
julia> using MPIPreferences
65+
66+
julia> MPIPreferences.use_jll_binary("OpenMPI_jll")
67+
┌ Info: MPIPreferences changed
68+
└ binary = "OpenMPI_jll"
69+
```
70+
71+
Next you need to restart Julia (!) and re-instantiate your packages:
72+
73+
```sh
74+
julia> using Pkg
75+
76+
julia> Pkg.instantiate()
77+
```
78+
79+
This is necessary because other jll packages (e.g. `HDF5_jll`) may
80+
depend on MPI, and a different build of `HDF5_jll` needs to be
81+
installed for ABI compatibility.
82+
83+
To switch back to `MPICH_jll`, repeat the steps above with
84+
`"MPICH_JLL"` as argument to `MPIPreferences.use_jll_binary`. Don't
85+
forget to restart Julia and re-instantiate your packages again.
86+
87+
88+
89+
## [Using MPItrampoline](@id using_mpitrampoline)
90+
91+
MPItrampoline is an easier and safer way to use external MPI
92+
implementations. MPItrampoline defines an ABI for MPI calls (similar
93+
to the way
94+
[`libblastrampoline`](https://github.com/JuliaLinearAlgebra/libblastrampoline)
95+
works for linear algebra), which allows switching between different
96+
MPI backends without recompiling code. Unfortunately this ABI is not
97+
yet standardized (but it might be in [MPI
98+
5](https://www.mpi-forum.org)!), and therefore you have to install a
99+
small wrapper library for every MPI implementation that you want to
100+
use via MPItrampoline.
101+
102+
The general design is:
103+
- There is a pre-installed MPI implementation on your system (e.g.
104+
supporting CUDA or Slingshot)
105+
- You (or a system administrator) installs
106+
[`MPIwrapper`](https://github.com/eschnett/MPIwrapper), which
107+
implements the MPI ABI
108+
109+
On the Julia side, the following happens:
110+
- MPItrampoline provides the regular MPI functionality, internally
111+
calling out via the MPI ABI to any MPI implementation
112+
- Other packages (ADIOS2, HDF5, or MPI.jl) can always rely on
113+
MPItrampoline
114+
- At run time (when starting Julia), you choose which MPI
115+
implementation you use by setting an environment variable
116+
117+
118+
The documentation for
119+
[MPItrampoline](https://github.com/eschnett/MPItrampoline) describes
120+
how to install MPIwrapper. This is possibly as simple as
121+
122+
```sh
123+
cmake -B build -DMPIEXEC_EXECUTABLE=mpiexec -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=$HOME/mpiwrapper
124+
cmake --build build
125+
cmake --install build
126+
```
127+
128+
but nothing is ever simple on an HPC system. It might be necessary to
129+
load certain modules, or to specify more cmake MPI configuration
130+
options.
131+
132+
Define an environment variable to select this MPI implemenation:
133+
134+
```sh
135+
export MPITRAMPOLINE_LIB="$HOME/mpiwrapper/lib/libmpiwrapper.so"
136+
```
137+
138+
pointing to the shared library provided by the MPIwrapper you just
139+
built. (If you do not set this environment variable the MPItrampoline
140+
will fall back onto a built-in MPICH. That is, in principle MPI.jl
141+
could switch over to always using `MPItrampoline_jll`!)
142+
143+
Next you switch MPI.jl over to using `MPItrampoline_jll` as jll
144+
binary:
145+
146+
```sh
147+
julia> using MPIPreferences
148+
149+
julia> MPIPreferences.use_jll_binary("MPItrampoline_jll")
150+
┌ Info: MPIPreferences changed
151+
└ binary = "MPItrampoline_jll"
152+
```
153+
154+
and then restart Julia (see above) and re-instantiate your packages:
155+
156+
```sh
157+
julia> using Pkg
158+
159+
julia> Pkg.instantiate()
160+
```
161+
162+
You are ready to test this out:
163+
```sh
164+
julia> using MPI
165+
166+
julia> MPI.Get_library_version()
167+
"MPIwrapper 2.11.0, using MPIABI 2.10.0, wrapping:\nMPICH Version: 4.2.1\nMPICH Release date: Wed Apr 17 15:30:02 CDT 2024\nMPICH ABI: 16:1:4\nMPICH Device: ch3:nemesis\nMPICH configure: --build=x86_64-linux-musl --host=x86_64-apple-darwin14 --disable-dependency-tracking --disable-doc --enable-shared=no --enable-static=yes --enable-threads=multiple --with-device=ch3 --prefix=/workspace/destdir/lib/mpich --enable-two-level-namespace\nMPICH CC: cc -fPIC -DPIC -fno-common -O2\nMPICH CXX: c++ -fPIC -DPIC -O2\nMPICH F77: gfortran -fPIC -DPIC -O2\nMPICH FC: gfortran -fPIC -DPIC -O2\nMPICH features: \n"
168+
```
169+
170+
171+
26172
## [Using a system-provided MPI backend](@id using_system_mpi)
27173

174+
This is an alternative way to using an external MPI implementation
175+
that does not rely on MPItrampoline.
176+
28177
### Requirements
29178

30179
MPI.jl requires a shared library installation of a C MPI library, supporting the MPI 3.0
@@ -175,6 +324,8 @@ julia --project -e 'using MPIPreferences; MPIPreferences.use_jll_binary("MPItram
175324
If you omit the JLL binary name, the default is selected for the respective
176325
operating system.
177326

327+
328+
178329
## Configuration of the MPI.jl testsuite
179330

180331
### Testing against a different MPI implementation
@@ -216,6 +367,7 @@ The test suite can also be modified by the following variables:
216367
- `JULIA_MPI_TEST_ABI`: Check that the specified MPI ABI is used for the tests
217368

218369

370+
219371
## Migration from MPI.jl v0.19 or earlier
220372

221373
For MPI.jl v0.20, environment variables were used to configure which MPI

0 commit comments

Comments
 (0)