Skip to content
Snippets Groups Projects
Commit e2e2bbd0 authored by Jonas Greitemann's avatar Jonas Greitemann
Browse files

Enable rebind_communicator in update multiplexer

...using type traits and meta programming. The multiplexer (mux) will
only support the rebind_communicator member function if at least one of
its constituent updates has it. The mux then forward the call only to
those. The `pt_adapter` assumes that the simulation base class supports
rebind_communicator to pass it on; however this mechanism always one to
use the frustmag simulation w/o parallel tempering in which case also no
`mpi::communicator` has to be defined, i.e. the program compiles without
MPI headers and libs.
parent d1802f0d
No related branches found
No related tags found
No related merge requests found
......@@ -36,7 +36,7 @@
#include <vector>
template <typename Hamiltonian, template <typename> typename Update>
class frustmag_sim : public alps::mcbase, Update<Hamiltonian> {
class frustmag_sim : public alps::mcbase, protected Update<Hamiltonian> {
using rng_type = std::mt19937;
#ifdef USE_CONCEPTS
static_assert(LatticeHamiltonian<Hamiltonian, rng_type>,
......
......@@ -25,8 +25,48 @@
#include <type_traits>
#include <utility>
// forward declaration
namespace mpi {
struct communicator;
}
namespace update {
namespace {
template <typename...>
using void_t = void;
template <typename B>
struct negation : std::integral_constant<bool, !bool(B::value)> {};
template <typename T>
static auto test_rebind_communicator(int)
-> detail::sfinae_true<decltype(
std::declval<T>().rebind_communicator(
std::declval<mpi::communicator const&>()))>;
template <typename>
static auto test_rebind_communicator(long) -> std::false_type;
template <typename T>
struct communicator_rebindable : decltype(test_rebind_communicator<T>(0)) {};
template <bool...>
struct bool_pack;
template <bool... bs>
using all_true = std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>;
template <bool... bs>
using all_false = std::is_same<bool_pack<bs..., false>, bool_pack<false, bs...>>;
template <bool... bs>
using any_true = negation<all_false<bs...>>;
template <bool... bs>
using any_false = negation<all_true<bs...>>;
}
template <typename LatticeH, template <typename> typename... Updates>
struct mux {
#ifdef USE_CONCEPTS
......@@ -45,7 +85,7 @@ public:
}
mux(alps::params const& parameters)
: updates{(static_cast<std::void_t<Updates<LatticeH>>>(0), parameters)...}
: updates{(static_cast<void_t<Updates<LatticeH>>>(0), parameters)...}
{
}
......@@ -55,6 +95,12 @@ public:
return update_impl(hamiltonian, rng, Indices{});
}
template <typename = std::enable_if_t<any_true<communicator_rebindable<Updates<LatticeH>>::value...>::value>>
void rebind_communicator(mpi::communicator const& comm_new) {
using Indices = std::make_index_sequence<sizeof...(Updates)>;
rebind_communicator_impl(comm_new, Indices{});
}
private:
template <typename RNG, size_t... I>
acceptance_type update_impl(LatticeH & hamiltonian, RNG & rng,
......@@ -62,6 +108,30 @@ private:
{
return {std::get<I>(updates).update(hamiltonian, rng)[0]...};
}
template <size_t... I>
void rebind_communicator_impl(mpi::communicator const& comm_new,
std::index_sequence<I...>)
{
int dummy[] =
{rebind_communicator_if_possible(std::get<I>(updates), comm_new)...};
}
template <typename Update,
typename = std::enable_if_t<communicator_rebindable<Update>::value>>
int rebind_communicator_if_possible(Update & u,
mpi::communicator const& comm_new)
{
u.rebind_communicator(comm_new);
return 0;
}
template <typename Update,
typename = std::enable_if_t<!communicator_rebindable<Update>::value>,
int dummy = 0>
int rebind_communicator_if_possible(Update &, mpi::communicator const&) {
return 0;
}
};
template <template <typename> typename... Updates>
......
......@@ -44,7 +44,11 @@
#include <boost/multi_array.hpp>
#ifdef FRUSTMAG
using sim_type = pt_adapter<test_adapter<sim_base>>;
#else
using sim_type = embarrassing_adapter<test_adapter<sim_base>>;
#endif
using results_type = alps::results_type<sim_type>::type;
int main(int argc, char** argv)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment