Reputation: 31
I am working on a numerical solver written in Fortran which uses MPI for parallelization on large clusters (up to about 500 processes). Currently we are including mpi via
#include "mpif.h"
which, from my understanding, is deprecated and strongly discouraged. In an effort to modernize and clean up our mpi communications, we would like to switch to using the more modern mpi_f08 module. The issue we are facing is that we need to maintain the possibility of compiling a version based on the old mpi header in order to not break the coupling with another solver. I'd much appreciate some advice on how to elegantly maintain this compatibility.
Question #1: What would be an elegant way to either include the header or use the module depending on a preprocessor flag without having #ifdef statements scattered throughout the code?
My thought so far would to define a module
module mpi_module
#ifdef MPI_LEGACY
#include "mpif.h"
#else
use mpi_f08
#endif
end module
and use this module everywhere where the mpi header file is currently included. Is this a viable approach or would this have any unwanted effects which I'm currently overlooking?
Question #2: What would be an elegant way to switch between integers and the new derived types from mpi_f08 depending on the preprocessor flag? (Again, without scattering #ifdef statements throughout the code)
My initial thought on this would be to use something like
#ifdef MPI_LEGACY
#define _mpiOp_ integer
#else
#define _mpiOp_ type(MPI_Op)
#endif
so that I can simply replace
integer :: OP
by
_mpiOp_ :: OP
to obtain compatibility with both ways of including MPI. I'm also not quite happy with this solution yet, since, in my understanding, you can not put these kinds of preprocessor definitions into a module. Thus, you'd end up with a module plus a header file which you necessarily have to remember to include together each time. Again, I'm grateful for any potential flaws with this approach and any alternatives that you can point out.
Sorry for the long post, but I wanted to make my thoughts as clear as possible. I'm looking forward to your input!
Upvotes: 3
Views: 654
Reputation: 60088
The old and the new way are way too different. Not only you have a use statement instead of an include statement and a derived instead of an integer for an Op. Many routines will have different signatures and use different types.
So I am afraid the answer is that there is no elegant way. You are making a conglomerate of two things that are way too different to be elegantly combined.
As has been mentioned in the comments, the first step to get more modern is to do use mpi
instead of include "mpif.h"
. This already enables the compiler to catch many kinds of bugs when the routines are called incorrectly. Tje extent, to which these checks will be possible, will depend on the details of the MPI library configuration. Namely, the extent of generic interfaces generated instead of just external statements.
If you have to combine your code with another code that uses the old way, it makes good sense to first do use mpi
, see how it goes, and think whether it makes sense to go further.
Upvotes: 1