- Home
- About DUNE
- Download
- Documentation
- Community
- Development
00001 // -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 00002 // vi: set et ts=8 sw=4 sts=4: 00003 00011 #ifndef DUNE_COMMON_MPIGUARD_HH 00012 #define DUNE_COMMON_MPIGUARD_HH 00013 00014 #include <dune/common/mpihelper.hh> 00015 #include <dune/common/collectivecommunication.hh> 00016 #include <dune/common/mpicollectivecommunication.hh> 00017 #include <dune/common/exceptions.hh> 00018 00019 namespace Dune 00020 { 00021 00022 #ifndef DOXYGEN 00023 00024 /* 00025 Interface class for the communication needed by MPIGuard 00026 */ 00027 struct GuardCommunicator 00028 { 00029 // cleanup 00030 virtual ~GuardCommunicator() {}; 00031 // all the communication methods we need 00032 virtual int rank() = 0; 00033 virtual int size() = 0; 00034 virtual int sum(int i) = 0; 00035 // create a new GuardCommunicator pointer 00036 template <class C> 00037 static GuardCommunicator * create(const C & c); 00038 }; 00039 00040 namespace { 00041 /* 00042 templated implementation of different communication classes 00043 */ 00044 // the default class will always fail, due to the missing implementation of "sum" 00045 template <class Imp> 00046 struct GenericGuardCommunicator 00047 : public GuardCommunicator 00048 {}; 00049 // specialization for CollectiveCommunication 00050 template <class T> 00051 struct GenericGuardCommunicator< CollectiveCommunication<T> > 00052 : public GuardCommunicator 00053 { 00054 const CollectiveCommunication<T> comm; 00055 GenericGuardCommunicator(const CollectiveCommunication<T> & c) : 00056 comm(c) {} 00057 virtual int rank() { return comm.rank(); }; 00058 virtual int size() { return comm.size(); }; 00059 virtual int sum(int i) { return comm.sum(i); } 00060 }; 00061 00062 #if HAVE_MPI 00063 // specialization for MPI_Comm 00064 template <> 00065 struct GenericGuardCommunicator<MPI_Comm> 00066 : public GenericGuardCommunicator< CollectiveCommunication<MPI_Comm> > 00067 { 00068 GenericGuardCommunicator(const MPI_Comm & c) : 00069 GenericGuardCommunicator< CollectiveCommunication<MPI_Comm> >( 00070 CollectiveCommunication<MPI_Comm>(c)) {} 00071 }; 00072 #endif 00073 } // anonymous namespace 00074 00075 template<class C> 00076 GuardCommunicator * GuardCommunicator::create(const C & comm) 00077 { 00078 return new GenericGuardCommunicator<C>(comm); 00079 } 00080 #endif 00081 00085 class MPIGuardError : public ParallelError {}; 00086 00119 class MPIGuard 00120 { 00121 GuardCommunicator * comm_; 00122 bool active_; 00123 00124 // we don't want to copy this class 00125 MPIGuard (const MPIGuard &); 00126 00127 public: 00132 MPIGuard (bool active=true) : 00133 comm_(GuardCommunicator::create( 00134 MPIHelper::getCollectiveCommunication())), 00135 active_(active) 00136 {} 00137 00143 MPIGuard (MPIHelper & m, bool active=true) : 00144 comm_(GuardCommunicator::create( 00145 m.getCollectiveCommunication())), 00146 active_(active) 00147 {} 00148 00159 template <class C> 00160 MPIGuard (const C & comm, bool active=true) : 00161 comm_(GuardCommunicator::create(comm)), 00162 active_(active) 00163 {} 00164 00167 ~MPIGuard() 00168 { 00169 if (active_) 00170 { 00171 active_ = false; 00172 finalize(false); 00173 } 00174 delete comm_; 00175 } 00176 00181 void reactivate() { 00182 if (active_ == true) 00183 finalize(); 00184 active_ = true; 00185 } 00186 00197 void finalize(bool success = true) 00198 { 00199 int result = success?0:1; 00200 bool was_active = active_; 00201 active_ = false; 00202 result = comm_->sum(result); 00203 if (result>0 && was_active) 00204 { 00205 DUNE_THROW(MPIGuardError, "Terminating process " 00206 << comm_->rank() << " due to " 00207 << result << " remote error(s)"); 00208 } 00209 } 00210 }; 00211 00212 } 00213 00214 #endif // DUNE_COMMON_MPIGUARD_HH
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].