#pragma once #include "gsl/gsl" #include #include #include "Configuration.hpp" #include "MpiEnvironment.hpp" #include "State.hpp" #include "Util.hpp" class Communicator { constexpr static std::size_t NoNeighbors{8}; template using Vector = boost::container::static_vector; CommunicationMode _commMode; Vector _neighbors; Vector _sizes; Vector _sendTypes; const Vector& _recvTypes{_sendTypes}; Vector _sendDisplacements; Vector _recvDisplacements; MPI_Comm _commDistGraph{MPI_COMM_NULL}; MPI_Datatype _haloRowType; MPI_Datatype _haloColumnType; MPI_Datatype _haloCornerType{MPI_CHAR}; void ReportInvalidCommunicationModeError() const; public: Communicator() = default; 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& model); class MpiRequest { public: template using DoubleVector = boost::container::static_vector; private: DoubleVector _reqs; bool finished{}; public: MpiRequest(DoubleVector reqs); void Wait(); ~MpiRequest(); }; MpiRequest AsyncCommunicate(gsl::multi_span& model); };