vSMC
vSMC: Scalable Monte Carlo
backend_omp.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/smp/backend_omp.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2015, 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_OMP_HPP
33 #define VSMC_SMP_BACKEND_OMP_HPP
34 
36 #include <omp.h>
37 
38 namespace vsmc
39 {
40 
42 
43 template <typename StateBase>
46 class StateOMP : public StateBase
47 {
48  public:
50 
51  explicit StateOMP(size_type N) : StateBase(N) {}
52 
53  template <typename IntType>
54  void copy(size_type N, const IntType *src_idx)
55  {
56 #if _OPENMP < 200805
57  using stype = typename std::make_signed<size_type>::type;
58  stype n = static_cast<stype>(N);
59 #pragma omp parallel for default(shared)
60  for (stype i = 0; i < n; ++i) {
61  this->copy_particle(
62  static_cast<size_type>(src_idx[i]), static_cast<size_type>(i));
63  }
64 #else // _OPENMP < 200805
65 #pragma omp parallel for default(shared)
66  for (size_type i = 0; i < N; ++i)
67  this->copy_particle(static_cast<size_type>(src_idx[i]), i);
68 #endif // _OPENMP < 200805
69  }
70 }; // class StateOMP
71 
74 template <typename T, typename Derived>
75 class InitializeOMP : public InitializeBase<T, Derived>
76 {
77  public:
78  std::size_t operator()(Particle<T> &particle, void *param)
79  {
80  using size_type = typename Particle<T>::size_type;
81  const size_type N = particle.size();
82  this->eval_param(particle, param);
83  this->eval_pre(particle);
84  std::size_t accept = 0;
85 #if _OPENMP < 200805
86  using stype = typename std::make_signed<size_type>::type;
87  stype n = static_cast<stype>(N);
88 #pragma omp parallel for reduction(+ : accept) default(shared)
89  for (stype i = 0; i < n; ++i) {
90  accept += this->eval_sp(
91  SingleParticle<T>(static_cast<size_type>(i), &particle));
92  }
93 #else // _OPENMP < 200805
94 #pragma omp parallel for reduction(+ : accept) default(shared)
95  for (size_type i = 0; i < N; ++i)
96  accept += this->eval_sp(SingleParticle<T>(i, &particle));
97 #endif // _OPENMP < 200805
98  this->eval_post(particle);
99 
100  return accept;
101  }
102 
103  protected:
105 }; // class InitializeOMP
106 
109 template <typename T, typename Derived>
110 class MoveOMP : public MoveBase<T, Derived>
111 {
112  public:
113  std::size_t operator()(std::size_t iter, Particle<T> &particle)
114  {
115  using size_type = typename Particle<T>::size_type;
116  const size_type N = particle.size();
117  this->eval_pre(iter, particle);
118  std::size_t accept = 0;
119 #if _OPENMP < 200805
120  using stype = typename std::make_signed<size_type>::type;
121  stype n = static_cast<stype>(N);
122 #pragma omp parallel for reduction(+ : accept) default(shared)
123  for (stype i = 0; i < n; ++i) {
124  accept += this->eval_sp(
125  iter, SingleParticle<T>(static_cast<size_type>(i), &particle));
126  }
127 #else // _OPENMP < 200805
128 #pragma omp parallel for reduction(+ : accept) default(shared)
129  for (size_type i = 0; i < N; ++i)
130  accept += this->eval_sp(iter, SingleParticle<T>(i, &particle));
131 #endif // _OPENMP < 200805
132  this->eval_post(iter, particle);
133 
134  return accept;
135  }
136 
137  protected:
139 }; // class MoveOMP
140 
143 template <typename T, typename Derived>
144 class MonitorEvalOMP : public MonitorEvalBase<T, Derived>
145 {
146  public:
148  std::size_t iter, std::size_t dim, Particle<T> &particle, double *r)
149  {
150  using size_type = typename Particle<T>::size_type;
151  const size_type N = particle.size();
152  this->eval_pre(iter, particle);
153 #if _OPENMP < 200805
154  using stype = typename std::make_signed<size_type>::type;
155  stype n = static_cast<stype>(N);
156 #pragma omp parallel for default(shared)
157  for (stype i = 0; i < n; ++i) {
158  this->eval_sp(iter, dim,
159  SingleParticle<T>(static_cast<size_type>(i), &particle),
160  r + static_cast<std::size_t>(i) * dim);
161  }
162 #else // _OPENMP < 200805
163 #pragma omp parallel for default(shared)
164  for (size_type i = 0; i < N; ++i) {
165  this->eval_sp(iter, dim, SingleParticle<T>(i, &particle),
166  r + static_cast<std::size_t>(i) * dim);
167  }
168 #endif // _OPENMP < 200805
169  this->eval_post(iter, particle);
170  }
171 
172  protected:
174 }; // class MonitorEvalOMP
175 
178 template <typename T, typename Derived>
179 class PathEvalOMP : public PathEvalBase<T, Derived>
180 {
181  public:
182  double operator()(std::size_t iter, Particle<T> &particle, double *r)
183  {
184  using size_type = typename Particle<T>::size_type;
185  const size_type N = particle.size();
186  this->eval_pre(iter, particle);
187 #if _OPENMP < 200805
188  using stype = typename std::make_signed<size_type>::type;
189  stype n = static_cast<stype>(N);
190 #pragma omp parallel for default(shared)
191  for (stype i = 0; i < n; ++i) {
192  r[i] = this->eval_sp(
193  iter, SingleParticle<T>(static_cast<size_type>(i), &particle));
194  }
195 #else // _OPENMP < 200805
196 #pragma omp parallel for default(shared)
197  for (size_type i = 0; i < N; ++i)
198  r[i] = this->eval_sp(iter, SingleParticle<T>(i, &particle));
199 #endif // _OPENMP < 200805
200  this->eval_post(iter, particle);
201 
202  return this->eval_grid(iter, particle);
203  }
204 
205  protected:
207 }; // class PathEvalOMP
208 
209 } // namespace vsmc
210 
211 #endif // VSMC_SMP_BACKEND_OMP_HPP
Definition: monitor.hpp:49
SizeType< T > size_type
Definition: particle.hpp:51
Particle class representing the whole particle set.
Definition: particle.hpp:48
void eval_param(Particle< T > &particle, void *param)
Particle::value_type subtype using OpenMP.
Definition: backend_omp.hpp:46
std::size_t eval_sp(SingleParticle< T > sp)
void copy(size_type N, const IntType *src_idx)
Definition: backend_omp.hpp:54
Sampler<T>::move_type subtype using OpenMP.
Definition: backend_omp.hpp:41
Monitor evalution base dispatch class.
void operator()(std::size_t iter, std::size_t dim, Particle< T > &particle, double *r)
Monitor<T>::eval_type subtype using OpenMP.
Definition: backend_omp.hpp:41
Path<T>::eval_type subtype using OpenMP.
Definition: backend_omp.hpp:41
std::size_t operator()(Particle< T > &particle, void *param)
Definition: backend_omp.hpp:78
StateOMP(size_type N)
Definition: backend_omp.hpp:51
#define VSMC_DEFINE_SMP_BACKEND_FORWARD(Name)
void eval_pre(Particle< T > &particle)
SizeType< StateBase > size_type
Definition: backend_omp.hpp:49
double operator()(std::size_t iter, Particle< T > &particle, double *r)
Move base dispatch class.
Sampler<T>::init_type subtype using OpenMP.
Definition: backend_omp.hpp:41
typename SizeTypeTrait< T >::type SizeType
Definition: traits.hpp:212
Path evalution base dispatch class.
size_type size() const
Number of particles.
Definition: particle.hpp:122
void eval_post(Particle< T > &particle)
#define VSMC_DEFINE_SMP_BACKEND_SPECIAL(SMP, Name)
std::size_t operator()(std::size_t iter, Particle< T > &particle)
A thin wrapper over a complete Particle.
Initialize base dispatch class.