MPIProcess.h

Go to the documentation of this file.
00001 // @(#)root/minuit2:$Id: MPIProcess.h 29227 2009-06-25 15:22:12Z brun $
00002 // Author: A. Lazzaro 2009
00003 /***************************************************************************
00004  * Package: Minuit2                                                        *
00005  *    File: $Id: MPIProcess.h 29227 2009-06-25 15:22:12Z brun $         *
00006  *  Author: Alfio Lazzaro, alfio.lazzaro@mi.infn.it                        *
00007  *                                                                         *
00008  * Copyright: (C) 2008 by Universita' and INFN, Milan                      *
00009  ***************************************************************************/
00010 
00011 #ifndef ROOT_Minuit2_MPIProcess
00012 #define ROOT_Minuit2_MPIProcess
00013 
00014 // disable MPI calls
00015 //#define MPIPROC
00016 
00017 #include "Minuit2/MnMatrix.h"
00018 
00019 #ifdef MPIPROC
00020 #include "mpi.h"
00021 #endif
00022 
00023 
00024 namespace ROOT {
00025 
00026 namespace Minuit2 {
00027 
00028    class MPITerminate {
00029    public:
00030       ~MPITerminate() { 
00031 #ifdef MPIPROC
00032          if (MPI::Is_initialized() && !(MPI::Is_finalized())) {
00033             std::cout << "Info --> MPITerminate:: End MPI on #"
00034                       << MPI::COMM_WORLD.Get_rank() << " processor"
00035                       << std::endl;
00036 
00037             MPI::Finalize();
00038          }
00039 #endif
00040       }
00041 
00042    };
00043 
00044 
00045    class MPIProcess {
00046    public:
00047       MPIProcess(unsigned int nelements, unsigned int indexComm);
00048       ~MPIProcess();
00049 
00050       inline unsigned int NumElements4JobIn() const { return fNumElements4JobIn; }
00051       inline unsigned int NumElements4JobOut() const { return fNumElements4JobOut; }
00052 
00053       inline unsigned int NumElements4Job(unsigned int rank) const
00054       { return NumElements4JobIn()+((rank<NumElements4JobOut()) ? 1 : 0); }
00055 
00056       inline unsigned int StartElementIndex() const 
00057       { return ((fRank<NumElements4JobOut()) ? (fRank*NumElements4Job(fRank)) :
00058                 (fNelements-(fSize-fRank)*NumElements4Job(fRank))); }
00059 
00060       inline unsigned int EndElementIndex() const
00061       { return StartElementIndex()+NumElements4Job(fRank); }
00062 
00063       inline unsigned int GetMPISize() const { return fSize; }
00064       inline unsigned int GetMPIRank() const { return fRank; }
00065 
00066       bool SyncVector(ROOT::Minuit2::MnAlgebraicVector &mnvector);  
00067       bool SyncSymMatrixOffDiagonal(ROOT::Minuit2::MnAlgebraicSymMatrix &mnmatrix);  
00068 
00069       static unsigned int GetMPIGlobalRank() { StartMPI(); return fgGlobalRank; }
00070       static unsigned int GetMPIGlobalSize() { StartMPI(); return fgGlobalSize; }
00071       static inline void StartMPI() {
00072 #ifdef MPIPROC  
00073          if (!(MPI::Is_initialized())) {    
00074             MPI::Init();    
00075             std::cout << "Info --> MPIProcess::StartMPI: Start MPI on #" 
00076                       << MPI::COMM_WORLD.Get_rank() << " processor"
00077                       << std::endl;
00078          }
00079          fgGlobalSize = MPI::COMM_WORLD.Get_size();
00080          fgGlobalRank = MPI::COMM_WORLD.Get_rank();
00081 #endif
00082       }
00083 
00084       static void TerminateMPI() { 
00085 #ifdef MPIPROC
00086          if (fgCommunicators[0]!=0 && fgCommunicators[1]!=0) {
00087             delete fgCommunicators[0]; fgCommunicators[0] = 0; fgIndecesComm[0] = 0;
00088             delete fgCommunicators[1]; fgCommunicators[1] = 0; fgIndecesComm[1] = 0;
00089          }
00090       
00091          MPITerminate();
00092 
00093 #endif
00094       }
00095 
00096       static bool SetCartDimension(unsigned int dimX, unsigned int dimY);
00097       static bool SetDoFirstMPICall(bool doFirstMPICall = true);
00098 
00099       inline void SumReduce(const double& sub, double& total) {
00100          total = sub;
00101 
00102 #ifdef MPIPROC
00103          if (fSize>1) {
00104             fgCommunicator->Allreduce(&sub,&total,1,MPI::DOUBLE,MPI::SUM);
00105          }
00106 #endif
00107       }
00108 
00109    private:
00110 
00111 #ifdef MPIPROC
00112       void MPISyncVector(double *ivector, int svector, double *ovector);
00113 #endif
00114 
00115    private:
00116       unsigned int fNelements;
00117       unsigned int fSize;
00118       unsigned int fRank;  
00119 
00120       static unsigned int fgGlobalSize;
00121       static unsigned int fgGlobalRank;  
00122 
00123       static unsigned int fgCartSizeX;
00124       static unsigned int fgCartSizeY;
00125       static unsigned int fgCartDimension;
00126       static bool fgNewCart;
00127 
00128       unsigned int fNumElements4JobIn;
00129       unsigned int fNumElements4JobOut;
00130 
00131 #ifdef MPIPROC
00132       static MPI::Intracomm *fgCommunicator;
00133       static int fgIndexComm; // maximum 2 communicators, so index can be 0 and 1
00134       static MPI::Intracomm *fgCommunicators[2]; // maximum 2 communicators
00135       static unsigned int fgIndecesComm[2];
00136 #endif
00137 
00138    };
00139 
00140 } // namespace Minuit2
00141 } // namespace ROOT
00142 
00143 #endif
00144 
00145 

Generated on Tue Jul 5 14:25:46 2011 for ROOT_528-00b_version by  doxygen 1.5.1