MCKL
Monte Carlo Kernel Library
backend_std.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/smp/backend_std.hpp
3 //----------------------------------------------------------------------------
4 // MCKL: Monte Carlo Kernel Library
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2018, 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 MCKL_SMP_BACKEND_STD_HPP
33 #define MCKL_SMP_BACKEND_STD_HPP
34 
35 #include <mckl/core/iterator.hpp>
37 #include <future>
38 #include <thread>
39 
40 namespace mckl {
41 
43 {
44  public:
45  BackendSTD(const BackendSTD &) = delete;
46  BackendSTD &operator=(const BackendSTD &) = delete;
47 
48  static BackendSTD &instance()
49  {
50  static BackendSTD backend;
51 
52  return backend;
53  }
54 
55  void reset() { np_ = std::thread::hardware_concurrency(); }
56 
57  unsigned np() const { return np_; }
58 
59  void np(unsigned n) { np_ = n; }
60 
61  private:
62  unsigned np_;
63 
64  BackendSTD() : np_(std::thread::hardware_concurrency()) {}
65 }; // class BackendSTD
66 
67 namespace internal {
68 
69 template <typename T>
71 {
72  const std::size_t N = static_cast<std::size_t>(particle.size());
73  const std::size_t n =
74  static_cast<std::size_t>(std::max(1U, BackendSTD::instance().np()));
75  const std::size_t m = N / n;
76  const std::size_t r = N % n;
77 
78  ParticleIndex<T> b = particle.begin();
80  range.reserve(n);
81  for (std::size_t i = 0; i != n; ++i) {
82  const std::size_t l = m + (i < r ? 1 : 0);
83  range.emplace_back(b, b + l);
84  b += l;
85  }
86 
87  return range;
88 }
89 
90 } // namespace internal
91 
94 template <typename T, typename Derived>
95 class SMCSamplerEvalSMP<T, Derived, BackendSTD>
96  : public SMCSamplerEvalBase<T, Derived>
97 {
98  public:
99  void operator()(std::size_t iter, Particle<T> &particle)
100  {
101  run(iter, particle);
102  }
103 
104  protected:
105  MCKL_DEFINE_SMP_BACKEND_SPECIAL(STD, SMCSamplerEval)
106 
107  void run(std::size_t iter, Particle<T> &particle)
108  {
109  run(iter, particle, 1);
110  }
111 
112  template <typename... Args>
113  void run(std::size_t iter, Particle<T> &particle, std::size_t, Args &&...)
114  {
115  this->eval_first(iter, particle);
116  mckl::Vector<std::future<void>> task_group;
117  for (auto range : internal::backend_std_range(particle)) {
118  task_group.push_back(std::async(
119  std::launch::async, [this, iter, &particle, range]() {
120  this->eval_range(iter, range);
121  }));
122  }
123  for (auto &task : task_group) {
124  task.wait();
125  }
126  this->eval_last(iter, particle);
127  }
128 }; // class SMCSamplerEvalSMP
129 
132 template <typename T, typename Derived>
133 class SMCEstimatorEvalSMP<T, Derived, BackendSTD>
134  : public SMCEstimatorEvalBase<T, Derived>
135 {
136  public:
138  std::size_t iter, std::size_t dim, Particle<T> &particle, double *r)
139  {
140  run(iter, dim, particle, r);
141  }
142 
143  protected:
144  MCKL_DEFINE_SMP_BACKEND_SPECIAL(STD, SMCEstimatorEval)
145 
146  void run(
147  std::size_t iter, std::size_t dim, Particle<T> &particle, double *r)
148  {
149  run(iter, dim, particle, r, 1);
150  }
151 
152  template <typename... Args>
153  void run(std::size_t iter, std::size_t dim, Particle<T> &particle,
154  double *r, std::size_t, Args &&...)
155  {
156  this->eval_first(iter, particle);
157  mckl::Vector<std::future<void>> task_group;
158  for (auto range : internal::backend_std_range(particle)) {
159  task_group.push_back(std::async(
160  std::launch::async, [this, iter, dim, &particle, r, range]() {
161  this->eval_range(iter, dim, range,
162  r + static_cast<std::size_t>(range.ibegin()) * dim);
163  }));
164  }
165  for (auto &task : task_group) {
166  task.wait();
167  }
168  this->eval_last(iter, particle);
169  }
170 }; // class SMCEstimatorEvalSMP
171 
174 template <typename T, typename Derived>
176 
179 template <typename T, typename Derived>
181 
182 } // namespace mckl
183 
184 #endif // MCKL_SMP_BACKEND_STD_HPP
SMCSampler evaluation base dispatch class.
SMCEstimator<T>::eval_type subtype using the standard library.
BackendSTD & operator=(const BackendSTD &)=delete
void np(unsigned n)
Definition: backend_std.hpp:59
void operator()(std::size_t iter, std::size_t dim, Particle< T > &particle, double *r)
std::vector< T, Alloc > Vector
std::vector with Allocator as the default allocator
Definition: memory.hpp:435
STL namespace.
void run(std::size_t iter, std::size_t dim, Particle< T > &particle, double *r, std::size_t, Args &&...)
unsigned np() const
Definition: backend_std.hpp:57
ParticleIndex< T > begin()
Get a ParticleIndex<T> object for the first particle.
Definition: particle.hpp:385
SMCSMCSampler<T>::eval_type.
SMCEstimator<T>::eval_type.
SMCSampler<T>::eval_type subtype using the standard library.
Definition: backend_std.hpp:95
size_type size() const
The number of particles.
Definition: particle.hpp:318
Definition: mcmc.hpp:40
SMCEstimator evalution base dispatch class.
mckl::Vector< ParticleRange< T > > backend_std_range(Particle< T > &particle)
Definition: backend_std.hpp:70
A thin wrapper over a complete Particle.
Definition: particle.hpp:86
void operator()(std::size_t iter, Particle< T > &particle)
Definition: backend_std.hpp:99
Particle system.
Definition: particle.hpp:45
static BackendSTD & instance()
Definition: backend_std.hpp:48
#define MCKL_DEFINE_SMP_BACKEND_SPECIAL(Impl, Name)
void run(std::size_t iter, Particle< T > &particle, std::size_t, Args &&...)