PstreamReduceOps.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2016-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
29 
30 Description
31  Inter-processor communication reduction functions.
32 
33 \*---------------------------------------------------------------------------*/
34 
35 #ifndef Foam_PstreamReduceOps_H
36 #define Foam_PstreamReduceOps_H
37 
38 #include "Pstream.H"
39 #include "FixedList.H"
40 #include "ops.H"
41 
42 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
43 
44 namespace Foam
45 {
46 
47 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
48 
49 //- Reduce inplace (cf. MPI Allreduce)
50 //- using specified communication schedule.
51 template<class T, class BinaryOp>
52 void reduce
53 (
54  const List<UPstream::commsStruct>& comms,
55  T& value,
56  const BinaryOp& bop,
57  const int tag,
58  const label comm
59 )
60 {
61  if (UPstream::warnComm >= 0 && comm != UPstream::warnComm)
62  {
63  Pout<< "** reducing:" << value << " with comm:" << comm << endl;
65  }
66  Pstream::gather(comms, value, bop, tag, comm);
67  Pstream::broadcast(value, comm);
68 }
69 
70 
71 //- Reduce inplace (cf. MPI Allreduce)
72 //- using linear/tree communication schedule
73 template<class T, class BinaryOp>
74 void reduce
75 (
76  T& value,
77  const BinaryOp& bop,
78  const int tag = UPstream::msgType(),
79  const label comm = UPstream::worldComm
80 )
81 {
82  if (UPstream::is_parallel(comm))
83  {
84  Foam::reduce(UPstream::whichCommunication(comm), value, bop, tag, comm);
85  }
86 }
87 
88 
89 //- Reduce inplace (cf. MPI Allreduce)
90 //- multiple values (same size on all ranks!)
91 template<class T, class BinaryOp>
92 void reduce
93 (
94  T values[],
95  const int size,
96  const BinaryOp&,
97  const int tag,
98  const label comm
99 )
100 {
102 }
103 
104 //- Non-blocking reduce inplace (cf. MPI Iallreduce)
105 //- single value. Sets request.
106 template<class T, class BinaryOp>
107 void reduce
108 (
109  T& Value,
110  const BinaryOp&,
111  const int tag,
112  const label comm,
113  UPstream::Request& req
114 )
115 {
117 }
118 
119 //- Non-blocking reduce inplace (cf. MPI Iallreduce)
120 //- single value. Sets request.
121 template<class T, class BinaryOp>
122 void reduce
123 (
124  T& Value,
125  const BinaryOp&,
126  const int tag,
127  const label comm,
128  label& request
129 )
130 {
132 }
133 
134 //- Non-blocking reduce inplace (cf. MPI Iallreduce)
135 //- of multiple values (same size on all ranks!). Sets request.
136 template<class T, class BinaryOp>
137 void reduce
138 (
139  T values[],
140  const int size,
141  const BinaryOp&,
142  const int tag,
143  const label comm,
145 )
146 {
148 }
149 
150 //- Non-blocking reduce inplace (cf. MPI Iallreduce)
151 //- of multiple values (same size on all ranks!). Sets request.
152 template<class T, class BinaryOp>
153 void reduce
154 (
155  T values[],
156  const int size,
157  const BinaryOp&,
158  const int tag,
159  const label comm,
160  label& request
161 )
162 {
164 }
165 
166 
167 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
168 
169 // Special reductions for bool
170 
171 //- Logical (and) inplace reduction. Uses UPstream::reduceAnd
172 void reduce
173 (
174  bool& value,
175  const andOp<bool>&,
176  const int tag = UPstream::msgType(),
177  const label comm = UPstream::worldComm
178 );
179 
180 //- Logical (or) inplace reduction. Uses UPstream::reduceOr
181 void reduce
182 (
183  bool& value,
184  const orOp<bool>&,
185  const int tag = UPstream::msgType(),
186  const label comm = UPstream::worldComm
187 );
188 
189 
190 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
191 
192 // Common reductions
193 
194 #undef Pstream_CommonReductions
195 #define Pstream_CommonReductions(Native) \
196  \
197  \
198 void reduce \
199 ( \
200  Native values[], \
201  const int size, \
202  const minOp<Native>&, \
203  const int tag = UPstream::msgType(), \
204  const label comm = UPstream::worldComm \
205 ); \
206  \
207  \
208 void reduce \
209 ( \
210  Native& value, \
211  const minOp<Native>&, \
212  const int tag = UPstream::msgType(), \
213  const label comm = UPstream::worldComm \
214 ); \
215  \
216  \
217 template<unsigned N> \
218 inline void reduce \
219 ( \
220  FixedList<Native, N>& values, \
221  const minOp<Native>&, \
222  const int tag = UPstream::msgType(), \
223  const label comm = UPstream::worldComm \
224 ) \
225 { \
226  reduce(values.data(), int(values.size()), minOp<Native>(), tag, comm); \
227 } \
228  \
229  \
230 void reduce \
231 ( \
232  Native values[], \
233  const int size, \
234  const maxOp<Native>&, \
235  const int tag, \
236  const label comm \
237 ); \
238  \
239  \
240 void reduce \
241 ( \
242  Native& value, \
243  const maxOp<Native>&, \
244  const int tag = UPstream::msgType(), \
245  const label comm = UPstream::worldComm \
246 ); \
247  \
248  \
249 template<unsigned N> \
250 inline void reduce \
251 ( \
252  FixedList<Native, N>& values, \
253  const maxOp<Native>&, \
254  const int tag = UPstream::msgType(), \
255  const label comm = UPstream::worldComm \
256 ) \
257 { \
258  reduce(values.data(), int(values.size()), maxOp<Native>(), tag, comm); \
259 } \
260  \
261  \
262 void reduce \
263 ( \
264  Native values[], \
265  const int size, \
266  const sumOp<Native>&, \
267  const int tag, \
268  const label comm \
269 ); \
270  \
271  \
272 void reduce \
273 ( \
274  Native& value, \
275  const sumOp<Native>&, \
276  const int tag = UPstream::msgType(), \
277  const label comm = UPstream::worldComm \
278 ); \
279  \
280  \
281 template<unsigned N> \
282 inline void reduce \
283 ( \
284  FixedList<Native, N>& values, \
285  const sumOp<Native>&, \
286  const int tag = UPstream::msgType(), \
287  const label comm = UPstream::worldComm \
288 ) \
289 { \
290  reduce(values.data(), int(values.size()), sumOp<Native>(), tag, comm); \
291 }
292 
293 
294 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
295 
296 // Floating-point reductions
297 
298 #undef Pstream_FloatReductions
299 #define Pstream_FloatReductions(Native) \
300  \
301 Pstream_CommonReductions(Native); \
302  \
303  \
304 void reduce \
305 ( \
306  Native values[], \
307  const int size, \
308  const sumOp<Native>&, \
309  const int tag, \
310  const label comm, \
311  UPstream::Request& req \
312 ); \
313  \
314  \
315  \
316 void reduce \
317 ( \
318  Native values[], \
319  const int size, \
320  const sumOp<Native>&, \
321  const int tag, \
322  const label comm, \
323  label& requestID \
324 ); \
325  \
326  \
327 void reduce \
328 ( \
329  Native& value, \
330  const sumOp<Native>&, \
331  const int tag, \
332  const label comm, \
333  UPstream::Request& req \
334 ); \
335  \
336  \
337  \
338 void reduce \
339 ( \
340  Native& value, \
341  const sumOp<Native>&, \
342  const int tag, \
343  const label comm, \
344  label& requestID \
345 );
346 
347 
348 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
349 
350 // Bitwise reductions
351 
352 #undef Pstream_BitwiseReductions
353 #define Pstream_BitwiseReductions(Native) \
354  \
355  \
356 void reduce \
357 ( \
358  Native values[], \
359  const int size, \
360  const bitOrOp<Native>&, \
361  const int tag = UPstream::msgType(), \
362  const label comm = UPstream::worldComm \
363 ); \
364  \
365  \
366 void reduce \
367 ( \
368  Native& value, \
369  const bitOrOp<Native>&, \
370  const int tag = UPstream::msgType(), \
371  const label comm = UPstream::worldComm \
372 );
373 
374 
375 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
376 
377 Pstream_CommonReductions(int32_t);
378 Pstream_CommonReductions(int64_t);
379 Pstream_CommonReductions(uint32_t);
380 Pstream_CommonReductions(uint64_t);
381 
384 
385 Pstream_BitwiseReductions(unsigned char);
386 Pstream_BitwiseReductions(unsigned int);
387 
388 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
390 #undef Pstream_CommonReductions
391 #undef Pstream_FloatReductions
392 #undef Pstream_BitwiseReductions
393 
395 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
396 
397 //- Reduce inplace (cf. MPI Allreduce)
398 //- the sum of both value and count (for averaging)
399 template<class T>
400 void sumReduce
401 (
402  T& value,
403  label& count,
404  const int tag = UPstream::msgType(),
405  const label comm = UPstream::worldComm
406 )
407 {
408  if (UPstream::is_parallel(comm))
409  {
410  Foam::reduce(value, sumOp<T>(), tag, comm);
411  Foam::reduce(count, sumOp<label>(), tag, comm);
412  }
413 }
414 
416 // Floating-point sum-reduce
417 
418 #undef Pstream_SumReduce
419 #define Pstream_SumReduce(Native) \
420  \
421  \
422 void sumReduce \
423 ( \
424  Native& value, \
425  label& count, \
426  const int tag = UPstream::msgType(), \
427  const label comm = UPstream::worldComm \
428 );
429 
430 
431 Pstream_SumReduce(float);
432 Pstream_SumReduce(double);
434 #undef Pstream_SumReduce
435 
436 
437 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
438 
439 // Convenience wrappers for some reduction operations
440 // - defined after all specialisations are known
441 
442 //- Perform reduction on a copy, using specified binary operation
443 // \return the resulting value
444 template<class T, class BinaryOp>
446 (
447  const T& value,
448  const BinaryOp& bop,
449  const int tag = UPstream::msgType(),
450  const label comm = UPstream::worldComm
451 )
452 {
453  T work(value);
454  Foam::reduce(work, bop, tag, comm);
455  return work;
456 }
457 
458 
459 //- Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd
460 // \return the resulting value
461 inline bool returnReduceAnd
462 (
463  const bool value,
464  const label comm = UPstream::worldComm
465 )
466 {
467  bool work(value);
468  UPstream::reduceAnd(work, comm);
469  return work;
470 }
471 
472 
473 //- Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr
474 // \return the resulting value
475 inline bool returnReduceOr
476 (
477  const bool value,
478  const label comm = UPstream::worldComm
479 )
480 {
481  bool work(value);
482  UPstream::reduceOr(work, comm);
483  return work;
484 }
485 
486 
487 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
488 
489 } // End namespace Foam
490 
491 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
492 
493 #endif
494 
495 // ************************************************************************* //
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:56
void sumReduce(T &value, label &count, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) the sum of both value and count (for averaging) ...
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
Various functors for unary and binary operations. Can be used for parallel combine-reduce operations ...
static void reduceOr(bool &value, const label communicator=worldComm)
Logical (or) reduction (MPI_AllReduce)
static const List< commsStruct > & whichCommunication(const label communicator=worldComm)
Communication schedule for linear/tree all-to-master (proc 0). Chooses based on the value of UPstream...
Definition: UPstream.H:1213
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1229
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition: UPstream.H:409
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
static void broadcast(Type &value, const label comm=UPstream::worldComm)
Broadcast content (contiguous or non-contiguous) to all communicator ranks. Does nothing in non-paral...
#define Pstream_FloatReductions(Native)
static void gather(const List< commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Gather (reduce) data, appyling bop to combine value from different processors. The basis for Foam::re...
Definition: PstreamGather.C:37
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Definition: HashOps.H:164
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
bool returnReduceAnd(const bool value, const label comm=UPstream::worldComm)
Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd.
static void reduceAnd(bool &value, const label communicator=worldComm)
Logical (and) reduction (MPI_AllReduce)
#define Pstream_BitwiseReductions(Native)
An opaque wrapper for MPI_Request with a vendor-independent representation independent of any <mpi...
Definition: UPstream.H:1573
static bool is_parallel(const label communicator=worldComm)
True if parallel algorithm or exchange is required.
Definition: UPstream.H:1111
static label warnComm
Debugging: warn for use of any communicator differing from warnComm.
Definition: UPstream.H:414
#define Pstream_CommonReductions(Native)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
#define Pstream_SumReduce(Native)
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
static void printStack(Ostream &os, int size=-1)
Helper function to print a stack, with optional upper limit.
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:686
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Namespace for OpenFOAM.