127 template <
typename T,
typename S>
144template <
typename T =
void>
148template <
typename T =
void>
152template <
typename T =
void>
156template <
typename T =
void>
160template <
typename T =
void>
164template <
typename T =
void>
168template <
typename T =
void>
172template <
typename T =
void>
176template <
typename T =
void>
180template <
typename T =
void>
184template <
typename T =
void>
204#ifdef KAMPING_DOXYGEN_ONLY
220template <
typename Op,
typename Datatype>
246template <
typename Op,
typename T,
typename Enable =
void>
251template <
typename T,
typename S>
252struct mpi_operation_traits<
255 typename std::enable_if<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
256 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::floating
259 static constexpr T
identity = std::numeric_limits<T>::lowest();
265template <
typename T,
typename S>
266struct mpi_operation_traits<
269 typename std::enable_if<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
270 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::floating
273 static constexpr T
identity = std::numeric_limits<T>::max();
279template <
typename T,
typename S>
280struct mpi_operation_traits<
283 typename std::enable_if<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
284 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::floating
285 || builtin_type<T>::category == TypeCategory::complex
294template <
typename T,
typename S>
295struct mpi_operation_traits<
298 typename std::enable_if<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
299 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::floating
300 || builtin_type<T>::category == TypeCategory::complex
309template <
typename T,
typename S>
310struct mpi_operation_traits<
313 typename std::enable_if<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
314 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::logical
323template <
typename T,
typename S>
324struct mpi_operation_traits<
327 typename std::enable_if<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
328 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::logical
331 static constexpr T
identity =
false;
337template <
typename T,
typename S>
338struct mpi_operation_traits<
341 typename std::enable_if<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
342 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::logical
345 static constexpr T
identity =
false;
351template <
typename T,
typename S>
352struct mpi_operation_traits<
355 typename std::enable_if<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
356 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::byte
359 static constexpr T
identity = ~(T{0});
365template <
typename T,
typename S>
366struct mpi_operation_traits<
369 typename std::enable_if<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
370 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::byte
379template <
typename T,
typename S>
380struct mpi_operation_traits<
383 typename std::enable_if<(std::is_same_v<S, void> || std::is_same_v<T, S>)&&(
384 builtin_type<T>::category == TypeCategory::integer || builtin_type<T>::category == TypeCategory::byte
402template <
typename Functor>
438template <
bool is_commutative,
typename T,
typename Op>
442 std::is_default_constructible_v<Op>,
443 "This wrapper only works with default constructible functors, i.e., not with lambdas."
455 static_assert(std::is_invocable_r_v<T, Op, T const&, T const&>,
"Type of custom operation does not match.");
469 return _operation(
lhs,
rhs);
493template <
bool is_commutative>
546#ifdef KAMPING_DOXYGEN_ONLY
552template <
typename T,
typename Op,
typename Commutative>
578template <
typename T,
typename Op,
typename Commutative,
class Enable =
void>
583 kamping::ops::internal::
584 commutative_tag> || std::is_same_v<Commutative, kamping::ops::internal::non_commutative_tag>,
585 "For custom operations you have to specify whether they are commutative."
591 static constexpr bool commutative = std::is_same_v<Commutative, kamping::ops::internal::commutative_tag>;
594 return _operation(
lhs,
rhs);
598 return _operation.get_mpi_op();
602 UserOperationWrapper<commutative, T, Op> _operation;
607class ReduceOperation<T, MPI_Op, ops::internal::undefined_commutative_tag, void> {
613 T
operator()(T
const& lhs, T
const& rhs)
const {
614 KASSERT(_op != MPI_OP_NULL,
"Cannot call MPI_OP_NULL.");
617 if constexpr (!std::is_same_v<
decltype(operation), ops::null<> >) {
618 result = operation(lhs, rhs);
622 MPI_Reduce_local(&lhs, &result, 1, mpi_datatype<T>(), _op);
636template <
typename T,
typename Op,
typename Commutative>
637class ReduceOperation<T, Op, Commutative, typename
std::enable_if<mpi_operation_traits<Op, T>::is_builtin>::type> {
639 std::is_same_v<Commutative, kamping::ops::internal::undefined_commutative_tag>,
640 "For builtin operations you don't need to specify whether they are commutative."
652 T
operator()(T
const& lhs, T
const& rhs)
const {
653 return Op{}(lhs, rhs);
661template <
typename T,
typename Op,
typename Commutative>
662class ReduceOperation<T, Op, Commutative, typename
std::enable_if<!std::is_default_constructible_v<Op> >::type> {
666 kamping::ops::internal::
667 commutative_tag> || std::is_same_v<Commutative, kamping::ops::internal::non_commutative_tag>,
668 "For custom operations you have to specify whether they are commutative."
676 static Op func = _op;
679 T* invec_ =
static_cast<T*
>(invec);
680 T* inoutvec_ =
static_cast<T*
>(inoutvec);
681 std::transform(invec_, invec_ + *len, inoutvec_, inoutvec_, func);
686 static constexpr bool commutative = std::is_same_v<Commutative, kamping::ops::internal::commutative_tag>;
689 return _operation.get_mpi_op();
692 T
operator()(T
const& lhs, T
const& rhs)
const {
693 return _op(lhs, rhs);
697 return _operation.identity();
702 UserOperationPtrWrapper<commutative> _operation;
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:553
ReduceOperation(Op &&op, Commutative commutative)
Constructs on operation wrapper.
static constexpr bool commutative
indicates if this operation is commutative
Definition mpi_ops.hpp:564
T operator()(T const &lhs, T const &rhs) const
Call the underlying operation with the provided arguments.
static constexpr bool is_builtin
indicates if this is a builtin operation
Definition mpi_ops.hpp:563
Wrapper for a user defined reduction operation based on a function pointer.
Definition mpi_ops.hpp:494
UserOperationPtrWrapper(mpi_custom_operation_type ptr)
creates an MPI operation for the specified function pointer
Definition mpi_ops.hpp:521
MPI_Op get_mpi_op()
Definition mpi_ops.hpp:536
UserOperationPtrWrapper(UserOperationPtrWrapper< is_commutative > &&other_op)
move constructor
Definition mpi_ops.hpp:508
UserOperationPtrWrapper< is_commutative > & operator=(UserOperationPtrWrapper< is_commutative > &&other_op)
move assignment
Definition mpi_ops.hpp:499
UserOperationPtrWrapper()
creates an empty operation wrapper
Definition mpi_ops.hpp:514
Wrapper for a user defined reduction operation based on a functor object.
Definition mpi_ops.hpp:439
static void execute(void *invec, void *inoutvec, int *len, MPI_Datatype *)
wrapper around the provided functor which is called by MPI
Definition mpi_ops.hpp:460
MPI_Op get_mpi_op()
Definition mpi_ops.hpp:480
T operator()(T const &lhs, T const &rhs) const
Call the wrapped operation.
Definition mpi_ops.hpp:468
UserOperationWrapper(Op &&op)
creates an MPI operation for the specified functor
Definition mpi_ops.hpp:454
@ op
Tag used to represent a reduce operation in a MPI call.
Utility that maps C++ types to types that can be understood by MPI.
void(*)(void *, void *, int *, MPI_Datatype *) mpi_custom_operation_type
type used by user-defined operations passed to MPI_Op_create
Definition mpi_ops.hpp:430
auto with_operation_functor(MPI_Op op, Functor &&func)
Helper function that maps an MPI_Op to the matching functor from kamping::ops. In case no function ma...
Definition mpi_ops.hpp:403
std::logical_and< T > logical_and
builtin logical and operation (aka MPI_LAND)
Definition mpi_ops.hpp:161
constexpr internal::commutative_tag commutative
global tag for commutativity
Definition mpi_ops.hpp:197
kamping::internal::logical_xor_impl< T > logical_xor
builtin logical xor operation (aka MPI_LXOR)
Definition mpi_ops.hpp:177
std::bit_or< T > bit_or
builtin bitwise or operation (aka MPI_BOR)
Definition mpi_ops.hpp:173
std::logical_or< T > logical_or
builtin logical or operation (aka MPI_LOR)
Definition mpi_ops.hpp:169
kamping::internal::min_impl< T > min
builtin minimum operation (aka MPI_MIN)
Definition mpi_ops.hpp:149
std::bit_and< T > bit_and
builtin bitwise and operation (aka MPI_BAND)
Definition mpi_ops.hpp:165
std::bit_xor< T > bit_xor
builtin bitwise xor operation (aka MPI_BXOR)
Definition mpi_ops.hpp:181
std::plus< T > plus
builtin summation operation (aka MPI_SUM)
Definition mpi_ops.hpp:153
constexpr internal::non_commutative_tag non_commutative
global tag for non-commutativity
Definition mpi_ops.hpp:198
std::multiplies< T > multiplies
builtin multiplication operation (aka MPI_PROD)
Definition mpi_ops.hpp:157
constexpr bool operator()(T const &lhs, S const &rhs) const
Returns the logical xor of the two parameters.
Definition mpi_ops.hpp:128
Wrapper struct for logical xor, as the standard library does not provided a function object for it.
Definition mpi_ops.hpp:106
constexpr bool operator()(T const &lhs, T const &rhs) const
Returns the logical xor of the two parameters.
Definition mpi_ops.hpp:111
constexpr auto operator()(T const &lhs, T const &rhs) const
Returns the maximum of the two parameters.
Definition mpi_ops.hpp:61
Wrapper struct for std::max.
Definition mpi_ops.hpp:38
constexpr T operator()(T const &lhs, T const &rhs) const
Returns the maximum of the two parameters.
Definition mpi_ops.hpp:43
constexpr auto operator()(T const &lhs, T const &rhs) const
Returns the maximum of the two parameters.
Definition mpi_ops.hpp:95
Wrapper struct for std::min.
Definition mpi_ops.hpp:74
constexpr T operator()(T const &lhs, T const &rhs) const
returns the maximum of the two parameters
Definition mpi_ops.hpp:79
Type trait for checking whether a functor is a builtin MPI reduction operation and query correspondin...
Definition mpi_ops.hpp:221
static constexpr T identity
The identity of this operation applied on this datatype.
Definition mpi_ops.hpp:234
static constexpr bool is_builtin
true if the operation defined by Op is a builtin MPI operation for the type Datatype
Definition mpi_ops.hpp:227
static MPI_Op op()
get the MPI_Op for a builtin type
tag for a commutative reduce operation
Definition mpi_ops.hpp:189
tag for a non-commutative reduce operation
Definition mpi_ops.hpp:191
tag for a reduce operation without manually declared commutativity (this is only used internally for ...
Definition mpi_ops.hpp:194
builtin null operation (aka MPI_OP_NULL)
Definition mpi_ops.hpp:185