PstreamGather.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-2022 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 "OPstream.H"
36 #include "IPstream.H"
37 #include "contiguous.H"
38 
39 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
40 
41 template<class T, class BinaryOp>
43 (
44  const List<UPstream::commsStruct>& comms,
45  T& value,
46  const BinaryOp& bop,
47  const int tag,
48  const label comm
49 )
50 {
51  if (UPstream::is_parallel(comm))
52  {
53  // My communication order
54  const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
55 
56  // Receive from my downstairs neighbours
57  for (const label belowID : myComm.below())
58  {
59  T received;
60 
62  {
64  (
66  belowID,
67  reinterpret_cast<char*>(&received),
68  sizeof(T),
69  tag,
70  comm
71  );
72  }
73  else
74  {
75  IPstream fromBelow
76  (
78  belowID,
79  0,
80  tag,
81  comm
82  );
83  fromBelow >> received;
84  }
85 
86  value = bop(value, received);
87  }
88 
89  // Send up value
90  if (myComm.above() != -1)
91  {
93  {
95  (
97  myComm.above(),
98  reinterpret_cast<const char*>(&value),
99  sizeof(T),
100  tag,
101  comm
102  );
103  }
104  else
105  {
106  OPstream toAbove
107  (
109  myComm.above(),
110  0,
111  tag,
112  comm
113  );
114  toAbove << value;
115  }
116  }
117  }
118 }
119 
120 
121 template<class T>
123 (
124  const List<UPstream::commsStruct>& comms,
125  T& value,
126  const int tag,
127  const label comm
128 )
129 {
130  #ifndef Foam_Pstream_scatter_nobroadcast
131  Pstream::broadcast(value, comm);
132  #else
133  if (UPstream::is_parallel(comm))
134  {
135  // My communication order
136  const commsStruct& myComm = comms[UPstream::myProcNo(comm)];
137 
138  // Receive from up
139  if (myComm.above() != -1)
140  {
141  if (is_contiguous<T>::value)
142  {
144  (
146  myComm.above(),
147  reinterpret_cast<char*>(&value),
148  sizeof(T),
149  tag,
150  comm
151  );
152  }
153  else
154  {
155  IPstream fromAbove
156  (
158  myComm.above(),
159  0,
160  tag,
161  comm
162  );
163  fromAbove >> value;
164  }
165  }
166 
167  // Send to my downstairs neighbours. Note reverse order (compared to
168  // receiving). This is to make sure to send to the critical path
169  // (only when using a tree schedule!) first.
170  forAllReverse(myComm.below(), belowI)
171  {
172  const label belowID = myComm.below()[belowI];
173 
174  if (is_contiguous<T>::value)
175  {
177  (
179  belowID,
180  reinterpret_cast<const char*>(&value),
181  sizeof(T),
182  tag,
183  comm
184  );
185  }
186  else
187  {
188  OPstream toBelow
189  (
191  belowID,
192  0,
193  tag,
194  comm
195  );
196  toBelow << value;
197  }
198  }
199  }
200  #endif
201 }
202 
203 
204 template<class T, class BinaryOp>
206 (
207  T& value,
208  const BinaryOp& bop,
209  const int tag,
210  const label comm
211 )
212 {
213  Pstream::gather(UPstream::whichCommunication(comm), value, bop, tag, comm);
214 }
215 
216 
217 template<class T>
218 void Foam::Pstream::scatter(T& value, const int tag, const label comm)
219 {
220  #ifndef Foam_Pstream_scatter_nobroadcast
221  Pstream::broadcast(value, comm);
222  #else
223  Pstream::scatter(UPstream::whichCommunication(comm), value, tag, comm);
224  #endif
225 }
226 
227 
228 // ************************************************************************* //
const labelList & below() const noexcept
The procIDs of the processors directly below.
Definition: UPstream.H:193
static label read(const UPstream::commsTypes commsType, const int fromProcNo, char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm, UPstream::Request *req=nullptr)
Read buffer contents from given processor.
Definition: UIPstreamRead.C:35
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
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 myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
label above() const noexcept
The procID of the processor directly above.
Definition: UPstream.H:188
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...
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
Input inter-processor communications stream.
Definition: IPstream.H:49
"scheduled" : (MPI_Send, MPI_Recv)
static bool is_parallel(const label communicator=worldComm)
True if parallel algorithm or exchange is required.
Definition: UPstream.H:1111
Structure for communicating between processors.
Definition: UPstream.H:104
Output inter-processor communications stream.
Definition: OPstream.H:49
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
const volScalarField & T
A template class to specify that a data type can be considered as being contiguous in memory...
Definition: contiguous.H:70
static bool write(const UPstream::commsTypes commsType, const int toProcNo, const char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm, UPstream::Request *req=nullptr, const UPstream::sendModes sendMode=UPstream::sendModes::normal)
Write buffer contents to given processor.
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:437
static void scatter(const List< commsStruct > &comms, T &value, const int tag, const label comm)
Broadcast data: Distribute without modification.