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-2024 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 linear/tree communication schedule
51 template<class T, class BinaryOp>
52 void reduce
53 (
54  T& value,
55  const BinaryOp& bop,
56  const int tag = UPstream::msgType(),
57  const label comm = UPstream::worldComm
58 )
59 {
60  if (UPstream::is_parallel(comm))
61  {
62  if (UPstream::warnComm >= 0 && comm != UPstream::warnComm)
63  {
64  Perr<< "** reducing:" << value << " with comm:" << comm << endl;
66  }
67  Pstream::gather(value, bop, tag, comm);
68  Pstream::broadcast(value, comm);
69  }
70 }
71 
72 
73 //- Reduce inplace (cf. MPI Allreduce)
74 //- multiple values (same size on all ranks!)
75 template<class T, class BinaryOp>
76 void reduce
77 (
78  T values[],
79  const int size,
80  const BinaryOp&,
81  const int tag,
82  const label comm
83 )
84 {
86 }
87 
88 //- Non-blocking reduce inplace (cf. MPI Iallreduce)
89 //- single value. Sets request.
90 template<class T, class BinaryOp>
91 void reduce
92 (
93  T& Value,
94  const BinaryOp&,
95  const int tag,
96  const label comm,
98 )
99 {
101 }
102 
103 //- Non-blocking reduce inplace (cf. MPI Iallreduce)
104 //- single value. Sets request.
105 template<class T, class BinaryOp>
106 void reduce
107 (
108  T& Value,
109  const BinaryOp&,
110  const int tag,
111  const label comm,
112  label& request
113 )
114 {
116 }
117 
118 //- Non-blocking reduce inplace (cf. MPI Iallreduce)
119 //- of multiple values (same size on all ranks!). Sets request.
120 template<class T, class BinaryOp>
121 void reduce
122 (
123  T values[],
124  const int size,
125  const BinaryOp&,
126  const int tag,
127  const label comm,
128  UPstream::Request& req
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,
144  label& request
145 )
146 {
148 }
149 
150 
151 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
152 
153 // Special reductions for bool
154 
155 //- Logical (and) inplace reduction. Uses UPstream::reduceAnd
156 void reduce
157 (
158  bool& value,
159  const andOp<bool>&,
160  const int tag = UPstream::msgType(),
161  const label comm = UPstream::worldComm
162 );
163 
164 //- Logical (or) inplace reduction. Uses UPstream::reduceOr
165 void reduce
166 (
167  bool& value,
168  const orOp<bool>&,
169  const int tag = UPstream::msgType(),
170  const label comm = UPstream::worldComm
171 );
172 
173 
174 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
175 
176 // Common reductions
177 
178 #undef Pstream_CommonReductions
179 #define Pstream_CommonReductions(Native) \
180  \
181  \
182 void reduce \
183 ( \
184  Native values[], \
185  const int size, \
186  const minOp<Native>&, \
187  const int tag = UPstream::msgType(), \
188  const label comm = UPstream::worldComm \
189 ); \
190  \
191  \
192 void reduce \
193 ( \
194  Native& value, \
195  const minOp<Native>&, \
196  const int tag = UPstream::msgType(), \
197  const label comm = UPstream::worldComm \
198 ); \
199  \
200  \
201 template<unsigned N> \
202 inline void reduce \
203 ( \
204  FixedList<Native, N>& values, \
205  const minOp<Native>&, \
206  const int tag = UPstream::msgType(), \
207  const label comm = UPstream::worldComm \
208 ) \
209 { \
210  reduce(values.data(), int(values.size()), minOp<Native>(), tag, comm); \
211 } \
212  \
213  \
214 void reduce \
215 ( \
216  Native values[], \
217  const int size, \
218  const maxOp<Native>&, \
219  const int tag, \
220  const label comm \
221 ); \
222  \
223  \
224 void reduce \
225 ( \
226  Native& value, \
227  const maxOp<Native>&, \
228  const int tag = UPstream::msgType(), \
229  const label comm = UPstream::worldComm \
230 ); \
231  \
232  \
233 template<unsigned N> \
234 inline void reduce \
235 ( \
236  FixedList<Native, N>& values, \
237  const maxOp<Native>&, \
238  const int tag = UPstream::msgType(), \
239  const label comm = UPstream::worldComm \
240 ) \
241 { \
242  reduce(values.data(), int(values.size()), maxOp<Native>(), tag, comm); \
243 } \
244  \
245  \
246 void reduce \
247 ( \
248  Native values[], \
249  const int size, \
250  const sumOp<Native>&, \
251  const int tag, \
252  const label comm \
253 ); \
254  \
255  \
256 void reduce \
257 ( \
258  Native& value, \
259  const sumOp<Native>&, \
260  const int tag = UPstream::msgType(), \
261  const label comm = UPstream::worldComm \
262 ); \
263  \
264  \
265 template<unsigned N> \
266 inline void reduce \
267 ( \
268  FixedList<Native, N>& values, \
269  const sumOp<Native>&, \
270  const int tag = UPstream::msgType(), \
271  const label comm = UPstream::worldComm \
272 ) \
273 { \
274  reduce(values.data(), int(values.size()), sumOp<Native>(), tag, comm); \
275 }
276 
277 
278 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
279 
280 // Floating-point reductions
281 
282 #undef Pstream_FloatReductions
283 #define Pstream_FloatReductions(Native) \
284  \
285 Pstream_CommonReductions(Native); \
286  \
287  \
288 void reduce \
289 ( \
290  Native values[], \
291  const int size, \
292  const sumOp<Native>&, \
293  const int tag, \
294  const label comm, \
295  UPstream::Request& req \
296 ); \
297  \
298  \
299  \
300 void reduce \
301 ( \
302  Native values[], \
303  const int size, \
304  const sumOp<Native>&, \
305  const int tag, \
306  const label comm, \
307  label& requestID \
308 ); \
309  \
310  \
311 void reduce \
312 ( \
313  Native& value, \
314  const sumOp<Native>&, \
315  const int tag, \
316  const label comm, \
317  UPstream::Request& req \
318 ); \
319  \
320  \
321  \
322 void reduce \
323 ( \
324  Native& value, \
325  const sumOp<Native>&, \
326  const int tag, \
327  const label comm, \
328  label& requestID \
329 );
330 
331 
332 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
333 
334 // Bitwise reductions
335 
336 #undef Pstream_BitwiseReductions
337 #define Pstream_BitwiseReductions(Native) \
338  \
339  \
340 void reduce \
341 ( \
342  Native values[], \
343  const int size, \
344  const bitOrOp<Native>&, \
345  const int tag = UPstream::msgType(), \
346  const label comm = UPstream::worldComm \
347 ); \
348  \
349  \
350 void reduce \
351 ( \
352  Native& value, \
353  const bitOrOp<Native>&, \
354  const int tag = UPstream::msgType(), \
355  const label comm = UPstream::worldComm \
356 );
357 
358 
359 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
360 
361 Pstream_CommonReductions(int32_t);
362 Pstream_CommonReductions(int64_t);
363 Pstream_CommonReductions(uint32_t);
364 Pstream_CommonReductions(uint64_t);
365 
368 
369 Pstream_BitwiseReductions(unsigned char);
370 Pstream_BitwiseReductions(unsigned int);
372 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
374 #undef Pstream_CommonReductions
375 #undef Pstream_FloatReductions
376 #undef Pstream_BitwiseReductions
378 
379 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
380 
381 //- Reduce inplace (cf. MPI Allreduce)
382 //- the sum of both value and count (for averaging)
383 template<class T>
384 void sumReduce
385 (
386  T& value,
387  label& count,
388  const int tag = UPstream::msgType(),
389  const label comm = UPstream::worldComm
390 )
391 {
392  if (UPstream::is_parallel(comm))
393  {
394  Foam::reduce(value, sumOp<T>(), tag, comm);
395  Foam::reduce(count, sumOp<label>(), tag, comm);
396  }
397 }
398 
399 
400 // Floating-point sum-reduce
401 
402 #undef Pstream_SumReduce
403 #define Pstream_SumReduce(Native) \
404  \
405  \
406 void sumReduce \
407 ( \
408  Native& value, \
409  label& count, \
410  const int tag = UPstream::msgType(), \
411  const label comm = UPstream::worldComm \
412 );
413 
414 
416 Pstream_SumReduce(double);
417 
418 #undef Pstream_SumReduce
419 
420 
421 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
422 
423 // Convenience wrappers - defined after all specialisations are known
424 
425 //- Perform reduction on a copy, using specified binary operation
426 // \return the resulting value
427 template<class T, class BinaryOp>
429 (
430  const T& value,
431  const BinaryOp& bop,
432  const int tag = UPstream::msgType(),
433  const label comm = UPstream::worldComm
434 )
435 {
436  T work(value);
437  Foam::reduce(work, bop, tag, comm);
438  return work;
439 }
440 
441 
442 //- Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd
443 // \return the resulting value
444 inline bool returnReduceAnd
445 (
446  const bool value,
447  const label comm = UPstream::worldComm
448 )
449 {
450  bool work(value);
451  UPstream::reduceAnd(work, comm);
452  return work;
453 }
454 
455 
456 //- Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr
457 // \return the resulting value
458 inline bool returnReduceOr
459 (
460  const bool value,
461  const label comm = UPstream::worldComm
462 )
463 {
464  bool work(value);
465  UPstream::reduceOr(work, comm);
466  return work;
467 }
468 
469 
470 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
471 
472 } // End namespace Foam
473 
474 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
475 
476 #endif
477 
478 // ************************************************************************* //
prefixOSstream Perr
OSstream wrapped stderr (std::cerr) with parallel prefix.
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 int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1252
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition: UPstream.H:421
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)
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
static void gather(T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Gather (reduce) data, applying bop to combine value from different processors. The basis for Foam::re...
Definition: PstreamGather.C:37
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 without any <mpi...
Definition: UPstream.H:1741
static bool is_parallel(const label communicator=worldComm)
True if parallel algorithm or exchange is required.
Definition: UPstream.H:1123
static label warnComm
Debugging: warn for use of any communicator differing from warnComm.
Definition: UPstream.H:426
#define Pstream_CommonReductions(Native)
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
#define Pstream_SumReduce(Native)
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:696
void reduce(T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) using linear/tree communication schedule.
Namespace for OpenFOAM.