English Finnish
%_openmpi_load \
. /etc/profile.d/modules.sh; \
module load mpi/openmpi-%{_arch}; \
export CFLAGS="$CFLAGS %{optflags}";
%_openmpi_unload \
. /etc/profile.d/modules.sh; \
module unload mpi/openmpi-%{_arch};
loading and unloading the compiler in spec files is as easy as `+%{_openmpi_load}+` and `+%{_openmpi_unload}+`.
Automatic setting of the module loading path in python interpreters is done using a `+.pth+` file placed in one of the directories normally searched for modules (`+%{python2_sitearch}+`, `+%{python3_sitearch}+`). Those `+.pth+` files should append the directory specified with $MPI_PYTHON2_SITEARCH or $MPI_PYTHON3_SITEARCH environment variable, depending on the interpreter version, to `+sys.path+`, and do nothing if those variables are unset. Module files MUST NOT set PYTHONPATH directly, since it cannot be set for both Python versions at the same time.
If the environment module sets compiler flags such as `+CFLAGS+` (thus overriding the ones exported in `+%configure+`, the RPM macro MUST make them use the Fedora optimization flags `+%{optflags}+` once again (as in the example above in which the openmpi-%\{_arch} module sets CFLAGS).
Packaging of MPI software
Software that supports MPI MUST be packaged also in serial mode [i.e. no MPI], if it is supported by upstream. (for instance: `+foo+`).
If possible, the packager MUST package versions for each MPI compiler in Fedora (e.g. if something can only be built with mpich and mvapich2, then mvapich1 and openmpi packages do not need to be made).
MPI implementation specific files MUST be installed in the directories used by the used MPI compiler (`+$MPI_BIN+`, `+$MPI_LIB+` and so on).
The binaries MUST be suffixed with `+$MPI_SUFFIX+` (e.g. _openmpi for Open MPI, _mpich for MPICH and _mvapich2 for MVAPICH2). This is for two reasons: the serial version of the program can still be run when an MPI module is loaded and the user is always aware of the version s/he is running. This does not need to hurt the use of shell scripts:
# Which MPI implementation do we use?
#module load mpi/mvapich2-i386
#module load mpi/openmpi-i386
module load mpi/mpich-i386
# Run preprocessor
foo -preprocess < foo.in
# Run calculation
mpirun -np 4 foo${MPI_SUFFIX}
# Run some processing
mpirun -np 4 bar${MPI_SUFFIX} -process
# Collect results
bar -collect
The MPI enabled bits MUST be placed in a subpackage with the suffix denoting the MPI compiler used (for instance: `+foo-openmpi+` for Open MPI [the traditional MPI compiler in Fedora] or `+foo-mpich+` for MPICH). For directory ownership and to guarantee the pickup of the correct MPI runtime, the MPI subpackages MUST require the correct MPI compiler's runtime package.
Each MPI build of shared libraries SHOULD have a separate -libs subpackage for the libraries (e.g. foo-mpich-libs). As in the case of MPI compilers, library configuration (in `+/etc/ld.so.conf.d+`) MUST NOT be made.
In case the headers are the same regardless of the compilation method and architecture (e.g. 32-bit serial, 64-bit Open MPI, MPICH), they MUST be split into a separate `+-headers+` subpackage (e.g. 'foo-headers'). Fortran modules are architecture specific and as such are placed in the (MPI implementation specific) `+-devel+` package (foo-devel for the serial version and foo-openmpi-devel for the Open MPI version).
Each MPI build MUST have a separate -devel subpackage (e.g. foo-mpich-devel) that includes the development libraries and `+Requires: %{name}-headers+` if such a package exists. The goal is to be able to install and develop using e.g. 'foo-mpich-devel' without needing to install e.g. openmpi or the serial version of the package.
Files must be shared between packages as much as possible. Compiler independent parts, such as data files in `+%{_datadir}/%{name}+` and man files MUST be put into a `+-common+` subpackage that is required by all of the binary packages (the serial package and all of the MPI packages).
A sample spec file
# Define a macro for calling ../configure instead of ./configure
%global dconfigure %(printf %%s '%configure' | sed 's!\./configure!../configure!g')
Name: foo
Requires: %{name}-common = %{version}-%{release}