19#ifndef UTILS_MPI_GATHERV_HPP
20#define UTILS_MPI_GATHERV_HPP
22#include <boost/mpi/communicator.hpp>
23#include <boost/mpi/datatype.hpp>
24#include <boost/mpi/exception.hpp>
25#include <boost/mpi/nonblocking.hpp>
36void gatherv_impl(
const boost::mpi::communicator &comm,
const T *in_values,
37 int in_size, T *out_values,
const int *sizes,
38 const int *displs,
int root, boost::mpl::true_) {
39 if (in_values ==
nullptr)
42 MPI_Datatype type = boost::mpi::get_mpi_datatype<T>(*in_values);
45 if ((in_values == out_values) && (comm.rank() == root)) {
46 BOOST_MPI_CHECK_RESULT(MPI_Gatherv,
47 (MPI_IN_PLACE, 0, type, out_values,
48 const_cast<int *
>(sizes),
const_cast<int *
>(displs),
51 BOOST_MPI_CHECK_RESULT(MPI_Gatherv,
52 (
const_cast<T *
>(in_values), in_size, type,
53 out_values,
const_cast<int *
>(sizes),
54 const_cast<int *
>(displs), type, root, comm));
59void gatherv_impl(
const boost::mpi::communicator &comm,
const T *in_values,
60 int in_size, T *out_values,
const int *sizes,
61 const int *displs,
int root, boost::mpl::false_) {
62 if (comm.rank() == root) {
63 auto const n_nodes = comm.size();
66 if (in_values && out_values && in_values != out_values) {
67 std::copy_n(in_values, in_size, out_values + displs[root]);
70 std::vector<boost::mpi::request> req;
71 for (
int i = 0; i < n_nodes; i++) {
76 req.emplace_back(comm.irecv(i, 42, out_values + displs[i], sizes[i]));
79 boost::mpi::wait_all(req.begin(), req.end());
81 comm.send(root, 42, in_values, in_size);
87void gatherv(
const boost::mpi::communicator &comm,
const T *in_values,
88 int in_size, T *out_values,
const int *sizes,
const int *displs,
90 detail::gatherv_impl(comm, in_values, in_size, out_values, sizes, displs,
95void gatherv(
const boost::mpi::communicator &comm,
const T *in_values,
96 int in_size, T *out_values,
const int *sizes,
int root) {
97 if (comm.rank() == root) {
98 std::vector<int> displ(
static_cast<unsigned int>(comm.size()));
101 for (
unsigned int i = 0; i < displ.size(); i++) {
106 detail::gatherv_impl(comm, in_values, in_size, out_values, sizes,
110 detail::gatherv_impl(comm, in_values, in_size, out_values,
nullptr,
nullptr,
116void gatherv(
const boost::mpi::communicator &comm,
const T *in_values,
117 int in_size,
int root) {
118 assert(comm.rank() != root &&
119 "This overload can not be called on the root rank.");
120 gatherv(comm, in_values, in_size,
static_cast<T *
>(
nullptr),
nullptr,
nullptr,
void gatherv(const boost::mpi::communicator &comm, const T *in_values, int in_size, T *out_values, const int *sizes, const int *displs, int root)