OpenFOAM logo
Open Source CFD Toolkit

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-2005 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 the
00013     Free Software Foundation; either version 2 of the License, or (at your
00014     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, write to the Free Software Foundation,
00023     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00024 
00025 Class
00026     Pstream
00027 
00028 Description
00029     Inter-processor comunications stream
00030 
00031 SourceFiles
00032     Pstream.C
00033     IPread.C
00034     OPwrite.C
00035     Pprint.C
00036     gatherScatter.C
00037     combineGatherScatter.C
00038     gatherScatterList.C
00039 
00040 \*---------------------------------------------------------------------------*/
00041 
00042 #ifndef Pstream_H
00043 #define Pstream_H
00044 
00045 #include "labelList.H"
00046 #include "DynamicList.H"
00047 #include "HashTable.H"
00048 #include "string.H"
00049 
00050 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00051 
00052 namespace Foam
00053 {
00054 
00055 /*---------------------------------------------------------------------------*\
00056                            Class Pstream Declaration
00057 \*---------------------------------------------------------------------------*/
00058 
00059 class Pstream
00060 {
00061 
00062 public:
00063 
00064     class commsStruct
00065     {
00066         // Private data
00067 
00068             //- procID of above processor
00069             label above_;
00070 
00071             //- procIDs of processors directly below me
00072             labelList below_;
00073 
00074             //- procIDs of all processors below (so not just directly below)
00075             labelList allBelow_;
00076 
00077             //- procIDs of all processors not below. (inverse set of allBelow_
00078             //  and minus myProcNo)
00079             labelList allNotBelow_;
00080 
00081 
00082     public:
00083 
00084         // Constructors
00085 
00086             //- Construct null
00087             commsStruct();
00088 
00089             //- Construct from components
00090             commsStruct
00091             (
00092                 const label,
00093                 const labelList&,
00094                 const labelList&,
00095                 const labelList&
00096             );
00097 
00098             //- Construct from components; construct allNotBelow_
00099             commsStruct
00100             (
00101                 const label nProcs,
00102                 const label myProcID,
00103                 const label,
00104                 const labelList&,
00105                 const labelList&
00106             );
00107 
00108 
00109         // Member Functions
00110 
00111             // Access
00112 
00113                 label above() const
00114                 {
00115                     return above_;
00116                 } 
00117 
00118                 const labelList& below() const
00119                 {
00120                     return below_;
00121                 }
00122 
00123                 const labelList& allBelow() const
00124                 {
00125                     return allBelow_;
00126                 }
00127 
00128                 const labelList& allNotBelow() const
00129                 {
00130                     return allNotBelow_;
00131                 }
00132 
00133 
00134         // Member operators
00135 
00136             bool operator==(const commsStruct&) const;
00137 
00138             bool operator!=(const commsStruct&) const;
00139 
00140 
00141          // Ostream Operator
00142 
00143             friend Ostream& operator<<(Ostream&, const commsStruct&);
00144     };
00145 
00146 
00147 private:
00148 
00149     // Private data
00150 
00151         static int myProcNo_;
00152         static bool parRun_;
00153 
00154         static List<int> procIDs_;
00155         static const int msgType_;
00156 
00157         static List<commsStruct> linearCommunication_;
00158         static List<commsStruct> treeCommunication_;
00159 
00160 
00161     // Private member functions
00162 
00163         //- Set data for parallel running
00164         static void setParRun();
00165 
00166         //- Calculate linear communication schedule
00167         static void calcLinearComm(const label nProcs);
00168 
00169         //- Calculate tree communication schedule
00170         static void calcTreeComm(const label nProcs);
00171 
00172         //- Helper function for tree communication schedule determination
00173         //  Collects all processorIDs below a processor
00174         static void collectReceives
00175         (
00176             const label procID,
00177             const List<DynamicList<label> >& receives,
00178             DynamicList<label>& allReceives
00179         );
00180 
00181         //- Initialize all communication schedules. Callback from
00182         //  Pstream::init()
00183         static void initCommunicationSchedule();
00184 
00185 
00186 protected:
00187 
00188     // Protected data
00189 
00190         //- Transfer buffer
00191         List<char> buf_;
00192 
00193         //- Current buffer read/write location
00194         int bufPosition_;
00195 
00196 
00197     // Protected member functions
00198 
00199         //- Increase the size of the transfer buffer
00200         inline void enlargeBuffer(size_t count);
00201 
00202 
00203 public:
00204 
00205     // Declare name of the class and its debug switch
00206     ClassName("Pstream");
00207 
00208 
00209     // Static data
00210 
00211         //- Should compact transfer be used in which floats replace doubles
00212         //  reducing the bandwidth requirement at the expense of some loss
00213         //  in accuracy
00214         static bool floatTransfer;
00215 
00216         //- Number of processors at which the sum algorithm changes from linear
00217         //  to tree
00218         static int nProcsSimpleSum;
00219 
00220 
00221     // Constructors
00222 
00223         //- Construct given optional buffer size
00224         Pstream(const label bufSize = 0)
00225         :
00226             bufPosition_(0)
00227         {
00228             if (bufSize)
00229             {
00230                 buf_.setSize(bufSize + 2*sizeof(scalar) + 1);
00231             }
00232         }
00233 
00234 
00235     // Member functions
00236 
00237         //- Add the valid option this type of communications library
00238         //  adds/requires on the command line
00239         static void addValidParOptions(HashTable<string>& validParOptions);
00240 
00241         //- Initialisation function called from main
00242         //  Spawns slave processes and initialises inter-communication
00243         static bool init(int& argc, char**& argv);
00244 
00245         //- Is this a parallel run?
00246         static bool parRun()
00247         {
00248             return parRun_;
00249         }
00250 
00251         //- Number of processes in parallel run
00252         static label nProcs()
00253         {
00254             return procIDs_.size();
00255         }
00256 
00257         //- Am I the master process
00258         static bool master()
00259         {
00260             return myProcNo_ == 0;
00261         }
00262 
00263         //- Process index of the master
00264         static int masterNo()
00265         {
00266             return 0;
00267         }
00268 
00269         //- Number of this process (starting from masterNo() = 0)
00270         static int myProcNo()
00271         {
00272             return myProcNo_;
00273         }
00274 
00275         //- Process IDs
00276         static const List<int>& procIDs()
00277         {
00278             return procIDs_;
00279         }
00280 
00281         //- Process ID of given process index
00282         static int procID(int procNo)
00283         {
00284             return procIDs_[procNo];
00285         }
00286 
00287         //- Process index of first slave
00288         static int firstSlave()
00289         {
00290             return 1;
00291         }
00292 
00293         //- Process index of last slave
00294         static int lastSlave()
00295         {
00296             return nProcs() - 1;
00297         }
00298 
00299         //- Communication schedule for linear all-to-master (proc 0)
00300         static const List<commsStruct>& linearCommunication()
00301         {
00302             return linearCommunication_;
00303         }
00304 
00305         //- Communication schedule for tree all-to-master (proc 0)
00306         static const List<commsStruct>& treeCommunication()
00307         {
00308             return treeCommunication_;
00309         }
00310 
00311         //- Message tag of standard messages
00312         static int msgType()
00313         {
00314             return msgType_;
00315         }
00316 
00317         //- Exit program
00318         static void exit(int errnum = 1);
00319 
00320         //- Abort program
00321         static void abort();
00322 
00323 
00324         // Gather and scatter
00325 
00326             //- Gather data. Apply bop to combine Value
00327             //  from different processors
00328             template <class T, class BinaryOp>
00329             static void gather
00330             (
00331                 const List<commsStruct>& comms,
00332                 T& Value,
00333                 const BinaryOp& bop
00334             );
00335 
00336             //- Like above but switches between linear/tree communication
00337             template <class T, class BinaryOp>
00338             static void gather(T& Value, const BinaryOp& bop);
00339 
00340             //- Scatter data. Distribute without modification. Reverse of gather
00341             template <class T>
00342             static void scatter(const List<commsStruct>& comms, T& Value);
00343 
00344             //- Like above but switches between linear/tree communication
00345             template <class T>
00346             static void scatter(T& Value);
00347 
00348 
00349         // Combine variants. Inplace combine values from processors.
00350         // (Uses construct from Istream instead of <<)
00351 
00352             template <class T, class CombineOp>
00353             static void combineGather
00354             (
00355                 const List<commsStruct>& comms,
00356                 T& Value,
00357                 const CombineOp& cop
00358             );
00359 
00360             //- Like above but switches between linear/tree communication
00361             template <class T, class CombineOp>
00362             static void combineGather(T& Value, const CombineOp& cop);
00363 
00364             //- Scatter data. Reverse of combineGather
00365             template <class T>
00366             static void combineScatter
00367             (
00368                 const List<commsStruct>& comms,
00369                 T& Value
00370             );
00371 
00372             //- Like above but switches between linear/tree communication
00373             template <class T>
00374             static void combineScatter(T& Value);
00375 
00376         // Combine variants working on whole List at a time.
00377 
00378             template <class T, class CombineOp>
00379             static void listCombineGather
00380             (
00381                 const List<commsStruct>& comms,
00382                 List<T>& Value,
00383                 const CombineOp& cop
00384             );
00385 
00386             //- Like above but switches between linear/tree communication
00387             template <class T, class CombineOp>
00388             static void listCombineGather(List<T>& Value, const CombineOp& cop);
00389 
00390             //- Scatter data. Reverse of combineGather
00391             template <class T>
00392             static void listCombineScatter
00393             (
00394                 const List<commsStruct>& comms,
00395                 List<T>& Value
00396             );
00397 
00398             //- Like above but switches between linear/tree communication
00399             template <class T>
00400             static void listCombineScatter(List<T>& Value);
00401 
00402 
00403         // Gather/scatter keeping the individual processor data separate.
00404         // Values is a List of size Pstream::nProcs() where
00405         // Values[Pstream::myProcNo()] is the data for the current processor.
00406 
00407             //- Gather data but keep individual values separate
00408             template <class T>
00409             static void gatherList
00410             (
00411                 const List<commsStruct>& comms,
00412                 List<T>& Values
00413             );
00414 
00415             //- Like above but switches between linear/tree communication
00416             template <class T>
00417             static void gatherList(List<T>& Values);
00418 
00419             //- Scatter data. Reverse of gatherList
00420             template <class T>
00421             static void scatterList
00422             (
00423                 const List<commsStruct>& comms,
00424                 List<T>& Values
00425             );
00426 
00427             //- Like above but switches between linear/tree communication
00428             template <class T>
00429             static void scatterList(List<T>& Values);
00430 };
00431 
00432 
00433 inline void Pstream::enlargeBuffer(size_t count)
00434 {
00435     buf_.setSize(max(int(buf_.size() + count), 2*buf_.size()));
00436 }
00437 
00438 
00439 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00440 
00441 } // End namespace Foam
00442 
00443 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00444 
00445 #ifdef NoRepository
00446 #   include "gatherScatter.C"
00447 #   include "combineGatherScatter.C"
00448 #   include "gatherScatterList.C"
00449 #endif
00450 
00451 
00452 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00453 
00454 #endif
00455 
00456 // ************************************************************************* //
For further information go to www.openfoam.org