initial commit for version 1.6.x patch release
[OpenFOAM-1.6.x.git] / src / OpenFOAM / db / IOstreams / Pstreams / Pstream.H
blobdff94c259f78ee2cbe7811d244432f43576a7c7f
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 1991-2009 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     PstreamsPrint.C
34     PstreamCommsStruct.C
35     gatherScatter.C
36     combineGatherScatter.C
37     gatherScatterList.C
39 \*---------------------------------------------------------------------------*/
41 #ifndef Pstream_H
42 #define Pstream_H
44 #include "labelList.H"
45 #include "DynamicList.H"
46 #include "HashTable.H"
47 #include "string.H"
48 #include "NamedEnum.H"
50 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
52 namespace Foam
55 /*---------------------------------------------------------------------------*\
56                            Class Pstream Declaration
57 \*---------------------------------------------------------------------------*/
59 class Pstream
62 public:
64     //- Types of communications
65     enum commsTypes
66     {
67         blocking,
68         scheduled,
69         nonBlocking
70     };
72     static const NamedEnum<commsTypes, 3> commsTypeNames;
74     //- Structure for communicating between processors
75     class commsStruct
76     {
77         // Private data
79             //- procID of above processor
80             label above_;
82             //- procIDs of processors directly below me
83             labelList below_;
85             //- procIDs of all processors below (so not just directly below)
86             labelList allBelow_;
88             //- procIDs of all processors not below. (inverse set of allBelow_
89             //  and minus myProcNo)
90             labelList allNotBelow_;
93     public:
95         // Constructors
97             //- Construct null
98             commsStruct();
100             //- Construct from components
101             commsStruct
102             (
103                 const label,
104                 const labelList&,
105                 const labelList&,
106                 const labelList&
107             );
109             //- Construct from components; construct allNotBelow_
110             commsStruct
111             (
112                 const label nProcs,
113                 const label myProcID,
114                 const label,
115                 const labelList&,
116                 const labelList&
117             );
120         // Member Functions
122             // Access
124                 label above() const
125                 {
126                     return above_;
127                 }
129                 const labelList& below() const
130                 {
131                     return below_;
132                 }
134                 const labelList& allBelow() const
135                 {
136                     return allBelow_;
137                 }
139                 const labelList& allNotBelow() const
140                 {
141                     return allNotBelow_;
142                 }
145         // Member operators
147             bool operator==(const commsStruct&) const;
149             bool operator!=(const commsStruct&) const;
152          // Ostream Operator
154             friend Ostream& operator<<(Ostream&, const commsStruct&);
155     };
158 private:
160     // Private data
162         static int myProcNo_;
163         static bool parRun_;
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
186         (
187             const label procID,
188             const List<DynamicList<label> >& receives,
189             DynamicList<label>& allReceives
190         );
192         //- Initialize all communication schedules. Callback from
193         //  Pstream::init()
194         static void initCommunicationSchedule();
197 protected:
199     // Protected data
201         //- Communications type of this stream
202         commsTypes commsType_;
204         //- Transfer buffer
205         List<char> buf_;
207         //- Current buffer read/write location
208         int bufPosition_;
211     // Protected member functions
213         //- Increase the size of the transfer buffer
214         inline void enlargeBuffer(size_t count);
217 public:
219     // Declare name of the class and its debug switch
220     ClassName("Pstream");
223     // Static data
225         //- Should compact transfer be used in which floats replace doubles
226         //  reducing the bandwidth requirement at the expense of some loss
227         //  in accuracy
228         static bool floatTransfer;
230         //- Number of processors at which the sum algorithm changes from linear
231         //  to tree
232         static int nProcsSimpleSum;
234         //- Default commsType
235         static commsTypes defaultCommsType;
238     // Constructors
240         //- Construct given optional buffer size
241         Pstream
242         (
243             const commsTypes commsType,
244             const label bufSize = 0
245         )
246         :
247             commsType_(commsType),
248             bufPosition_(0)
249         {
250             if (bufSize)
251             {
252                 buf_.setSize(bufSize + 2*sizeof(scalar) + 1);
253             }
254         }
257     // Member functions
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?
268         static bool parRun()
269         {
270             return parRun_;
271         }
273         //- Number of processes in parallel run
274         static label nProcs()
275         {
276             return procIDs_.size();
277         }
279         //- Am I the master process
280         static bool master()
281         {
282             return myProcNo_ == 0;
283         }
285         //- Process index of the master
286         static int masterNo()
287         {
288             return 0;
289         }
291         //- Number of this process (starting from masterNo() = 0)
292         static int myProcNo()
293         {
294             return myProcNo_;
295         }
297         //- Process IDs
298         static const List<int>& procIDs()
299         {
300             return procIDs_;
301         }
303         //- Process ID of given process index
304         static int procID(int procNo)
305         {
306             return procIDs_[procNo];
307         }
309         //- Process index of first slave
310         static int firstSlave()
311         {
312             return 1;
313         }
315         //- Process index of last slave
316         static int lastSlave()
317         {
318             return nProcs() - 1;
319         }
321         //- Communication schedule for linear all-to-master (proc 0)
322         static const List<commsStruct>& linearCommunication()
323         {
324             return linearCommunication_;
325         }
327         //- Communication schedule for tree all-to-master (proc 0)
328         static const List<commsStruct>& treeCommunication()
329         {
330             return treeCommunication_;
331         }
333         //- Message tag of standard messages
334         static int msgType()
335         {
336             return msgType_;
337         }
339             //- Get the communications type of the stream
340             commsTypes commsType() const
341             {
342                 return commsType_;
343             }
345             //- Set the communications type of the stream
346             commsTypes commsType(const commsTypes ct)
347             {
348                 commsTypes oldCommsType = commsType_;
349                 commsType_ = ct;
350                 return oldCommsType;
351             }
353         //- Exit program
354         static void exit(int errnum = 1);
356         //- Abort program
357         static void abort();
360         // Gather and scatter
362             //- Gather data. Apply bop to combine Value
363             //  from different processors
364             template <class T, class BinaryOp>
365             static void gather
366             (
367                 const List<commsStruct>& comms,
368                 T& Value,
369                 const BinaryOp& bop
370             );
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. Reverse of gather
377             template <class T>
378             static void scatter(const List<commsStruct>& comms, T& Value);
380             //- Like above but switches between linear/tree communication
381             template <class T>
382             static void scatter(T& Value);
385         // Combine variants. Inplace combine values from processors.
386         // (Uses construct from Istream instead of <<)
388             template <class T, class CombineOp>
389             static void combineGather
390             (
391                 const List<commsStruct>& comms,
392                 T& Value,
393                 const CombineOp& cop
394             );
396             //- Like above but switches between linear/tree communication
397             template <class T, class CombineOp>
398             static void combineGather(T& Value, const CombineOp& cop);
400             //- Scatter data. Reverse of combineGather
401             template <class T>
402             static void combineScatter
403             (
404                 const List<commsStruct>& comms,
405                 T& Value
406             );
408             //- Like above but switches between linear/tree communication
409             template <class T>
410             static void combineScatter(T& Value);
412         // Combine variants working on whole List at a time.
414             template <class T, class CombineOp>
415             static void listCombineGather
416             (
417                 const List<commsStruct>& comms,
418                 List<T>& Value,
419                 const CombineOp& cop
420             );
422             //- Like above but switches between linear/tree communication
423             template <class T, class CombineOp>
424             static void listCombineGather(List<T>& Value, const CombineOp& cop);
426             //- Scatter data. Reverse of combineGather
427             template <class T>
428             static void listCombineScatter
429             (
430                 const List<commsStruct>& comms,
431                 List<T>& Value
432             );
434             //- Like above but switches between linear/tree communication
435             template <class T>
436             static void listCombineScatter(List<T>& Value);
438         // Combine variants working on whole map at a time. Container needs to
439         // have iterators and find() defined.
441             template <class Container, class CombineOp>
442             static void mapCombineGather
443             (
444                 const List<commsStruct>& comms,
445                 Container& Values,
446                 const CombineOp& cop
447             );
449             //- Like above but switches between linear/tree communication
450             template <class Container, class CombineOp>
451             static void mapCombineGather
452             (
453                 Container& Values,
454                 const CombineOp& cop
455             );
457             //- Scatter data. Reverse of combineGather
458             template <class Container>
459             static void mapCombineScatter
460             (
461                 const List<commsStruct>& comms,
462                 Container& Values
463             );
465             //- Like above but switches between linear/tree communication
466             template <class Container>
467             static void mapCombineScatter(Container& Values);
471         // Gather/scatter keeping the individual processor data separate.
472         // Values is a List of size Pstream::nProcs() where
473         // Values[Pstream::myProcNo()] is the data for the current processor.
475             //- Gather data but keep individual values separate
476             template <class T>
477             static void gatherList
478             (
479                 const List<commsStruct>& comms,
480                 List<T>& Values
481             );
483             //- Like above but switches between linear/tree communication
484             template <class T>
485             static void gatherList(List<T>& Values);
487             //- Scatter data. Reverse of gatherList
488             template <class T>
489             static void scatterList
490             (
491                 const List<commsStruct>& comms,
492                 List<T>& Values
493             );
495             //- Like above but switches between linear/tree communication
496             template <class T>
497             static void scatterList(List<T>& Values);
501 inline void Pstream::enlargeBuffer(size_t count)
503     buf_.setSize(max(int(buf_.size() + count), 2*buf_.size()));
507 Ostream& operator<<(Ostream&, const Pstream::commsStruct&);
510 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
512 } // End namespace Foam
514 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
516 #ifdef NoRepository
517 #   include "gatherScatter.C"
518 #   include "combineGatherScatter.C"
519 #   include "gatherScatterList.C"
520 #endif
523 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
525 #endif
527 // ************************************************************************* //