DUNE PDELab (2.7)

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
19namespace 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
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.111.3 (Jul 15, 22:36, 2024)