vSMC
vSMC: Scalable Monte Carlo
backend_ppl.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/smp/backend_ppl.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_SMP_BACKEND_PPL_HPP
33 #define VSMC_SMP_BACKEND_PPL_HPP
34 
36 #include <ppl.h>
37 
38 namespace vsmc {
39 
41 
42 template <typename BaseState>
45 class StatePPL : public BaseState
46 {
47  public :
48 
50 
51  explicit StatePPL (size_type N) : BaseState(N) {}
52 
53  template <typename IntType>
54  void copy (size_type N, const IntType *copy_from)
55  {
57 
58  ::concurrency::parallel_for(static_cast<size_type>(0), N,
59  copy_work_<IntType>(this, copy_from));
60  }
61 
62  private :
63 
64  template <typename IntType>
65  struct copy_work_
66  {
67  copy_work_ (StatePPL<BaseState> *state, const IntType *copy_from) :
68  state_(state), copy_from_(copy_from) {}
69 
70  void operator() (size_type to) const
71  {state_->copy_particle(copy_from_[to], to);}
72 
73  private :
74 
75  StatePPL<BaseState> *const state_;
76  const IntType *const copy_from_;
77  }; // class copy_work_
78 }; // class StatePPL
79 
82 template <typename T, typename Derived>
83 class InitializePPL : public InitializeBase<T, Derived>
84 {
85  public :
86 
87  std::size_t operator() (Particle<T> &particle, void *param)
88  {
89  typedef typename Particle<T>::size_type size_type;
90  const size_type N = static_cast<size_type>(particle.size());
91  this->initialize_param(particle, param);
92  this->pre_processor(particle);
93  ::concurrency::combinable<std::size_t> accept(accept_init_);
94  ::concurrency::parallel_for(static_cast<size_type>(0), N,
95  work_(this, &particle, &accept));
96  this->post_processor(particle);
97 
98  return accept.combine(accept_accu_);
99  }
100 
101  protected :
102 
103  VSMC_DEFINE_SMP_IMPL_COPY(PPL, Initialize)
104 
105  private :
106 
107  struct work_
108  {
109  typedef typename Particle<T>::size_type size_type;
110 
111  work_ (InitializePPL<T, Derived> *init,
112  Particle<T> *particle,
113  ::concurrency::combinable<std::size_t> *accept) :
114  init_(init), particle_(particle), accept_(accept) {}
115 
116  void operator() (size_type i) const
117  {
118  accept_->local() += init_->initialize_state(
119  SingleParticle<T>(i, particle_));
120  }
121 
122  private :
123 
124  InitializePPL<T, Derived> *const init_;
125  Particle<T> *const particle_;
126  ::concurrency::combinable<std::size_t> *const accept_;
127  }; // class work_
128 
129  static std::size_t accept_init_ () {return 0;}
130  static std::size_t accept_accu_ (std::size_t a, std::size_t b)
131  {return a + b;}
132 }; // class InitializePPL
133 
136 template <typename T, typename Derived>
137 class MovePPL : public MoveBase<T, Derived>
138 {
139  public :
140 
141  std::size_t operator() (std::size_t iter, Particle<T> &particle)
142  {
143  typedef typename Particle<T>::size_type size_type;
144  const size_type N = static_cast<size_type>(particle.size());
145  this->pre_processor(iter, particle);
146  ::concurrency::combinable<std::size_t> accept(accept_init_);
147  ::concurrency::parallel_for(static_cast<size_type>(0), N,
148  work_(this, iter, &particle, &accept));
149  this->post_processor(iter, particle);
150 
151  return accept.combine(accept_accu_);
152  }
153 
154  protected :
155 
157 
158  private :
159 
160  struct work_
161  {
162  typedef typename Particle<T>::size_type size_type;
163 
164  work_ (MovePPL<T, Derived> *move, std::size_t iter,
165  Particle<T> *particle,
166  ::concurrency::combinable<std::size_t> *accept):
167  move_(move), particle_(particle), accept_(accept), iter_(iter) {}
168 
169  void operator() (size_type i) const
170  {
171  accept_->local() += move_->move_state(iter_,
172  SingleParticle<T>(i, particle_));
173  }
174 
175  private :
176 
177  MovePPL<T, Derived> *const move_;
178  Particle<T> *const particle_;
179  ::concurrency::combinable<std::size_t> *const accept_;
180  const std::size_t iter_;
181  }; // class work_
182 
183  static std::size_t accept_init_ () {return 0;}
184  static std::size_t accept_accu_ (std::size_t a, std::size_t b)
185  {return a + b;}
186 }; // class MovePPL
187 
190 template <typename T, typename Derived>
191 class MonitorEvalPPL : public MonitorEvalBase<T, Derived>
192 {
193  public :
194 
195  void operator() (std::size_t iter, std::size_t dim,
196  const Particle<T> &particle, double *res)
197  {
198  typedef typename Particle<T>::size_type size_type;
199  const size_type N = static_cast<size_type>(particle.size());
200  this->pre_processor(iter, particle);
201  ::concurrency::parallel_for(static_cast<size_type>(0), N,
202  work_(this, iter, dim, &particle, res));
203  this->post_processor(iter, particle);
204  }
205 
206  protected :
207 
208  VSMC_DEFINE_SMP_IMPL_COPY(PPL, MonitorEval)
209 
210  private :
211 
212  struct work_
213  {
214  typedef typename Particle<T>::size_type size_type;
215 
216  work_ (MonitorEvalPPL<T, Derived> *monitor,
217  std::size_t iter, std::size_t dim,
218  const Particle<T> *particle, double *res) :
219  monitor_(monitor), particle_(particle), res_(res),
220  iter_(iter), dim_(dim) {}
221 
222  void operator() (size_type i) const
223  {
224  monitor_->monitor_state(iter_, dim_,
225  ConstSingleParticle<T>(i, particle_), res_ + i * dim_);
226  }
227 
228  private :
229 
230  MonitorEvalPPL<T, Derived> *const monitor_;
231  const Particle<T> *const particle_;
232  double *const res_;
233  const std::size_t iter_;
234  const std::size_t dim_;
235  }; // class work_
236 }; // class MonitorEvalPPL
237 
240 template <typename T, typename Derived>
241 class PathEvalPPL : public PathEvalBase<T, Derived>
242 {
243  public :
244 
245  double operator() (std::size_t iter, const Particle<T> &particle,
246  double *res)
247  {
248  typedef typename Particle<T>::size_type size_type;
249  const size_type N = static_cast<size_type>(particle.size());
250  this->pre_processor(iter, particle);
251  ::concurrency::parallel_for(static_cast<size_type>(0), N,
252  work_(this, iter, &particle, res));
253  this->post_processor(iter, particle);
254 
255  return this->path_grid(iter, particle);
256  }
257 
258  protected :
259 
261 
262  private :
263 
264  struct work_
265  {
266  typedef typename Particle<T>::size_type size_type;
267 
268  work_ (PathEvalPPL<T, Derived> *path, std::size_t iter,
269  const Particle<T> *particle, double *res) :
270  path_(path), particle_(particle), res_(res), iter_(iter) {}
271 
272  void operator() (size_type i) const
273  {
274  res_[i] = path_->path_state(iter_,
275  ConstSingleParticle<T>(i, particle_));
276  }
277 
278  private :
279 
280  PathEvalPPL<T, Derived> *const path_;
281  const Particle<T> *const particle_;
282  double *const res_;
283  const std::size_t iter_;
284  }; // class work_
285 }; // PathEvalPPL
286 
287 } // namespace vsmc
288 
289 #endif // VSMC_SMP_BACKEND_PPL_HPP
Sampler::init_type subtype using Parallel Pattern Library.
Definition: backend_ppl.hpp:40
Definition: adapter.hpp:37
Particle class representing the whole particle set.
Definition: particle.hpp:48
void initialize_param(Particle< T > &particle, void *param)
traits::SizeTypeTrait< BaseState >::type size_type
Definition: backend_ppl.hpp:49
#define VSMC_RUNTIME_ASSERT_SMP_BACKEND_BASE_COPY_SIZE_MISMATCH(name)
Path::eval_type subtype using Parallel Pattern Library.
Definition: backend_ppl.hpp:40
void pre_processor(Particle< T > &particle)
void post_processor(std::size_t iter, const Particle< T > &particle)
double path_grid(std::size_t iter, const Particle< T > &particle)
void post_processor(std::size_t iter, Particle< T > &particle)
void operator()(std::size_t iter, std::size_t dim, const Particle< T > &particle, double *res)
void pre_processor(std::size_t iter, Particle< T > &particle)
StatePPL(size_type N)
Definition: backend_ppl.hpp:51
void post_processor(std::size_t iter, const Particle< T > &particle)
void copy(size_type N, const IntType *copy_from)
Definition: backend_ppl.hpp:54
Monitor::eval_type subtype using Parallel Pattern Library.
Definition: backend_ppl.hpp:40
remove_reference< T >::type && move(T &&t) noexcept
void pre_processor(std::size_t iter, const Particle< T > &particle)
Sampler::move_type subtype using Parallel Pattern Library.
Definition: backend_ppl.hpp:40
traits::SizeTypeTrait< T >::type size_type
Definition: particle.hpp:52
internal::SizeTypeDispatch< T, value >::type type
Definition: traits.hpp:148
void post_processor(Particle< T > &particle)
Particle::value_type subtype using Parallel Pattern Library.
Definition: backend_ppl.hpp:45
size_type size() const
Number of particles.
Definition: particle.hpp:146
std::size_t operator()(Particle< T > &particle, void *param)
Definition: backend_ppl.hpp:87
A thin wrapper over a complete Particle.
void pre_processor(std::size_t iter, const Particle< T > &particle)
std::size_t operator()(std::size_t iter, Particle< T > &particle)
#define VSMC_DEFINE_SMP_FORWARD(Name)
Definition: forward.hpp:38
A const variant to SingleParticle.
#define VSMC_DEFINE_SMP_IMPL_COPY(Impl, Name)
double operator()(std::size_t iter, const Particle< T > &particle, double *res)
void parallel_for(const Range &range, WorkType &&work)
Parallel for using std::thread.