9#include <kernel/util/dist.hpp>
10#include <kernel/util/time_stamp.hpp>
11#include <kernel/util/statistics.hpp>
12#include <kernel/lafem/matrix_mirror.hpp>
13#include <kernel/lafem/power_diag_matrix.hpp>
35 template<
typename MT_,
typename VMT_>
46#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
75#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
77 const std::vector<VMT_>& mirrors_row,
const std::vector<VMT_>& mirrors_col) :
82 _recv_reqs(ranks.size()),
84 _recv_bufs(ranks.size())
86 const std::size_t n = ranks.size();
88 XASSERTM(mirrors_row.size() == n,
"invalid row vector mirror count");
89 XASSERTM(mirrors_col.size() == n,
"invalid column vector mirror count");
94 for(std::size_t i(0); i < n; ++i)
96 const VMT_& mir_r = mirrors_row.at(i);
97 const VMT_& mir_c = mirrors_col.at(i);
104 SynchMatrix(
const Dist::Comm&,
const std::vector<int>& ranks,
const std::vector<VMT_>&,
const std::vector<VMT_>&) :
123#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
126 XASSERTM(!_initialized,
"SynchMatrix object is already initialized");
128 const std::size_t n =
_ranks.size();
131 for(std::size_t i(0); i < n; ++i)
137 std::vector<std::array<Index,4>> recv_dims(n), send_dims(n);
140 for(std::size_t i(0); i < n; ++i)
142 _recv_reqs[i] =
_comm.
irecv(recv_dims.at(i).data(), std::size_t(4),
_ranks.at(i));
146 for(std::size_t i(0); i < n; ++i)
149 send_dims.at(i)[0] = sbuf.
rows();
150 send_dims.at(i)[1] = sbuf.
columns();
160 for(std::size_t i(0); i < n; ++i)
163 Index nrows = recv_dims.at(i)[0];
164 Index ncols = recv_dims.at(i)[1];
165 Index nepnz = recv_dims.at(i)[2];
166 Index nnze = recv_dims.at(i)[3];
173 for(std::size_t i(0); i < n; ++i)
175 _recv_reqs[i] =
_comm.
irecv(_recv_bufs.at(i).row_ptr(), _recv_bufs.at(i).rows()+std::size_t(1),
_ranks.at(i));
182 for(std::size_t i(0); i < n; ++i)
191 for(std::size_t i(0); i < n; ++i)
193 _recv_reqs[i] =
_comm.
irecv(_recv_bufs.at(i).col_ind(), _recv_bufs.at(i).used_elements(),
_ranks.at(i));
200 for(std::size_t i(0); i < n; ++i)
212 void init(
const MT_&)
214 XASSERTM(!_initialized,
"SynchMatrix object is already initialized");
225#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
228 XASSERTM(_initialized,
"SynchMatrix object has not been initialized");
230 const std::size_t n =
_ranks.size();
233 for(std::size_t i(0); i < n; ++i)
242 for(std::size_t i(0); i < n; ++i)
254 for(std::size_t idx(0u); _recv_reqs.
wait_any(idx); )
257 _mirrors.at(idx).scatter_axpy(matrix, _recv_bufs.at(idx));
266 XASSERTM(_initialized,
"SynchMatrix object has not been initialized");
271 template <
typename MT_,
typename SVMT_,
int blocks_>
275 using VMT_ =
typename SVMT_::SubMirrorType;
279#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
280 std::vector<std::shared_ptr<SynchMatrix<MT_, VMT_>>> synch_matrix_list;
281 std::vector<std::vector<VMT_>> mirrors_row_split;
282 std::vector<std::vector<VMT_>> mirrors_col_split;
285#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
287 const std::vector<SVMT_>& mirrors_row,
const std::vector<SVMT_>& mirrors_col) :
289 synch_matrix_list(blocks_),
290 mirrors_row_split(blocks_),
291 mirrors_col_split(blocks_)
293 for (
int block(0) ; block < blocks_ ; ++block)
295 for (
Index i(0) ; i < mirrors_row.size() ; ++i)
299 for (
Index i(0) ; i < mirrors_col.size() ; ++i)
304 synch_matrix_list.at((
size_t)block) = std::make_shared<SynchMatrix<MT_, VMT_>>(comm, ranks, mirrors_row_split.at((
size_t)block), mirrors_col_split.at((
size_t)block));
309 SynchMatrix(
const Dist::Comm&,
const std::vector<int>& ranks,
const std::vector<SVMT_>&,
const std::vector<SVMT_>&) :
316#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
319 XASSERTM(!_initialized,
"SynchMatrix object is already initialized");
321 for (
int block(0) ; block < blocks_ ; ++block)
323 synch_matrix_list.at((
size_t)block)->init(matrix.
get(block, block));
331 XASSERTM(!_initialized,
"SynchMatrix object is already initialized");
336#if defined(FEAT_HAVE_MPI) || defined(DOXYGEN)
339 XASSERTM(_initialized,
"SynchMatrix object has not been initialized");
341 for (
int block(0) ; block < blocks_ ; ++block)
343 synch_matrix_list.at((
size_t)block)->exec(matrix.
get(block, block));
349 XASSERTM(_initialized,
"SynchMatrix object has not been initialized");
374 template<
typename MT_,
typename VMT_>
376 const std::vector<VMT_>& mirrors_row,
const std::vector<VMT_>& mirrors_col)
#define XASSERT(expr)
Assertion macro definition.
#define XASSERTM(expr, msg)
Assertion macro definition with custom message.
Request irecv(void *buffer, std::size_t count, const Datatype &datatype, int source, int tag=0) const
Nonblocking Receive.
Request isend(const void *buffer, std::size_t count, const Datatype &datatype, int dest, int tag=0) const
Nonblocking Send.
Communication Request vector class.
Request & get_request(std::size_t idx)
Returns a (const) reference to a single request in the vector.
bool wait_any(std::size_t &idx, Status &status)
Blocks until one of the active requests has been fulfilled.
void wait_all()
Blocks until all active requests are fulfilled.
Ticket class for asynchronous global matrix conversion.
std::vector< BufferMatrixType > _send_bufs
send and receive buffers
void exec(MT_ &matrix)
Converts a type-0 matrix to a type-1 matrix.
LAFEM::MatrixMirrorBuffer< typename MT_::DataType, typename MT_::IndexType > BufferMatrixType
the buffer matrix type
SynchMatrix(const SynchMatrix &)=delete
deleted copy constructor
SynchMatrix & operator=(const SynchMatrix &)=delete
deleted copy assignment operator
std::vector< int > _ranks
the neighbor ranks
Dist::RequestVector _send_reqs
send and receive request vectors
SynchMatrix(const Dist::Comm &comm, const std::vector< int > &ranks, const std::vector< VMT_ > &mirrors_row, const std::vector< VMT_ > &mirrors_col)
Constructor.
LAFEM::MatrixMirror< typename MT_::DataType, typename MT_::IndexType > MatrixMirrorType
the matrix mirror type
const Dist::Comm & _comm
our communicator
void init(const MT_ &matrix)
Initializes the internal buffers for synchronization.
std::vector< MatrixMirrorType > _mirrors
the matrix mirrors
Matrix Mirror Buffer class template.
Index val_size() const
Retrieve total length of value array.
DT_ * val()
Retrieve non zero element array.
Index columns() const
Retrieve matrix column count.
Index entries_per_nonzero() const
Retrieve entries per non zero element count.
Index used_elements() const
Retrieve non zero element count.
Index rows() const
Retrieve matrix row count.
Matrix-Mirror class template.
Power-Diag-Matrix meta class template.
SubMatrixType & get(int i, int j)
Returns a sub-matrix block.
void synch_matrix(MT_ &target, const Dist::Comm &comm, const std::vector< int > &ranks, const std::vector< VMT_ > &mirrors_row, const std::vector< VMT_ > &mirrors_col)
Synchronizes a type-0 matrix.
std::uint64_t Index
Index data type.