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());