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 "dynamicLabelList.H"
49 #include "optimisationSwitch.H"
51 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
56 /*---------------------------------------------------------------------------*\
57 Class Pstream Declaration
58 \*---------------------------------------------------------------------------*/
65 //- Types of communications
73 static const NamedEnum<commsTypes, 3> commsTypeNames;
75 //- Structure for communicating between processors
80 //- procID of above processor
83 //- procIDs of processors directly below me
86 //- procIDs of all processors below (so not just directly below)
89 //- procIDs of all processors not below. (inverse set of allBelow_
90 // and minus myProcNo)
91 labelList allNotBelow_;
101 //- Construct from components
110 //- Construct from components; construct allNotBelow_
114 const label myProcID,
130 const labelList& below() const
135 const labelList& allBelow() const
140 const labelList& allNotBelow() const
148 bool operator==(const commsStruct&) const;
150 bool operator!=(const commsStruct&) const;
155 friend Ostream& operator<<(Ostream&, const commsStruct&);
163 static int myProcNo_;
166 static List<int> procIDs_;
167 static const int msgType_;
169 static List<commsStruct> linearCommunication_;
170 static List<commsStruct> treeCommunication_;
173 // Private member functions
175 //- Set data for parallel running
176 static void setParRun();
178 //- Calculate linear communication schedule
179 static void calcLinearComm(const label nProcs);
181 //- Calculate tree communication schedule
182 static void calcTreeComm(const label nProcs);
184 //- Helper function for tree communication schedule determination
185 // Collects all processorIDs below a processor
186 static void collectReceives
189 const dynamicLabelListList& receives,
190 dynamicLabelList& allReceives
193 //- Initialize all communication schedules. Callback from
195 static void initCommunicationSchedule();
202 //- Communications type of this stream
203 commsTypes commsType_;
208 //- Current buffer read/write location
212 // Protected member functions
214 //- Increase the size of the transfer buffer
215 inline void enlargeBuffer(size_t count);
220 // Declare name of the class and its debug switch
221 ClassName("Pstream");
226 //- Should compact transfer be used in which floats replace doubles
227 // reducing the bandwidth requirement at the expense of some loss
229 static const debug::optimisationSwitch floatTransfer;
231 //- Number of processors at which the sum algorithm changes from linear
233 static const debug::optimisationSwitch nProcsSimpleSum;
235 //- Default commsType
236 static const debug::optimisationSwitch defaultCommsType;
238 //- Default comms with a cast
239 inline static Pstream::commsTypes defaultComms()
241 return static_cast<Pstream::commsTypes>
243 Pstream::defaultCommsType()
250 //- Construct given optional buffer size
253 const commsTypes commsType,
254 const label bufSize = 0
257 commsType_(commsType),
262 buf_.setSize(bufSize + 2*sizeof(scalar) + 1);
269 //- Add the valid option this type of communications library
270 // adds/requires on the command line
271 static void addValidParOptions(HashTable<string>& validParOptions);
273 //- Initialisation function called from main
274 // Spawns slave processes and initialises inter-communication
275 static bool init(int& argc, char**& argv);
277 //- Is this a parallel run?
283 //- Number of processes in parallel run
284 static label nProcs()
286 return procIDs_.size();
289 //- Am I the master process
292 return myProcNo_ == masterNo();
295 //- Process index of the master
296 static int masterNo()
301 //- Number of this process (starting from masterNo() = 0)
302 static int myProcNo()
308 static const List<int>& procIDs()
313 //- Process ID of given process index
314 static int procID(int procNo)
316 return procIDs_[procNo];
319 //- Process index of first slave
320 static int firstSlave()
325 //- Process index of last slave
326 static int lastSlave()
331 //- Communication schedule for linear all-to-master (proc 0)
332 static const List<commsStruct>& linearCommunication()
334 return linearCommunication_;
337 //- Communication schedule for tree all-to-master (proc 0)
338 static const List<commsStruct>& treeCommunication()
340 return treeCommunication_;
343 //- Message tag of standard messages
349 //- Get the communications type of the stream
350 commsTypes commsType() const
355 //- Set the communications type of the stream
356 commsTypes commsType(const commsTypes ct)
358 commsTypes oldCommsType = commsType_;
364 static void exit(int errnum = 1);
370 // Gather and scatter
372 //- Gather data. Apply bop to combine Value
373 // from different processors
374 template <class T, class BinaryOp>
377 const List<commsStruct>& comms,
382 //- Like above but switches between linear/tree communication
383 template <class T, class BinaryOp>
384 static void gather(T& Value, const BinaryOp& bop);
386 //- Scatter data. Distribute without modification.
389 static void scatter(const List<commsStruct>& comms, T& Value);
391 //- Like above but switches between linear/tree communication
393 static void scatter(T& Value);
396 // Combine variants. Inplace combine values from processors.
397 // (Uses construct from Istream instead of <<)
399 template <class T, class CombineOp>
400 static void combineGather
402 const List<commsStruct>& comms,
407 //- Like above but switches between linear/tree communication
408 template <class T, class CombineOp>
409 static void combineGather(T& Value, const CombineOp& cop);
411 //- Scatter data. Reverse of combineGather
413 static void combineScatter
415 const List<commsStruct>& comms,
419 //- Like above but switches between linear/tree communication
421 static void combineScatter(T& Value);
423 // Combine variants working on whole List at a time.
425 template <class T, class CombineOp>
426 static void listCombineGather
428 const List<commsStruct>& comms,
433 //- Like above but switches between linear/tree communication
434 template <class T, class CombineOp>
435 static void listCombineGather
441 //- Scatter data. Reverse of combineGather
443 static void listCombineScatter
445 const List<commsStruct>& comms,
449 //- Like above but switches between linear/tree communication
451 static void listCombineScatter(List<T>& Value);
453 // Combine variants working on whole map at a time. Container needs to
454 // have iterators and find() defined.
456 template <class Container, class CombineOp>
457 static void mapCombineGather
459 const List<commsStruct>& comms,
464 //- Like above but switches between linear/tree communication
465 template <class Container, class CombineOp>
466 static void mapCombineGather
472 //- Scatter data. Reverse of combineGather
473 template <class Container>
474 static void mapCombineScatter
476 const List<commsStruct>& comms,
480 //- Like above but switches between linear/tree communication
481 template <class Container>
482 static void mapCombineScatter(Container& Values);
486 // Gather/scatter keeping the individual processor data separate.
487 // Values is a List of size Pstream::nProcs() where
488 // Values[Pstream::myProcNo()] is the data for the current processor.
490 //- Gather data but keep individual values separate
492 static void gatherList
494 const List<commsStruct>& comms,
498 //- Like above but switches between linear/tree communication
500 static void gatherList(List<T>& Values);
502 //- Scatter data. Reverse of gatherList
504 static void scatterList
506 const List<commsStruct>& comms,
510 //- Like above but switches between linear/tree communication
512 static void scatterList(List<T>& Values);
516 inline void Pstream::enlargeBuffer(size_t count)
518 buf_.setSize(max(int(buf_.size() + count), 2*buf_.size()));
522 Ostream& operator<<(Ostream&, const Pstream::commsStruct&);
525 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
527 } // End namespace Foam
529 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
532 # include "gatherScatter.C"
533 # include "combineGatherScatter.C"
534 # include "gatherScatterList.C"
538 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
542 // ************************************************************************* //