PstreamGlobals.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2013-2015 OpenFOAM Foundation
9  Copyright (C) 2022-2025 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Namespace
28  Foam::PstreamGlobals
29 
30 Description
31  Global functions and variables for working with parallel streams,
32  but principally for MPI.
33 
34 SourceFiles
35  PstreamGlobals.C
36 
37 \*---------------------------------------------------------------------------*/
38 
39 #ifndef Foam_PstreamGlobals_H
40 #define Foam_PstreamGlobals_H
41 
42 #include "DynamicList.H"
43 #include "FixedList.H"
44 #include "UPstream.H" // For UPstream::Request
45 #include "openfoam_mpi.H"
46 
47 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
48 
49 namespace Foam
50 {
51 namespace PstreamGlobals
52 {
53 
54 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
55 
56 // Track if MPI_Comm_free is needed for communicator index in MPICommunicators_
57 extern DynamicList<bool> pendingMPIFree_;
58 
59 // Current communicators, which may be allocated or predefined
60 // (eg, MPI_COMM_SELF, MPI_COMM_WORLD)
61 extern DynamicList<MPI_Comm> MPICommunicators_;
62 
63 //- Outstanding non-blocking operations.
64 extern DynamicList<MPI_Request> outstandingRequests_;
65 
66 // The fundamental count for each UPstream::dataTypes entry
68 
69 //- Fundamental count for each valid UPstream::dataTypes entry
70 //- Indexed by UPstream::dataTypes enum
72 
73 // For UPstream::dataTypes lookup, includes space for last 'invalid' entry
75 
76 //- MPI data types corresponding to fundamental and OpenFOAM types.
77 //- Indexed by UPstream::dataTypes enum
79 
80 // For UPstream::opCodes lookup, includes space for last 'invalid' entry
82 
83 //- MPI operation types, indexed by UPstream::opCodes enum
85 
86 
87 
88 // * * * * * * * * * * * * * * * Communicators * * * * * * * * * * * * * * * //
89 
90 //- Initialize bookkeeping for MPI communicator index
91 void initCommunicator(const label index);
92 
93 //- Fatal if communicator is outside the allocated range
94 inline void checkCommunicator(int comm, int rank)
95 {
96  if (FOAM_UNLIKELY(comm < 0 || comm >= MPICommunicators_.size()))
97  {
99  << "rank:" << rank << " : illegal communicator "
100  << comm << nl
101  << "Communicator should be within range [0,"
103  << ')' << Foam::abort(FatalError);
104  }
105 }
106 
107 //- True if warn communicator is active and not equal to given communicator
108 inline bool warnCommunicator(int comm) noexcept
109 {
110  return (UPstream::warnComm >= 0 && comm != UPstream::warnComm);
111 }
112 
113 
114 // * * * * * * * * * * * * * * * * Data Types * * * * * * * * * * * * * * * //
115 
116 //- Create mapping into MPIdataTypes_ and define user data types
117 void initDataTypes();
119 //- Free any user data types
120 void deinitDataTypes();
121 
122 //- Debugging only: check if data type mappings are non-null
123 bool checkDataTypes();
124 
125 //- Debugging only: print data type names (all or just user-defined)
126 void printDataTypes(bool all = false);
127 
128 //- Lookup of dataTypes enumeration as an MPI_Datatype
129 inline MPI_Datatype getDataType(UPstream::dataTypes id)
130 {
131  return MPIdataTypes_[static_cast<int>(id)];
132 }
133 
134 //- Fatal if data type is not valid
135 inline void checkDataType(UPstream::dataTypes id)
136 {
138  {
140  << "Invalid data type"
142  }
143 }
144 
145 //- Return MPI internal name for specified MPI_Datatype
146 std::string dataType_name(MPI_Datatype datatype);
147 
148 //- Return MPI internal name for dataTypes enumeration
149 inline std::string dataType_name(UPstream::dataTypes id)
150 {
151  return dataType_name(MPIdataTypes_[static_cast<int>(id)]);
152 }
153 
154 
155 // * * * * * * * * * * * * * * * * Op Codes * * * * * * * * * * * * * * * * //
156 
157 //- Create mapping into MPIopCodes_
158 void initOpCodes();
159 
160 //- Free any user-defined op codes
161 void deinitOpCodes();
162 
163 //- Debugging only: check if op code mappings are non-null
164 bool checkOpCodes();
165 
166 //- Lookup of opCodes enumeration as an MPI_Op
167 inline MPI_Op getOpCode(UPstream::opCodes id)
168 {
169  return MPIopCodes_[static_cast<int>(id)];
170 }
171 
172 //- Fatal if opcode is not valid
173 inline void checkOpCode(UPstream::opCodes id)
174 {
176  {
178  << "Invalid operation code"
180  }
181 }
182 
183 
184 // * * * * * * * * * * * * * * * * Requests * * * * * * * * * * * * * * * * //
185 
186 //- Reset UPstream::Request to MPI_REQUEST_NULL
187 // Does not affect the stack of outstanding requests
188 inline void reset_request(UPstream::Request* req) noexcept
189 {
190  if (req) *req = UPstream::Request(MPI_REQUEST_NULL);
191 }
192 
193 
194 //- Transcribe MPI_Request to UPstream::Request
195 //- (does not affect the stack of outstanding requests)
196 //- or else push onto list of outstanding requests
197 inline void push_request
198 (
199  MPI_Request request,
200  UPstream::Request* req = nullptr
201 )
202 {
203  if (req)
204  {
205  // Transcribe as UPstream::Request
206  *req = UPstream::Request(request);
207  }
208  else if (MPI_REQUEST_NULL != request)
209  {
210  // Push onto list of requests
211  PstreamGlobals::outstandingRequests_.push_back(request);
212  }
213 }
214 
215 
216 // * * * * * * * * * * * * * * Convenience Methods * * * * * * * * * * * * * //
217 
218 //- Broadcast a single int64 value.
219 //
220 // Ensures consistent data types. Used within the following:
221 // - UIPBstream::bufferIPCrecv()
222 // - UOPBstream::bufferIPCsend()
223 // - UOPBstream::send(Foam::zero, ...)
224 
225 inline bool broadcast_int64(int64_t& value, int comm)
226 {
227  return
228  (
229  MPI_SUCCESS
230  == MPI_Bcast(&value, 1, MPI_INT64_T, 0, MPICommunicators_[comm])
231  );
232 }
233 
234 
235 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
236 
237 } // End namespace PstreamGlobals
238 } // End namespace Foam
240 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
241 
242 #endif
243 
244 // ************************************************************************* //
DynamicList< MPI_Request > outstandingRequests_
Outstanding non-blocking operations.
Foam::FixedList< MPI_Datatype, 17 > DataTypeLookupTable
void deinitOpCodes()
Free any user-defined op codes.
A 1D vector of objects of type <T> with a fixed length <N>.
Definition: HashTable.H:107
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
void checkCommunicator(int comm, int rank)
Fatal if communicator is outside the allocated range.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:600
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
DynamicList< MPI_Comm > MPICommunicators_
void initDataTypes()
Create mapping into MPIdataTypes_ and define user data types.
bool checkOpCodes()
Debugging only: check if op code mappings are non-null.
opCodes
Mapping of some MPI op codes.
Definition: UPstream.H:145
DynamicList< bool > pendingMPIFree_
void reset_request(UPstream::Request *req) noexcept
Reset UPstream::Request to MPI_REQUEST_NULL.
void checkDataType(UPstream::dataTypes id)
Fatal if data type is not valid.
void initOpCodes()
Create mapping into MPIopCodes_.
An opaque wrapper for MPI_Request with a vendor-independent representation without any <mpi...
Definition: UPstream.H:2599
Foam::FixedList< MPI_Op, 13 > OpCodesLookupTable
#define FOAM_UNLIKELY(cond)
Definition: stdFoam.H:64
MPI_Op getOpCode(UPstream::opCodes id)
Lookup of opCodes enumeration as an MPI_Op.
static label warnComm
Debugging: warn for use of any communicator differing from warnComm.
Definition: UPstream.H:992
errorManip< error > abort(error &err)
Definition: errorManip.H:139
void initCommunicator(const label index)
Initialize bookkeeping for MPI communicator index.
Header for low-level interfaces between MPI and OpenFOAM. The detail interfaces are subject to change...
const direction noexcept
Definition: scalarImpl.H:255
void printDataTypes(bool all=false)
Debugging only: print data type names (all or just user-defined)
bool warnCommunicator(int comm) noexcept
True if warn communicator is active and not equal to given communicator.
dataTypes
Mapping of some fundamental and aggregate types to MPI data types.
Definition: UPstream.H:103
void deinitDataTypes()
Free any user data types.
DataTypeCountLookupTable dataTypesCount_
Fundamental count for each valid UPstream::dataTypes entry Indexed by UPstream::dataTypes enum...
MPI_Datatype getDataType(UPstream::dataTypes id)
Lookup of dataTypes enumeration as an MPI_Datatype.
bool checkDataTypes()
Debugging only: check if data type mappings are non-null.
bool all(const UList< bool > &bools)
True if all entries are &#39;true&#39; or if the set is empty.
Definition: BitOps.H:83
::Foam::direction rank(const expressions::valueTypeCode) noexcept
The vector-space rank associated with given valueTypeCode.
Definition: exprTraits.C:70
void push_request(MPI_Request request, UPstream::Request *req=nullptr)
Transcribe MPI_Request to UPstream::Request (does not affect the stack of outstanding requests) or el...
void checkOpCode(UPstream::opCodes id)
Fatal if opcode is not valid.
OpCodesLookupTable MPIopCodes_
MPI operation types, indexed by UPstream::opCodes enum.
bool broadcast_int64(int64_t &value, int comm)
Broadcast a single int64 value.
DataTypeLookupTable MPIdataTypes_
MPI data types corresponding to fundamental and OpenFOAM types. Indexed by UPstream::dataTypes enum...
Namespace for OpenFOAM.
std::string dataType_name(MPI_Datatype datatype)
Return MPI internal name for specified MPI_Datatype.
Foam::FixedList< int, 17 > DataTypeCountLookupTable