MPICPP is a simple C++ interface for the MPI C library standard. It brings a few tried-and-true C++ principles to bear over the plain C API:
- True RAII: no user ever has to call an explicit destructor or finalize function.
The
mpicpp::environmentclass initializes and finalizes MPI. Thempicpp::commclass takes ownership of the communicator, destroys it in its destructor and duplicates it in the copy constructor. Thempicpp::requestclass waits on the request in its destructor. - Exception-based error handling. All return codes from MPI C API functions
are put through
mpicpp::handle_errorwhich will throw an exception of typempicpp::exceptionin the case of anything butMPI_SUCCESS. - Template-based MPI datatype deduction for fundamental types in C++.
Since
MPI_Datatypeis in general a runtime-constructed object as opposed to a fully compile-time description, we don't attempt to implementMPI_Datatypeconstruction for arbitrary user types. Instead we simply map fundamental C++ types to their built-inMPI_Datatype. - Blocking is a special case of non-blocking via RAII.
We only wrap the non-blocking communication APIs,
and return an
mpicpp::requestfrom these calls. Since thempicpp::requestobject callsMPI_Waitin its destructor, then calling the non-blocking MPICPP method and simply ignoring its return value is equivalent to calling the blocking MPI C API.
Here is an example of usage:
#include <iostream>
#include "mpicpp.hpp"
int main(int argc, char** argv) {
auto mpi_env = mpicpp::environment(argc, argv);
auto comm = mpicpp::comm::world();
double value = 1.0;
// MPI_Datatype is deduced because double is a fundamental type
// ignoring the return value makes this blocking
comm.iallreduce(&value, 1, mpicpp::op::sum());
std::cout << "sum of ones is " << value << '\n';
// MPI_Finalize is called from environment destructor
}At Sandia, MPICPP is SCR# 2757