I need the MPI world communicator to be accessible in functions/class member functions. But by design/convention, MPI environments and communicators are always defined and initialized at the beginning of int main()
.
The only, simple solution I can think of using a global pointer to the communicator.
Does anybody know of a better way? Is it dangerous to use the global pointer solution?
This problem applies equally well to bare-bones MPI, and to Boost::MPI (which I use below)
Example of my proposed solution (untested):
//globals.h
extern boost::mpi::communicator * my_MPI_world_ptr;
and
//main.cpp
...
int main(int argc, char* argv[])
{
boost::mpi::environment my_boost_mpi_env(argc, argv);
boost::mpi::communicator my_MPI_world;
my_MPI_world_ptr = &my_MPI_world;
my_MPI_rank = my_MPI_world_ptr->rank();
size_MPI_WORLD = my_MPI_world_ptr->size();
my_class an_Object;
an_Object.member_function_that_uses__MPI_world();
...
}
For boost mpi, the default constructed (i.e., empty initializer) communicator corresponds to
MPI_COMM_WORLD
, so you could simply define anotherinside your function use it as if it is the one you defined outside.
MPI_INIT
is called when constructingmpi::environment
. So as long as this is placed in the beginning of the of your main program, you are free to define a globalmpi::communicator
somewhere else. It is not necessary to use a pointer. (Actually you can even placeMPI_INIT
somewhere else as well, see below).For bare-bones MPI, I have tested that calling
MPI_INIT
elsewhere besides the main is also allowed. For example, you can define the following wrapper for a global worker in a header file,and in the source file, define a global instance at any place outside
main()
:The construction and destruction of the global variable should be able to take care of
MPI
initialization and finalization, before and after anyMPI
function call.Do you mean the actual MPI
MPI_COMM_WORLD
communicator (or the Boost wrapper of it)? That is already global. If you are using a different communicator to separate communication from a library that you are writing, it would be better to avoid using a global variable for it at all. In that case, you might want to just pass it (or a pointer to it) around and store it in the classes that need it.I don't like global pointers in general: who's responsible for deleting them? How do you make sure the pointer is not accessed before the object is created, or after the object is destroyed?
I'd be tempted to wrap the pointer and its access in a class. (Warning: The following hasn't seen a compiler so might have all sorts of issues, and I'm not familiar with MPI)
Your own objects that used to use the pointer could work in the same way: their constructor could be passed a reference to your boost::mpi::communicator, or if the set of operations on your boost::mpi::communicator are well defined, they could be passed a reference to the wrapper.