I wanted to use boost::mpi communicators in my class, because I want my class to take care of all MPI calls. I used this style to make them static members of my class.
// works.cpp
// mpic++ -o works works.cpp -lboost_mpi
#include <boost/mpi.hpp>
#include <iostream>
class Example {
static boost::mpi::environment env;
static boost::mpi::communicator world;
public:
Example() {
std::cout << world.rank() << std::endl;
}
};
boost::mpi::environment Example::env;
boost::mpi::communicator Example::world;
int main() {
auto e = Example();
}
This works just fine, e.g., mpirun -n 4 ./works prints the numbers 0 to 3, as expected. I later wanted to template my class. I was at first worried about how to initialize my static member variables, but read this answer, which suggested it was all fine
// fails.cpp
// mpic++ -o fails fails.cpp -lboost_mpi
#include <boost/mpi.hpp>
#include <iostream>
template<typename T>
class Example {
static boost::mpi::environment env;
static boost::mpi::communicator world;
public:
Example() {
std::cout << world.rank() << std::endl;
}
};
template <typename T>
boost::mpi::environment Example<T>::env;
template <typename T>
boost::mpi::communicator Example<T>::world;
int main() {
auto e = Example<double>();
}
However, this in fact gives me
$ mpirun -n 4 ./fails
*** The MPI_Comm_rank() function was called before MPI_INIT was invoked.
*** This is disallowed by the MPI standard.
*** Your MPI job will now abort.
...
Something is going wrong here, but what? and why? I think I am misunderstanding a few things here.