FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

Pstream.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Class
00025     Foam::Pstream
00026 
00027 Description
00028     Inter-processor communications stream
00029 
00030 SourceFiles
00031     Pstream.C
00032     PstreamsPrint.C
00033     PstreamCommsStruct.C
00034     gatherScatter.C
00035     combineGatherScatter.C
00036     gatherScatterList.C
00037 
00038 \*---------------------------------------------------------------------------*/
00039 
00040 #ifndef Pstream_H
00041 #define Pstream_H
00042 
00043 #include "PstreamImpl.H"
00044 #include <OpenFOAM/labelList.H>
00045 #include <OpenFOAM/DynamicList.H>
00046 #include <OpenFOAM/HashTable.H>
00047 #include <OpenFOAM/string.H>
00048 #include <OpenFOAM/NamedEnum.H>
00049 
00050 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00051 
00052 namespace Foam
00053 {
00054 
00055 /*---------------------------------------------------------------------------*\
00056                            Class Pstream Declaration
00057 \*---------------------------------------------------------------------------*/
00058 
00059 class Pstream
00060 : public helper_::PstreamBase
00061 {
00062 
00063 public:
00064 
00065     //- Types of communications
00066     using helper_::PstreamBase::commsTypes;
00067 
00068     static const NamedEnum<commsTypes, 3> commsTypeNames;
00069 
00070     //- Structure for communicating between processors
00071     class commsStruct
00072     {
00073         // Private data
00074 
00075             //- procID of above processor
00076             label above_;
00077 
00078             //- procIDs of processors directly below me
00079             labelList below_;
00080 
00081             //- procIDs of all processors below (so not just directly below)
00082             labelList allBelow_;
00083 
00084             //- procIDs of all processors not below. (inverse set of allBelow_
00085             //  and minus myProcNo)
00086             labelList allNotBelow_;
00087 
00088 
00089     public:
00090 
00091         // Constructors
00092 
00093             //- Construct null
00094             commsStruct();
00095 
00096             //- Construct from components
00097             commsStruct
00098             (
00099                 const label,
00100                 const labelList&,
00101                 const labelList&,
00102                 const labelList&
00103             );
00104 
00105             //- Construct from components; construct allNotBelow_
00106             commsStruct
00107             (
00108                 const label nProcs,
00109                 const label myProcID,
00110                 const label,
00111                 const labelList&,
00112                 const labelList&
00113             );
00114 
00115 
00116         // Member Functions
00117 
00118             // Access
00119 
00120                 label above() const
00121                 {
00122                     return above_;
00123                 }
00124 
00125                 const labelList& below() const
00126                 {
00127                     return below_;
00128                 }
00129 
00130                 const labelList& allBelow() const
00131                 {
00132                     return allBelow_;
00133                 }
00134 
00135                 const labelList& allNotBelow() const
00136                 {
00137                     return allNotBelow_;
00138                 }
00139 
00140 
00141         // Member operators
00142 
00143             bool operator==(const commsStruct&) const;
00144 
00145             bool operator!=(const commsStruct&) const;
00146 
00147 
00148          // Ostream Operator
00149 
00150             friend Ostream& operator<<(Ostream&, const commsStruct&);
00151     };
00152 
00153 
00154 private:
00155 
00156     // Private data
00157 
00158         static int myProcNo_;
00159         static bool parRun_;
00160 
00161         static List<int> procIDs_;
00162         static const int msgType_;
00163 
00164         static List<commsStruct> linearCommunication_;
00165         static List<commsStruct> treeCommunication_;
00166 
00167         static autoPtr<PstreamImpl> impl_;
00168 
00169 
00170     // Private member functions
00171 
00172         //- Calculate linear communication schedule
00173         static void calcLinearComm(const label nProcs);
00174 
00175         //- Calculate tree communication schedule
00176         static void calcTreeComm(const label nProcs);
00177 
00178         //- Helper function for tree communication schedule determination
00179         //  Collects all processorIDs below a processor
00180         static void collectReceives
00181         (
00182             const label procID,
00183             const List<DynamicList<label> >& receives,
00184             DynamicList<label>& allReceives
00185         );
00186 
00187         //- Initialize all communication schedules. Callback from
00188         //  PstreamImpl::init()
00189         static void initCommunicationSchedule();
00190 
00191         //- Fetches the PstreamImpl instance if necessary
00192         static autoPtr<PstreamImpl>& impl()
00193         {
00194             if(!impl_.valid())
00195             {
00196                 impl_ = PstreamImpl::New();
00197             }
00198             return impl_;
00199         }
00200 
00201 
00202 protected:
00203 
00204     // Protected data
00205 
00206         //- Communications type of this stream
00207         commsTypes commsType_;
00208 
00209         //- Transfer buffer
00210         List<char> buf_;
00211 
00212         //- Current buffer read/write location
00213         int bufPosition_;
00214 
00215 
00216     // Protected member functions
00217 
00218         //- Increase the size of the transfer buffer
00219         inline void enlargeBuffer(size_t count);
00220 
00221 
00222 public:
00223 
00224     // Declare name of the class and its debug switch
00225     ClassName("Pstream");
00226 
00227 
00228     // Static data
00229 
00230         //- Should compact transfer be used in which floats replace doubles
00231         //  reducing the bandwidth requirement at the expense of some loss
00232         //  in accuracy
00233         static bool floatTransfer;
00234 
00235         //- Number of processors at which the sum algorithm changes from linear
00236         //  to tree
00237         static int nProcsSimpleSum;
00238 
00239         //- Default commsType
00240         static commsTypes defaultCommsType;
00241 
00242 
00243     // Constructors
00244 
00245         //- Construct given optional buffer size
00246         Pstream
00247         (
00248             const commsTypes commsType,
00249             const label bufSize = 0
00250         )
00251         :
00252             commsType_(commsType),
00253             bufPosition_(0)
00254         {
00255             if (bufSize)
00256             {
00257                 buf_.setSize(bufSize + 2*sizeof(scalar) + 1);
00258             }
00259         }
00260 
00261 
00262     // Member functions
00263 
00264         //- Add the valid option this type of communications library
00265         //  adds/requires on the command line
00266         static void addValidParOptions(HashTable<string>& validParOptions)
00267         {
00268             impl()->addValidParOptions(validParOptions);
00269         }
00270 
00271         //- Initialisation function called from main
00272         //  Spawns slave processes and initialises inter-communication
00273         static bool init(int& argc, char**& argv)
00274         {
00275             return impl()->init(argc, argv, myProcNo_, procIDs_, parRun_);
00276         }
00277 
00278         //- Is this a parallel run?
00279         static bool parRun()
00280         {
00281             return parRun_;
00282         }
00283 
00284         //- Number of processes in parallel run
00285         static label nProcs()
00286         {
00287             return procIDs_.size();
00288         }
00289 
00290         //- Am I the master process
00291         static bool master()
00292         {
00293             return myProcNo_ == 0;
00294         }
00295 
00296         //- Process index of the master
00297         static int masterNo()
00298         {
00299             return 0;
00300         }
00301 
00302         //- Number of this process (starting from masterNo() = 0)
00303         static int myProcNo()
00304         {
00305             return myProcNo_;
00306         }
00307 
00308         //- Process IDs
00309         static const List<int>& procIDs()
00310         {
00311             return procIDs_;
00312         }
00313 
00314         //- Process ID of given process index
00315         static int procID(int procNo)
00316         {
00317             return procIDs_[procNo];
00318         }
00319 
00320         //- Process index of first slave
00321         static int firstSlave()
00322         {
00323             return 1;
00324         }
00325 
00326         //- Process index of last slave
00327         static int lastSlave()
00328         {
00329             return nProcs() - 1;
00330         }
00331 
00332         //- Communication schedule for linear all-to-master (proc 0)
00333         static const List<commsStruct>& linearCommunication()
00334         {
00335             return linearCommunication_;
00336         }
00337 
00338         //- Communication schedule for tree all-to-master (proc 0)
00339         static const List<commsStruct>& treeCommunication()
00340         {
00341             return treeCommunication_;
00342         }
00343 
00344         //- Message tag of standard messages
00345         static int msgType()
00346         {
00347             return msgType_;
00348         }
00349 
00350             //- Get the communications type of the stream
00351             commsTypes commsType() const
00352             {
00353                 return commsType_;
00354             }
00355 
00356             //- Set the communications type of the stream
00357             commsTypes commsType(const commsTypes ct)
00358             {
00359                 commsTypes oldCommsType = commsType_;
00360                 commsType_ = ct;
00361                 return oldCommsType;
00362             }
00363 
00364         //- Exit program
00365         static void exit(int errnum = 1)
00366         {
00367             impl()->exit(errnum);
00368         }
00369 
00370         //- Abort program
00371         static void abort()
00372         {
00373             impl()->abort();
00374         }
00375 
00376 
00377         // Gather and scatter
00378 
00379             //- Gather data. Apply bop to combine Value
00380             //  from different processors
00381             template <class T, class BinaryOp>
00382             static void gather
00383             (
00384                 const List<commsStruct>& comms,
00385                 T& Value,
00386                 const BinaryOp& bop
00387             );
00388 
00389             //- Like above but switches between linear/tree communication
00390             template <class T, class BinaryOp>
00391             static void gather(T& Value, const BinaryOp& bop);
00392 
00393             //- Scatter data. Distribute without modification. Reverse of gather
00394             template <class T>
00395             static void scatter(const List<commsStruct>& comms, T& Value);
00396 
00397             //- Like above but switches between linear/tree communication
00398             template <class T>
00399             static void scatter(T& Value);
00400 
00401 
00402         // Combine variants. Inplace combine values from processors.
00403         // (Uses construct from Istream instead of <<)
00404 
00405             template <class T, class CombineOp>
00406             static void combineGather
00407             (
00408                 const List<commsStruct>& comms,
00409                 T& Value,
00410                 const CombineOp& cop
00411             );
00412 
00413             //- Like above but switches between linear/tree communication
00414             template <class T, class CombineOp>
00415             static void combineGather(T& Value, const CombineOp& cop);
00416 
00417             //- Scatter data. Reverse of combineGather
00418             template <class T>
00419             static void combineScatter
00420             (
00421                 const List<commsStruct>& comms,
00422                 T& Value
00423             );
00424 
00425             //- Like above but switches between linear/tree communication
00426             template <class T>
00427             static void combineScatter(T& Value);
00428 
00429         // Combine variants working on whole List at a time.
00430 
00431             template <class T, class CombineOp>
00432             static void listCombineGather
00433             (
00434                 const List<commsStruct>& comms,
00435                 List<T>& Value,
00436                 const CombineOp& cop
00437             );
00438 
00439             //- Like above but switches between linear/tree communication
00440             template <class T, class CombineOp>
00441             static void listCombineGather(List<T>& Value, const CombineOp& cop);
00442 
00443             //- Scatter data. Reverse of combineGather
00444             template <class T>
00445             static void listCombineScatter
00446             (
00447                 const List<commsStruct>& comms,
00448                 List<T>& Value
00449             );
00450 
00451             //- Like above but switches between linear/tree communication
00452             template <class T>
00453             static void listCombineScatter(List<T>& Value);
00454 
00455         // Combine variants working on whole map at a time. Container needs to
00456         // have iterators and find() defined.
00457 
00458             template <class Container, class CombineOp>
00459             static void mapCombineGather
00460             (
00461                 const List<commsStruct>& comms,
00462                 Container& Values,
00463                 const CombineOp& cop
00464             );
00465 
00466             //- Like above but switches between linear/tree communication
00467             template <class Container, class CombineOp>
00468             static void mapCombineGather
00469             (
00470                 Container& Values,
00471                 const CombineOp& cop
00472             );
00473 
00474             //- Scatter data. Reverse of combineGather
00475             template <class Container>
00476             static void mapCombineScatter
00477             (
00478                 const List<commsStruct>& comms,
00479                 Container& Values
00480             );
00481 
00482             //- Like above but switches between linear/tree communication
00483             template <class Container>
00484             static void mapCombineScatter(Container& Values);
00485 
00486 
00487 
00488         // Gather/scatter keeping the individual processor data separate.
00489         // Values is a List of size Pstream::nProcs() where
00490         // Values[Pstream::myProcNo()] is the data for the current processor.
00491 
00492             //- Gather data but keep individual values separate
00493             template <class T>
00494             static void gatherList
00495             (
00496                 const List<commsStruct>& comms,
00497                 List<T>& Values
00498             );
00499 
00500             //- Like above but switches between linear/tree communication
00501             template <class T>
00502             static void gatherList(List<T>& Values);
00503 
00504             //- Scatter data. Reverse of gatherList
00505             template <class T>
00506             static void scatterList
00507             (
00508                 const List<commsStruct>& comms,
00509                 List<T>& Values
00510             );
00511 
00512             //- Like above but switches between linear/tree communication
00513             template <class T>
00514             static void scatterList(List<T>& Values);
00515 
00516     // Friends
00517 
00518         friend void ::Foam::reduce(scalar& Value, const sumOp<scalar>& bop);
00519         friend void ::Foam::PstreamImpl::initCommunicationSchedule();
00520 
00521 };
00522 
00523 
00524 inline void Pstream::enlargeBuffer(size_t count)
00525 {
00526     buf_.setSize(max(int(buf_.size() + count), 2*buf_.size()));
00527 }
00528 
00529 
00530 Ostream& operator<<(Ostream&, const Pstream::commsStruct&);
00531 
00532 
00533 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00534 
00535 } // End namespace Foam
00536 
00537 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00538 
00539 #ifdef NoRepository
00540 #   include <OpenFOAM/gatherScatter.C>
00541 #   include <OpenFOAM/combineGatherScatter.C>
00542 #   include <OpenFOAM/gatherScatterList.C>
00543 #endif
00544 
00545 
00546 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00547 
00548 #endif
00549 
00550 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines