91 if (not target.is_contiguous()) NDA_RUNTIME_ERROR <<
"Error in MPI reduce for nda::Array: Target array needs to be contiguous";
92 static_assert(std::decay_t<A>::layout_t::stride_order_encoded == std::decay_t<T>::layout_t::stride_order_encoded,
93 "Error in MPI reduce for nda::Array: Incompatible stride orders");
96 if (not mpi::has_env) {
102 if constexpr (not mpi::has_mpi_type<value_type>) {
104 target =
nda::map([
this](
auto const &x) {
return mpi::reduce(x, this->comm, this->root, this->all, this->op); })(rhs);
107 bool in_place = (target.data() == rhs.data());
109 if (rhs.size() != target.size())
110 NDA_RUNTIME_ERROR <<
"Error in MPI reduce for nda::Array: In-place reduction requires arrays of the same size";
113 if (std::abs(target.data() - rhs.data()) < rhs.size()) NDA_RUNTIME_ERROR <<
"Error in MPI reduce for nda::Array: Overlapping arrays";
116 void *target_ptr = (
void *)target.data();
117 void *rhs_ptr = (
void *)rhs.data();
118 auto count = rhs.size();
119 auto mpi_value_type = mpi::mpi_type<value_type>::get();
122 MPI_Reduce((comm.rank() == root ? MPI_IN_PLACE : rhs_ptr), rhs_ptr, count, mpi_value_type, op, root, comm.get());
124 MPI_Reduce(rhs_ptr, target_ptr, count, mpi_value_type, op, root, comm.get());
127 MPI_Allreduce(MPI_IN_PLACE, rhs_ptr, count, mpi_value_type, op, comm.get());
129 MPI_Allreduce(rhs_ptr, target_ptr, count, mpi_value_type, op, comm.get());