36#include "kamping/kassert/kassert.hpp"
43namespace kamping::ops::internal {
115 template <
typename T,
typename S>
130namespace kamping::ops {
133template <
typename T =
void>
137template <
typename T =
void>
141template <
typename T =
void>
145template <
typename T =
void>
149template <
typename T =
void>
153template <
typename T =
void>
157template <
typename T =
void>
161template <
typename T =
void>
165template <
typename T =
void>
169template <
typename T =
void>
173template <
typename T =
void>
185namespace kamping::types {
187#ifdef KAMPING_DOXYGEN_ONLY
203template <
typename Op,
typename T>
220template <
typename Op,
typename T,
typename Enable =
void>
225template <
typename T,
typename S>
226struct mpi_operation_traits<
229 std::enable_if_t<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
230 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::floating
233 static constexpr T
identity = std::numeric_limits<T>::lowest();
239template <
typename T,
typename S>
240struct mpi_operation_traits<
241 kamping::ops::min<S>,
243 std::enable_if_t<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
244 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::floating
247 static constexpr T
identity = std::numeric_limits<T>::max();
253template <
typename T,
typename S>
254struct mpi_operation_traits<
255 kamping::ops::plus<S>,
257 std::enable_if_t<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
258 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::floating
259 || builtin_type<T>::category == TypeCategory::complex
268template <
typename T,
typename S>
269struct mpi_operation_traits<
270 kamping::ops::multiplies<S>,
272 std::enable_if_t<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
273 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::floating
274 || builtin_type<T>::category == TypeCategory::complex
283template <
typename T,
typename S>
284struct mpi_operation_traits<
285 kamping::ops::logical_and<S>,
287 std::enable_if_t<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
288 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::logical
297template <
typename T,
typename S>
298struct mpi_operation_traits<
299 kamping::ops::logical_or<S>,
301 std::enable_if_t<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
302 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::logical
305 static constexpr T
identity =
false;
311template <
typename T,
typename S>
312struct mpi_operation_traits<
313 kamping::ops::logical_xor<S>,
315 std::enable_if_t<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
316 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::logical
319 static constexpr T
identity =
false;
325template <
typename T,
typename S>
326struct mpi_operation_traits<
327 kamping::ops::bit_and<S>,
329 std::enable_if_t<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
330 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::byte
333 static constexpr T
identity = ~(T{0});
339template <
typename T,
typename S>
340struct mpi_operation_traits<
341 kamping::ops::bit_or<S>,
343 std::enable_if_t<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
344 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::byte
353template <
typename T,
typename S>
354struct mpi_operation_traits<
355 kamping::ops::bit_xor<S>,
357 std::enable_if_t<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
358 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::byte
399 if (
this != &
other) {
445template <
bool is_commutative,
typename T,
typename Op>
448 std::is_default_constructible_v<Op>,
449 "ScopedFunctorOp requires a default-constructible functor. Use ScopedCallbackOp for lambdas."
451 static_assert(std::is_invocable_r_v<T, Op, T const&, T const&>,
"Op must be callable as T(T const&, T const&).");
453 std::is_destructible_v<T> && (std::is_move_constructible_v<T> || std::is_copy_constructible_v<T>),
454 "T must be destructible and move- or copy-constructible (T need not be assignable -- "
455 "_execute() combines by destroying and reconstructing elements in place, not by assignment)."
474 return _functor(
lhs,
rhs);
499 T*
in =
static_cast<T*
>(
invec);
501 for (
int i = 0;
i < *
len; ++
i) {
508 static ScopedOp _make_scoped_op() {
510 MPI_Op_create(_execute,
static_cast<int>(is_commutative), &raw);
511 return ScopedOp{raw,
true};
532template <
bool is_commutative>
580template <
typename Functor>
STL-compatible allocator for requesting memory using the builtin MPI allocator.
Definition allocator.hpp:32
RAII handle that creates an MPI_Op from a raw MPI callback function pointer.
Definition reduce_ops.hpp:533
MPI_Op get() const noexcept
Definition reduce_ops.hpp:556
void(*)(void *, void *, int *, MPI_Datatype *) callback_type
The MPI callback signature expected by MPI_Op_create.
Definition reduce_ops.hpp:536
ScopedCallbackOp(ScopedCallbackOp &&) noexcept=default
Move constructor. The moved-from handle becomes empty.
ScopedCallbackOp() noexcept=default
Constructs an empty, non-owning handle (MPI_OP_NULL).
RAII handle that creates an MPI_Op from a default-constructible C++ functor.
Definition reduce_ops.hpp:446
T operator()(T const &lhs, T const &rhs) const
Applies the functor to two values.
Definition reduce_ops.hpp:473
MPI_Op get() const noexcept
Definition reduce_ops.hpp:468
ScopedFunctorOp(Op op)
Creates an MPI_Op for the given functor.
Definition reduce_ops.hpp:460
RAII wrapper for an MPI_Op.
Definition reduce_ops.hpp:380
ScopedOp & operator=(ScopedOp &&other) noexcept
Move assignment. Frees any currently owned op, then transfers ownership.
Definition reduce_ops.hpp:398
MPI_Op get() const noexcept
Definition reduce_ops.hpp:413
ScopedOp(MPI_Op op, bool owns) noexcept
Wrap an existing MPI_Op.
Definition reduce_ops.hpp:388
ScopedOp() noexcept
Constructs an empty, non-owning handle (MPI_OP_NULL).
Definition reduce_ops.hpp:383
ScopedOp(ScopedOp &&other) noexcept
Move constructor. Transfers ownership; the moved-from handle no longer frees the op.
Definition reduce_ops.hpp:394
internal::OperationBuilder< Op, Commutative > op(Op &&op, Commutative commute=ops::internal::undefined_commutative_tag{})
Passes a reduction operation to ther underlying call. Accepts function objects, lambdas,...
Definition named_parameters.hpp:1219
Mapping of C++ datatypes to builtin MPI types.
std::logical_and< T > logical_and
Builtin logical AND (MPI_LAND).
Definition reduce_ops.hpp:150
constexpr internal::commutative_tag commutative
Tag: operation is commutative.
Definition reduce_ops.hpp:176
std::bit_or< T > bit_or
Builtin bitwise OR (MPI_BOR).
Definition reduce_ops.hpp:162
std::logical_or< T > logical_or
Builtin logical OR (MPI_LOR).
Definition reduce_ops.hpp:158
std::bit_and< T > bit_and
Builtin bitwise AND (MPI_BAND).
Definition reduce_ops.hpp:154
std::bit_xor< T > bit_xor
Builtin bitwise XOR (MPI_BXOR).
Definition reduce_ops.hpp:170
std::plus< T > plus
Builtin summation (MPI_SUM).
Definition reduce_ops.hpp:142
constexpr internal::non_commutative_tag non_commutative
Tag: operation is non-commutative.
Definition reduce_ops.hpp:177
std::multiplies< T > multiplies
Builtin multiplication (MPI_PROD).
Definition reduce_ops.hpp:146
Tag for a commutative user-defined reduce operation.
Definition reduce_ops.hpp:122
constexpr bool operator()(T const &lhs, S const &rhs) const
Returns the logical XOR of the two parameters.
Definition reduce_ops.hpp:116
Logical XOR function object (no STL equivalent).
Definition reduce_ops.hpp:99
constexpr bool operator()(T const &lhs, T const &rhs) const
Returns the logical XOR of the two parameters.
Definition reduce_ops.hpp:103
constexpr auto operator()(T const &lhs, T const &rhs) const
Returns the maximum of the two parameters.
Definition reduce_ops.hpp:67
Wrapper struct for std::max.
Definition reduce_ops.hpp:51
constexpr T operator()(T const &lhs, T const &rhs) const
Returns the maximum of the two parameters.
Definition reduce_ops.hpp:55
constexpr auto operator()(T const &lhs, T const &rhs) const
Returns the minimum of the two parameters.
Definition reduce_ops.hpp:91
Wrapper struct for std::min (same rationale as max_impl).
Definition reduce_ops.hpp:75
constexpr T operator()(T const &lhs, T const &rhs) const
Returns the minimum of the two parameters.
Definition reduce_ops.hpp:79
Tag for a non-commutative user-defined reduce operation.
Definition reduce_ops.hpp:124
Tag for a reduce operation without a manually declared commutativity (builtin ops only).
Definition reduce_ops.hpp:126
Null operation (MPI_OP_NULL).
Definition reduce_ops.hpp:174
Type trait that maps a (functor type, element type) pair to its builtin MPI_Op.
Definition reduce_ops.hpp:204
static constexpr bool is_builtin
true if Op applied to T corresponds to a predefined MPI operation constant.
Definition reduce_ops.hpp:206
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:211