Dune Core Modules (2.9.1)

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
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
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
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)