Loading...
Searching...
No Matches
mpiguard.hh
Go to the documentation of this file.
// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
// vi: set et ts=4 sw=2 sts=2:
// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
#ifndef DUNE_COMMON_PARALLEL_MPIGUARD_HH
#define DUNE_COMMON_PARALLEL_MPIGUARD_HH
#if HAVE_MPI
#include <mpi.h>
#endif
#include <dune/common/exceptions.hh>
#include <dune/common/parallel/communication.hh>
#include <dune/common/parallel/mpicommunication.hh>
#include <dune/common/parallel/mpihelper.hh>
namespace Dune
{
#ifndef DOXYGEN
/*
Interface class for the communication needed by MPIGuard
*/
struct GuardCommunicator
{
// cleanup
virtual ~GuardCommunicator() {};
// all the communication methods we need
virtual int rank() = 0;
virtual int size() = 0;
virtual int sum(int i) = 0;
// create a new GuardCommunicator pointer
template <class C>
static GuardCommunicator * create(const Communication<C> & c);
#if HAVE_MPI
inline
static GuardCommunicator * create(const MPI_Comm & c);
#endif
};
namespace {
/*
templated implementation of different communication classes
*/
// the default class will always fail, due to the missing implementation of "sum"
template <class Imp>
struct GenericGuardCommunicator
: public GuardCommunicator
{};
// specialization for Communication
template <class T>
struct GenericGuardCommunicator< Communication<T> >
: public GuardCommunicator
{
const Communication<T> comm;
GenericGuardCommunicator(const Communication<T> & c) :
comm(c) {}
int rank() override { return comm.rank(); };
int size() override { return comm.size(); };
int sum(int i) override { return comm.sum(i); }
};
#if HAVE_MPI
// specialization for MPI_Comm
template <>
struct GenericGuardCommunicator<MPI_Comm>
: public GenericGuardCommunicator< Communication<MPI_Comm> >
{
GenericGuardCommunicator(const MPI_Comm & c) :
GenericGuardCommunicator< Communication<MPI_Comm> >(
Communication<MPI_Comm>(c)) {}
};
#endif
} // anonymous namespace
template<class C>
GuardCommunicator * GuardCommunicator::create(const Communication<C> & comm)
{
return new GenericGuardCommunicator< Communication<C> >(comm);
}
#if HAVE_MPI
GuardCommunicator * GuardCommunicator::create(const MPI_Comm & comm)
{
return new GenericGuardCommunicator< Communication<MPI_Comm> >(comm);
}
#endif
#endif
class MPIGuardError : public ParallelError {};
class MPIGuard
{
GuardCommunicator * comm_;
bool active_;
// we don't want to copy this class
MPIGuard (const MPIGuard &);
public:
MPIGuard (bool active=true) :
comm_(GuardCommunicator::create(
MPIHelper::getCommunication())),
active_(active)
{}
MPIGuard (MPIHelper & m, bool active=true) :
comm_(GuardCommunicator::create(
m.getCommunication())),
active_(active)
{}
template <class C>
MPIGuard (const C & comm, bool active=true) :
comm_(GuardCommunicator::create(comm)),
active_(active)
{}
#if HAVE_MPI
MPIGuard (const MPI_Comm & comm, bool active=true) :
comm_(GuardCommunicator::create(comm)),
active_(active)
{}
#endif
~MPIGuard()
{
if (active_)
{
active_ = false;
finalize(false);
}
delete comm_;
}
void reactivate() {
if (active_ == true)
finalize();
active_ = true;
}
void finalize(bool success = true)
{
int result = success ? 0 : 1;
bool was_active = active_;
active_ = false;
result = comm_->sum(result);
if (result>0 && was_active)
{
DUNE_THROW(MPIGuardError, "Terminating process "
<< comm_->rank() << " due to "
<< result << " remote error(s)");
}
}
};
}
#endif // DUNE_COMMON_PARALLEL_MPIGUARD_HH
mpicommunication.hh
Implements an utility class that provides MPI's collective communication methods.
communication.hh
Implements an utility class that provides collective communication methods for sequential programs.
mpihelper.hh
Helpers for dealing with MPI.
exceptions.hh
A few common exception classes.
DUNE_THROW
#define DUNE_THROW(E,...)
Definition exceptions.hh:314
Dune
Dune namespace
Definition alignedallocator.hh:13
Dune::ParallelError
Default exception if an error in the parallel communication of the program occurred.
Definition exceptions.hh:381
Dune::Communication
Collective communication interface and sequential default implementation.
Definition communication.hh:100
Dune::MPIGuardError
This exception is thrown if the MPIGuard detects an error on a remote process.
Definition mpiguard.hh:103
Dune::MPIGuard::reactivate
void reactivate()
reactivate the guard.
Definition mpiguard.hh:206
Dune::MPIGuard::finalize
void finalize(bool success=true)
stop the guard.
Definition mpiguard.hh:222
Dune::MPIGuard::~MPIGuard
~MPIGuard()
destroy the guard and check for undetected exceptions
Definition mpiguard.hh:192
Dune::MPIGuard::MPIGuard
MPIGuard(const C &comm, bool active=true)
create an MPIGuard operating on an arbitrary communicator.
Definition mpiguard.hh:178
Dune::MPIGuard::MPIGuard
MPIGuard(const MPI_Comm &comm, bool active=true)
Definition mpiguard.hh:184
Dune::MPIGuard::MPIGuard
MPIGuard(bool active=true)
create an MPIGuard operating on the Communicator of the global Dune::MPIHelper
Definition mpiguard.hh:150
Dune::MPIGuard::MPIGuard
MPIGuard(MPIHelper &m, bool active=true)
create an MPIGuard operating on the Communicator of a special Dune::MPIHelper m
Definition mpiguard.hh:161
Dune::MPIHelper
A real mpi helper.
Definition mpihelper.hh:169