initial commit for version 1.5.x patch release
[OpenFOAM-1.5.x.git] / src / OpenFOAM / db / IOstreams / Pstreams / Pstream.H
blob0b7f9a527e4ac7961642fa918415370780a2bf4b
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
19     for more details.
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
25 Class
26     Foam::Pstream
28 Description
29     Inter-processor communications stream
31 SourceFiles
32     Pstream.C
33     IPread.C
34     OPwrite.C
35     Pprint.C
36     gatherScatter.C
37     combineGatherScatter.C
38     gatherScatterList.C
40 \*---------------------------------------------------------------------------*/
42 #ifndef Pstream_H
43 #define Pstream_H
45 #include "labelList.H"
46 #include "DynamicList.H"
47 #include "HashTable.H"
48 #include "string.H"
49 #include "NamedEnum.H"
51 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
53 namespace Foam
56 /*---------------------------------------------------------------------------*\
57                            Class Pstream Declaration
58 \*---------------------------------------------------------------------------*/
60 class Pstream
63 public:
65     //- Types of communications
66     enum commsTypes
67     {
68         blocking,
69         scheduled,
70         nonBlocking
71     };
73     static const NamedEnum<commsTypes, 3> commsTypeNames;
75     //- Structure for communicating between processors
76     class commsStruct
77     {
78         // Private data
80             //- procID of above processor
81             label above_;
83             //- procIDs of processors directly below me
84             labelList below_;
86             //- procIDs of all processors below (so not just directly below)
87             labelList allBelow_;
89             //- procIDs of all processors not below. (inverse set of allBelow_
90             //  and minus myProcNo)
91             labelList allNotBelow_;
94     public:
96         // Constructors
98             //- Construct null
99             commsStruct();
101             //- Construct from components
102             commsStruct
103             (
104                 const label,
105                 const labelList&,
106                 const labelList&,
107                 const labelList&
108             );
110             //- Construct from components; construct allNotBelow_
111             commsStruct
112             (
113                 const label nProcs,
114                 const label myProcID,
115                 const label,
116                 const labelList&,
117                 const labelList&
118             );
121         // Member Functions
123             // Access
125                 label above() const
126                 {
127                     return above_;
128                 }
130                 const labelList& below() const
131                 {
132                     return below_;
133                 }
135                 const labelList& allBelow() const
136                 {
137                     return allBelow_;
138                 }
140                 const labelList& allNotBelow() const
141                 {
142                     return allNotBelow_;
143                 }
146         // Member operators
148             bool operator==(const commsStruct&) const;
150             bool operator!=(const commsStruct&) const;
153          // Ostream Operator
155             #ifndef __CINT__
156             friend Ostream& operator<<(Ostream&, const commsStruct&);
157             #endif
158     };
161 private:
163     // Private data
165         static int myProcNo_;
166         static bool parRun_;
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
189         (
190             const label procID,
191             const List<DynamicList<label> >& receives,
192             DynamicList<label>& allReceives
193         );
195         //- Initialize all communication schedules. Callback from
196         //  Pstream::init()
197         static void initCommunicationSchedule();
200 protected:
202     // Protected data
204         //- Communications type of this stream
205         commsTypes commsType_;
207         //- Transfer buffer
208         List<char> buf_;
210         //- Current buffer read/write location
211         int bufPosition_;
214     // Protected member functions
216         //- Increase the size of the transfer buffer
217         inline void enlargeBuffer(size_t count);
220 public:
222     // Declare name of the class and its debug switch
223     ClassName("Pstream");
226     // Static data
228         //- Should compact transfer be used in which floats replace doubles
229         //  reducing the bandwidth requirement at the expense of some loss
230         //  in accuracy
231         static bool floatTransfer;
233         //- Number of processors at which the sum algorithm changes from linear
234         //  to tree
235         static int nProcsSimpleSum;
237         //- Default commsType
238         static commsTypes defaultCommsType;
241     // Constructors
243         //- Construct given optional buffer size
244         Pstream
245         (
246             const commsTypes commsType,
247             const label bufSize = 0
248         )
249         :
250             commsType_(commsType),
251             bufPosition_(0)
252         {
253             if (bufSize)
254             {
255                 buf_.setSize(bufSize + 2*sizeof(scalar) + 1);
256             }
257         }
260     // Member functions
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?
271         static bool parRun()
272         {
273             return parRun_;
274         }
276         //- Number of processes in parallel run
277         static label nProcs()
278         {
279             return procIDs_.size();
280         }
282         //- Am I the master process
283         static bool master()
284         {
285             return myProcNo_ == 0;
286         }
288         //- Process index of the master
289         static int masterNo()
290         {
291             return 0;
292         }
294         //- Number of this process (starting from masterNo() = 0)
295         static int myProcNo()
296         {
297             return myProcNo_;
298         }
300         //- Process IDs
301         static const List<int>& procIDs()
302         {
303             return procIDs_;
304         }
306         //- Process ID of given process index
307         static int procID(int procNo)
308         {
309             return procIDs_[procNo];
310         }
312         //- Process index of first slave
313         static int firstSlave()
314         {
315             return 1;
316         }
318         //- Process index of last slave
319         static int lastSlave()
320         {
321             return nProcs() - 1;
322         }
324         //- Communication schedule for linear all-to-master (proc 0)
325         static const List<commsStruct>& linearCommunication()
326         {
327             return linearCommunication_;
328         }
330         //- Communication schedule for tree all-to-master (proc 0)
331         static const List<commsStruct>& treeCommunication()
332         {
333             return treeCommunication_;
334         }
336         //- Message tag of standard messages
337         static int msgType()
338         {
339             return msgType_;
340         }
342             //- Get the communications type of the stream
343             commsTypes commsType() const
344             {
345                 return commsType_;
346             }
348             //- Set the communications type of the stream
349             commsTypes commsType(const commsTypes ct)
350             {
351                 commsTypes oldCommsType = commsType_;
352                 commsType_ = ct;
353                 return oldCommsType;
354             }
356         //- Exit program
357         static void exit(int errnum = 1);
359         //- Abort program
360         static void abort();
363         // Gather and scatter
365             //- Gather data. Apply bop to combine Value
366             //  from different processors
367             template <class T, class BinaryOp>
368             static void gather
369             (
370                 const List<commsStruct>& comms,
371                 T& Value,
372                 const BinaryOp& bop
373             );
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
380             template <class T>
381             static void scatter(const List<commsStruct>& comms, T& Value);
383             //- Like above but switches between linear/tree communication
384             template <class T>
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
393             (
394                 const List<commsStruct>& comms,
395                 T& Value,
396                 const CombineOp& cop
397             );
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
404             template <class T>
405             static void combineScatter
406             (
407                 const List<commsStruct>& comms,
408                 T& Value
409             );
411             //- Like above but switches between linear/tree communication
412             template <class T>
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
419             (
420                 const List<commsStruct>& comms,
421                 List<T>& Value,
422                 const CombineOp& cop
423             );
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
430             template <class T>
431             static void listCombineScatter
432             (
433                 const List<commsStruct>& comms,
434                 List<T>& Value
435             );
437             //- Like above but switches between linear/tree communication
438             template <class T>
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
446             (
447                 const List<commsStruct>& comms,
448                 Container& Values,
449                 const CombineOp& cop
450             );
452             //- Like above but switches between linear/tree communication
453             template <class Container, class CombineOp>
454             static void mapCombineGather
455             (
456                 Container& Values,
457                 const CombineOp& cop
458             );
460             //- Scatter data. Reverse of combineGather
461             template <class Container>
462             static void mapCombineScatter
463             (
464                 const List<commsStruct>& comms,
465                 Container& Values
466             );
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
479             template <class T>
480             static void gatherList
481             (
482                 const List<commsStruct>& comms,
483                 List<T>& Values
484             );
486             //- Like above but switches between linear/tree communication
487             template <class T>
488             static void gatherList(List<T>& Values);
490             //- Scatter data. Reverse of gatherList
491             template <class T>
492             static void scatterList
493             (
494                 const List<commsStruct>& comms,
495                 List<T>& Values
496             );
498             //- Like above but switches between linear/tree communication
499             template <class T>
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 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
519 #ifdef NoRepository
520 #   include "gatherScatter.C"
521 #   include "combineGatherScatter.C"
522 #   include "gatherScatterList.C"
523 #endif
526 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
528 #endif
530 // ************************************************************************* //