dune-common 2.10
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 © 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_PARALLEL_MPIGUARD_HH
14#define DUNE_COMMON_PARALLEL_MPIGUARD_HH
15
16#if HAVE_MPI
17#include <mpi.h>
18#endif
19
24
25namespace Dune
26{
27
28#ifndef DOXYGEN
29
30 /*
31 Interface class for the communication needed by MPIGuard
32 */
33 struct GuardCommunicator
34 {
35 // cleanup
36 virtual ~GuardCommunicator() {};
37 // all the communication methods we need
38 virtual int rank() = 0;
39 virtual int size() = 0;
40 virtual int sum(int i) = 0;
41 // create a new GuardCommunicator pointer
42 template <class C>
43 static GuardCommunicator * create(const Communication<C> & c);
44#if HAVE_MPI
45 inline
46 static GuardCommunicator * create(const MPI_Comm & c);
47#endif
48 };
49
50 namespace {
51 /*
52 templated implementation of different communication classes
53 */
54 // the default class will always fail, due to the missing implementation of "sum"
55 template <class Imp>
56 struct GenericGuardCommunicator
57 : public GuardCommunicator
58 {};
59 // specialization for Communication
60 template <class T>
61 struct GenericGuardCommunicator< Communication<T> >
62 : public GuardCommunicator
63 {
64 const Communication<T> comm;
65 GenericGuardCommunicator(const Communication<T> & c) :
66 comm(c) {}
67 int rank() override { return comm.rank(); };
68 int size() override { return comm.size(); };
69 int sum(int i) override { return comm.sum(i); }
70 };
71
72#if HAVE_MPI
73 // specialization for MPI_Comm
74 template <>
75 struct GenericGuardCommunicator<MPI_Comm>
76 : public GenericGuardCommunicator< Communication<MPI_Comm> >
77 {
78 GenericGuardCommunicator(const MPI_Comm & c) :
79 GenericGuardCommunicator< Communication<MPI_Comm> >(
80 Communication<MPI_Comm>(c)) {}
81 };
82#endif
83 } // anonymous namespace
84
85 template<class C>
86 GuardCommunicator * GuardCommunicator::create(const Communication<C> & comm)
87 {
88 return new GenericGuardCommunicator< Communication<C> >(comm);
89 }
90
91#if HAVE_MPI
92 GuardCommunicator * GuardCommunicator::create(const MPI_Comm & comm)
93 {
94 return new GenericGuardCommunicator< Communication<MPI_Comm> >(comm);
95 }
96#endif
97
98#endif
99
103 class MPIGuardError : public ParallelError {};
104
138 {
139 GuardCommunicator * comm_;
140 bool active_;
141
142 // we don't want to copy this class
143 MPIGuard (const MPIGuard &);
144
145 public:
150 MPIGuard (bool active=true) :
151 comm_(GuardCommunicator::create(
152 MPIHelper::getCommunication())),
153 active_(active)
154 {}
155
161 MPIGuard (MPIHelper & m, bool active=true) :
162 comm_(GuardCommunicator::create(
163 m.getCommunication())),
164 active_(active)
165 {}
166
177 template <class C>
178 MPIGuard (const C & comm, bool active=true) :
179 comm_(GuardCommunicator::create(comm)),
180 active_(active)
181 {}
182
183#if HAVE_MPI
184 MPIGuard (const MPI_Comm & comm, bool active=true) :
185 comm_(GuardCommunicator::create(comm)),
186 active_(active)
187 {}
188#endif
189
193 {
194 if (active_)
195 {
196 active_ = false;
197 finalize(false);
198 }
199 delete comm_;
200 }
201
206 void reactivate() {
207 if (active_ == true)
208 finalize();
209 active_ = true;
210 }
211
222 void finalize(bool success = true)
223 {
224 int result = success ? 0 : 1;
225 bool was_active = active_;
226 active_ = false;
227 result = comm_->sum(result);
228 if (result>0 && was_active)
229 {
230 DUNE_THROW(MPIGuardError, "Terminating process "
231 << comm_->rank() << " due to "
232 << result << " remote error(s)");
233 }
234 }
235 };
236
237}
238
239#endif // DUNE_COMMON_PARALLEL_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:103
detects a thrown exception and communicates to all other processes
Definition mpiguard.hh:138
void reactivate()
reactivate the guard.
Definition mpiguard.hh:206
void finalize(bool success=true)
stop the guard.
Definition mpiguard.hh:222
~MPIGuard()
destroy the guard and check for undetected exceptions
Definition mpiguard.hh:192
MPIGuard(const C &comm, bool active=true)
create an MPIGuard operating on an arbitrary communicator.
Definition mpiguard.hh:178
MPIGuard(const MPI_Comm &comm, bool active=true)
Definition mpiguard.hh:184
MPIGuard(bool active=true)
create an MPIGuard operating on the Communicator of the global Dune::MPIHelper
Definition mpiguard.hh:150
MPIGuard(MPIHelper &m, bool active=true)
create an MPIGuard operating on the Communicator of a special Dune::MPIHelper m
Definition mpiguard.hh:161
A real mpi helper.
Definition mpihelper.hh:181