00001 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- 00002 // vi: set et ts=4 sw=2 sts=2: 00003 #ifndef DUNE_MPIHELPER 00004 #define DUNE_MPIHELPER 00005 00006 #include <cassert> 00007 #include "collectivecommunication.hh" 00008 #if HAVE_MPI 00009 #include "mpi.h" 00010 #include "mpicollectivecommunication.hh" 00011 #endif 00012 00013 #include <dune/common/stdstreams.hh> 00014 #include <dune/common/visibility.hh> 00015 00016 namespace Dune 00017 { 00067 class FakeMPIHelper 00068 { 00069 public: 00070 enum { 00075 isFake = true 00076 }; 00077 00081 typedef No_Comm MPICommunicator; 00082 00089 DUNE_EXPORT static MPICommunicator getCommunicator () 00090 { 00091 static MPICommunicator comm; 00092 return comm; 00093 } 00094 00101 static MPICommunicator getLocalCommunicator () 00102 { 00103 return getCommunicator(); 00104 } 00105 00106 00107 00108 static CollectiveCommunication<MPICommunicator> 00109 getCollectiveCommunication() 00110 { 00111 return CollectiveCommunication<MPICommunicator>(getCommunicator()); 00112 } 00113 00129 DUNE_EXPORT static FakeMPIHelper& instance(int argc, char** argv) 00130 { 00131 (void)argc; (void)argv; 00132 // create singleton instance 00133 static FakeMPIHelper singleton; 00134 return singleton; 00135 } 00136 00140 int rank () const { return 0; } 00144 int size () const { return 1; } 00145 00146 private: 00147 FakeMPIHelper() {} 00148 FakeMPIHelper(const FakeMPIHelper&); 00149 FakeMPIHelper& operator=(const FakeMPIHelper); 00150 }; 00151 00152 #if HAVE_MPI 00153 00159 class MPIHelper 00160 { 00161 public: 00162 enum { 00167 isFake = false 00168 }; 00169 00173 typedef MPI_Comm MPICommunicator; 00174 00181 static MPICommunicator getCommunicator () 00182 { 00183 return MPI_COMM_WORLD; 00184 } 00185 00192 static MPICommunicator getLocalCommunicator () 00193 { 00194 return MPI_COMM_SELF; 00195 } 00196 00197 static CollectiveCommunication<MPICommunicator> 00198 getCollectiveCommunication() 00199 { 00200 return CollectiveCommunication<MPICommunicator>(getCommunicator()); 00201 } 00217 DUNE_EXPORT static MPIHelper& instance(int& argc, char**& argv) 00218 { 00219 // create singleton instance 00220 static MPIHelper singleton (argc, argv); 00221 return singleton; 00222 } 00223 00227 int rank () const { return rank_; } 00231 int size () const { return size_; } 00232 00233 private: 00234 int rank_; 00235 int size_; 00236 bool initializedHere_; 00237 void prevent_warning(int){} 00238 00240 MPIHelper(int& argc, char**& argv) 00241 : initializedHere_(false) 00242 { 00243 int wasInitialized = -1; 00244 MPI_Initialized( &wasInitialized ); 00245 if(!wasInitialized) 00246 { 00247 rank_ = -1; 00248 size_ = -1; 00249 static int is_initialized = MPI_Init(&argc, &argv); 00250 prevent_warning(is_initialized); 00251 initializedHere_ = true; 00252 } 00253 00254 MPI_Comm_rank(MPI_COMM_WORLD,&rank_); 00255 MPI_Comm_size(MPI_COMM_WORLD,&size_); 00256 00257 assert( rank_ >= 0 ); 00258 assert( size_ >= 1 ); 00259 00260 dverb << "Called MPI_Init on p=" << rank_ << "!" << std::endl; 00261 } 00263 ~MPIHelper() 00264 { 00265 int wasFinalized = -1; 00266 MPI_Finalized( &wasFinalized ); 00267 if(!wasFinalized && initializedHere_) 00268 { 00269 MPI_Finalize(); 00270 dverb << "Called MPI_Finalize on p=" << rank_ << "!" <<std::endl; 00271 } 00272 00273 } 00274 MPIHelper(const MPIHelper&); 00275 MPIHelper& operator=(const MPIHelper); 00276 }; 00277 #else 00278 // We do not have MPI therefore FakeMPIHelper 00279 // is the MPIHelper 00284 typedef FakeMPIHelper MPIHelper; 00285 00286 #endif 00287 00288 } // end namespace Dune 00289 #endif