ALPSCore reference
mpi_variant.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 
14 #ifndef ALPS_PARAMS_MPI_VARIANT_HPP_69d56023ac6048ca987f4be0f67122af
15 #define ALPS_PARAMS_MPI_VARIANT_HPP_69d56023ac6048ca987f4be0f67122af
16 
19 
21 
22 #include <cassert>
23 
24 namespace alps {
25  namespace mpi {
26 
27  inline void broadcast(const alps::mpi::communicator&, alps::params_ns::detail::None&, int) {
28  //std::cout << "DEBUG: Broadcasting None is no-op" << std::endl;
29  }
30 
31  namespace detail {
33  struct broadcast_sender {
34  const alps::mpi::communicator& comm_;
35  int root_;
36 
37  broadcast_sender(const alps::mpi::communicator& comm, int root) : comm_(comm), root_(root) {}
38 
39  template <typename T>
40  void operator()(const T& val) {
42  assert(comm_.rank()==root_ && "Should be only called by broadcast root");
43  broadcast(comm_, const_cast<T&>(val), root_);
44  }
45  };
46 
48  struct broadcast_receiver {
49  int target_which;
50  int which_count;
51  const alps::mpi::communicator& comm_;
52  int root_;
53 
54  broadcast_receiver(int which, const alps::mpi::communicator& comm, int root)
55  : target_which(which), which_count(0), comm_(comm), root_(root)
56  {}
57 
58  template <typename T>
59  boost::optional<T> operator()(const T*)
60  {
62  assert(comm_.rank()!=root_ && "Should NOT be called by broadcast root");
63  boost::optional<T> ret;
64  if (target_which==which_count) {
65  T val;
66  broadcast(comm_, val, root_);
67  ret=val;
68  }
69  ++which_count;
70  return ret;
71  }
72  };
73 
74  typedef alps::detail::variant_serializer<alps::params_ns::detail::dict_all_types,
75  broadcast_sender, broadcast_receiver> var_serializer;
76  typedef var_serializer::variant_type variant_type;
77 
78  } // detail::
79 
81  template <typename MPLSEQ>
82  inline void broadcast(const communicator& comm, typename boost::make_variant_over<MPLSEQ>::type& var, int root)
83  {
85 
86  int which=var.which();
87  broadcast(comm, which, root);
88 
89  if (comm.rank()==root) {
90  detail::broadcast_sender consumer(comm, root);
91  detail::var_serializer::consume(consumer, var);
92  } else {
93  detail::broadcast_receiver producer(which, comm, root);
94  var=detail::var_serializer::produce(producer);
95  }
96  }
97 
98  } // mpi::
99 } // alps::
100 
101 #endif /* ALPS_PARAMS_MPI_VARIANT_HPP_69d56023ac6048ca987f4be0f67122af */
Encapsulation of an MPI communicator and some communicator-related operations.
Definition: mpi.hpp:111
Header for boost::variant serialization.
Header for object-oriented interface to MPI for std::pair.
int rank() const
Returns process rank in this communicator.
Definition: mpi.hpp:156
void broadcast(const communicator &comm, T *vals, std::size_t count, int root)
Broadcasts array vals of a primitive type T, length count on communicator comm with root root ...
Definition: mpi.hpp:270