Bugfix: restored floatTransfer flag
[foam-extend-3.2.git] / src / foam / db / IOstreams / Pstreams / Pstream.H
blob502c071ca03a75ee8ec0792a2fc1d5e13762ed0b
1 /*---------------------------------------------------------------------------*\
2   =========                 |
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 -------------------------------------------------------------------------------
8 License
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/>.
24 Class
25     Foam::Pstream
27 Description
28     Inter-processor communications stream
30 SourceFiles
31     Pstream.C
32     PstreamsPrint.C
33     PstreamCommsStruct.C
34     gatherScatter.C
35     combineGatherScatter.C
36     gatherScatterList.C
38 \*---------------------------------------------------------------------------*/
40 #ifndef Pstream_H
41 #define Pstream_H
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 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
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             friend Ostream& operator<<(Ostream&, const commsStruct&);
156     };
159 private:
161     // Private data
163         static int myProcNo_;
164         static bool parRun_;
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
187         (
188             const label procID,
189             const dynamicLabelListList& receives,
190             dynamicLabelList& allReceives
191         );
193         //- Initialize all communication schedules. Callback from
194         //  Pstream::init()
195         static void initCommunicationSchedule();
198 protected:
200     // Protected data
202         //- Communications type of this stream
203         commsTypes commsType_;
205         //- Transfer buffer
206         List<char> buf_;
208         //- Current buffer read/write location
209         int bufPosition_;
212     // Protected member functions
214         //- Increase the size of the transfer buffer
215         inline void enlargeBuffer(size_t count);
218 public:
220     // Declare name of the class and its debug switch
221     ClassName("Pstream");
224     // Static data
226         //- Should compact transfer be used in which floats replace doubles
227         //  reducing the bandwidth requirement at the expense of some loss
228         //  in accuracy
229         static const debug::optimisationSwitch floatTransfer;
231         //- Number of processors at which the sum algorithm changes from linear
232         //  to tree
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()
240         {
241             return static_cast<Pstream::commsTypes>
242             (
243                 Pstream::defaultCommsType()
244             );
245         }
248     // Constructors
250         //- Construct given optional buffer size
251         Pstream
252         (
253             const commsTypes commsType,
254             const label bufSize = 0
255         )
256         :
257             commsType_(commsType),
258             bufPosition_(0)
259         {
260             if (bufSize)
261             {
262                 buf_.setSize(bufSize + 2*sizeof(scalar) + 1);
263             }
264         }
267     // Member functions
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?
278         static bool parRun()
279         {
280             return parRun_;
281         }
283         //- Number of processes in parallel run
284         static label nProcs()
285         {
286             return procIDs_.size();
287         }
289         //- Am I the master process
290         static bool master()
291         {
292             return myProcNo_ == masterNo();
293         }
295         //- Process index of the master
296         static int masterNo()
297         {
298             return 0;
299         }
301         //- Number of this process (starting from masterNo() = 0)
302         static int myProcNo()
303         {
304             return myProcNo_;
305         }
307         //- Process IDs
308         static const List<int>& procIDs()
309         {
310             return procIDs_;
311         }
313         //- Process ID of given process index
314         static int procID(int procNo)
315         {
316             return procIDs_[procNo];
317         }
319         //- Process index of first slave
320         static int firstSlave()
321         {
322             return 1;
323         }
325         //- Process index of last slave
326         static int lastSlave()
327         {
328             return nProcs() - 1;
329         }
331         //- Communication schedule for linear all-to-master (proc 0)
332         static const List<commsStruct>& linearCommunication()
333         {
334             return linearCommunication_;
335         }
337         //- Communication schedule for tree all-to-master (proc 0)
338         static const List<commsStruct>& treeCommunication()
339         {
340             return treeCommunication_;
341         }
343         //- Message tag of standard messages
344         static int msgType()
345         {
346             return msgType_;
347         }
349             //- Get the communications type of the stream
350             commsTypes commsType() const
351             {
352                 return commsType_;
353             }
355             //- Set the communications type of the stream
356             commsTypes commsType(const commsTypes ct)
357             {
358                 commsTypes oldCommsType = commsType_;
359                 commsType_ = ct;
360                 return oldCommsType;
361             }
363         //- Exit program
364         static void exit(int errnum = 1);
366         //- Abort program
367         static void abort();
370         // Gather and scatter
372             //- Gather data. Apply bop to combine Value
373             //  from different processors
374             template <class T, class BinaryOp>
375             static void gather
376             (
377                 const List<commsStruct>& comms,
378                 T& Value,
379                 const BinaryOp& bop
380             );
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.
387             //  Reverse of gather
388             template <class T>
389             static void scatter(const List<commsStruct>& comms, T& Value);
391             //- Like above but switches between linear/tree communication
392             template <class T>
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
401             (
402                 const List<commsStruct>& comms,
403                 T& Value,
404                 const CombineOp& cop
405             );
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
412             template <class T>
413             static void combineScatter
414             (
415                 const List<commsStruct>& comms,
416                 T& Value
417             );
419             //- Like above but switches between linear/tree communication
420             template <class T>
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
427             (
428                 const List<commsStruct>& comms,
429                 List<T>& Value,
430                 const CombineOp& cop
431             );
433             //- Like above but switches between linear/tree communication
434             template <class T, class CombineOp>
435             static void listCombineGather
436             (
437                 List<T>& Value,
438                 const CombineOp& cop
439             );
441             //- Scatter data. Reverse of combineGather
442             template <class T>
443             static void listCombineScatter
444             (
445                 const List<commsStruct>& comms,
446                 List<T>& Value
447             );
449             //- Like above but switches between linear/tree communication
450             template <class T>
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
458             (
459                 const List<commsStruct>& comms,
460                 Container& Values,
461                 const CombineOp& cop
462             );
464             //- Like above but switches between linear/tree communication
465             template <class Container, class CombineOp>
466             static void mapCombineGather
467             (
468                 Container& Values,
469                 const CombineOp& cop
470             );
472             //- Scatter data. Reverse of combineGather
473             template <class Container>
474             static void mapCombineScatter
475             (
476                 const List<commsStruct>& comms,
477                 Container& Values
478             );
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
491             template <class T>
492             static void gatherList
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 gatherList(List<T>& Values);
502             //- Scatter data. Reverse of gatherList
503             template <class T>
504             static void scatterList
505             (
506                 const List<commsStruct>& comms,
507                 List<T>& Values
508             );
510             //- Like above but switches between linear/tree communication
511             template <class T>
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 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
531 #ifdef NoRepository
532 #   include "gatherScatter.C"
533 #   include "combineGatherScatter.C"
534 #   include "gatherScatterList.C"
535 #endif
538 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
540 #endif
542 // ************************************************************************* //