vSMC
vSMC: Scalable Monte Carlo
mkl.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/rng/mkl.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_RNG_MKL_HPP
33 #define VSMC_RNG_MKL_HPP
34 
36 
37 namespace vsmc
38 {
39 
40 namespace internal
41 {
42 
44 {
45  public:
46  static constexpr MKL_INT min VSMC_MNE() { return 0; }
47  static constexpr MKL_INT max VSMC_MNE() { return 0; }
48  static void set(MKL_INT) {}
49  static constexpr MKL_INT get() { return 0; }
50 }; // class OffsetZero
51 
52 template <MKL_INT MaxOffset>
54 {
55  public:
56  MKLOffsetDynamic() : offset_(0) {}
57 
58  static constexpr MKL_INT min VSMC_MNE() { return 0; }
59  static constexpr MKL_INT max VSMC_MNE() { return MaxOffset; }
60 
61  void set(MKL_INT n)
62  {
64  offset_ = n % MaxOffset;
65  }
66 
67  MKL_INT get() const { return offset_; }
68 
69  private:
70  MKL_INT offset_;
71 }; // class OffsetDynamic
72 
73 template <MKL_INT>
74 class MKLOffset
75 {
76  public:
78 }; // class MKLOffset
79 
80 template <>
82 {
83  public:
84  using type =
86 }; // class MKLOffset
87 
88 template <>
89 class MKLOffset<VSL_BRNG_MT2203>
90 {
91  public:
93 }; // class MKLOffset
94 
95 template <>
96 class MKLOffset<VSL_BRNG_WH>
97 {
98  public:
100 }; // class MKLOffset
101 
102 template <int>
104 
105 template <>
107 {
108  public:
109  using type = unsigned;
110 }; // class MKLResultTypeTrait
111 
112 template <>
114 {
115  public:
116  using type = unsigned MKL_INT64;
117 }; // class MKLResultTypeTrait
118 
119 template <int Bits>
121 
122 template <int>
124 
125 template <>
126 class MKLUniformBits<32>
127 {
128  public:
129  static void eval(MKLStream &stream, MKL_INT n, unsigned *r)
130  {
131  stream.uniform_bits32(n, r);
132  }
133 }; // class MKLUniformBits
134 
135 template <>
136 class MKLUniformBits<64>
137 {
138  public:
139  static void eval(MKLStream &stream, MKL_INT n, unsigned MKL_INT64 *r)
140  {
141  stream.uniform_bits64(n, r);
142  }
143 }; // class MKLUniformBits
144 
146 {
147  public:
148  static void eval(MKLStream &stream, long long nskip)
149  {
150  stream.skip_ahead(nskip);
151  }
152 }; // class DiscardSkipAhead
153 
154 template <MKL_INT BRNG, int Bits>
156 {
157  public:
158  static void eval(MKLStream &stream, long long nskip)
159  {
160  if (nskip == 0)
161  return;
162 
163  std::array<MKLResultType<Bits>, 1000> buffer;
164  const MKL_INT k = static_cast<MKL_INT>(buffer.size());
165  while (nskip > k) {
166  MKLUniformBits<Bits>::eval(stream, k, buffer.data());
167  nskip -= k;
168  }
170  stream, static_cast<MKL_INT>(nskip), buffer.data());
171  }
172 }; // class DiscardGeneral
173 
174 template <MKL_INT BRNG, int Bits>
176 {
177  public:
179 }; // clas MKLDiscard
180 
181 template <int Bits>
182 class MKLDiscard<VSL_BRNG_MCG59, Bits>
183 {
184  public:
186 }; // clas MKLDiscard
187 
188 template <int Bits>
189 class MKLDiscard<VSL_BRNG_MT19937, Bits>
190 {
191  public:
193 }; // clas MKLDiscard
194 
195 template <int Bits>
196 class MKLDiscard<VSL_BRNG_SFMT19937, Bits>
197 {
198  public:
200 }; // clas MKLDiscard
201 
202 } // namespace vsmc::internal
203 
206 template <MKL_INT BRNG, int Bits>
207 class MKLEngine
208 {
209  public:
211 
212  explicit MKLEngine(MKL_UINT s = 1) : index_(M_) { seed(s); }
213 
214  template <typename SeedSeq>
215  explicit MKLEngine(SeedSeq &seq,
216  typename std::enable_if<internal::is_seed_seq<SeedSeq, MKL_UINT,
217  MKLEngine<BRNG, Bits>>::value>::type * = nullptr)
218  : index_(M_)
219  {
220  seed(seq);
221  }
222 
223  MKLEngine(MKL_UINT s, MKL_INT offset) { seed(s, offset); }
224 
225  void seed(MKL_UINT s) { seed(s, 0); }
226 
227  template <typename SeedSeq>
228  void seed(SeedSeq &seq,
229  typename std::enable_if<
231  {
232  MKL_UINT s;
233  seq.generate(&s, &s + 1);
234  seed(s, 0);
235  }
236 
237  void seed(MKL_UINT s, MKL_INT offset)
238  {
239  typename internal::MKLOffset<BRNG>::type off;
240  off.set(offset);
241  stream_.reset(BRNG + off.get(), s);
242  index_ = M_;
243  }
244 
246  {
247  if (index_ == M_) {
249  stream_, static_cast<MKL_INT>(M_), buffer_.data());
250  index_ = 0;
251  }
252 
253  return buffer_[index_++];
254  }
255 
256  void operator()(std::size_t n, result_type *r)
257  {
259  stream_, static_cast<MKL_INT>(n), r);
260  }
261 
262  void discard(long long nskip)
263  {
265  index_ = M_;
266  }
267 
268  static constexpr result_type min VSMC_MNE()
269  {
270  return std::numeric_limits<result_type>::min VSMC_MNE();
271  }
272 
273  static constexpr result_type max VSMC_MNE()
274  {
275  return std::numeric_limits<result_type>::max VSMC_MNE();
276  }
277 
278  MKLStream &stream() { return stream_; }
279  const MKLStream &stream() const { return stream_; }
280 
281  friend bool operator==(
282  const MKLEngine<BRNG, Bits> &eng1, const MKLEngine<BRNG, Bits> &eng2)
283  {
284  if (eng1.stream_.get_brng() != eng2.stream_.get_brng())
285  return false;
286  std::size_t n = static_cast<std::size_t>(eng1.stream_.get_size());
287  Vector<char> s1(n);
288  Vector<char> s2(n);
289  eng1.stream_.save_m(s1.data());
290  eng2.stream_.save_m(s2.data());
291  if (s1 != s2)
292  return false;
293  if (eng1.buffer_ != eng2.buffer_)
294  return false;
295  if (eng1.index_ != eng2.index_)
296  return false;
297  return true;
298  }
299 
300  friend bool operator!=(
301  const MKLEngine<BRNG, Bits> &eng1, const MKLEngine<BRNG, Bits> &eng2)
302  {
303  return !(eng1 == eng2);
304  }
305 
306  template <typename CharT, typename Traits>
307  friend std::basic_ostream<CharT, Traits> &operator<<(
308  std::basic_ostream<CharT, Traits> &os,
309  const MKLEngine<BRNG, Bits> &eng)
310  {
311  if (!os.good())
312  return os;
313 
314  os << eng.stream_.get_brng() << ' ';
315  std::size_t n = static_cast<std::size_t>(eng.stream_.get_size());
316  if (n % sizeof(std::uint64_t) != 0)
317  n += sizeof(std::uint64_t) - n % sizeof(std::uint64_t);
318  n /= sizeof(std::uint64_t);
320  eng.stream_.save_m(reinterpret_cast<char *>(s.data()));
321  for (std::size_t i = 0; i != n; ++i)
322  os << s[i] << ' ';
323  os << eng.buffer_ << ' ';
324  os << eng.index_;
325 
326  return os;
327  }
328 
329  template <typename CharT, typename Traits>
330  friend std::basic_istream<CharT, Traits> &operator>>(
331  std::basic_istream<CharT, Traits> &is, MKLEngine<BRNG, Bits> &eng)
332  {
333  if (!is.good())
334  return is;
335 
336  MKL_INT brng = 0;
337  MKLStream stream(BRNG, 1);
338  std::array<result_type, M_> buffer;
339  std::size_t index = 0;
340 
341  is >> std::ws >> brng;
342  if (is.good())
343  stream.reset(brng, 1);
344  else
345  return is;
346 
347  std::size_t n = static_cast<std::size_t>(eng.stream_.get_size());
348  if (n % sizeof(std::uint64_t) != 0)
349  n += sizeof(std::uint64_t) - n % sizeof(std::uint64_t);
350  n /= sizeof(std::uint64_t);
352  for (std::size_t i = 0; i != n; ++i)
353  is >> std::ws >> s[i];
354  if (is.good())
355  stream.load_m(reinterpret_cast<const char *>(s.data()));
356  else
357  return is;
358 
359  is >> std::ws >> buffer;
360  is >> std::ws >> index;
361 
362  if (is.good()) {
363  eng.stream_ = stream;
364  eng.buffer_ = buffer;
365  eng.index_ = index;
366  }
367 
368  return is;
369  }
370 
371  private:
372  static constexpr std::size_t M_ = 1000;
373 
374  MKLStream stream_;
375  std::array<result_type, M_> buffer_;
376  std::size_t index_;
377 }; // class MKLEngine
378 
382 
386 
390 
394 
398 
403 
408 
414 
418 
422 
423 #if INTEL_MKL_VERSION >= 110300
424 
427 using MKL_ARS5 = MKLEngine<VSL_BRNG_ARS5, 32>;
428 
431 using MKL_ARS5_64 = MKLEngine<VSL_BRNG_ARS5, 64>;
432 
435 using MKL_PHILOX4X32X10 = MKLEngine<VSL_BRNG_PHILOX4X32X10, 32>;
436 
439 using MKL_PHILOX4X32X10_64 = MKLEngine<VSL_BRNG_PHILOX4X32X10, 64>;
440 
441 #endif // INTEL_MKL_VERSION >= 110300
442 
443 template <MKL_INT BRNG, int Bits>
444 inline void rng_rand(MKLEngine<BRNG, Bits> &rng, std::size_t n,
446 {
447  rng(n, r);
448 }
449 
450 template <MKL_INT BRNG, int Bits>
452  MKLEngine<BRNG, Bits> &rng, std::size_t n, int *r, double p)
453 {
454  rng.stream().bernoulli(static_cast<MKL_INT>(n), r, p);
455 }
456 
457 template <MKL_INT BRNG, int Bits>
459  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float a, float b)
460 {
461  rng.stream().uniform(static_cast<MKL_INT>(n), r, a, b);
462 }
463 
464 template <MKL_INT BRNG, int Bits>
466  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double a, double b)
467 {
468  rng.stream().uniform(static_cast<MKL_INT>(n), r, a, b);
469 }
470 
471 template <MKL_INT BRNG, int Bits>
472 inline void u01_distribution(
473  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r)
474 {
475  rng.stream().uniform(static_cast<MKL_INT>(n), r, 0, 1);
476 }
477 
478 template <MKL_INT BRNG, int Bits>
479 inline void u01_distribution(
480  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r)
481 {
482  rng.stream().uniform(static_cast<MKL_INT>(n), r, 0, 1);
483 }
484 
485 template <MKL_INT BRNG, int Bits>
486 inline void normal_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
487  float *r, float mean, float stddev)
488 {
489  rng.stream().gaussian(static_cast<MKL_INT>(n), r, mean, stddev);
490 }
491 
492 template <MKL_INT BRNG, int Bits>
493 inline void normal_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
494  double *r, double mean, double stddev)
495 {
496  rng.stream().gaussian(static_cast<MKL_INT>(n), r, mean, stddev);
497 }
498 
499 template <MKL_INT BRNG, int Bits>
501  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float lambda)
502 {
503  rng.stream().exponential(static_cast<MKL_INT>(n), r, 0, 1 / lambda);
504 }
505 
506 template <MKL_INT BRNG, int Bits>
508  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double lambda)
509 {
510  rng.stream().exponential(static_cast<MKL_INT>(n), r, 0, 1 / lambda);
511 }
512 
513 template <MKL_INT BRNG, int Bits>
514 inline void laplace_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
515  float *r, float location, float scale)
516 {
517  rng.stream().laplace(static_cast<MKL_INT>(n), r, location, scale);
518 }
519 
520 template <MKL_INT BRNG, int Bits>
521 inline void laplace_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
522  double *r, double location, double scale)
523 {
524  rng.stream().laplace(static_cast<MKL_INT>(n), r, location, scale);
525 }
526 
527 template <MKL_INT BRNG, int Bits>
529  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float a, float b)
530 {
531  rng.stream().weibull(static_cast<MKL_INT>(n), r, a, 0, b);
532 }
533 
534 template <MKL_INT BRNG, int Bits>
536  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double a, double b)
537 {
538  rng.stream().weibull(static_cast<MKL_INT>(n), r, a, 0, b);
539 }
540 
541 template <MKL_INT BRNG, int Bits>
543  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float a, float b)
544 {
545  rng.stream().cauchy(static_cast<MKL_INT>(n), r, a, b);
546 }
547 
548 template <MKL_INT BRNG, int Bits>
550  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double a, double b)
551 {
552  rng.stream().cauchy(static_cast<MKL_INT>(n), r, a, b);
553 }
554 
555 template <MKL_INT BRNG, int Bits>
557  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float sigma)
558 {
559  rng.stream().rayleigh(
560  static_cast<MKL_INT>(n), r, 0, const_sqrt_2<float>() * sigma);
561 }
562 
563 template <MKL_INT BRNG, int Bits>
565  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double sigma)
566 {
567  rng.stream().rayleigh(
568  static_cast<MKL_INT>(n), r, 0, const_sqrt_2<double>() * sigma);
569 }
570 
571 template <MKL_INT BRNG, int Bits>
573  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float m, float s)
574 {
575  rng.stream().lognormal(static_cast<MKL_INT>(n), r, m, s, 0, 1);
576 }
577 
578 template <MKL_INT BRNG, int Bits>
580  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double m, double s)
581 {
582  rng.stream().lognormal(static_cast<MKL_INT>(n), r, m, s, 0, 1);
583 }
584 
585 template <MKL_INT BRNG, int Bits>
587  MKLEngine<BRNG, Bits> &rng, std::size_t n, float *r, float a, float b)
588 {
589  rng.stream().gumbel(static_cast<MKL_INT>(n), r, a, b);
590  sub(n, 2 * a, r, r);
591 }
592 
593 template <MKL_INT BRNG, int Bits>
595  MKLEngine<BRNG, Bits> &rng, std::size_t n, double *r, double a, double b)
596 {
597  rng.stream().gumbel(static_cast<MKL_INT>(n), r, a, b);
598  sub(n, 2 * a, r, r);
599 }
600 
601 template <MKL_INT BRNG, int Bits>
602 inline void gamma_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
603  float *r, float alpha, float beta)
604 {
605  rng.stream().gamma(static_cast<MKL_INT>(n), r, alpha, 0, beta);
606 }
607 
608 template <MKL_INT BRNG, int Bits>
609 inline void gamma_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
610  double *r, double alpha, double beta)
611 {
612  rng.stream().gamma(static_cast<MKL_INT>(n), r, alpha, 0, beta);
613 }
614 
615 template <MKL_INT BRNG, int Bits>
616 inline void beta_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
617  float *r, float alpha, float beta)
618 {
619  rng.stream().beta(static_cast<MKL_INT>(n), r, alpha, beta, 0, 1);
620 }
621 
622 template <MKL_INT BRNG, int Bits>
623 inline void beta_distribution(MKLEngine<BRNG, Bits> &rng, std::size_t n,
624  double *r, double alpha, double beta)
625 {
626  rng.stream().beta(static_cast<MKL_INT>(n), r, alpha, beta, 0, 1);
627 }
628 
629 } // namespace vsmc
630 
631 #endif // VSMC_RNG_MKL_HPP
static void set(MKL_INT)
Definition: mkl.hpp:48
Definition: monitor.hpp:49
int uniform_bits32(MKL_INT n, unsigned *r, MKL_INT method=VSL_RNG_METHOD_UNIFORMBITS32_STD)
viRngUniform32
Definition: mkl.hpp:634
void seed(MKL_UINT s, MKL_INT offset)
Definition: mkl.hpp:237
result_type operator()()
Definition: mkl.hpp:245
void laplace_distribution(RNGType &, std::size_t, RealType *, RealType, RealType)
Generating laplace random variates.
void bernoulli_distribution(RNGType &rng, std::size_t n, IntType *r, IntType p)
Generating bernoulli random variates.
Used to specify a dimension template parameter is dynamic.
Definition: defines.hpp:48
void cauchy_distribution(RNGType &rng, std::size_t n, RealType *r, RealType a, RealType b)
Generating cauchy random variates.
typename std::conditional< std::is_scalar< T >::value, std::vector< T, AlignedAllocator< T >>, std::vector< T >>::type Vector
AlignedVector for scalar type and std::vector for others.
ulong uint64_t
Definition: opencl.h:40
void lognormal_distribution(RNGType &, std::size_t, RealType *, RealType, RealType)
Generating lognormal random variates.
friend bool operator==(const MKLEngine< BRNG, Bits > &eng1, const MKLEngine< BRNG, Bits > &eng2)
Definition: mkl.hpp:281
MKL RNG C++11 engine.
Definition: common.hpp:692
void rng_rand(RNGType &rng, BernoulliDistribution< IntType > &dist, std::size_t n, IntType *r)
double const_sqrt_2< double >() noexcept
Definition: constants.hpp:215
void exponential_distribution(RNGType &rng, std::size_t n, RealType *r, RealType lambda)
Generating exponential random variates.
void u01_distribution(RNGType &, std::size_t, RealType *)
Generate standard uniform random variates.
MKLEngine(MKL_UINT s, MKL_INT offset)
Definition: mkl.hpp:223
void seed(MKL_UINT s)
Definition: mkl.hpp:225
void discard(long long nskip)
Definition: mkl.hpp:262
void normal_distribution(RNGType &, std::size_t, RealType *, RealType, RealType)
Generating normal random variates.
MKLEngine(SeedSeq &seq, typename std::enable_if< internal::is_seed_seq< SeedSeq, MKL_UINT, MKLEngine< BRNG, Bits >>::value >::type *=nullptr)
Definition: mkl.hpp:215
void rayleigh_distribution(RNGType &, std::size_t, RealType *, RealType)
Generating rayleigh random variates.
static constexpr MKL_INT get()
Definition: mkl.hpp:49
#define VSMC_MNE
Definition: defines.hpp:38
static void eval(MKLStream &stream, MKL_INT n, unsigned MKL_INT64 *r)
Definition: mkl.hpp:139
void seed(SeedSeq &seq, typename std::enable_if< internal::is_seed_seq< SeedSeq, MKL_UINT >::value >::type *=nullptr)
Definition: mkl.hpp:228
void weibull_distribution(RNGType &, std::size_t, RealType *, RealType, RealType)
Generating weibull random variates.
int reset(MKL_INT brng, MKL_UINT seed)
vslNewStream
Definition: mkl.hpp:225
const MKLStream & stream() const
Definition: mkl.hpp:279
int skip_ahead(long long nskip)
vslSkipAheadStream
Definition: mkl.hpp:319
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, MKLEngine< BRNG, Bits > &eng)
Definition: mkl.hpp:330
void extreme_value_distribution(RNGType &rng, std::size_t n, RealType *r, RealType a, RealType b)
Generating extreme_value random variates.
int load_m(const char *memptr)
vslLoadStreamM
Definition: mkl.hpp:294
int uniform_bits64(MKL_INT n, unsigned MKL_INT64 *r, MKL_INT method=VSL_RNG_METHOD_UNIFORMBITS64_STD)
viRngUniform64
Definition: mkl.hpp:645
static constexpr MKL_INT min()
Definition: mkl.hpp:46
friend bool operator!=(const MKLEngine< BRNG, Bits > &eng1, const MKLEngine< BRNG, Bits > &eng2)
Definition: mkl.hpp:300
void sub(std::size_t n, const float *a, const float *b, float *y)
Definition: vmath.hpp:110
MKL VSLStreamStatePtr
Definition: mkl.hpp:178
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const MKLEngine< BRNG, Bits > &eng)
Definition: mkl.hpp:307
MKLStream & stream()
Definition: mkl.hpp:278
void beta_distribution(RNGType &rng, std::size_t n, RealType *r, RealType alpha, RealType beta)
Generating beta random variates.
float const_sqrt_2< float >() noexcept
Definition: constants.hpp:215
static constexpr MKL_INT max()
Definition: mkl.hpp:47
void uniform_real_distribution(RNGType &, std::size_t, RealType *, RealType, RealType)
Generate uniform real random variates.
static void eval(MKLStream &stream, MKL_INT n, unsigned *r)
Definition: mkl.hpp:129
void operator()(std::size_t n, result_type *r)
Definition: mkl.hpp:256
void gamma_distribution(RNGType &rng, std::size_t n, RealType *r, RealType alpha, RealType beta)
Generating gamma random variates.
MKLEngine(MKL_UINT s=1)
Definition: mkl.hpp:212
#define VSMC_RUNTIME_ASSERT_UTILITY_MKL_VSL_OFFSET(offset)
Definition: mkl.hpp:65
internal::MKLResultType< Bits > result_type
Definition: mkl.hpp:210
typename MKLResultTypeTrait< Bits >::type MKLResultType
Definition: mkl.hpp:120
static void eval(MKLStream &stream, long long nskip)
Definition: mkl.hpp:148
static void eval(MKLStream &stream, long long nskip)
Definition: mkl.hpp:158