Dune Core Modules (2.9.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 // SPDX-FileCopyrightInfo: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
4 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5 
13 #ifndef DUNE_COMMON_MPIGUARD_HH
14 #define DUNE_COMMON_MPIGUARD_HH
15 
16 #include "mpihelper.hh"
17 #include "communication.hh"
18 #include "mpicommunication.hh"
20 
21 namespace Dune
22 {
23 
24 #ifndef DOXYGEN
25 
26  /*
27  Interface class for the communication needed by MPIGuard
28  */
29  struct GuardCommunicator
30  {
31  // cleanup
32  virtual ~GuardCommunicator() {};
33  // all the communication methods we need
34  virtual int rank() = 0;
35  virtual int size() = 0;
36  virtual int sum(int i) = 0;
37  // create a new GuardCommunicator pointer
38  template <class C>
39  static GuardCommunicator * create(const Communication<C> & c);
40 #if HAVE_MPI
41  inline
42  static GuardCommunicator * create(const MPI_Comm & c);
43 #endif
44  };
45 
46  namespace {
47  /*
48  templated implementation of different communication classes
49  */
50  // the default class will always fail, due to the missing implementation of "sum"
51  template <class Imp>
52  struct GenericGuardCommunicator
53  : public GuardCommunicator
54  {};
55  // specialization for Communication
56  template <class T>
57  struct GenericGuardCommunicator< Communication<T> >
58  : public GuardCommunicator
59  {
60  const Communication<T> comm;
61  GenericGuardCommunicator(const Communication<T> & c) :
62  comm(c) {}
63  int rank() override { return comm.rank(); };
64  int size() override { return comm.size(); };
65  int sum(int i) override { return comm.sum(i); }
66  };
67 
68 #if HAVE_MPI
69  // specialization for MPI_Comm
70  template <>
71  struct GenericGuardCommunicator<MPI_Comm>
72  : public GenericGuardCommunicator< Communication<MPI_Comm> >
73  {
74  GenericGuardCommunicator(const MPI_Comm & c) :
75  GenericGuardCommunicator< Communication<MPI_Comm> >(
76  Communication<MPI_Comm>(c)) {}
77  };
78 #endif
79  } // anonymous namespace
80 
81  template<class C>
82  GuardCommunicator * GuardCommunicator::create(const Communication<C> & comm)
83  {
84  return new GenericGuardCommunicator< Communication<C> >(comm);
85  }
86 
87 #if HAVE_MPI
88  GuardCommunicator * GuardCommunicator::create(const MPI_Comm & comm)
89  {
90  return new GenericGuardCommunicator< Communication<MPI_Comm> >(comm);
91  }
92 #endif
93 
94 #endif
95 
99  class MPIGuardError : public ParallelError {};
100 
133  class MPIGuard
134  {
135  GuardCommunicator * comm_;
136  bool active_;
137 
138  // we don't want to copy this class
139  MPIGuard (const MPIGuard &);
140 
141  public:
146  MPIGuard (bool active=true) :
147  comm_(GuardCommunicator::create(
148  MPIHelper::getCommunication())),
149  active_(active)
150  {}
151 
157  MPIGuard (MPIHelper & m, bool active=true) :
158  comm_(GuardCommunicator::create(
159  m.getCommunication())),
160  active_(active)
161  {}
162 
173  template <class C>
174  MPIGuard (const C & comm, bool active=true) :
175  comm_(GuardCommunicator::create(comm)),
176  active_(active)
177  {}
178 
179 #if HAVE_MPI
180  MPIGuard (const MPI_Comm & comm, bool active=true) :
181  comm_(GuardCommunicator::create(comm)),
182  active_(active)
183  {}
184 #endif
185 
189  {
190  if (active_)
191  {
192  active_ = false;
193  finalize(false);
194  }
195  delete comm_;
196  }
197 
202  void reactivate() {
203  if (active_ == true)
204  finalize();
205  active_ = true;
206  }
207 
218  void finalize(bool success = true)
219  {
220  int result = success ? 0 : 1;
221  bool was_active = active_;
222  active_ = false;
223  result = comm_->sum(result);
224  if (result>0 && was_active)
225  {
226  DUNE_THROW(MPIGuardError, "Terminating process "
227  << comm_->rank() << " due to "
228  << result << " remote error(s)");
229  }
230  }
231  };
232 
233 }
234 
235 #endif // DUNE_COMMON_MPIGUARD_HH
This exception is thrown if the MPIGuard detects an error on a remote process.
Definition: mpiguard.hh:99
detects a thrown exception and communicates to all other processes
Definition: mpiguard.hh:134
void reactivate()
reactivate the guard.
Definition: mpiguard.hh:202
void finalize(bool success=true)
stop the guard.
Definition: mpiguard.hh:218
~MPIGuard()
destroy the guard and check for undetected exceptions
Definition: mpiguard.hh:188
MPIGuard(const C &comm, bool active=true)
create an MPIGuard operating on an arbitrary communicator.
Definition: mpiguard.hh:174
MPIGuard(bool active=true)
create an MPIGuard operating on the Communicator of the global Dune::MPIHelper
Definition: mpiguard.hh:146
MPIGuard(MPIHelper &m, bool active=true)
create an MPIGuard operating on the Communicator of a special Dune::MPIHelper m
Definition: mpiguard.hh:157
A real mpi helper.
Definition: mpihelper.hh:179
Default exception if an error in the parallel communication of the program occurred.
Definition: exceptions.hh:287
A few common exception classes.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
Implements an utility class that provides MPI's collective communication methods.
Helpers for dealing with MPI.
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 3, 22:32, 2024)