Dune Core Modules (2.7.1)

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  inline
40  static GuardCommunicator * create(const MPI_Comm & c);
41 #endif
42  };
43 
44  namespace {
45  /*
46  templated implementation of different communication classes
47  */
48  // the default class will always fail, due to the missing implementation of "sum"
49  template <class Imp>
50  struct GenericGuardCommunicator
51  : public GuardCommunicator
52  {};
53  // specialization for Communication
54  template <class T>
55  struct GenericGuardCommunicator< Communication<T> >
56  : public GuardCommunicator
57  {
58  const Communication<T> comm;
59  GenericGuardCommunicator(const Communication<T> & c) :
60  comm(c) {}
61  int rank() override { return comm.rank(); };
62  int size() override { return comm.size(); };
63  int sum(int i) override { return comm.sum(i); }
64  };
65 
66 #if HAVE_MPI
67  // specialization for MPI_Comm
68  template <>
69  struct GenericGuardCommunicator<MPI_Comm>
70  : public GenericGuardCommunicator< Communication<MPI_Comm> >
71  {
72  GenericGuardCommunicator(const MPI_Comm & c) :
73  GenericGuardCommunicator< Communication<MPI_Comm> >(
74  Communication<MPI_Comm>(c)) {}
75  };
76 #endif
77  } // anonymous namespace
78 
79  template<class C>
80  GuardCommunicator * GuardCommunicator::create(const CollectiveCommunication<C> & comm)
81  {
82  return new GenericGuardCommunicator< CollectiveCommunication<C> >(comm);
83  }
84 
85 #if HAVE_MPI
86  GuardCommunicator * GuardCommunicator::create(const MPI_Comm & comm)
87  {
88  return new GenericGuardCommunicator< CollectiveCommunication<MPI_Comm> >(comm);
89  }
90 #endif
91 
92 #endif
93 
97  class MPIGuardError : public ParallelError {};
98 
131  class MPIGuard
132  {
133  GuardCommunicator * comm_;
134  bool active_;
135 
136  // we don't want to copy this class
137  MPIGuard (const MPIGuard &);
138 
139  public:
144  MPIGuard (bool active=true) :
145  comm_(GuardCommunicator::create(
146  MPIHelper::getCommunication())),
147  active_(active)
148  {}
149 
155  MPIGuard (MPIHelper & m, bool active=true) :
156  comm_(GuardCommunicator::create(
157  m.getCommunication())),
158  active_(active)
159  {}
160 
171  template <class C>
172  MPIGuard (const C & comm, bool active=true) :
173  comm_(GuardCommunicator::create(comm)),
174  active_(active)
175  {}
176 
177 #if HAVE_MPI
178  MPIGuard (const MPI_Comm & comm, bool active=true) :
179  comm_(GuardCommunicator::create(comm)),
180  active_(active)
181  {}
182 #endif
183 
187  {
188  if (active_)
189  {
190  active_ = false;
191  finalize(false);
192  }
193  delete comm_;
194  }
195 
200  void reactivate() {
201  if (active_ == true)
202  finalize();
203  active_ = true;
204  }
205 
216  void finalize(bool success = true)
217  {
218  int result = success ? 0 : 1;
219  bool was_active = active_;
220  active_ = false;
221  result = comm_->sum(result);
222  if (result>0 && was_active)
223  {
224  DUNE_THROW(MPIGuardError, "Terminating process "
225  << comm_->rank() << " due to "
226  << result << " remote error(s)");
227  }
228  }
229  };
230 
231 }
232 
233 #endif // DUNE_COMMON_MPIGUARD_HH
This exception is thrown if the MPIGuard detects an error on a remote process.
Definition: mpiguard.hh:97
detects a thrown exception and communicates to all other processes
Definition: mpiguard.hh:132
void reactivate()
reactivate the guard.
Definition: mpiguard.hh:200
void finalize(bool success=true)
stop the guard.
Definition: mpiguard.hh:216
~MPIGuard()
destroy the guard and check for undetected exceptions
Definition: mpiguard.hh:186
MPIGuard(const C &comm, bool active=true)
create an MPIGuard operating on an arbitrary communicator.
Definition: mpiguard.hh:172
MPIGuard(bool active=true)
create an MPIGuard operating on the Communicator of the global Dune::MPIHelper
Definition: mpiguard.hh:144
MPIGuard(MPIHelper &m, bool active=true)
create an MPIGuard operating on the Communicator of a special Dune::MPIHelper m
Definition: mpiguard.hh:155
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 8, 22:30, 2024)