1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
28 Inter-processor communications stream
35 combineGatherScatter.C
38 \*---------------------------------------------------------------------------*/
43 #include "labelList.H"
44 #include "DynamicList.H"
45 #include "HashTable.H"
46 #include "foamString.H"
47 #include "NamedEnum.H"
48 #include "optimisationSwitch.H"
50 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
55 /*---------------------------------------------------------------------------*\
56 Class Pstream Declaration
57 \*---------------------------------------------------------------------------*/
64 //- Types of communications
72 static const NamedEnum<commsTypes, 3> commsTypeNames;
74 //- Structure for communicating between processors
79 //- procID of above processor
82 //- procIDs of processors directly below me
85 //- procIDs of all processors below (so not just directly below)
88 //- procIDs of all processors not below. (inverse set of allBelow_
89 // and minus myProcNo)
90 labelList allNotBelow_;
100 //- Construct from components
109 //- Construct from components; construct allNotBelow_
113 const label myProcID,
129 const labelList& below() const
134 const labelList& allBelow() const
139 const labelList& allNotBelow() const
147 bool operator==(const commsStruct&) const;
149 bool operator!=(const commsStruct&) const;
154 friend Ostream& operator<<(Ostream&, const commsStruct&);
162 static int myProcNo_;
165 static List<int> procIDs_;
166 static const int msgType_;
168 static List<commsStruct> linearCommunication_;
169 static List<commsStruct> treeCommunication_;
172 // Private member functions
174 //- Set data for parallel running
175 static void setParRun();
177 //- Calculate linear communication schedule
178 static void calcLinearComm(const label nProcs);
180 //- Calculate tree communication schedule
181 static void calcTreeComm(const label nProcs);
183 //- Helper function for tree communication schedule determination
184 // Collects all processorIDs below a processor
185 static void collectReceives
188 const List<DynamicList<label> >& receives,
189 DynamicList<label>& allReceives
192 //- Initialize all communication schedules. Callback from
194 static void initCommunicationSchedule();
201 //- Communications type of this stream
202 commsTypes commsType_;
207 //- Current buffer read/write location
211 // Protected member functions
213 //- Increase the size of the transfer buffer
214 inline void enlargeBuffer(size_t count);
219 // Declare name of the class and its debug switch
220 ClassName("Pstream");
225 //- Should compact transfer be used in which floats replace doubles
226 // reducing the bandwidth requirement at the expense of some loss
228 static const debug::optimisationSwitch floatTransfer;
230 //- Number of processors at which the sum algorithm changes from linear
232 static const debug::optimisationSwitch nProcsSimpleSum;
234 //- Default commsType
235 static const debug::optimisationSwitch defaultCommsType;
240 //- Construct given optional buffer size
243 const commsTypes commsType,
244 const label bufSize = 0
247 commsType_(commsType),
252 buf_.setSize(bufSize + 2*sizeof(scalar) + 1);
259 //- Add the valid option this type of communications library
260 // adds/requires on the command line
261 static void addValidParOptions(HashTable<string>& validParOptions);
263 //- Initialisation function called from main
264 // Spawns slave processes and initialises inter-communication
265 static bool init(int& argc, char**& argv);
267 //- Is this a parallel run?
273 //- Number of processes in parallel run
274 static label nProcs()
276 return procIDs_.size();
279 //- Am I the master process
282 return myProcNo_ == masterNo();
285 //- Process index of the master
286 static int masterNo()
291 //- Number of this process (starting from masterNo() = 0)
292 static int myProcNo()
298 static const List<int>& procIDs()
303 //- Process ID of given process index
304 static int procID(int procNo)
306 return procIDs_[procNo];
309 //- Process index of first slave
310 static int firstSlave()
315 //- Process index of last slave
316 static int lastSlave()
321 //- Communication schedule for linear all-to-master (proc 0)
322 static const List<commsStruct>& linearCommunication()
324 return linearCommunication_;
327 //- Communication schedule for tree all-to-master (proc 0)
328 static const List<commsStruct>& treeCommunication()
330 return treeCommunication_;
333 //- Message tag of standard messages
339 //- Get the communications type of the stream
340 commsTypes commsType() const
345 //- Set the communications type of the stream
346 commsTypes commsType(const commsTypes ct)
348 commsTypes oldCommsType = commsType_;
354 static void exit(int errnum = 1);
360 // Gather and scatter
362 //- Gather data. Apply bop to combine Value
363 // from different processors
364 template <class T, class BinaryOp>
367 const List<commsStruct>& comms,
372 //- Like above but switches between linear/tree communication
373 template <class T, class BinaryOp>
374 static void gather(T& Value, const BinaryOp& bop);
376 //- Scatter data. Distribute without modification.
379 static void scatter(const List<commsStruct>& comms, T& Value);
381 //- Like above but switches between linear/tree communication
383 static void scatter(T& Value);
386 // Combine variants. Inplace combine values from processors.
387 // (Uses construct from Istream instead of <<)
389 template <class T, class CombineOp>
390 static void combineGather
392 const List<commsStruct>& comms,
397 //- Like above but switches between linear/tree communication
398 template <class T, class CombineOp>
399 static void combineGather(T& Value, const CombineOp& cop);
401 //- Scatter data. Reverse of combineGather
403 static void combineScatter
405 const List<commsStruct>& comms,
409 //- Like above but switches between linear/tree communication
411 static void combineScatter(T& Value);
413 // Combine variants working on whole List at a time.
415 template <class T, class CombineOp>
416 static void listCombineGather
418 const List<commsStruct>& comms,
423 //- Like above but switches between linear/tree communication
424 template <class T, class CombineOp>
425 static void listCombineGather
431 //- Scatter data. Reverse of combineGather
433 static void listCombineScatter
435 const List<commsStruct>& comms,
439 //- Like above but switches between linear/tree communication
441 static void listCombineScatter(List<T>& Value);
443 // Combine variants working on whole map at a time. Container needs to
444 // have iterators and find() defined.
446 template <class Container, class CombineOp>
447 static void mapCombineGather
449 const List<commsStruct>& comms,
454 //- Like above but switches between linear/tree communication
455 template <class Container, class CombineOp>
456 static void mapCombineGather
462 //- Scatter data. Reverse of combineGather
463 template <class Container>
464 static void mapCombineScatter
466 const List<commsStruct>& comms,
470 //- Like above but switches between linear/tree communication
471 template <class Container>
472 static void mapCombineScatter(Container& Values);
476 // Gather/scatter keeping the individual processor data separate.
477 // Values is a List of size Pstream::nProcs() where
478 // Values[Pstream::myProcNo()] is the data for the current processor.
480 //- Gather data but keep individual values separate
482 static void gatherList
484 const List<commsStruct>& comms,
488 //- Like above but switches between linear/tree communication
490 static void gatherList(List<T>& Values);
492 //- Scatter data. Reverse of gatherList
494 static void scatterList
496 const List<commsStruct>& comms,
500 //- Like above but switches between linear/tree communication
502 static void scatterList(List<T>& Values);
506 inline void Pstream::enlargeBuffer(size_t count)
508 buf_.setSize(max(int(buf_.size() + count), 2*buf_.size()));
512 Ostream& operator<<(Ostream&, const Pstream::commsStruct&);
515 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
517 } // End namespace Foam
519 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
522 # include "gatherScatter.C"
523 # include "combineGatherScatter.C"
524 # include "gatherScatterList.C"
528 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
532 // ************************************************************************* //