allReduceTemplates.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2012-2018 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "allReduce.H"
27 
28 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
29 
30 template<class Type, class BinaryOp>
31 void Foam::allReduce
32 (
33  Type& Value,
34  int MPICount,
35  MPI_Datatype MPIType,
36  MPI_Op MPIOp,
37  const BinaryOp& bop,
38  const int tag,
39  const label communicator
40 )
41 {
42  if (!UPstream::parRun())
43  {
44  return;
45  }
46 
47  if (UPstream::nProcs(communicator) <= UPstream::nProcsSimpleSum)
48  {
49  if (UPstream::master(communicator))
50  {
51  for
52  (
53  int slave=UPstream::firstSlave();
54  slave<=UPstream::lastSlave(communicator);
55  slave++
56  )
57  {
58  Type value;
59 
60  if
61  (
62  MPI_Recv
63  (
64  &value,
65  MPICount,
66  MPIType,
67  slave, // UPstream::procID(slave),
68  tag,
70  MPI_STATUS_IGNORE
71  )
72  )
73  {
75  << "MPI_Recv failed"
77  }
78 
79  Value = bop(Value, value);
80  }
81  }
82  else
83  {
84  if
85  (
86  MPI_Send
87  (
88  &Value,
89  MPICount,
90  MPIType,
91  UPstream::masterNo(),//UPstream::procID(masterNo()),
92  tag,
94  )
95  )
96  {
98  << "MPI_Send failed"
100  }
101  }
102 
103 
104  if (UPstream::master(communicator))
105  {
106  for
107  (
108  int slave=UPstream::firstSlave();
109  slave<=UPstream::lastSlave(communicator);
110  slave++
111  )
112  {
113  if
114  (
115  MPI_Send
116  (
117  &Value,
118  MPICount,
119  MPIType,
120  slave, // UPstream::procID(slave),
121  tag,
123  )
124  )
125  {
127  << "MPI_Send failed"
129  }
130  }
131  }
132  else
133  {
134  if
135  (
136  MPI_Recv
137  (
138  &Value,
139  MPICount,
140  MPIType,
141  UPstream::masterNo(),//UPstream::procID(masterNo()),
142  tag,
143  PstreamGlobals::MPICommunicators_[communicator],
144  MPI_STATUS_IGNORE
145  )
146  )
147  {
149  << "MPI_Recv failed"
151  }
152  }
153  }
154  else
155  {
156  Type sum;
157  MPI_Allreduce
158  (
159  &Value,
160  &sum,
161  MPICount,
162  MPIType,
163  MPIOp,
165  );
166  Value = sum;
167  }
168 }
169 
170 
171 // ************************************************************************* //
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
Various functions to wrap MPI_Allreduce.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
errorManip< error > abort(error &err)
Definition: errorManip.H:131
DynamicList< MPI_Comm > MPICommunicators_
void allReduce(Type &Value, int count, MPI_Datatype MPIType, MPI_Op op, const BinaryOp &bop, const int tag, const label communicator)