ALPSCore reference
accumulator_wrapper.cpp
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 
8 #include <sstream>
9 
10 namespace alps {
11  namespace accumulators {
12 
13  //
14  // constructors
15  //
16 
18  : m_variant()
19  {}
20 
22  : m_variant(rhs.m_variant)
23  {}
24 
26  ar[""] >> *this;
27  }
28 
29  //
30  // merge
31  //
32 
34  struct accumulator_wrapper::merge_visitor: public boost::static_visitor<> {
35  // The accumulator we want to merge (RHS):
36  const accumulator_wrapper& rhs_acc;
37 
38  // Remember the RHS accumulator
39  merge_visitor(const accumulator_wrapper& b): rhs_acc(b) {}
40 
41  // This is called by apply_visitor()
42  template <typename P> // P can be dereferenced to base_wrapper<T>
43  void operator()(P& lhs_ptr)
44  {
45  const P* rhs_ptr=boost::get<P>(& rhs_acc.m_variant);
46  if (!rhs_ptr) throw std::runtime_error("Only accumulators of the same type can be merged"
47  + ALPS_STACKTRACE);
48  detail::check_ptr(*rhs_ptr);
49  lhs_ptr->merge(**rhs_ptr);
50  }
51  };
53  merge_visitor visitor(rhs_acc);
54  boost::apply_visitor(visitor, m_variant);
55  }
56 
57  //
58  // clone / new_clone
59  //
60 
61  struct accumulator_wrapper::copy_visitor: public boost::static_visitor<> {
62  accumulator_wrapper& acc_wrap_;
63  copy_visitor(accumulator_wrapper& aw): acc_wrap_(aw) {}
64 
65  template <typename T> // T is shared_ptr< base_wrapper<U> >
66  void operator()(const T& val)
67  {
68  acc_wrap_.m_variant=T(val->clone());
69  }
70  };
72  {
74  copy_visitor vis(result);
75  boost::apply_visitor(vis, m_variant);
76  return result;
77  }
79  {
81  copy_visitor vis(*result);
82  boost::apply_visitor(vis, m_variant);
83  return result;
84  }
85 
86  //
87  // operator=
88  //
89 
90  struct accumulator_wrapper::assign_visitor: public boost::static_visitor<> {
91  assign_visitor(accumulator_wrapper * s): self(s) {}
92  template<typename T> void operator()(T & arg) const {
93  self->m_variant = arg;
94  }
95  mutable accumulator_wrapper * self;
96  };
97  accumulator_wrapper & accumulator_wrapper::operator=(std::shared_ptr<accumulator_wrapper> const & rhs) {
98  boost::apply_visitor(assign_visitor(this), rhs->m_variant);
99  return *this;
100  }
101 
102  //
103  // count
104  //
105 
106  struct count_visitor: public boost::static_visitor<boost::uint64_t> {
107  template<typename T> boost::uint64_t operator()(T const & arg) const {
108  detail::check_ptr(arg);
109  return arg->count();
110  }
111  };
112  boost::uint64_t accumulator_wrapper::count() const {
113  count_visitor visitor;
114  return boost::apply_visitor(visitor, m_variant);
115  }
116 
117  //
118  // save
119  //
120 
121  struct save_visitor: public boost::static_visitor<> {
122  save_visitor(hdf5::archive & a): ar(a) {}
123  template<typename T> void operator()(T & arg) const {
124  detail::check_ptr(arg);
125  ar[""] = *arg;
126  }
127  hdf5::archive & ar;
128  };
130  boost::apply_visitor(save_visitor(ar), m_variant);
131  }
132 
133  //
134  // load
135  //
136 
137  struct load_visitor: public boost::static_visitor<> {
138  load_visitor(hdf5::archive & a): ar(a) {}
139  template<typename T> void operator()(T const & arg) const {
140  detail::check_ptr(arg);
141  ar[""] >> *arg;
142  }
143  hdf5::archive & ar;
144  };
146  boost::apply_visitor(load_visitor(ar), m_variant);
147  }
148 
149  //
150  // reset
151  //
152 
153  struct reset_visitor: public boost::static_visitor<> {
154  template<typename T> void operator()(T const & arg) const {
155  detail::check_ptr(arg);
156  arg->reset();
157  }
158  };
160  boost::apply_visitor(reset_visitor(), m_variant);
161  }
162 
163  //
164  // result
165  //
166 
167  struct result_visitor: public boost::static_visitor<> {
168  template<typename T> void operator()(T const & arg) {
169  detail::check_ptr(arg);
170  value = std::shared_ptr<result_wrapper>(new result_wrapper(arg->result()));
171  }
172  std::shared_ptr<result_wrapper> value;
173  };
174  std::shared_ptr<result_wrapper> accumulator_wrapper::result() const {
175  result_visitor visitor;
176  boost::apply_visitor(visitor, m_variant);
177  return visitor.value;
178  }
179 
180  //
181  // print
182  //
183 
184  struct print_visitor: public boost::static_visitor<> {
185  print_visitor(std::ostream & o, bool t): os(o), terse(t) {}
186  template<typename T> void operator()(T const & arg) const {
187  detail::check_ptr(arg);
188  arg->print(os, terse);
189  }
190  std::ostream & os;
191  bool terse;
192  };
193  void accumulator_wrapper::print(std::ostream & os, bool terse) const {
194  boost::apply_visitor(print_visitor(os, terse), m_variant);
195  }
196 
197  //
198  // collective_merge
199  //
200 
201 #ifdef ALPS_HAVE_MPI
202  struct collective_merge_visitor: public boost::static_visitor<> {
203  collective_merge_visitor(alps::mpi::communicator const & c, int r): comm(c), root(r) {}
204  template<typename T> void operator()(T & arg) const { arg->collective_merge(comm, root); }
205  template<typename T> void operator()(T const & arg) const { arg->collective_merge(comm, root); }
206  alps::mpi::communicator const & comm;
207  int root;
208  };
209 
210  void accumulator_wrapper::collective_merge(alps::mpi::communicator const & comm, int root) {
211  boost::apply_visitor(collective_merge_visitor(comm, root), m_variant);
212  if (comm.rank()!=root) this->reset();
213  }
214 #endif
215 
216  //
217  // Free functions
218  //
219 
220  std::ostream & operator<<(std::ostream & os, const accumulator_wrapper & arg) {
221  arg.print(os, false); // verbose (non-terse) printing by default
222  return os;
223  }
224  detail::printable_type short_print(const accumulator_wrapper& arg)
225  {
226  std::ostringstream ostr;
227  arg.print(ostr,true);
228  return ostr.str();
229  }
230 
231  detail::printable_type full_print(const accumulator_wrapper& arg)
232  {
233  std::ostringstream ostr;
234  arg.print(ostr,false);
235  return ostr.str();
236  }
237 
239  return arg.reset();
240  }
241 
242  }
243 }
detail::printable_type short_print(const result_wrapper &arg)
Return an "ostream-able" object to print result in a terse format.
Encapsulation of an MPI communicator and some communicator-related operations.
Definition: mpi.hpp:111
accumulator_wrapper & operator=(std::shared_ptr< accumulator_wrapper > const &rhs)
F::result_type apply_visitor(F &visitor, dictionary::const_iterator it)
Const-access visitor to a value by an iterator.
Definition: dictionary.hpp:110
detail::printable_type full_print(const result_wrapper &arg)
Return an "ostream-able" object to print result in a verbose format.
void merge(const accumulator_wrapper &rhs_acc)
Merge another accumulator into this one.
std::shared_ptr< result_wrapper > result() const
#define ALPS_STACKTRACE
Definition: stacktrace.hpp:37
int rank() const
Returns process rank in this communicator.
Definition: mpi.hpp:156
T r(T x, T y=T(), T z=T())
accumulator_wrapper * new_clone() const
Returns a pointer to a new-allocated copy with the wrapped accumulator cloned.
accumulator_wrapper & operator<<(T const &value)
void print(std::ostream &os, bool terse=false) const
accumulator_wrapper clone() const
Returns a copy with the wrapped accumulator cloned.