30#include "kamping/kassert/kassert.hpp"
49#ifdef KAMPING_DOXYGEN_ONLY
55template <
typename T,
typename Op,
typename Commutative>
82template <
typename T,
typename Op,
typename Commutative,
class Enable =
void>
87 kamping::ops::internal::
88 commutative_tag> || std::is_same_v<Commutative, kamping::ops::internal::non_commutative_tag>,
89 "For custom operations you have to specify whether they are commutative."
95 static constexpr bool commutative = std::is_same_v<Commutative, kamping::ops::internal::commutative_tag>;
102 return _operation.get();
111class ReduceOperation<T, MPI_Op, ops::internal::undefined_commutative_tag, void> {
116 T
operator()(T
const& lhs, T
const& rhs)
const {
117 KAMPING_ASSERT(_op != MPI_OP_NULL,
"Cannot call MPI_OP_NULL.");
119 internal::with_operation_functor(_op, [&result, lhs, rhs,
this](
auto operation) {
120 if constexpr (!std::is_same_v<
decltype(operation), ops::null<> >) {
121 result = operation(lhs, rhs);
124 MPI_Reduce_local(&lhs, &result, 1, mpi_datatype<T>(), _op);
139template <
typename T,
typename Op,
typename Commutative>
140class ReduceOperation<T, Op, Commutative,
std::enable_if_t<mpi_operation_traits<Op, T>::is_builtin> > {
142 std::is_same_v<Commutative, kamping::ops::internal::undefined_commutative_tag>,
143 "For builtin operations you don't need to specify whether they are commutative."
155 T
operator()(T
const& lhs, T
const& rhs)
const {
156 return Op{}(lhs, rhs);
165template <
typename T,
typename Op,
typename Commutative>
166class ReduceOperation<T, Op, Commutative,
std::enable_if_t<!std::is_default_constructible_v<Op> > > {
170 kamping::ops::internal::
171 commutative_tag> || std::is_same_v<Commutative, kamping::ops::internal::non_commutative_tag>,
172 "For custom operations you have to specify whether they are commutative."
179 static Op func = _op;
182 [](
void* invec,
void* inoutvec,
int* len, MPI_Datatype* ) {
183 T* invec_ =
static_cast<T*
>(invec);
184 T* inoutvec_ =
static_cast<T*
>(inoutvec);
185 std::transform(invec_, invec_ + *len, inoutvec_, inoutvec_, func);
190 static constexpr bool commutative = std::is_same_v<Commutative, kamping::ops::internal::commutative_tag>;
193 return _operation.get();
196 T
operator()(T
const& lhs, T
const& rhs)
const {
197 return _op(lhs, rhs);
STL-compatible allocator for requesting memory using the builtin MPI allocator.
Definition allocator.hpp:32
Wraps an operation and translates it to a builtin MPI_Op or constructs a custom operation.
Definition mpi_ops.hpp:56
ReduceOperation(Op &&op, Commutative commutative)
Constructs an operation wrapper.
static constexpr bool commutative
True if the operation is commutative.
Definition mpi_ops.hpp:64
T operator()(T const &lhs, T const &rhs) const
Call the underlying operation with the provided arguments.
static constexpr bool is_builtin
True if this is a predefined MPI operation.
Definition mpi_ops.hpp:63
T identity()
Returns the identity element for this operation and data type.
RAII handle that creates an MPI_Op from a raw MPI callback function pointer.
Definition reduce_ops.hpp:501
RAII handle that creates an MPI_Op from a default-constructible C++ functor.
Definition reduce_ops.hpp:442
Utility that maps C++ types to types that can be understood by MPI.
MPI reduction operation functor vocabulary, type traits, and RAII handle.
auto with_operation_functor(MPI_Op op, Functor &&func)
Calls func with the functor object corresponding to the given builtin MPI_Op.
Definition reduce_ops.hpp:549
Type trait that maps a (functor type, element type) pair to its builtin MPI_Op.
Definition reduce_ops.hpp:202
static MPI_Op op()
Returns the predefined MPI_Op constant for this operation.
static constexpr T identity
The identity element for this operation and data type.
Definition reduce_ops.hpp:209