Report patch name instead of index in debug
[foam-extend-3.2.git] / src / foam / db / IOstreams / Pstreams / Pstream.H
blob4b29259cc5348d00c33fbe1b7670dda9ea956a04
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 "optimisationSwitch.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 const debug::optimisationSwitch floatTransfer;
230         //- Number of processors at which the sum algorithm changes from linear
231         //  to tree
232         static const debug::optimisationSwitch nProcsSimpleSum;
234         //- Default commsType
235         static const debug::optimisationSwitch 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_ == masterNo();
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.
377             //  Reverse of gather
378             template <class T>
379             static void scatter(const List<commsStruct>& comms, T& Value);
381             //- Like above but switches between linear/tree communication
382             template <class T>
383             static void scatter(T& Value);
386         // Combine variants. Inplace combine values from processors.
387         // (Uses construct from Istream instead of <<)
389             template <class T, class CombineOp>
390             static void combineGather
391             (
392                 const List<commsStruct>& comms,
393                 T& Value,
394                 const CombineOp& cop
395             );
397             //- Like above but switches between linear/tree communication
398             template <class T, class CombineOp>
399             static void combineGather(T& Value, const CombineOp& cop);
401             //- Scatter data. Reverse of combineGather
402             template <class T>
403             static void combineScatter
404             (
405                 const List<commsStruct>& comms,
406                 T& Value
407             );
409             //- Like above but switches between linear/tree communication
410             template <class T>
411             static void combineScatter(T& Value);
413         // Combine variants working on whole List at a time.
415             template <class T, class CombineOp>
416             static void listCombineGather
417             (
418                 const List<commsStruct>& comms,
419                 List<T>& Value,
420                 const CombineOp& cop
421             );
423             //- Like above but switches between linear/tree communication
424             template <class T, class CombineOp>
425             static void listCombineGather
426             (
427                 List<T>& Value,
428                 const CombineOp& cop
429             );
431             //- Scatter data. Reverse of combineGather
432             template <class T>
433             static void listCombineScatter
434             (
435                 const List<commsStruct>& comms,
436                 List<T>& Value
437             );
439             //- Like above but switches between linear/tree communication
440             template <class T>
441             static void listCombineScatter(List<T>& Value);
443         // Combine variants working on whole map at a time. Container needs to
444         // have iterators and find() defined.
446             template <class Container, class CombineOp>
447             static void mapCombineGather
448             (
449                 const List<commsStruct>& comms,
450                 Container& Values,
451                 const CombineOp& cop
452             );
454             //- Like above but switches between linear/tree communication
455             template <class Container, class CombineOp>
456             static void mapCombineGather
457             (
458                 Container& Values,
459                 const CombineOp& cop
460             );
462             //- Scatter data. Reverse of combineGather
463             template <class Container>
464             static void mapCombineScatter
465             (
466                 const List<commsStruct>& comms,
467                 Container& Values
468             );
470             //- Like above but switches between linear/tree communication
471             template <class Container>
472             static void mapCombineScatter(Container& Values);
476         // Gather/scatter keeping the individual processor data separate.
477         // Values is a List of size Pstream::nProcs() where
478         // Values[Pstream::myProcNo()] is the data for the current processor.
480             //- Gather data but keep individual values separate
481             template <class T>
482             static void gatherList
483             (
484                 const List<commsStruct>& comms,
485                 List<T>& Values
486             );
488             //- Like above but switches between linear/tree communication
489             template <class T>
490             static void gatherList(List<T>& Values);
492             //- Scatter data. Reverse of gatherList
493             template <class T>
494             static void scatterList
495             (
496                 const List<commsStruct>& comms,
497                 List<T>& Values
498             );
500             //- Like above but switches between linear/tree communication
501             template <class T>
502             static void scatterList(List<T>& Values);
506 inline void Pstream::enlargeBuffer(size_t count)
508     buf_.setSize(max(int(buf_.size() + count), 2*buf_.size()));
512 Ostream& operator<<(Ostream&, const Pstream::commsStruct&);
515 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
517 } // End namespace Foam
519 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
521 #ifdef NoRepository
522 #   include "gatherScatter.C"
523 #   include "combineGatherScatter.C"
524 #   include "gatherScatterList.C"
525 #endif
528 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
530 #endif
532 // ************************************************************************* //