Recently, I used MPI to parallelize my simulation program to speed up. The way I adopted was to rewrite one function that is very time-consuming but easy to be parallelized.
The simplified model of non-MPI program is as follows,
int main( int argc, char* argv[] ){
// some declaration here
Some_OBJ.Serial_Function_1();
Some_OBJ.Serial_Function_2();
Some_OBJ.Serial_Function_3();
return 0;
}
While my MPI version is,
#include "mpi.h"
int main( int argc, char* argv[] ){
// some declaration here
MPI_Init( NULL, NULL );
Some_OBJ.Serial_Function_1();
Some_OBJ.Parallel_Function_2(); // I rewrite this function to replace Some_OBJ.Serial_Function_2();
Some_OBJ.Serial_Function_3();
MPI_Finalize();
return 0;
}
I copied my non MPI code to a new folder, something like mpi_simulation, and add a mpi function, revised the main file to . It works, but very inconveniently. If I update some functions, say OBJ.Serial_Function_1(), I need to copy the code with caution even if I just change a constant. There are still some slight differences between these versions of programs. I felt exhausted to keep them in accordance.
So I wander if there is any way to let MPI program dependent on non MPI version, so that my revisions can be easily applied to both of them safely and conveniently.
Thanks.
Update I finally adopt haraldkl's suggestion. The method is to define a macro to enclose all functions that use MPI interfaces, like this:
#ifdef USE_MPI
void Some_OBJ::Parallel_Function_2(){
// ...
}
#endif
To initialize MPI automatically, I define a singleton called MPI_plugin:
#ifdef USE_MPI
class MPI_plugin{
private:
static MPI_plugin auto_MPI;
MPI_plugin(){
MPI_Init( NULL, NULL );
}
public:
~MPI_plugin(){
MPI_Finalize();
}
};
MPI_plugin::MPI_plugin auto_MPI;
#endif
Including MPI_plugin.h in main.cpp can survive me from adding MPI_Init() and MPI_Finalize() in main.cpp when compiling MPI version. The last step is to add a PHONY target "mpi" in makefile:
CPP := mpic++
OTHER_FLAGS := -DUSE_MPI
.PHONY: mpi
mpi: ${MPI_TARGET}
...
I hope it helpful to anyone who meets the same problem.
#ifdef XXX Some_OBJ::Parallel_Function_2(){ // do something }