Dune Core Modules (2.7.0)

mpiguard.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 
11 #ifndef DUNE_COMMON_MPIGUARD_HH
12 #define DUNE_COMMON_MPIGUARD_HH
13 
14 #include "mpihelper.hh"
15 #include "communication.hh"
16 #include "mpicommunication.hh"
18 
19 namespace Dune
20 {
21 
22 #ifndef DOXYGEN
23 
24  /*
25  Interface class for the communication needed by MPIGuard
26  */
27  struct GuardCommunicator
28  {
29  // cleanup
30  virtual ~GuardCommunicator() {};
31  // all the communication methods we need
32  virtual int rank() = 0;
33  virtual int size() = 0;
34  virtual int sum(int i) = 0;
35  // create a new GuardCommunicator pointer
36  template <class C>
37  static GuardCommunicator * create(const CollectiveCommunication<C> & c);
38 #if HAVE_MPI
39  static GuardCommunicator * create(const MPI_Comm & c);
40 #endif
41  };
42 
43  namespace {
44  /*
45  templated implementation of different communication classes
46  */
47  // the default class will always fail, due to the missing implementation of "sum"
48  template <class Imp>
49  struct GenericGuardCommunicator
50  : public GuardCommunicator
51  {};
52  // specialization for Communication
53  template <class T>
54  struct GenericGuardCommunicator< Communication<T> >
55  : public GuardCommunicator
56  {
57  const Communication<T> comm;
58  GenericGuardCommunicator(const Communication<T> & c) :
59  comm(c) {}
60  int rank() override { return comm.rank(); };
61  int size() override { return comm.size(); };
62  int sum(int i) override { return comm.sum(i); }
63  };
64 
65 #if HAVE_MPI
66  // specialization for MPI_Comm
67  template <>
68  struct GenericGuardCommunicator<MPI_Comm>
69  : public GenericGuardCommunicator< Communication<MPI_Comm> >
70  {
71  GenericGuardCommunicator(const MPI_Comm & c) :
72  GenericGuardCommunicator< Communication<MPI_Comm> >(
73  Communication<MPI_Comm>(c)) {}
74  };
75 #endif
76  } // anonymous namespace
77 
78  template<class C>
79  GuardCommunicator * GuardCommunicator::create(const CollectiveCommunication<C> & comm)
80  {
81  return new GenericGuardCommunicator< CollectiveCommunication<C> >(comm);
82  }
83 
84 #if HAVE_MPI
85  GuardCommunicator * GuardCommunicator::create(const MPI_Comm & comm)
86  {
87  return new GenericGuardCommunicator< CollectiveCommunication<MPI_Comm> >(comm);
88  }
89 #endif
90 
91 #endif
92 
96  class MPIGuardError : public ParallelError {};
97 
130  class MPIGuard
131  {
132  GuardCommunicator * comm_;
133  bool active_;
134 
135  // we don't want to copy this class
136  MPIGuard (const MPIGuard &);
137 
138  public:
143  MPIGuard (bool active=true) :
144  comm_(GuardCommunicator::create(
145  MPIHelper::getCommunication())),
146  active_(active)
147  {}
148 
154  MPIGuard (MPIHelper & m, bool active=true) :
155  comm_(GuardCommunicator::create(
156  m.getCommunication())),
157  active_(active)
158  {}
159 
170  template <class C>
171  MPIGuard (const C & comm, bool active=true) :
172  comm_(GuardCommunicator::create(comm)),
173  active_(active)
174  {}
175 
176 #if HAVE_MPI
177  MPIGuard (const MPI_Comm & comm, bool active=true) :
178  comm_(GuardCommunicator::create(comm)),
179  active_(active)
180  {}
181 #endif
182 
186  {
187  if (active_)
188  {
189  active_ = false;
190  finalize(false);
191  }
192  delete comm_;
193  }
194 
199  void reactivate() {
200  if (active_ == true)
201  finalize();
202  active_ = true;
203  }
204 
215  void finalize(bool success = true)
216  {
217  int result = success ? 0 : 1;
218  bool was_active = active_;
219  active_ = false;
220  result = comm_->sum(result);
221  if (result>0 && was_active)
222  {
223  DUNE_THROW(MPIGuardError, "Terminating process "
224  << comm_->rank() << " due to "
225  << result << " remote error(s)");
226  }
227  }
228  };
229 
230 }
231 
232 #endif // DUNE_COMMON_MPIGUARD_HH
This exception is thrown if the MPIGuard detects an error on a remote process.
Definition: mpiguard.hh:96
detects a thrown exception and communicates to all other processes
Definition: mpiguard.hh:131
void reactivate()
reactivate the guard.
Definition: mpiguard.hh:199
void finalize(bool success=true)
stop the guard.
Definition: mpiguard.hh:215
~MPIGuard()
destroy the guard and check for undetected exceptions
Definition: mpiguard.hh:185
MPIGuard(const C &comm, bool active=true)
create an MPIGuard operating on an arbitrary communicator.
Definition: mpiguard.hh:171
MPIGuard(bool active=true)
create an MPIGuard operating on the Communicator of the global Dune::MPIHelper
Definition: mpiguard.hh:143
MPIGuard(MPIHelper &m, bool active=true)
create an MPIGuard operating on the Communicator of a special Dune::MPIHelper m
Definition: mpiguard.hh:154
A real mpi helper.
Definition: mpihelper.hh:169
Default exception if an error in the parallel communication of the program occurred.
Definition: exceptions.hh:285
Implements an utility class that provides collective communication methods for sequential programs.
A few common exception classes.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
Implements an utility class that provides MPI's collective communication methods.
Helpers for dealing with MPI.
Dune namespace.
Definition: alignedallocator.hh:14
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)