5#ifndef IPPL_MPI_OPERATIONS_H
6#define IPPL_MPI_OPERATIONS_H
8#include <Kokkos_Complex.hpp>
20 enum struct binaryOperationKind {
36 constexpr static binaryOperationKind value = binaryOperationKind::SUM;
40 constexpr static binaryOperationKind value = binaryOperationKind::MULTIPLICATION;
44 constexpr static binaryOperationKind value = binaryOperationKind::MIN;
48 constexpr static binaryOperationKind value = binaryOperationKind::MAX;
58 static std::map<std::pair<std::type_index, std::type_index>, MPI_Op> mpiOperations;
60 template <
typename CppOpType,
typename Datatype_IfNotTrivial>
62 constexpr MPI_Op operator()()
const noexcept {
78 template <
class Op,
typename Type>
86 std::pair<std::type_index, std::type_index> pear{std::type_index(
typeid(Op)),
87 std::type_index(
typeid(Type))};
88 if (mpiOperations.contains(pear)) {
89 return mpiOperations.at(pear);
97 [](
void* inputBuffer,
void* outputBuffer,
int* len, MPI_Datatype*) {
98 Type* input = (Type*)inputBuffer;
100 Type* output = (Type*)outputBuffer;
102 for (
int i = 0; i < *len; i++) {
103 if constexpr (opKind == binaryOperationKind::SUM) {
104 output[i] += input[i];
106 if constexpr (opKind == binaryOperationKind::MIN) {
107 output[i] = min(output[i], input[i]);
109 if constexpr (opKind == binaryOperationKind::MAX) {
110 output[i] = max(output[i], input[i]);
112 if constexpr (opKind == binaryOperationKind::MULTIPLICATION) {
113 output[i] *= input[i];
118 mpiOperations[pear] = ret;
123#define IPPL_MPI_OP(CppOp, MPIOp) \
124 template <typename Datatype_IfNotTrivial> \
125 struct getMpiOpImpl<CppOp, Datatype_IfNotTrivial> { \
126 constexpr MPI_Op operator()() const noexcept { return MPIOp; } \
129 struct is_ippl_mpi_type<CppOp> : std::true_type {};
138 IPPL_MPI_OP(std::plus<char>, MPI_SUM);
139 IPPL_MPI_OP(std::plus<short>, MPI_SUM);
140 IPPL_MPI_OP(std::plus<int>, MPI_SUM);
141 IPPL_MPI_OP(std::plus<long>, MPI_SUM);
142 IPPL_MPI_OP(std::plus<long long>, MPI_SUM);
143 IPPL_MPI_OP(std::plus<unsigned char>, MPI_SUM);
144 IPPL_MPI_OP(std::plus<unsigned short>, MPI_SUM);
145 IPPL_MPI_OP(std::plus<unsigned int>, MPI_SUM);
146 IPPL_MPI_OP(std::plus<unsigned long>, MPI_SUM);
147 IPPL_MPI_OP(std::plus<unsigned long long>, MPI_SUM);
148 IPPL_MPI_OP(std::plus<float>, MPI_SUM);
149 IPPL_MPI_OP(std::plus<double>, MPI_SUM);
150 IPPL_MPI_OP(std::plus<long double>, MPI_SUM);
152 IPPL_MPI_OP(std::plus<std::complex<float>>, MPI_SUM);
153 IPPL_MPI_OP(std::plus<std::complex<double>>, MPI_SUM);
154 IPPL_MPI_OP(std::plus<Kokkos::complex<float>>, MPI_SUM);
155 IPPL_MPI_OP(std::plus<Kokkos::complex<double>>, MPI_SUM);
157 IPPL_MPI_OP(std::less<char>, MPI_MIN);
158 IPPL_MPI_OP(std::less<short>, MPI_MIN);
159 IPPL_MPI_OP(std::less<int>, MPI_MIN);
160 IPPL_MPI_OP(std::less<long>, MPI_MIN);
161 IPPL_MPI_OP(std::less<long long>, MPI_MIN);
162 IPPL_MPI_OP(std::less<unsigned char>, MPI_MIN);
163 IPPL_MPI_OP(std::less<unsigned short>, MPI_MIN);
164 IPPL_MPI_OP(std::less<unsigned int>, MPI_MIN);
165 IPPL_MPI_OP(std::less<unsigned long>, MPI_MIN);
166 IPPL_MPI_OP(std::less<unsigned long long>, MPI_MIN);
167 IPPL_MPI_OP(std::less<float>, MPI_MIN);
168 IPPL_MPI_OP(std::less<double>, MPI_MIN);
169 IPPL_MPI_OP(std::less<long double>, MPI_MIN);
171 IPPL_MPI_OP(std::greater<char>, MPI_MAX);
172 IPPL_MPI_OP(std::greater<short>, MPI_MAX);
173 IPPL_MPI_OP(std::greater<int>, MPI_MAX);
174 IPPL_MPI_OP(std::greater<long>, MPI_MAX);
175 IPPL_MPI_OP(std::greater<long long>, MPI_MAX);
176 IPPL_MPI_OP(std::greater<unsigned char>, MPI_MAX);
177 IPPL_MPI_OP(std::greater<unsigned short>, MPI_MAX);
178 IPPL_MPI_OP(std::greater<unsigned int>, MPI_MAX);
179 IPPL_MPI_OP(std::greater<unsigned long>, MPI_MAX);
180 IPPL_MPI_OP(std::greater<unsigned long long>, MPI_MAX);
181 IPPL_MPI_OP(std::greater<float>, MPI_MAX);
182 IPPL_MPI_OP(std::greater<double>, MPI_MAX);
183 IPPL_MPI_OP(std::greater<long double>, MPI_MAX);
185 IPPL_MPI_OP(std::multiplies<short>, MPI_PROD);
186 IPPL_MPI_OP(std::multiplies<int>, MPI_PROD);
187 IPPL_MPI_OP(std::multiplies<long>, MPI_PROD);
188 IPPL_MPI_OP(std::multiplies<long long>, MPI_PROD);
189 IPPL_MPI_OP(std::multiplies<unsigned short>, MPI_PROD);
190 IPPL_MPI_OP(std::multiplies<unsigned int>, MPI_PROD);
191 IPPL_MPI_OP(std::multiplies<unsigned long>, MPI_PROD);
192 IPPL_MPI_OP(std::multiplies<unsigned long long>, MPI_PROD);
193 IPPL_MPI_OP(std::multiplies<float>, MPI_PROD);
194 IPPL_MPI_OP(std::multiplies<double>, MPI_PROD);
195 IPPL_MPI_OP(std::multiplies<long double>, MPI_PROD);
197 IPPL_MPI_OP(std::logical_or<bool>, MPI_LOR);
198 IPPL_MPI_OP(std::logical_and<bool>, MPI_LAND);
200 template <
typename Op,
typename Datatype>
201 MPI_Op get_mpi_op() {
202 if constexpr (is_ippl_mpi_type<Op>::value) {
203 return getMpiOpImpl<Op, Datatype>{}();
205 return getNontrivialMpiOpImpl<Op, Datatype>{}();
Definition Operations.h:51
Definition Operations.h:54
Definition Operations.h:61
Helper struct to look up and store MPI_Op types for custom types and custom operations.
Definition Operations.h:79
MPI_Op operator()()
Get the MPI_Op for this CppOp + Type combo.
Definition Operations.h:85
Definition Operations.h:53