NeoN
A framework for CFD software
Loading...
Searching...
No Matches
operators.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2023 - 2026 NeoN authors
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <complex>
8#ifdef NF_WITH_MPI_SUPPORT
9#include <mpi.h>
10#endif
11#include <type_traits>
12#include <vector>
13
14#include "NeoN/core/error.hpp"
16
17namespace NeoN
18{
19
20#ifdef NF_WITH_MPI_SUPPORT
21
22namespace mpi
23{
27enum class ReduceOp
28{
29 Max,
30 Min,
31 Sum,
32 Prod,
33 Land,
34 Band,
35 Lor,
36 Bor,
37 Maxloc,
38 Minloc
39};
40
47constexpr MPI_Op getOp(const ReduceOp op)
48{
49 switch (op)
50 {
51 case ReduceOp::Max:
52 return MPI_MAX;
53 case ReduceOp::Min:
54 return MPI_MIN;
55 case ReduceOp::Sum:
56 return MPI_SUM;
57 case ReduceOp::Prod:
58 return MPI_PROD;
59 case ReduceOp::Land:
60 return MPI_LAND;
61 case ReduceOp::Band:
62 return MPI_BAND;
63 case ReduceOp::Lor:
64 return MPI_LOR;
65 case ReduceOp::Bor:
66 return MPI_BOR;
67 case ReduceOp::Maxloc:
68 return MPI_MAXLOC;
69 case ReduceOp::Minloc:
70 return MPI_MINLOC;
71 default:
72 NF_ERROR_EXIT("Invalid MPI reduce operation requested.");
73 return MPI_LOR; // This is to suppress the warning
74 }
75}
76
83template<typename valueType>
84constexpr MPI_Datatype getType()
85{
86 if constexpr (std::is_same_v<valueType, char>) return MPI_CHAR;
87 else if constexpr (std::is_same_v<valueType, wchar_t>)
88 return MPI_WCHAR;
89 else if constexpr (std::is_same_v<valueType, short>)
90 return MPI_SHORT;
91 else if constexpr (std::is_same_v<valueType, int>)
92 return MPI_INT;
93 else if constexpr (std::is_same_v<valueType, long>)
94 return MPI_LONG;
95 else if constexpr (std::is_same_v<valueType, long long>)
96 return MPI_LONG_LONG;
97 else if constexpr (std::is_same_v<valueType, unsigned short>)
98 return MPI_UNSIGNED_SHORT;
99 else if constexpr (std::is_same_v<valueType, unsigned>)
100 return MPI_UNSIGNED;
101 else if constexpr (std::is_same_v<valueType, unsigned long>)
102 return MPI_UNSIGNED_LONG;
103 else if constexpr (std::is_same_v<valueType, unsigned long long>)
104 return MPI_UNSIGNED_LONG_LONG;
105 else if constexpr (std::is_same_v<valueType, float>)
106 return MPI_FLOAT;
107 else if constexpr (std::is_same_v<valueType, double>)
108 return MPI_DOUBLE;
109 else if constexpr (std::is_same_v<valueType, long double>)
110 return MPI_LONG_DOUBLE;
111 else if constexpr (std::is_same_v<valueType, bool>)
112 return MPI_CXX_BOOL;
113 else if constexpr (std::is_same_v<valueType, std::complex<float>>)
114 return MPI_CXX_FLOAT_COMPLEX;
115 else if constexpr (std::is_same_v<valueType, std::complex<double>>)
116 return MPI_CXX_DOUBLE_COMPLEX;
117 else if constexpr (std::is_same_v<valueType, std::complex<long double>>)
118 return MPI_CXX_LONG_DOUBLE_COMPLEX;
119 else
120 NF_ERROR_EXIT("Invalid MPI datatype requested.");
121 return MPI_CHAR; // This is to suppress the warning
122}
123
134template<typename valueType>
135void allReduce(valueType& value, const ReduceOp op, MPI_Comm comm)
136{
137 MPI_Allreduce(
138 MPI_IN_PLACE, reinterpret_cast<void*>(&value), 1, getType<valueType>(), getOp(op), comm
139 );
140}
141
151template<>
152inline void allReduce(Vec3& vector, const ReduceOp op, MPI_Comm comm)
153{
154 MPI_Allreduce(
155 MPI_IN_PLACE,
156 reinterpret_cast<void*>(vector.data()),
157 static_cast<mpi_label_t>(vector.size()),
158 getType<scalar>(),
159 getOp(op),
160 comm
161 );
162}
163
176template<typename valueType>
177void isend(
178 const valueType* buffer,
179 const mpi_label_t size,
180 mpi_label_t rankReceive,
181 mpi_label_t tag,
182 MPI_Comm comm,
183 MPI_Request* request
184)
185{
186 mpi_label_t err =
187 MPI_Isend(buffer, size, getType<valueType>(), rankReceive, tag, comm, request);
188 NF_DEBUG_ASSERT(err == MPI_SUCCESS, "MPI_Isend failed.");
189}
190
203template<typename valueType>
204void irecv(
205 valueType* buffer,
206 const mpi_label_t size,
207 mpi_label_t rankSend,
208 mpi_label_t tag,
209 MPI_Comm comm,
210 MPI_Request* request
211)
212{
213 mpi_label_t err = MPI_Irecv(buffer, size, getType<valueType>(), rankSend, tag, comm, request);
214 NF_DEBUG_ASSERT(err == MPI_SUCCESS, "MPI_Irecv failed.");
215}
216
224inline bool test(MPI_Request* request)
225{
226 mpi_label_t flag;
227 mpi_label_t err = MPI_Test(request, &flag, MPI_STATUS_IGNORE);
228 NF_DEBUG_ASSERT(err == MPI_SUCCESS, "MPI_Test failed.");
229 return static_cast<bool>(flag);
230}
231
239inline void waitAll(MPI_Request* requests, const mpi_label_t count)
240{
241 if (count == 0) return;
242 mpi_label_t err = MPI_Waitall(count, requests, MPI_STATUSES_IGNORE);
243 NF_DEBUG_ASSERT(err == MPI_SUCCESS, "MPI_Waitall failed.");
244}
245
252inline void waitAll(std::vector<MPI_Request>& requests)
253{
254 waitAll(requests.data(), static_cast<mpi_label_t>(requests.size()));
255}
256
268template<typename valueType>
269void allToAll(
270 const valueType* sendBuf,
271 mpi_label_t sendCount,
272 valueType* recvBuf,
273 mpi_label_t recvCount,
274 MPI_Comm comm
275)
276{
277 mpi_label_t err = MPI_Alltoall(
278 sendBuf, sendCount, getType<valueType>(), recvBuf, recvCount, getType<valueType>(), comm
279 );
280 NF_DEBUG_ASSERT(err == MPI_SUCCESS, "MPI_Alltoall failed.");
281}
282
296template<typename valueType>
297void allToAllV(
298 const valueType* sendBuf,
299 const mpi_label_t* sendCounts,
300 const mpi_label_t* sendDispls,
301 valueType* recvBuf,
302 const mpi_label_t* recvCounts,
303 const mpi_label_t* recvDispls,
304 MPI_Comm comm
305)
306{
307 mpi_label_t err = MPI_Alltoallv(
308 sendBuf,
309 sendCounts,
310 sendDispls,
311 getType<valueType>(),
312 recvBuf,
313 recvCounts,
314 recvDispls,
315 getType<valueType>(),
316 comm
317 );
318 NF_DEBUG_ASSERT(err == MPI_SUCCESS, "MPI_Alltoallv failed.");
319}
320
321} // namespace mpi
322
323#endif
324
325}
#define NF_ERROR_EXIT(message)
Macro for printing an error message and aborting the program.
Definition error.hpp:90
#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:190
Integer types used throughout NeoN.
Definition array.hpp:18
int mpi_label_t
Definition label.hpp:57