NeoFOAM
WIP Prototype of a modern OpenFOAM core
Loading...
Searching...
No Matches
operators.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: MIT
2// SPDX-FileCopyrightText: 2023 NeoFOAM authors
3#pragma once
4
5#include <complex>
6#ifdef NF_WITH_MPI_SUPPORT
7#include <mpi.h>
8#endif
9#include <type_traits>
10
13
14namespace NeoFOAM
15{
16
17#ifdef NF_WITH_MPI_SUPPORT
18
19namespace mpi
20{
24enum class ReduceOp
25{
26 Max,
27 Min,
28 Sum,
29 Prod,
30 Land,
31 Band,
32 Lor,
33 Bor,
34 Maxloc,
35 Minloc
36};
37
44constexpr MPI_Op getOp(const ReduceOp op)
45{
46 switch (op)
47 {
48 case ReduceOp::Max:
49 return MPI_MAX;
50 case ReduceOp::Min:
51 return MPI_MIN;
52 case ReduceOp::Sum:
53 return MPI_SUM;
54 case ReduceOp::Prod:
55 return MPI_PROD;
56 case ReduceOp::Land:
57 return MPI_LAND;
58 case ReduceOp::Band:
59 return MPI_BAND;
60 case ReduceOp::Lor:
61 return MPI_LOR;
62 case ReduceOp::Bor:
63 return MPI_BOR;
64 case ReduceOp::Maxloc:
65 return MPI_MAXLOC;
66 case ReduceOp::Minloc:
67 return MPI_MINLOC;
68 default:
69 NF_ERROR_EXIT("Invalid MPI reduce operation requested.");
70 return MPI_LOR; // This is to suppress the warning
71 }
72}
73
80template<typename valueType>
81constexpr MPI_Datatype getType()
82{
83 if constexpr (std::is_same_v<valueType, char>) return MPI_CHAR;
84 else if constexpr (std::is_same_v<valueType, wchar_t>)
85 return MPI_WCHAR;
86 else if constexpr (std::is_same_v<valueType, short>)
87 return MPI_SHORT;
88 else if constexpr (std::is_same_v<valueType, int>)
89 return MPI_INT;
90 else if constexpr (std::is_same_v<valueType, long>)
91 return MPI_LONG;
92 else if constexpr (std::is_same_v<valueType, long long>)
93 return MPI_LONG_LONG;
94 else if constexpr (std::is_same_v<valueType, unsigned short>)
95 return MPI_UNSIGNED_SHORT;
96 else if constexpr (std::is_same_v<valueType, unsigned>)
97 return MPI_UNSIGNED;
98 else if constexpr (std::is_same_v<valueType, unsigned long>)
99 return MPI_UNSIGNED_LONG;
100 else if constexpr (std::is_same_v<valueType, unsigned long long>)
101 return MPI_UNSIGNED_LONG_LONG;
102 else if constexpr (std::is_same_v<valueType, float>)
103 return MPI_FLOAT;
104 else if constexpr (std::is_same_v<valueType, double>)
105 return MPI_DOUBLE;
106 else if constexpr (std::is_same_v<valueType, long double>)
107 return MPI_LONG_DOUBLE;
108 else if constexpr (std::is_same_v<valueType, bool>)
109 return MPI_CXX_BOOL;
110 else if constexpr (std::is_same_v<valueType, std::complex<float>>)
111 return MPI_CXX_FLOAT_COMPLEX;
112 else if constexpr (std::is_same_v<valueType, std::complex<double>>)
113 return MPI_CXX_DOUBLE_COMPLEX;
114 else if constexpr (std::is_same_v<valueType, std::complex<long double>>)
115 return MPI_CXX_LONG_DOUBLE_COMPLEX;
116 else
117 NF_ERROR_EXIT("Invalid MPI datatype requested.");
118 return MPI_CHAR; // This is to suppress the warning
119}
120
131template<typename valueType>
132void allReduce(valueType& value, const ReduceOp op, MPI_Comm comm)
133{
134 MPI_Allreduce(
135 MPI_IN_PLACE, reinterpret_cast<void*>(&value), 1, getType<valueType>(), getOp(op), comm
136 );
137}
138
148template<>
149inline void allReduce(Vector& vector, const ReduceOp op, MPI_Comm comm)
150{
151 MPI_Allreduce(
152 MPI_IN_PLACE,
153 reinterpret_cast<void*>(vector.data()),
154 static_cast<mpi_label_t>(vector.size()),
155 getType<scalar>(),
156 getOp(op),
157 comm
158 );
159}
160
173template<typename valueType>
174void isend(
175 const valueType* buffer,
176 const mpi_label_t size,
177 mpi_label_t rankReceive,
178 mpi_label_t tag,
179 MPI_Comm comm,
180 MPI_Request* request
181)
182{
183 mpi_label_t err =
184 MPI_Isend(buffer, size, getType<valueType>(), rankReceive, tag, comm, request);
185 NF_DEBUG_ASSERT(err == MPI_SUCCESS, "MPI_Isend failed.");
186}
187
200template<typename valueType>
201void irecv(
202 valueType* buffer,
203 const mpi_label_t size,
204 mpi_label_t rankSend,
205 mpi_label_t tag,
206 MPI_Comm comm,
207 MPI_Request* request
208)
209{
210 mpi_label_t err = MPI_Irecv(buffer, size, getType<valueType>(), rankSend, tag, comm, request);
211 NF_DEBUG_ASSERT(err == MPI_SUCCESS, "MPI_Irecv failed.");
212}
213
221inline bool test(MPI_Request* request)
222{
223 mpi_label_t flag;
224 mpi_label_t err = MPI_Test(request, &flag, MPI_STATUS_IGNORE);
225 NF_DEBUG_ASSERT(err == MPI_SUCCESS, "MPI_Test failed.");
226 return static_cast<bool>(flag);
227}
228
229} // namespace mpi
230
231#endif
232
233}
#define NF_ERROR_EXIT(message)
Macro for printing an error message and aborting the program.
Definition error.hpp:108
#define NF_DEBUG_ASSERT(condition, message)
Macro for asserting a condition and printing an error message if the condition is false (only in debu...
Definition error.hpp:211
int mpi_label_t
Definition label.hpp:18