DUNE PDELab (git)

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
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(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
Default exception if an error in the parallel communication of the program occurred.
Definition: exceptions.hh:287
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:218
Implements an utility class that provides MPI's collective communication methods.
Helpers for dealing with MPI.
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 23, 23:29, 2024)