dune-common 2.9.0
Loading...
Searching...
No Matches
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
21namespace 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
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
A few common exception classes.
Implements an utility class that provides collective communication methods for sequential programs.
Helpers for dealing with MPI.
Implements an utility class that provides MPI's collective communication methods.
#define DUNE_THROW(E, m)
Definition exceptions.hh:218
Dune namespace.
Definition alignedallocator.hh:13
Default exception if an error in the parallel communication of the program occurred.
Definition exceptions.hh:287
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(const MPI_Comm &comm, bool active=true)
Definition mpiguard.hh:180
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