allReduceTemplates.C
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-2015 OpenFOAM Foundation
9  Copyright (C) 2019-2020 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 \*---------------------------------------------------------------------------*/
28 
29 #include "allReduce.H"
30 #include "profilingPstream.H"
31 
32 // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
33 
34 template<class Type, class BinaryOp>
35 void Foam::allReduce
36 (
37  Type& Value,
38  int MPICount,
39  MPI_Datatype MPIType,
40  MPI_Op MPIOp,
41  const BinaryOp& bop,
42  const int tag,
43  const label communicator
44 )
45 {
46  if (!UPstream::parRun())
47  {
48  return;
49  }
50 
51  profilingPstream::beginTiming();
52 
53  if (UPstream::nProcs(communicator) <= UPstream::nProcsSimpleSum)
54  {
55  if (UPstream::master(communicator))
56  {
57  for (const int proci : UPstream::subProcs(communicator))
58  {
59  Type value;
60 
61  if
62  (
63  MPI_Recv
64  (
65  &value,
66  MPICount,
67  MPIType,
68  proci,
69  tag,
71  MPI_STATUS_IGNORE
72  )
73  )
74  {
76  << "MPI_Recv failed"
78  }
79 
80  Value = bop(Value, value);
81  }
82  }
83  else
84  {
85  if
86  (
87  MPI_Send
88  (
89  &Value,
90  MPICount,
91  MPIType,
92  UPstream::masterNo(),
93  tag,
95  )
96  )
97  {
99  << "MPI_Send failed"
101  }
102  }
103 
104 
105  if (UPstream::master(communicator))
106  {
107  for (const int proci : UPstream::subProcs(communicator))
108  {
109  if
110  (
111  MPI_Send
112  (
113  &Value,
114  MPICount,
115  MPIType,
116  proci,
117  tag,
119  )
120  )
121  {
123  << "MPI_Send failed"
125  }
126  }
127  }
128  else
129  {
130  if
131  (
132  MPI_Recv
133  (
134  &Value,
135  MPICount,
136  MPIType,
137  UPstream::masterNo(),
138  tag,
139  PstreamGlobals::MPICommunicators_[communicator],
140  MPI_STATUS_IGNORE
141  )
142  )
143  {
145  << "MPI_Recv failed"
147  }
148  }
149  }
150  else
151  {
152  Type sum;
153  MPI_Allreduce
154  (
155  &Value,
156  &sum,
157  MPICount,
158  MPIType,
159  MPIOp,
161  );
162  Value = sum;
163  }
164 
165  profilingPstream::addReduceTime();
166 }
167 
168 
169 template<class Type>
170 void Foam::iallReduce
171 (
172  void* recvBuf,
173  int MPICount,
174  MPI_Datatype MPIType,
175  MPI_Op MPIOp,
176  const label communicator,
177  label& requestID
178 )
179 {
180  if (!UPstream::parRun())
181  {
182  return;
183  }
184 
185  if (UPstream::warnComm != -1 && communicator != UPstream::warnComm)
186  {
187  Pout<< "** non-blocking reducing:"
188  << UList<Type>(static_cast<Type*>(recvBuf), MPICount)
189  << " with comm:" << communicator
190  << " warnComm:" << UPstream::warnComm << endl;
191  error::printStack(Pout);
192  }
193 
194  profilingPstream::beginTiming();
195 
196 #if defined(MPI_VERSION) && (MPI_VERSION >= 3)
197  MPI_Request request;
198  if
199  (
200  MPI_Iallreduce
201  (
202  MPI_IN_PLACE,
203  recvBuf,
204  MPICount,
205  MPIType,
206  MPIOp,
207  PstreamGlobals::MPICommunicators_[communicator],
208  &request
209  )
210  )
211  {
213  << "MPI_Iallreduce failed for "
214  << UList<Type>(static_cast<Type*>(recvBuf), MPICount)
216  }
217 
219  {
221  PstreamGlobals::outstandingRequests_[requestID] = request;
222  }
223  else
224  {
225  requestID = PstreamGlobals::outstandingRequests_.size();
226  PstreamGlobals::outstandingRequests_.append(request);
227  }
228 
229  if (UPstream::debug)
230  {
231  Pout<< "UPstream::allocateRequest for non-blocking reduce"
232  << " : request:" << requestID << endl;
233  }
234 #else
235  // Non-blocking not yet implemented in mpi
236  if
237  (
238  MPI_Allreduce
239  (
240  MPI_IN_PLACE,
241  recvBuf,
242  MPICount,
243  MPIType,
244  MPIOp,
246  )
247  )
248  {
250  << "MPI_Allreduce failed for "
251  << UList<Type>(static_cast<Type*>(recvBuf), MPICount)
253  }
254  requestID = -1;
255 #endif
256 
257  profilingPstream::addReduceTime();
258 }
259 
260 
261 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::PstreamGlobals::freedRequests_
DynamicList< label > freedRequests_
Definition: PstreamGlobals.C:33
Foam::PstreamGlobals::outstandingRequests_
DynamicList< MPI_Request > outstandingRequests_
Outstanding non-blocking operations.
Definition: PstreamGlobals.C:32
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::iallReduce
void iallReduce(void *Value, int count, MPI_Datatype MPIType, MPI_Op op, const label communicator, label &requestID)
Definition: allReduceTemplates.C:171
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::PstreamGlobals::MPICommunicators_
DynamicList< MPI_Comm > MPICommunicators_
Definition: PstreamGlobals.C:39
Foam::allReduce
void allReduce(Type &Value, int count, MPI_Datatype MPIType, MPI_Op op, const BinaryOp &bop, const int tag, const label communicator)
Definition: allReduceTemplates.C:36
Foam::FatalError
error FatalError
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
allReduce.H
Various functions to wrap MPI_Allreduce.
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::UList< Type >
Foam::sum
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
Definition: DimensionedFieldFunctions.C:327
Foam::DynamicList::remove
T remove()
Remove and return the last element. Fatal on an empty list.
Definition: DynamicListI.H:704
profilingPstream.H