vSMC
vSMC: Scalable Monte Carlo
state_tuple.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/core/state_tuple.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013,2014, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef VSMC_CORE_STATE_TUPLE_HPP
33 #define VSMC_CORE_STATE_TUPLE_HPP
34 
35 #include <vsmc/internal/common.hpp>
37 #include <tuple>
38 
39 #define VSMC_RUNTIME_ASSERT_CORE_STATE_TUPLE_COPY_SIZE_MISMATCH \
40  VSMC_RUNTIME_ASSERT((N == static_cast<size_type>(this->size())), \
41  ("**StateTuple::copy** SIZE MISMATCH"))
42 
43 namespace vsmc {
44 
47 template <MatrixOrder Order, typename T, typename... Types>
49 {
50  public :
51 
52  typedef std::size_t size_type;
53  typedef std::tuple<T, Types...> state_tuple_type;
54  typedef std::tuple<T *, Types *...> state_tuple_ptr_type;
55  typedef std::tuple<const T *, const Types *...> state_tuple_cptr_type;
56 
57  template <std::size_t Pos> struct state_type
58  {typedef typename std::tuple_element<Pos, state_tuple_type>::type type;};
59 
61  {
63 
64  state_pack_type (const state_pack_type &other) : data_(other.data_) {}
65 
66  state_pack_type (const state_tuple_type &tp) : data_(tp) {}
67 
69  {
70  if (this != &other)
71  data_ = other.data_;
72 
73  return *this;
74  }
75 
76 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
78  data_(cxx11::move(other.data_)) {}
79 
80  state_pack_type (state_tuple_type &&tp) : data_(cxx11::move(tp)) {}
81 
83  {
84  if (this != &other)
85  data_ = cxx11::move(other.data_);
86 
87  return *this;
88  }
89 #endif
90 
91  state_tuple_type &data () {return data_;}
92 
93  const state_tuple_type &data () const {return data_;}
94 
95  template <typename Archive>
96  void serialize (Archive &ar, const unsigned)
97  {serialize(ar, Position<0>());}
98 
99  template <typename Archive>
100  void serialize (Archive &ar, const unsigned) const
101  {serialize(ar, Position<0>());}
102 
103  private :
104 
105  state_tuple_type data_;
106  static VSMC_CONSTEXPR const std::size_t dim_ = sizeof...(Types) + 1;
107 
108  template <typename Archive, std::size_t Pos>
109  void serialize (Archive &ar, Position<Pos>)
110  {
111  ar & std::get<Pos>(data_);
113  }
114 
115  template <typename Archive>
116  void serialize (Archive &, Position<dim_>) {}
117 
118  template <typename Archive, std::size_t Pos>
119  void serialize (Archive &ar, Position<Pos>) const
120  {
121  ar & std::get<Pos>(data_);
122  serialize(ar, Position<Pos + 1>());
123  }
124 
125  template <typename Archive>
126  void serialize (Archive &, Position<dim_>) const {}
127  }; // struct state_pack_type
128 
129  template <typename S>
131  {
134  SingleParticleBase<S>(id, particle_ptr) {}
135 
136  static VSMC_CONSTEXPR std::size_t dim () {return S::dim();}
137 
138  template <std::size_t Pos>
140  {
141  return this->mutable_particle_ptr()->value().
142  state(this->id(), Position<Pos>());
143  }
144 
145  template <std::size_t Pos>
146  typename state_type<Pos>::type &state () const
147  {return this->state(Position<Pos>());}
148  }; // struct single_particle_type
149 
150  template <typename S>
152  {
154  const Particle<S> *particle_ptr) :
155  ConstSingleParticleBase<S>(id, particle_ptr) {}
156 
157  static VSMC_CONSTEXPR std::size_t dim () {return S::dim();}
158 
159  template <std::size_t Pos>
160  const typename state_type<Pos>::type &state (Position<Pos>) const
161  {
162  return this->particle_ptr()->value().
163  state(this->id(), Position<Pos>());
164  }
165 
166  template <std::size_t Pos>
167  const typename state_type<Pos>::type &state () const
168  {return this->state(Position<Pos>());}
169  }; // struct const_single_particle_type
170 
171  size_type size () const {return size_;}
172 
173  static VSMC_CONSTEXPR std::size_t dim () {return dim_;}
174 
175  template <std::size_t Pos, typename OutputIter>
176  void read_state (Position<Pos>, OutputIter first) const
177  {
178  const StateTuple<Order, T, Types...> *sptr =
179  static_cast<const StateTuple<Order, T, Types...> *>(this);
180  for (size_type i = 0; i != size_; ++i, ++first)
181  *first = sptr->state(i, Position<Pos>());
182  }
183 
184  template <std::size_t Pos, typename OutputIter>
185  void read_state (OutputIter first) const
186  {read_state(Position<Pos>(), first);}
187 
188  template <typename CharT, typename Traits>
189  std::basic_ostream<CharT, Traits> &print (
190  std::basic_ostream<CharT, Traits> &os, char sepchar = '\t') const
191  {
192  if (dim_ == 0 || size_ == 0 || !os.good())
193  return os;
194 
195  for (size_type i = 0; i != size_; ++i)
196  print_particle(os, i, sepchar, Position<0>());
197 
198  return os;
199  }
200 
201  protected :
202 
203  explicit StateTupleBase (size_type N) : size_(N) {}
204 
205  private :
206 
207  size_type size_;
208  static VSMC_CONSTEXPR const std::size_t dim_ = sizeof...(Types) + 1;
209 
210  template <std::size_t Pos, typename CharT, typename Traits>
211  void print_particle (std::basic_ostream<CharT, Traits> &os, size_type id,
212  char sepchar, Position<Pos>) const
213  {
214  const StateTuple<Order, T, Types...> *sptr =
215  static_cast<const StateTuple<Order, T, Types...> *>(this);
216  os << sptr->state(id, Position<Pos>()) << sepchar;
217  print_particle(os, id, sepchar, Position<Pos + 1>());
218  }
219 
220  template <typename CharT, typename Traits>
221  void print_particle (std::basic_ostream<CharT, Traits> &os, size_type id,
222  char, Position<dim_ - 1>) const
223  {
224  const StateTuple<Order, T, Types...> *sptr =
225  static_cast<const StateTuple<Order, T, Types...> *>(this);
226  os << sptr->state(id, Position<dim_ - 1>()) << '\n';
227  }
228 }; // class StateTupleBase
229 
230 template <typename CharT, typename Traits,
231  MatrixOrder Order, typename T, typename... Types>
232 inline std::basic_ostream<CharT, Traits> &operator<< (
233  std::basic_ostream<CharT, Traits> &os,
235 {return stuple.print(os);}
236 
239 template <typename T, typename... Types>
240 class StateTuple<RowMajor, T, Types...> :
241  public StateTupleBase<RowMajor, T, Types...>
242 {
243  public :
244 
245  typedef StateTupleBase<RowMajor, T, Types...>
248  typedef typename state_tuple_base_type::state_pack_type state_pack_type;
249 
250  explicit StateTuple (size_type N) : state_tuple_base_type(N), state_(N) {}
251 
252  template <std::size_t Pos>
253  typename state_tuple_base_type::template state_type<Pos>::type
254  &state (size_type id, Position<Pos>)
255  {return std::get<Pos>(state_[id]);}
256 
257  template <std::size_t Pos>
258  const typename state_tuple_base_type::template state_type<Pos>::type
259  &state (size_type id, Position<Pos>) const
260  {return std::get<Pos>(state_[id]);}
261 
262  template <std::size_t Pos>
263  typename state_tuple_base_type::template state_type<Pos>::type
264  &state (size_type id)
265  {return state(id, Position<Pos>());}
266 
267  template <std::size_t Pos>
268  const typename state_tuple_base_type::template state_type<Pos>::type
269  &state (size_type id) const
270  {return state(id, Position<Pos>());}
271 
273  {return &state_[0];}
274 
276  {return &state_[0];}
277 
278  template <typename IntType>
279  void copy (size_type N, const IntType *copy_from)
280  {
282 
283  for (size_type to = 0; to != N; ++to)
284  copy_particle(copy_from[to], to);
285  }
286 
287  void copy_particle (size_type from, size_type to)
288  {state_[to] = state_[from];}
289 
290  state_pack_type state_pack (size_type id) const
291  {return state_pack_type(state_[id]);}
292 
293  void state_unpack (size_type id, const state_pack_type &pack)
294  {state_[id] = pack.data();}
295 
296 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
297  void state_unpack (size_type id, state_pack_type &&pack)
298  {state_[id] = cxx11::move(pack.data());}
299 #endif
300 
301  private :
302 
303  static VSMC_CONSTEXPR const std::size_t dim_ = sizeof...(Types) + 1;
304  std::vector<std::tuple<T, Types...> > state_;
305 }; // StateTuple
306 
309 template <typename T, typename... Types>
310 class StateTuple<ColMajor, T, Types...> :
311  public StateTupleBase<ColMajor, T, Types...>
312 {
313  public :
314 
315  typedef StateTupleBase<ColMajor, T, Types...>
318  typedef typename state_tuple_base_type::state_pack_type state_pack_type;
319 
320  explicit StateTuple (size_type N) : state_tuple_base_type(N)
321  {init_state(N, Position<0>());}
322 
323  template <std::size_t Pos>
324  typename state_tuple_base_type::template state_type<Pos>::type
325  &state (size_type id, Position<Pos>)
326  {return std::get<Pos>(state_)[id];}
327 
328  template <std::size_t Pos>
329  const typename state_tuple_base_type::template state_type<Pos>::type
330  &state (size_type id, Position<Pos>) const
331  {return std::get<Pos>(state_)[id];}
332 
333  template <std::size_t Pos>
334  typename state_tuple_base_type::template state_type<Pos>::type
335  &state (size_type id)
336  {return state(id, Position<Pos>());}
337 
338  template <std::size_t Pos>
339  const typename state_tuple_base_type::template state_type<Pos>::type
340  &state (size_type id) const
341  {return state(id, Position<Pos>());}
342 
343  template <std::size_t Pos>
344  typename state_tuple_base_type::template state_type<Pos>::type
345  *data (Position<Pos>) {return &std::get<Pos>(state_)[0];}
346 
347  template <std::size_t Pos>
348  const typename state_tuple_base_type::template state_type<Pos>::type
349  *data (Position<Pos>) const {return &std::get<Pos>(state_)[0];}
350 
351  template <std::size_t Pos>
352  typename state_tuple_base_type::template state_type<Pos>::type
353  *data () {return &std::get<Pos>(state_)[0];}
354 
355  template <std::size_t Pos>
356  const typename state_tuple_base_type::template state_type<Pos>::type
357  *data () const {return &std::get<Pos>(state_)[0];}
358 
360  {
362  insert_data(dptr, Position<0>());
363 
364  return dptr;
365  }
366 
368  {
370  insert_data(dptr, Position<0>());
371 
372  return dptr;
373  }
374 
375  template <typename IntType>
376  void copy (size_type N, const IntType *copy_from)
377  {
379 
380  for (size_type to = 0; to != N; ++to)
381  copy_particle(copy_from[to], to);
382  }
383 
384  void copy_particle (size_type from, size_type to)
385  {
386  if (from == to)
387  return;
388 
389  copy_particle(from, to, Position<0>());
390  }
391 
392  state_pack_type state_pack (size_type id) const
393  {
394  state_pack_type pack;
395  pack_particle(id, pack, Position<0>());
396 
397  return pack;
398  }
399 
400  void state_unpack (size_type id, const state_pack_type &pack)
401  {unpack_particle(id, pack, Position<0>());}
402 
403 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
404  void state_unpack (size_type id, state_pack_type &&pack)
405  {unpack_particle(id, cxx11::move(pack), Position<0>());}
406 #endif
407 
408  private :
409 
410  static VSMC_CONSTEXPR const std::size_t dim_ = sizeof...(Types) + 1;
411  std::tuple<std::vector<T>, std::vector<Types>...> state_;
412 
413  template <std::size_t Pos>
414  void init_state (size_type N, Position<Pos>)
415  {
416  std::get<Pos>(state_).resize(N);
417  init_state(N, Position<Pos + 1>());
418  }
419 
420  void init_state (size_type N, Position<sizeof...(Types)>)
421  {std::get<sizeof...(Types)>(state_).resize(N);}
422 
423  template <std::size_t Pos, typename PTRType>
424  void insert_data (PTRType &dptr, Position<Pos>) const
425  {
426  std::get<Pos>(dptr) = data<Pos>();
427  insert_data(dptr, Position<Pos + 1>());
428  }
429 
430  template <typename PTRType>
431  void insert_data (PTRType &dptr, Position<sizeof...(Types)>) const
432  {std::get<sizeof...(Types)>(dptr) = data<sizeof...(Types)>();}
433 
434  template <std::size_t Pos>
435  void copy_particle (size_type from, size_type to, Position<Pos>)
436  {
437  state(to, Position<Pos>()) = state(from, Position<Pos>());
438  copy_particle(from, to, Position<Pos + 1>());
439  }
440 
441  void copy_particle (size_type, size_type, Position<dim_>) {}
442 
443  template <std::size_t Pos>
444  void pack_particle (size_type id, state_pack_type &pack,
445  Position<Pos>) const
446  {
447  std::get<Pos>(pack.data()) = state(id, Position<Pos>());
448  pack_particle(id, pack, Position<Pos + 1>());
449  }
450 
451  void pack_particle (size_type, state_pack_type &,
452  Position<dim_>) const {}
453 
454  template <std::size_t Pos>
455  void unpack_particle (size_type id, const state_pack_type &pack,
456  Position<Pos>)
457  {
458  state(id, Position<Pos>()) = std::get<Pos>(pack.data());
459  unpack_particle(id, pack, Position<Pos + 1>());
460  }
461 
462  void unpack_particle (size_type, const state_pack_type &,
463  Position<dim_>) {}
464 
465 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
466  template <std::size_t Pos>
467  void unpack_particle (size_type id, state_pack_type &&pack,
468  Position<Pos>)
469  {
470  state(id, Position<Pos>()) = cxx11::move(std::get<Pos>(pack.data()));
471  unpack_particle(id, cxx11::move(pack), Position<Pos + 1>());
472  }
473 
474  void unpack_particle (size_type, state_pack_type &&, Position<dim_>) {}
475 #endif
476 }; // class StateTuple
477 
478 } // namespace vsmc
479 
480 #endif // VSMC_CORE_STATE_TUPLE_HPP
const state_tuple_base_type::template state_type< Pos >::type & state(size_type id, Position< Pos >) const
const Particle< S > * particle_ptr() const
state_tuple_base_type::template state_type< Pos >::type * data()
StateTupleBase< RowMajor, T, Types...> state_tuple_base_type
Definition: adapter.hpp:37
Particle class representing the whole particle set.
Definition: particle.hpp:48
Particle< S > * mutable_particle_ptr() const
state_tuple_base_type::state_tuple_type * data()
#define VSMC_CONSTEXPR
constexpr
Definition: defines.hpp:55
state_tuple_base_type::size_type size_type
const state_tuple_base_type::template state_type< Pos >::type * data() const
static constexpr std::size_t dim()
value_type & value()
Read and write access to the value collection object.
Definition: particle.hpp:149
state_pack_type(state_pack_type &&other)
Definition: state_tuple.hpp:77
void serialize(Archive &ar, const unsigned)
Definition: state_tuple.hpp:96
void state_unpack(size_type id, const state_pack_type &pack)
const state_tuple_base_type::template state_type< Pos >::type & state(size_type id) const
const state_type< Pos >::type & state(Position< Pos >) const
#define VSMC_RUNTIME_ASSERT_CORE_STATE_TUPLE_COPY_SIZE_MISMATCH
Definition: state_tuple.hpp:39
const_single_particle_type(typename Particle< S >::size_type id, const Particle< S > *particle_ptr)
state_tuple_base_type::state_pack_type state_pack_type
state_type< Pos >::type & state() const
StateTupleBase(size_type N)
Base type of StateTuple.
Definition: state_tuple.hpp:48
std::tuple< const T *, const Types *...> state_tuple_cptr_type
Definition: state_tuple.hpp:55
void read_state(Position< Pos >, OutputIter first) const
const state_tuple_base_type::state_tuple_type * data() const
const state_tuple_base_type::template state_type< Pos >::type & state(size_type id) const
Function template argument used for position.
Definition: defines.hpp:126
void copy_particle(size_type from, size_type to)
Data are stored column by column in memory.
Definition: defines.hpp:104
T & get(Array< T, N > &ary)
Array ADL of get.
Definition: array.hpp:322
state_pack_type state_pack(size_type id) const
state_tuple_base_type::template state_type< Pos >::type & state(size_type id)
size_type size() const
state_tuple_base_type::state_tuple_ptr_type data()
void copy(size_type N, const IntType *copy_from)
state_tuple_base_type::state_tuple_cptr_type data() const
void copy_particle(size_type from, size_type to)
state_tuple_base_type::template state_type< Pos >::type & state(size_type id)
Data are stored row by row in memory.
Definition: defines.hpp:103
remove_reference< T >::type && move(T &&t) noexcept
std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const Sampler< T > &sampler)
Definition: sampler.hpp:884
A const variant to SingleParticle.
const state_tuple_type & data() const
Definition: state_tuple.hpp:93
const state_tuple_base_type::template state_type< Pos >::type * data(Position< Pos >) const
void serialize(Archive &ar, const unsigned) const
std::tuple< T, Types...> state_tuple_type
Definition: state_tuple.hpp:53
state_pack_type & operator=(const state_pack_type &other)
Definition: state_tuple.hpp:68
void state_unpack(size_type id, const state_pack_type &pack)
static constexpr std::size_t dim()
state_tuple_base_type::state_pack_type state_pack_type
std::tuple_element< Pos, state_tuple_type >::type type
Definition: state_tuple.hpp:58
state_pack_type state_pack(size_type id) const
state_tuple_base_type::template state_type< Pos >::type & state(size_type id, Position< Pos >)
const state_type< Pos >::type & state() const
MatrixOrder
Matrix order.
Definition: defines.hpp:102
state_tuple_base_type::template state_type< Pos >::type * data(Position< Pos >)
A thin wrapper over a complete Particle.
state_tuple_base_type::size_type size_type
std::basic_ostream< CharT, Traits > & print(std::basic_ostream< CharT, Traits > &os, char sepchar= '\t') const
state_pack_type(state_tuple_type &&tp)
Definition: state_tuple.hpp:80
state_pack_type(const state_tuple_type &tp)
Definition: state_tuple.hpp:66
std::size_t size_type
Definition: state_tuple.hpp:52
const Particle< S > * particle_ptr() const
void state_unpack(size_type id, state_pack_type &&pack)
void copy(size_type N, const IntType *copy_from)
state_type< Pos >::type & state(Position< Pos >) const
StateTupleBase< ColMajor, T, Types...> state_tuple_base_type
std::tuple< T *, Types *...> state_tuple_ptr_type
Definition: state_tuple.hpp:54
state_tuple_base_type::template state_type< Pos >::type & state(size_type id, Position< Pos >)
const state_tuple_base_type::template state_type< Pos >::type & state(size_type id, Position< Pos >) const
state_pack_type(const state_pack_type &other)
Definition: state_tuple.hpp:64
void read_state(OutputIter first) const
void state_unpack(size_type id, state_pack_type &&pack)
single_particle_type(typename Particle< S >::size_type id, Particle< S > *particle_ptr)