Newer
Older
#include <boost/container/static_vector.hpp>
#include "Configuration.hpp"
#include "MpiEnvironment.hpp"
// creates the graph topology and does the communication
class Communicator {
constexpr static std::size_t NoNeighbors{8};
// for very small container with known max size, this is a performance
// improvement
Thomas Steinreiter
committed
template <typename T>
using Vector = boost::container::static_vector<T, NoNeighbors>;
public:
// Life cycle handling for MPI_Requests
class MpiRequest { // TODO: unnest
public:
template <typename T>
using DoubleVector =
boost::container::static_vector<T, NoNeighbors * 2>;
private:
DoubleVector<MPI_Request> _reqs;
bool finished{};
public:
MpiRequest(DoubleVector<MPI_Request> reqs);
void Wait();
~MpiRequest();
};
private:
CommunicationMode _commMode;
Thomas Steinreiter
committed
Vector<int> _neighbors;
Vector<int> _sizes;
Vector<MPI_Datatype> _sendTypes;
const Vector<MPI_Datatype>& _recvTypes{_sendTypes};
Vector<MPI_Aint> _sendDisplacements;
Vector<MPI_Aint> _recvDisplacements;
MPI_Comm _commDistGraph{MPI_COMM_NULL};
// data types
MPI_Datatype _haloRowType{};
MPI_Datatype _haloColumnType{};
MPI_Datatype _haloCornerType{MPI_CHAR};
public:
Communicator(const MpiEnvironment& env, CommunicationMode commMode,
const Size& gridSize, const Size& tileSize);
~Communicator();
void swap(Communicator& first, Communicator& second);
Communicator(Communicator&) = delete;
Communicator& operator=(Communicator&) = delete;
Communicator(Communicator&& other) noexcept;
Communicator& operator=(Communicator&& other) noexcept;
void Communicate(gsl::multi_span<State, -1, -1>& model);
MpiRequest AsyncCommunicate(gsl::multi_span<State, -1, -1>& model);