vSMC
vSMC: Scalable Monte Carlo
backend_base.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/smp/backend_base.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2016, 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_BASE_HPP
33 #define VSMC_SMP_BACKEND_BASE_HPP
34 
35 #include <vsmc/internal/common.hpp>
36 
37 #if VSMC_NO_RUNTIME_ASSERT
38 #define VSMC_BACKEND_BASE_DESTRUCTOR_PREFIX
39 #else
40 #define VSMC_BACKEND_BASE_DESTRUCTOR_PREFIX virtual
41 #endif
42 
43 #define VSMC_DEFINE_SMP_BACKEND_BASE_SPECIAL(Name) \
44  Name##Base() = default; \
45  Name##Base(const Name##Base<T, Derived> &) = default; \
46  Name##Base<T, Derived> &operator=(const Name##Base<T, Derived> &) = \
47  default; \
48  Name##Base(Name##Base<T, Derived> &&) = default; \
49  Name##Base<T, Derived> &operator=(Name##Base<T, Derived> &&) = default; \
50  VSMC_BACKEND_BASE_DESTRUCTOR_PREFIX ~Name##Base() {}
51 
52 #define VSMC_DEFINE_SMP_BACKEND_BASE_SPECIAL_VIRTUAL(Name) \
53  Name##Base() = default; \
54  Name##Base(const Name##Base<T, Virtual> &) = default; \
55  Name##Base<T, Virtual> &operator=(const Name##Base<T, Virtual> &) = \
56  default; \
57  Name##Base(Name##Base<T, Virtual> &&) = default; \
58  Name##Base<T, Virtual> &operator=(Name##Base<T, Virtual> &&) = default; \
59  virtual ~Name##Base() {}
60 
61 #define VSMC_DEFINE_SMP_BACKEND_SPECIAL(SMP, Name) \
62  Name##SMP() = default; \
63  Name##SMP(const Name##SMP<T, Derived> &) = default; \
64  Name##SMP<T, Derived> &operator=(Name##SMP<T, Derived> &) = default; \
65  Name##SMP(Name##SMP<T, Derived> &&) = default; \
66  Name##SMP<T, Derived> &operator=(Name##SMP<T, Derived> &&) = default; \
67  ~Name##SMP() {}
68 
69 #define VSMC_DEFINE_SMP_BACKEND_FORWARD(Name) \
70  template <typename T, typename = Virtual> \
71  class Initialize##Name; \
72  template <typename T, typename = Virtual> \
73  class Move##Name; \
74  template <typename T, typename = Virtual> \
75  class MonitorEval##Name;
76 
77 #define VSMC_RUNTIME_ASSERT_SMP_BACKEND_BASE_DERIVED(basename) \
78  VSMC_RUNTIME_ASSERT((dynamic_cast<Derived *>(this) != nullptr), \
79  "DERIVED FROM " #basename \
80  " WITH INCORRECT **Derived** TEMPLATE PARAMTER");
81 
82 namespace vsmc
83 {
84 
88 class Virtual;
89 
92 template <typename T, typename Derived>
94 {
95  public:
96  std::size_t eval_sp(SingleParticle<T> sp)
97  {
98  return eval_sp_dispatch(sp, &Derived::eval_sp);
99  }
100 
101  void eval_param(Particle<T> &particle, void *param)
102  {
103  eval_param_dispatch(particle, param, &Derived::eval_param);
104  }
105 
106  void eval_pre(Particle<T> &particle)
107  {
108  eval_pre_dispatch(particle, &Derived::eval_pre);
109  }
110 
111  void eval_post(Particle<T> &particle)
112  {
113  eval_post_dispatch(particle, &Derived::eval_post);
114  }
115 
116  protected:
118 
119  private:
120  // non-static non-const
121 
122  template <typename D>
123  std::size_t eval_sp_dispatch(
124  SingleParticle<T> sp, std::size_t (D::*)(SingleParticle<T>))
125  {
126  return static_cast<Derived *>(this)->eval_sp(sp);
127  }
128 
129  template <typename D>
130  void eval_param_dispatch(
131  Particle<T> &particle, void *param, void (D::*)(Particle<T> &, void *))
132  {
133  static_cast<Derived *>(this)->eval_param(particle, param);
134  }
135 
136  template <typename D>
137  void eval_pre_dispatch(Particle<T> &particle, void (D::*)(Particle<T> &))
138  {
139  static_cast<Derived *>(this)->eval_pre(particle);
140  }
141 
142  template <typename D>
143  void eval_post_dispatch(Particle<T> &particle, void (D::*)(Particle<T> &))
144  {
145  static_cast<Derived *>(this)->eval_post(particle);
146  }
147 
148  // non-static const
149 
150  template <typename D>
151  std::size_t eval_sp_dispatch(
152  SingleParticle<T> sp, std::size_t (D::*)(SingleParticle<T>) const)
153  {
154  return static_cast<Derived *>(this)->eval_sp(sp);
155  }
156 
157  template <typename D>
158  void eval_param_dispatch(Particle<T> &particle, void *param,
159  void (D::*)(Particle<T> &, void *) const)
160  {
161  static_cast<Derived *>(this)->eval_param(particle, param);
162  }
163 
164  template <typename D>
165  void eval_pre_dispatch(
166  Particle<T> &particle, void (D::*)(Particle<T> &) const)
167  {
168  static_cast<Derived *>(this)->eval_pre(particle);
169  }
170 
171  template <typename D>
172  void eval_post_dispatch(
173  Particle<T> &particle, void (D::*)(Particle<T> &) const)
174  {
175  static_cast<Derived *>(this)->eval_post(particle);
176  }
177 
178  // static
179 
180  std::size_t eval_sp_dispatch(
181  SingleParticle<T> sp, std::size_t (*)(SingleParticle<T>))
182  {
183  return Derived::eval_sp(sp);
184  }
185 
186  void eval_param_dispatch(
187  Particle<T> &particle, void *param, void (*)(Particle<T> &, void *))
188  {
189  Derived::eval_param(particle, param);
190  }
191 
192  void eval_pre_dispatch(Particle<T> &particle, void (*)(Particle<T> &))
193  {
194  Derived::eval_pre(particle);
195  }
196 
197  void eval_post_dispatch(Particle<T> &particle, void (*)(Particle<T> &))
198  {
199  Derived::eval_post(particle);
200  }
201 
202  // base
203 
204  std::size_t eval_sp_dispatch(
206  {
207  return 0;
208  }
209 
210  void eval_param_dispatch(
211  Particle<T> &, void *, void (InitializeBase::*)(Particle<T> &, void *))
212  {
213  }
214 
215  void eval_pre_dispatch(
216  Particle<T> &, void (InitializeBase::*)(Particle<T> &))
217  {
218  }
219 
220  void eval_post_dispatch(
221  Particle<T> &, void (InitializeBase::*)(Particle<T> &))
222  {
223  }
224 }; // class InitializeBase
225 
228 template <typename T>
229 class InitializeBase<T, Virtual>
230 {
231  public:
232  virtual std::size_t eval_sp(SingleParticle<T>) { return 0; }
233  virtual void eval_param(Particle<T> &, void *) {}
234  virtual void eval_pre(Particle<T> &) {}
235  virtual void eval_post(Particle<T> &) {}
236 
237  protected:
239 }; // class InitializeBase<T, Virtual>
240 
243 template <typename T, typename Derived>
244 class MoveBase
245 {
246  public:
247  std::size_t eval_sp(std::size_t iter, SingleParticle<T> sp)
248  {
249  return eval_sp_dispatch(iter, sp, &Derived::eval_sp);
250  }
251 
252  void eval_pre(std::size_t iter, Particle<T> &particle)
253  {
254  eval_pre_dispatch(iter, particle, &Derived::eval_pre);
255  }
256 
257  void eval_post(std::size_t iter, Particle<T> &particle)
258  {
259  eval_post_dispatch(iter, particle, &Derived::eval_post);
260  }
261 
262  protected:
264 
265  private:
266  // non-static non-const
267 
268  template <typename D>
269  std::size_t eval_sp_dispatch(std::size_t iter, SingleParticle<T> sp,
270  std::size_t (D::*)(std::size_t, SingleParticle<T>))
271  {
272  return static_cast<Derived *>(this)->eval_sp(iter, sp);
273  }
274 
275  template <typename D>
276  void eval_pre_dispatch(std::size_t iter, Particle<T> &particle,
277  void (D::*)(std::size_t, Particle<T> &))
278  {
279  static_cast<Derived *>(this)->eval_pre(iter, particle);
280  }
281 
282  template <typename D>
283  void eval_post_dispatch(std::size_t iter, Particle<T> &particle,
284  void (D::*)(std::size_t, Particle<T> &))
285  {
286  static_cast<Derived *>(this)->eval_post(iter, particle);
287  }
288 
289  // non-static const
290 
291  template <typename D>
292  std::size_t eval_sp_dispatch(std::size_t iter, SingleParticle<T> sp,
293  std::size_t (D::*)(std::size_t, SingleParticle<T>) const)
294  {
295  return static_cast<Derived *>(this)->eval_sp(iter, sp);
296  }
297 
298  template <typename D>
299  void eval_pre_dispatch(std::size_t iter, Particle<T> &particle,
300  void (D::*)(std::size_t, Particle<T> &) const)
301  {
302  static_cast<Derived *>(this)->eval_pre(iter, particle);
303  }
304 
305  template <typename D>
306  void eval_post_dispatch(std::size_t iter, Particle<T> &particle,
307  void (D::*)(std::size_t, Particle<T> &) const)
308  {
309  static_cast<Derived *>(this)->eval_post(iter, particle);
310  }
311 
312  // static
313 
314  std::size_t eval_sp_dispatch(std::size_t iter, SingleParticle<T> sp,
315  std::size_t (*)(std::size_t, SingleParticle<T>))
316  {
317  return Derived::eval_sp(iter, sp);
318  }
319 
320  void eval_pre_dispatch(std::size_t iter, Particle<T> &particle,
321  void (*)(std::size_t, Particle<T> &))
322  {
323  Derived::eval_pre(iter, particle);
324  }
325 
326  void eval_post_dispatch(std::size_t iter, Particle<T> &particle,
327  void (*)(std::size_t, Particle<T> &))
328  {
329  Derived::eval_post(iter, particle);
330  }
331 
332  // base
333 
334  std::size_t eval_sp_dispatch(std::size_t, SingleParticle<T>,
335  std::size_t (MoveBase::*)(std::size_t, SingleParticle<T>))
336  {
337  return 0;
338  }
339 
340  void eval_pre_dispatch(std::size_t, Particle<T> &,
341  void (MoveBase::*)(std::size_t, Particle<T> &))
342  {
343  }
344 
345  void eval_post_dispatch(std::size_t, Particle<T> &,
346  void (MoveBase::*)(std::size_t, Particle<T> &))
347  {
348  }
349 }; // class MoveBase
350 
353 template <typename T>
354 class MoveBase<T, Virtual>
355 {
356  public:
357  virtual std::size_t eval_sp(std::size_t, SingleParticle<T>) { return 0; }
358  virtual void eval_pre(std::size_t, Particle<T> &) {}
359  virtual void eval_post(std::size_t, Particle<T> &) {}
360 
361  protected:
363 }; // class MoveBase<T, Virtual>
364 
367 template <typename T, typename Derived>
369 {
370  public:
371  void eval_sp(
372  std::size_t iter, std::size_t dim, SingleParticle<T> sp, double *r)
373  {
374  eval_sp_dispatch(iter, dim, sp, r, &Derived::eval_sp);
375  }
376 
377  void eval_pre(std::size_t iter, Particle<T> &particle)
378  {
379  eval_pre_dispatch(iter, particle, &Derived::eval_pre);
380  }
381 
382  void eval_post(std::size_t iter, Particle<T> &particle)
383  {
384  eval_post_dispatch(iter, particle, &Derived::eval_post);
385  }
386 
387  protected:
389 
390  private:
391  // non-static non-const
392 
393  template <typename D>
394  void eval_sp_dispatch(std::size_t iter, std::size_t dim,
395  SingleParticle<T> sp, double *r,
396  void (D::*)(std::size_t, std::size_t, SingleParticle<T>, double *))
397  {
398  static_cast<Derived *>(this)->eval_sp(iter, dim, sp, r);
399  }
400 
401  template <typename D>
402  void eval_pre_dispatch(std::size_t iter, Particle<T> &particle,
403  void (D::*)(std::size_t, Particle<T> &))
404  {
405  static_cast<Derived *>(this)->eval_pre(iter, particle);
406  }
407 
408  template <typename D>
409  void eval_post_dispatch(std::size_t iter, Particle<T> &particle,
410  void (D::*)(std::size_t, Particle<T> &))
411  {
412  static_cast<Derived *>(this)->eval_post(iter, particle);
413  }
414 
415  // non-static const
416 
417  template <typename D>
418  void eval_sp_dispatch(std::size_t iter, std::size_t dim,
419  SingleParticle<T> sp, double *r,
420  void (D::*)(std::size_t, std::size_t, SingleParticle<T>, double *)
421  const)
422  {
423  static_cast<Derived *>(this)->eval_sp(iter, dim, sp, r);
424  }
425 
426  template <typename D>
427  void eval_pre_dispatch(std::size_t iter, Particle<T> &particle,
428  void (D::*)(std::size_t, Particle<T> &) const)
429  {
430  static_cast<Derived *>(this)->eval_pre(iter, particle);
431  }
432 
433  template <typename D>
434  void eval_post_dispatch(std::size_t iter, Particle<T> &particle,
435  void (D::*)(std::size_t, Particle<T> &) const)
436  {
437  static_cast<Derived *>(this)->eval_post(iter, particle);
438  }
439 
440  // static
441 
442  void eval_sp_dispatch(std::size_t iter, std::size_t dim,
443  SingleParticle<T> sp, double *r,
444  void (*)(std::size_t, std::size_t, SingleParticle<T>, double *))
445  {
446  Derived::eval_sp(iter, dim, sp, r);
447  }
448 
449  void eval_pre_dispatch(std::size_t iter, Particle<T> &particle,
450  void (*)(std::size_t, Particle<T> &))
451  {
452  Derived::eval_pre(iter, particle);
453  }
454 
455  void eval_post_dispatch(std::size_t iter, Particle<T> &particle,
456  void (*)(std::size_t, Particle<T> &))
457  {
458  Derived::eval_post(iter, particle);
459  }
460 
461  // base
462 
463  void eval_sp_dispatch(std::size_t, std::size_t, SingleParticle<T>,
464  double *, void (MonitorEvalBase::*)(std::size_t, std::size_t,
465  SingleParticle<T>, double *))
466  {
467  }
468 
469  void eval_pre_dispatch(std::size_t, Particle<T> &,
470  void (MonitorEvalBase::*)(std::size_t, Particle<T> &))
471  {
472  }
473 
474  void eval_post_dispatch(std::size_t, Particle<T> &,
475  void (MonitorEvalBase::*)(std::size_t, Particle<T> &))
476  {
477  }
478 }; // class MonitorBase
479 
482 template <typename T>
483 class MonitorEvalBase<T, Virtual>
484 {
485  public:
486  virtual void eval_sp(std::size_t, std::size_t, SingleParticle<T>, double *)
487  {
488  }
489  virtual void eval_pre(std::size_t, Particle<T> &) {}
490  virtual void eval_post(std::size_t, Particle<T> &) {}
491 
492  protected:
494 }; // class MonitorEvalBase<T, Virtual>
495 
496 } // namespace vsmc
497 
498 #endif // VSMC_SMP_BACKEND_BASE_HPP
Definition: monitor.hpp:49
Particle class representing the whole particle set.
Definition: particle.hpp:48
void eval_param(Particle< T > &particle, void *param)
#define VSMC_DEFINE_SMP_BACKEND_BASE_SPECIAL(Name)
virtual void eval_param(Particle< T > &, void *)
std::size_t eval_sp(SingleParticle< T > sp)
virtual std::size_t eval_sp(std::size_t, SingleParticle< T >)
Monitor evalution base dispatch class.
void eval_sp(std::size_t iter, std::size_t dim, SingleParticle< T > sp, double *r)
STL namespace.
virtual void eval_pre(Particle< T > &)
void eval_pre(Particle< T > &particle)
virtual std::size_t eval_sp(SingleParticle< T >)
void eval_post(std::size_t iter, Particle< T > &particle)
virtual void eval_pre(std::size_t, Particle< T > &)
void eval_post(std::size_t iter, Particle< T > &particle)
void eval_pre(std::size_t iter, Particle< T > &particle)
Move base dispatch class.
virtual void eval_post(Particle< T > &)
#define VSMC_DEFINE_SMP_BACKEND_BASE_SPECIAL_VIRTUAL(Name)
virtual void eval_post(std::size_t, Particle< T > &)
virtual void eval_pre(std::size_t, Particle< T > &)
void eval_post(Particle< T > &particle)
std::size_t eval_sp(std::size_t iter, SingleParticle< T > sp)
virtual void eval_post(std::size_t, Particle< T > &)
A thin wrapper over a complete Particle.
virtual void eval_sp(std::size_t, std::size_t, SingleParticle< T >, double *)
void eval_pre(std::size_t iter, Particle< T > &particle)
Initialize base dispatch class.