vSMC  v3.0.0
Scalable Monte Carlo
backend_tbb.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/smp/backend_tbb.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_TBB_HPP
33 #define VSMC_SMP_BACKEND_TBB_HPP
34 
36 #include <tbb/blocked_range.h>
37 #include <tbb/parallel_for.h>
38 #include <tbb/parallel_reduce.h>
39 
40 namespace vsmc
41 {
42 
43 namespace internal
44 {
45 
46 template <typename IntType>
47 inline ::tbb::blocked_range<IntType> backend_tbb_range(
48  IntType N, std::size_t grainsize)
49 {
50  return grainsize == 0 ? ::tbb::blocked_range<IntType>(0, N) :
51  ::tbb::blocked_range<IntType>(0, N, grainsize);
52 }
53 
54 } // namespace internal
55 
58 template <typename T, typename Derived>
59 class SamplerEvalSMP<T, Derived, BackendTBB>
60  : public SamplerEvalBase<T, Derived>
61 {
62  public:
63  std::size_t operator()(std::size_t iter, Particle<T> &particle)
64  {
65  return run(iter, particle);
66  }
67 
68  protected:
69  VSMC_DEFINE_SMP_BACKEND_SPECIAL(TBB, SamplerEval)
70 
71  class work_type
72  {
73  public:
75 
77  std::size_t iter, Particle<T> *pptr)
78  : wptr_(wptr), iter_(iter), pptr_(pptr), accept_(0)
79  {
80  }
81 
82  work_type(const work_type &other, ::tbb::split)
83  : wptr_(other.wptr_)
84  , iter_(other.iter_)
85  , pptr_(other.pptr_)
86  , accept_(0)
87  {
88  }
89 
90  void operator()(const ::tbb::blocked_range<size_type> &range)
91  {
92  accept_ += wptr_->eval_range(
93  iter_, pptr_->range(range.begin(), range.end()));
94  }
95 
96  void join(const work_type &other) { accept_ += other.accept_; }
97 
98  std::size_t accept() const { return accept_; }
99 
100  private:
102  const std::size_t iter_;
103  Particle<T> *const pptr_;
104  std::size_t accept_;
105  }; // class work_type
106 
107  template <typename... Args>
108  std::size_t run(std::size_t iter, Particle<T> &particle,
109  std::size_t grainsize, Args &&... args)
110  {
111  this->eval_pre(iter, particle);
112  work_type work(this, iter, &particle);
113  ::tbb::parallel_reduce(
114  internal::backend_tbb_range(particle.size(), grainsize), work,
115  std::forward<Args>(args)...);
116  this->eval_post(iter, particle);
117 
118  return work.accept();
119  }
120 
121  std::size_t run(std::size_t iter, Particle<T> &particle)
122  {
123  return run(iter, particle, 0);
124  }
125 }; // class SamplerEvalSMP
126 
129 template <typename T, typename Derived>
130 class MonitorEvalSMP<T, Derived, BackendTBB>
131  : public MonitorEvalBase<T, Derived>
132 {
133  public:
135  std::size_t iter, std::size_t dim, Particle<T> &particle, double *r)
136  {
137  run(iter, dim, particle, r);
138  }
139 
140  protected:
141  VSMC_DEFINE_SMP_BACKEND_SPECIAL(TBB, MonitorEval)
142 
143  class work_type
144  {
145  public:
147 
149  std::size_t iter, std::size_t dim, Particle<T> *pptr, double *r)
150  : wptr_(wptr), iter_(iter), dim_(dim), pptr_(pptr), r_(r)
151  {
152  }
153 
154  void operator()(const ::tbb::blocked_range<size_type> &range) const
155  {
156  wptr_->eval_range(iter_, dim_,
157  pptr_->range(range.begin(), range.end()),
158  r_ + static_cast<std::size_t>(range.begin()) * dim_);
159  }
160 
161  private:
163  const std::size_t iter_;
164  const std::size_t dim_;
165  Particle<T> *const pptr_;
166  double *const r_;
167  }; // class work_type
168 
169  template <typename... Args>
170  void run(std::size_t iter, std::size_t dim, Particle<T> &particle,
171  double *r, std::size_t grainsize, Args &&... args)
172  {
173  this->eval_pre(iter, particle);
174  work_type work(this, iter, dim, &particle, r);
175  ::tbb::parallel_for(
176  internal::backend_tbb_range(particle.size(), grainsize), work,
177  std::forward<Args>(args)...);
178  this->eval_post(iter, particle);
179  }
180 
181  void run(
182  std::size_t iter, std::size_t dim, Particle<T> &particle, double *r)
183  {
184  run(iter, dim, particle, r, 1);
185  }
186 }; // class MonitorEvalSMP
187 
190 template <typename T, typename Derived>
192 
195 template <typename T, typename Derived>
197 
198 } // namespace vsmc
199 
200 #endif // VSMC_SMP_BACKEND_TBB_HPP
Definition: monitor.hpp:48
SizeType< T > size_type
Definition: particle.hpp:86
Particle class representing the whole particle set.
Definition: particle.hpp:83
std::size_t run(std::size_t iter, Particle< T > &particle)
Monitor<T>::eval_type.
work_type(const work_type &other,::tbb::split)
Definition: backend_tbb.hpp:82
void operator()(const ::tbb::blocked_range< size_type > &range)
Definition: backend_tbb.hpp:90
Monitor evalution base dispatch class.
std::size_t run(std::size_t iter, Particle< T > &particle, std::size_t grainsize, Args &&...args)
#define VSMC_DEFINE_SMP_BACKEND_SPECIAL(Impl, Name)
void run(std::size_t iter, std::size_t dim, Particle< T > &particle, double *r, std::size_t grainsize, Args &&...args)
void run(std::size_t iter, std::size_t dim, Particle< T > &particle, double *r)
void operator()(std::size_t iter, std::size_t dim, Particle< T > &particle, double *r)
void operator()(const ::tbb::blocked_range< size_type > &range) const
Sampler<T>::eval_type subtype using Intel Threading Building Blocks.
Definition: backend_tbb.hpp:59
std::size_t operator()(std::size_t iter, Particle< T > &particle)
Definition: backend_tbb.hpp:63
work_type(SamplerEvalSMP< T, Derived, BackendTBB > *wptr, std::size_t iter, Particle< T > *pptr)
Definition: backend_tbb.hpp:76
Sampler evaluation base dispatch class.
Sampler<T>::eval_type.
size_type size() const
Number of particles.
Definition: particle.hpp:120
Monitor<T>::eval_type subtype using Intel Threading Building Blocks.
work_type(MonitorEvalSMP< T, Derived, BackendTBB > *wptr, std::size_t iter, std::size_t dim, Particle< T > *pptr, double *r)
inline::tbb::blocked_range< IntType > backend_tbb_range(IntType N, std::size_t grainsize)
Definition: backend_tbb.hpp:47