fpm
fpm copied to clipboard
Support MPI natively
Many Fortran codes use MPI and we should teach fpm about it and support it natively.
There are two main approaches to it:
-
Use the mpi compiler wrappers such as
mpif90, which are provided by MPI implementations such asmpichoropenmpi. Those compiler wrappers call the compiler with correct flags to link all MPI libraries correctly. -
You call the compiler wrappers
mpif90to figure out what flags to use, then you supply those flags manually when executing the given compiler.
CMake supports both options and I have used both in my projects. There are pros and cons of each approach and I have discussed this with quite a lot of people already. I personally lean towards the second approach, which treats MPI as a 3rd party library that you depend on. Ultimately, that is what it is. However, for fpm, the user does not actually see how the compiler is being invoked anyway, so the first approach might also work. So I would choose whatever approach is easier to implement and maintain in fpm and I think we can even switch later (internally) if needed.
Let's discuss the user facing design. It seems it might be as simple as adding mpi=true into fpm.toml for each executable that should be compiled with MPI. And fpm would then transitively enable MPI for each module and dependency that the executable needs. In terms of choosing which MPI implementation should be used, we can start by using whatever mpif90 is available in PATH.
I love it. I think mpi=true is simple enough.
Though it'd be a nice UX for fpm to auto-detect use mpi or include mpif.h by parsing source files. And we're already parsing at least use statements, no? Then the user doesn't have to do anything special and fpm takes care of it.
We can later special-case vendor-specific MPIs that are called differently than mpif90.
Indeed, fpm could autodetect, and you can force mpi=true or mpi=false if the autodetection is wrong for some reason (say you have an mpi module in your project that is not actually an MPI).
MPI behaves similar to OpenMP in this regard, being explicit about dependencies would suggest a package manifest entry like
[dependencies]
mpi = "*" # Some MPI
mpi = "^3" # if MPI 3 features are required
mpi = { version="*", variant="mpich" } # if the MPICH implementation is explicitly required
mpi.git = "https://github.com/dftbplus/mpifx" # Use a wrapper library which in turn exports the MPI dependency
Which of course allows to select it on per executable basis as well through the dependencies table.
It makes a good candidate for a built-in dependencies which could be provided as mock packages like explained in https://github.com/fortran-lang/fpm/issues/161#issuecomment-753997973 as well.
Automatic detection and smart activation would also work in this approach, fpm would just add MPI to the dependency tree if the respective use statement or include files are required.
MPI support is available as documented here (thanks to @perazz!).
I think the versioning would be an interesting addition. Spack also has this for the MPI virtual dependency. Would one need to inspect the library symbols to assure compatibility?
Another development worth considering is the newly introduced MPI standard ABI. A prototype for the standalone mpi_f08 module is available in the vapaa project. You can learn more in Jeff Hammond's presentation linked here.