gatherScatter.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) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2019 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 Description
28  Gather data from all processors onto single processor according to some
29  communication schedule (usually linear-to-master or tree-to-master).
30  The gathered data will be a single value constructed from the values
31  on individual processors using a user-specified operator.
32 
33 \*---------------------------------------------------------------------------*/
34 
35 #include "UOPstream.H"
36 #include "OPstream.H"
37 #include "UIPstream.H"
38 #include "IPstream.H"
39 #include "contiguous.H"
40 
41 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
42 
43 namespace Foam
44 {
45 
46 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
47 
48 template<class T, class BinaryOp>
49 void Pstream::gather
50 (
51  const List<UPstream::commsStruct>& comms,
52  T& Value,
53  const BinaryOp& bop,
54  const int tag,
55  const label comm
56 )
57 {
58  if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
59  {
60  // Get my communication order
61  const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
62 
63  // Receive from my downstairs neighbours
64  forAll(myComm.below(), belowI)
65  {
66  T value;
67 
69  {
71  (
73  myComm.below()[belowI],
74  reinterpret_cast<char*>(&value),
75  sizeof(T),
76  tag,
77  comm
78  );
79  }
80  else
81  {
82  IPstream fromBelow
83  (
85  myComm.below()[belowI],
86  0,
87  tag,
88  comm
89  );
90  fromBelow >> value;
91  }
92 
93  Value = bop(Value, value);
94  }
95 
96  // Send up Value
97  if (myComm.above() != -1)
98  {
100  {
102  (
104  myComm.above(),
105  reinterpret_cast<const char*>(&Value),
106  sizeof(T),
107  tag,
108  comm
109  );
110  }
111  else
112  {
113  OPstream toAbove
114  (
116  myComm.above(),
117  0,
118  tag,
119  comm
120  );
121  toAbove << Value;
122  }
123  }
124  }
125 }
126 
127 
128 template<class T, class BinaryOp>
129 void Pstream::gather
130 (
131  T& Value,
132  const BinaryOp& bop,
133  const int tag,
134  const label comm
135 )
136 {
138  {
139  gather(UPstream::linearCommunication(comm), Value, bop, tag, comm);
140  }
141  else
142  {
143  gather(UPstream::treeCommunication(comm), Value, bop, tag, comm);
144  }
145 }
146 
147 
148 template<class T>
149 void Pstream::scatter
150 (
151  const List<UPstream::commsStruct>& comms,
152  T& Value,
153  const int tag,
154  const label comm
155 )
156 {
157  if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
158  {
159  // Get my communication order
160  const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
161 
162  // Receive from up
163  if (myComm.above() != -1)
164  {
166  {
168  (
170  myComm.above(),
171  reinterpret_cast<char*>(&Value),
172  sizeof(T),
173  tag,
174  comm
175  );
176  }
177  else
178  {
179  IPstream fromAbove
180  (
182  myComm.above(),
183  0,
184  tag,
185  comm
186  );
187  fromAbove >> Value;
188  }
189  }
190 
191  // Send to my downstairs neighbours. Note reverse order (compared to
192  // receiving). This is to make sure to send to the critical path
193  // (only when using a tree schedule!) first.
194  forAllReverse(myComm.below(), belowI)
195  {
197  {
199  (
201  myComm.below()[belowI],
202  reinterpret_cast<const char*>(&Value),
203  sizeof(T),
204  tag,
205  comm
206  );
207  }
208  else
209  {
210  OPstream toBelow
211  (
213  myComm.below()[belowI],
214  0,
215  tag,
216  comm
217  );
218  toBelow << Value;
219  }
220  }
221  }
222 }
223 
224 
225 template<class T>
226 void Pstream::scatter(T& Value, const int tag, const label comm)
227 {
229  {
230  scatter(UPstream::linearCommunication(comm), Value, tag, comm);
231  }
232  else
233  {
234  scatter(UPstream::treeCommunication(comm), Value, tag, comm);
235  }
236 }
237 
238 
239 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
240 
241 } // End namespace Foam
242 
243 // ************************************************************************* //
Foam::UPstream::linearCommunication
static const List< commsStruct > & linearCommunication(const label communicator=worldComm)
Communication schedule for linear all-to-master (proc 0)
Definition: UPstream.H:523
Foam::UOPstream::write
static bool write(const commsTypes commsType, const int toProcNo, const char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=UPstream::worldComm)
Write given buffer to given processor.
Definition: UOPwrite.C:36
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:53
OPstream.H
Foam::Pstream::scatter
static void scatter(const List< commsStruct > &comms, T &Value, const int tag, const label comm)
Scatter data. Distribute without modification. Reverse of gather.
Definition: gatherScatter.C:150
Foam::UPstream::commsStruct::below
const labelList & below() const noexcept
Definition: UPstream.H:135
Foam::UIPstream::read
static label read(const commsTypes commsType, const int fromProcNo, char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=UPstream::worldComm)
Read into given buffer from given processor.
Definition: UIPread.C:81
Foam::Pstream::gather
static void gather(const List< commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
Definition: gatherScatter.C:50
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
IPstream.H
Foam::T
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Definition: FieldFieldFunctions.C:58
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::UPstream::commsStruct
Structure for communicating between processors.
Definition: UPstream.H:83
Foam::UPstream::nProcsSimpleSum
static int nProcsSimpleSum
Definition: UPstream.H:278
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:463
UOPstream.H
Foam::UPstream::commsTypes::scheduled
contiguous.H
Foam::UPstream::parRun
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::UPstream::commsStruct::above
label above() const noexcept
Definition: UPstream.H:130
forAllReverse
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:309
Foam::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:53
Foam::UPstream::treeCommunication
static const List< commsStruct > & treeCommunication(const label communicator=worldComm)
Communication schedule for tree all-to-master (proc 0)
Definition: UPstream.H:532
UIPstream.H
Foam::UPstream::nProcs
static label nProcs(const label communicator=worldComm)
Number of processes in parallel run, and 1 for serial run.
Definition: UPstream.H:445
Foam::is_contiguous
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:75