1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM 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 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 Inter-processor communications stream
37 combineGatherScatter.C
40 \*---------------------------------------------------------------------------*/
45 #include "labelList.H"
46 #include "DynamicList.H"
47 #include "HashTable.H"
49 #include "NamedEnum.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;
156 friend Ostream& operator<<(Ostream&, const commsStruct&);
165 static int myProcNo_;
168 static List<int> procIDs_;
169 static const int msgType_;
171 static List<commsStruct> linearCommunication_;
172 static List<commsStruct> treeCommunication_;
175 // Private member functions
177 //- Set data for parallel running
178 static void setParRun();
180 //- Calculate linear communication schedule
181 static void calcLinearComm(const label nProcs);
183 //- Calculate tree communication schedule
184 static void calcTreeComm(const label nProcs);
186 //- Helper function for tree communication schedule determination
187 // Collects all processorIDs below a processor
188 static void collectReceives
191 const List<DynamicList<label> >& receives,
192 DynamicList<label>& allReceives
195 //- Initialize all communication schedules. Callback from
197 static void initCommunicationSchedule();
204 //- Communications type of this stream
205 commsTypes commsType_;
210 //- Current buffer read/write location
214 // Protected member functions
216 //- Increase the size of the transfer buffer
217 inline void enlargeBuffer(size_t count);
222 // Declare name of the class and its debug switch
223 ClassName("Pstream");
228 //- Should compact transfer be used in which floats replace doubles
229 // reducing the bandwidth requirement at the expense of some loss
231 static bool floatTransfer;
233 //- Number of processors at which the sum algorithm changes from linear
235 static int nProcsSimpleSum;
237 //- Default commsType
238 static commsTypes defaultCommsType;
243 //- Construct given optional buffer size
246 const commsTypes commsType,
247 const label bufSize = 0
250 commsType_(commsType),
255 buf_.setSize(bufSize + 2*sizeof(scalar) + 1);
262 //- Add the valid option this type of communications library
263 // adds/requires on the command line
264 static void addValidParOptions(HashTable<string>& validParOptions);
266 //- Initialisation function called from main
267 // Spawns slave processes and initialises inter-communication
268 static bool init(int& argc, char**& argv);
270 //- Is this a parallel run?
276 //- Number of processes in parallel run
277 static label nProcs()
279 return procIDs_.size();
282 //- Am I the master process
285 return myProcNo_ == 0;
288 //- Process index of the master
289 static int masterNo()
294 //- Number of this process (starting from masterNo() = 0)
295 static int myProcNo()
301 static const List<int>& procIDs()
306 //- Process ID of given process index
307 static int procID(int procNo)
309 return procIDs_[procNo];
312 //- Process index of first slave
313 static int firstSlave()
318 //- Process index of last slave
319 static int lastSlave()
324 //- Communication schedule for linear all-to-master (proc 0)
325 static const List<commsStruct>& linearCommunication()
327 return linearCommunication_;
330 //- Communication schedule for tree all-to-master (proc 0)
331 static const List<commsStruct>& treeCommunication()
333 return treeCommunication_;
336 //- Message tag of standard messages
342 //- Get the communications type of the stream
343 commsTypes commsType() const
348 //- Set the communications type of the stream
349 commsTypes commsType(const commsTypes ct)
351 commsTypes oldCommsType = commsType_;
357 static void exit(int errnum = 1);
363 // Gather and scatter
365 //- Gather data. Apply bop to combine Value
366 // from different processors
367 template <class T, class BinaryOp>
370 const List<commsStruct>& comms,
375 //- Like above but switches between linear/tree communication
376 template <class T, class BinaryOp>
377 static void gather(T& Value, const BinaryOp& bop);
379 //- Scatter data. Distribute without modification. Reverse of gather
381 static void scatter(const List<commsStruct>& comms, T& Value);
383 //- Like above but switches between linear/tree communication
385 static void scatter(T& Value);
388 // Combine variants. Inplace combine values from processors.
389 // (Uses construct from Istream instead of <<)
391 template <class T, class CombineOp>
392 static void combineGather
394 const List<commsStruct>& comms,
399 //- Like above but switches between linear/tree communication
400 template <class T, class CombineOp>
401 static void combineGather(T& Value, const CombineOp& cop);
403 //- Scatter data. Reverse of combineGather
405 static void combineScatter
407 const List<commsStruct>& comms,
411 //- Like above but switches between linear/tree communication
413 static void combineScatter(T& Value);
415 // Combine variants working on whole List at a time.
417 template <class T, class CombineOp>
418 static void listCombineGather
420 const List<commsStruct>& comms,
425 //- Like above but switches between linear/tree communication
426 template <class T, class CombineOp>
427 static void listCombineGather(List<T>& Value, const CombineOp& cop);
429 //- Scatter data. Reverse of combineGather
431 static void listCombineScatter
433 const List<commsStruct>& comms,
437 //- Like above but switches between linear/tree communication
439 static void listCombineScatter(List<T>& Value);
441 // Combine variants working on whole map at a time. Container needs to
442 // have iterators and find() defined.
444 template <class Container, class CombineOp>
445 static void mapCombineGather
447 const List<commsStruct>& comms,
452 //- Like above but switches between linear/tree communication
453 template <class Container, class CombineOp>
454 static void mapCombineGather
460 //- Scatter data. Reverse of combineGather
461 template <class Container>
462 static void mapCombineScatter
464 const List<commsStruct>& comms,
468 //- Like above but switches between linear/tree communication
469 template <class Container>
470 static void mapCombineScatter(Container& Values);
474 // Gather/scatter keeping the individual processor data separate.
475 // Values is a List of size Pstream::nProcs() where
476 // Values[Pstream::myProcNo()] is the data for the current processor.
478 //- Gather data but keep individual values separate
480 static void gatherList
482 const List<commsStruct>& comms,
486 //- Like above but switches between linear/tree communication
488 static void gatherList(List<T>& Values);
490 //- Scatter data. Reverse of gatherList
492 static void scatterList
494 const List<commsStruct>& comms,
498 //- Like above but switches between linear/tree communication
500 static void scatterList(List<T>& Values);
504 inline void Pstream::enlargeBuffer(size_t count)
506 buf_.setSize(max(int(buf_.size() + count), 2*buf_.size()));
510 Ostream& operator<<(Ostream&, const Pstream::commsStruct&);
513 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
515 } // End namespace Foam
517 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
520 # include "gatherScatter.C"
521 # include "combineGatherScatter.C"
522 # include "gatherScatterList.C"
526 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
530 // ************************************************************************* //