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