UPstreamWrapping.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) 2012-2016 OpenFOAM Foundation
9  Copyright (C) 2022-2023 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 InNamespace
28  Foam::PstreamDetail
29 
30 Description
31  Functions to wrap MPI_Bcast, MPI_Allreduce, MPI_Iallreduce etc.
32 
33 SourceFiles
34  UPstreamWrapping.txx
35 
36 \*---------------------------------------------------------------------------*/
37 
38 #ifndef Foam_UPstreamWrapping_H
39 #define Foam_UPstreamWrapping_H
40 
41 #include "UPstream.H"
42 
43 // Include MPI without any C++ bindings
44 #ifndef MPICH_SKIP_MPICXX
45 #define MPICH_SKIP_MPICXX
46 #endif
47 #ifndef OMPI_SKIP_MPICXX
48 #define OMPI_SKIP_MPICXX
49 #endif
50 #include <mpi.h>
51 
52 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
53 
54 namespace Foam
55 {
56 namespace PstreamDetail
57 {
58 
59 // Helper for casting to MPI_Request
60 struct Request
61 {
62  // To pointer
63  template<typename Type = MPI_Request>
64  static typename std::enable_if<std::is_pointer<Type>::value, Type>::type
65  get(const UPstream::Request& req) noexcept
66  {
67  return reinterpret_cast<Type>(req.value());
68  }
69 
70  // To integer
71  template<typename Type = MPI_Request>
72  static typename std::enable_if<std::is_integral<Type>::value, Type>::type
73  get(const UPstream::Request& req) noexcept
74  {
75  return static_cast<Type>(req.value());
76  }
77 };
78 
79 
80 // MPI_Bcast, using root=0
81 template<class Type>
82 void broadcast0
83 (
84  Type* values,
85  int count,
86  MPI_Datatype datatype,
87  const label comm
88 );
89 
90 // MPI_Reduce, using root=0
91 template<class Type>
92 void reduce0
93 (
94  Type* values,
95  int count,
96  MPI_Datatype datatype,
97  MPI_Op optype,
98  const label comm
99 );
100 
101 // MPI_Allreduce or MPI_Iallreduce
102 template<class Type>
103 void allReduce
104 (
105  Type* values,
106  int count,
107  MPI_Datatype datatype,
108  MPI_Op optype,
109  const label comm, // Communicator
110  UPstream::Request* req = nullptr, // Non-null for non-blocking
111  label* requestID = nullptr // (alternative to UPstream::Request)
112 );
113 
114 
115 // MPI_Alltoall or MPI_Ialltoall with one element per rank
116 template<class Type>
117 void allToAll
118 (
119  const UList<Type>& sendData,
120  UList<Type>& recvData,
121  MPI_Datatype datatype,
122  const label comm, // Communicator
123  UPstream::Request* req = nullptr, // Non-null for non-blocking
124  label* requestID = nullptr // (alternative to UPstream::Request)
125 );
126 
127 
128 // MPI_Alltoallv or MPI_Ialltoallv
129 template<class Type>
130 void allToAllv
131 (
132  const Type* sendData,
133  const UList<int>& sendCounts,
134  const UList<int>& sendOffsets,
135 
136  Type* recvData,
137  const UList<int>& recvCounts,
138  const UList<int>& recvOffsets,
139 
140  MPI_Datatype datatype,
141  const label comm, // Communicator
142  UPstream::Request* req = nullptr, // Non-null for non-blocking
143  label* requestID = nullptr // (alternative to UPstream::Request)
144 );
145 
146 
147 // Non-blocking consensual integer (size) exchange
148 template<class Type>
150 (
151  const UList<Type>& sendData,
152  UList<Type>& recvData,
153  MPI_Datatype datatype,
154  const int tag, // Message tag
155  const label comm // Communicator
156 );
157 
158 
159 // Non-blocking consensual integer (size) exchange
160 template<class Type>
162 (
163  const Map<Type>& sendData,
164  Map<Type>& recvData,
165  MPI_Datatype datatype,
166  const int tag, // Message tag
167  const label comm // Communicator
168 );
169 
170 
171 // MPI_Gather or MPI_Igather
172 template<class Type>
173 void gather
174 (
175  const Type* sendData, // Local send value
176  Type* recvData, // On master: recv buffer. Ignored elsewhere
177  int count, // Per rank send/recv count. Globally consistent!
178  MPI_Datatype datatype, // The send/recv data type
179  const label comm, // Communicator
180  UPstream::Request* req = nullptr, // Non-null for non-blocking
181  label* requestID = nullptr // (alternative to UPstream::Request)
182 );
183 
184 
185 // MPI_Scatter or MPI_Iscatter
186 template<class Type>
187 void scatter
188 (
189  const Type* sendData, // On master: send buffer. Ignored elsewhere
190  Type* recvData, // Local recv value
191  int count, // Per rank send/recv count. Globally consistent!
192  MPI_Datatype datatype, // The send/recv data type
193  const label comm, // Communicator
194  UPstream::Request* req = nullptr, // Non-null for non-blocking
195  label* requestID = nullptr // (alternative to UPstream::Request)
196 );
197 
198 
199 // MPI_Gatherv or MPI_Igatherv
200 template<class Type>
201 void gatherv
202 (
203  const Type* sendData,
204  int sendCount, // Ignored on master if recvCounts[0] == 0
205 
206  Type* recvData, // Ignored on non-root rank
207  const UList<int>& recvCounts, // Ignored on non-root rank
208  const UList<int>& recvOffsets, // Ignored on non-root rank
209 
210  MPI_Datatype datatype, // The send/recv data type
211  const label comm, // Communicator
212  UPstream::Request* req = nullptr, // Non-null for non-blocking
213  label* requestID = nullptr // (alternative to UPstream::Request)
214 );
215 
216 
217 // MPI_Scatterv or MPI_Iscatterv
218 template<class Type>
219 void scatterv
220 (
221  const Type* sendData, // Ignored on non-root rank
222  const UList<int>& sendCounts, // Ignored on non-root rank
223  const UList<int>& sendOffsets, // Ignored on non-root rank
224 
225  Type* recvData,
226  int recvCount,
227 
228  MPI_Datatype datatype, // The send/recv data type
229  const label comm, // Communicator
230  UPstream::Request* req = nullptr, // Non-null for non-blocking
231  label* requestID = nullptr // (alternative to UPstream::Request)
232 );
233 
234 
235 // MPI_Allgather or MPI_Iallgather
236 template<class Type>
237 void allGather
238 (
239  Type* allData, // The send/recv data
240  int count, // The send/recv count per element
241 
242  MPI_Datatype datatype, // The send/recv data type
243  const label comm, // Communicator
244  UPstream::Request* req = nullptr, // Non-null for non-blocking
245  label* requestID = nullptr // (alternative to UPstream::Request)
246 );
247 
248 
249 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
250 
251 } // End namespace PstreamDetail
252 } // End namespace Foam
253 
254 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
255 
256 #include "UPstreamWrapping.txx"
257 
258 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
259 
260 #endif
261 
262 // ************************************************************************* //
void allGather(Type *allData, int count, MPI_Datatype datatype, const label comm, UPstream::Request *req=nullptr, label *requestID=nullptr)
void gatherv(const Type *sendData, int sendCount, Type *recvData, const UList< int > &recvCounts, const UList< int > &recvOffsets, MPI_Datatype datatype, const label comm, UPstream::Request *req=nullptr, label *requestID=nullptr)
void gather(const Type *sendData, Type *recvData, int count, MPI_Datatype datatype, const label comm, UPstream::Request *req=nullptr, label *requestID=nullptr)
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
void scatterv(const Type *sendData, const UList< int > &sendCounts, const UList< int > &sendOffsets, Type *recvData, int recvCount, MPI_Datatype datatype, const label comm, UPstream::Request *req=nullptr, label *requestID=nullptr)
An opaque wrapper for MPI_Request with a vendor-independent representation independent of any <mpi...
Definition: UPstream.H:1573
const direction noexcept
Definition: Scalar.H:258
void scatter(const Type *sendData, Type *recvData, int count, MPI_Datatype datatype, const label comm, UPstream::Request *req=nullptr, label *requestID=nullptr)
void allToAll(const UList< Type > &sendData, UList< Type > &recvData, MPI_Datatype datatype, const label comm, UPstream::Request *req=nullptr, label *requestID=nullptr)
void broadcast0(Type *values, int count, MPI_Datatype datatype, const label comm)
void allToAllConsensus(const UList< Type > &sendData, UList< Type > &recvData, MPI_Datatype datatype, const int tag, const label comm)
void reduce0(Type *values, int count, MPI_Datatype datatype, MPI_Op optype, const label comm)
void allReduce(Type *values, int count, MPI_Datatype datatype, MPI_Op optype, const label comm, UPstream::Request *req=nullptr, label *requestID=nullptr)
Namespace for OpenFOAM.
A HashTable to objects of type <T> with a label key.
void allToAllv(const Type *sendData, const UList< int > &sendCounts, const UList< int > &sendOffsets, Type *recvData, const UList< int > &recvCounts, const UList< int > &recvOffsets, MPI_Datatype datatype, const label comm, UPstream::Request *req=nullptr, label *requestID=nullptr)