32 #ifndef VSMC_RNG_MKL_HPP 33 #define VSMC_RNG_MKL_HPP 37 #define VSMC_RUNTIME_ASSERT_RNG_MKL_OFFSET(offset) \ 38 VSMC_RUNTIME_ASSERT((offset < max()), \ 39 "**MKLOffsetDynamic** " \ 40 "EXCESS MAXIMUM NUMBER OF INDEPDENT RNG STREAMS") 51 static constexpr MKL_INT
min() {
return 0; }
52 static constexpr MKL_INT
max() {
return 0; }
53 static void set(MKL_INT) {}
54 static constexpr MKL_INT
get() {
return 0; }
57 template <MKL_INT MaxOffset>
63 static constexpr MKL_INT
min() {
return 0; }
64 static constexpr MKL_INT
max() {
return MaxOffset; }
69 offset_ = n % MaxOffset;
72 MKL_INT
get()
const {
return offset_; }
120 using type =
unsigned MKL_INT64;
158 template <MKL_INT BRNG,
int Bits>
167 std::array<MKLResultType<Bits>, 1024> buffer;
168 const MKL_INT k =
static_cast<MKL_INT
>(buffer.size());
174 stream, static_cast<MKL_INT>(nskip), buffer.data());
178 template <MKL_INT BRNG,
int Bits>
210 template <MKL_INT BRNG,
int Bits>
216 explicit MKLEngine(MKL_UINT s = 1) : index_(M_), stream_(BRNG, 0)
221 template <
typename SeedSeq>
225 : index_(M_), stream_(BRNG, 0)
230 MKLEngine(MKL_UINT s, MKL_INT offset) : index_(M_), stream_(BRNG, 0)
237 template <
typename SeedSeq>
239 typename std::enable_if<
243 seq.generate(&s, &s + 1);
247 void seed(MKL_UINT s, MKL_INT offset)
251 stream_.reset(BRNG + off.
get(), s);
259 stream_, static_cast<MKL_INT>(M_), buffer_.data());
263 return buffer_[index_++];
268 std::size_t remain = M_ - index_;
271 std::memcpy(r, buffer_.data() + index_,
sizeof(
result_type) * n);
276 std::memcpy(r, buffer_.data() + index_,
sizeof(
result_type) * remain);
281 const std::size_t m = n / M_;
282 const std::size_t l = n % M_;
283 for (std::size_t i = 0; i != m; ++i) {
285 stream_, static_cast<MKL_INT>(M_), r);
290 stream_, static_cast<MKL_INT>(M_), buffer_.data());
291 std::memcpy(r, buffer_.data(),
sizeof(
result_type) * l);
303 return std::numeric_limits<result_type>::min();
308 return std::numeric_limits<result_type>::max();
317 if (eng1.stream_.get_brng() != eng2.stream_.get_brng())
319 std::size_t n =
static_cast<std::size_t
>(eng1.stream_.get_size());
322 eng1.stream_.save_m(s1.data());
323 eng2.stream_.save_m(s2.data());
326 if (eng1.buffer_ != eng2.buffer_)
328 if (eng1.index_ != eng2.index_)
336 return !(eng1 == eng2);
339 template <
typename CharT,
typename Traits>
341 std::basic_ostream<CharT, Traits> &os,
347 os << eng.stream_.get_brng() <<
' ';
348 std::size_t n =
static_cast<std::size_t
>(eng.stream_.get_size());
353 eng.stream_.save_m(reinterpret_cast<char *>(s.data()));
354 for (std::size_t i = 0; i != n; ++i)
356 os << eng.buffer_ <<
' ';
362 template <
typename CharT,
typename Traits>
371 std::array<result_type, M_> buffer;
372 std::size_t index = 0;
374 is >> std::ws >> brng;
376 stream.
reset(brng, 1);
380 std::size_t n =
static_cast<std::size_t
>(eng.stream_.get_size());
385 for (std::size_t i = 0; i != n; ++i)
386 is >> std::ws >> s[i];
388 stream.
load_m(reinterpret_cast<const char *>(s.data()));
392 is >> std::ws >> buffer;
393 is >> std::ws >> index;
396 eng.stream_ = stream;
397 eng.buffer_ = buffer;
405 static constexpr std::size_t M_ = 1024;
407 alignas(32) std::array<result_type, M_> buffer_;
456 #if INTEL_MKL_VERSION >= 110300 474 #endif // INTEL_MKL_VERSION >= 110300 476 template <MKL_INT BRNG,
int Bits>
483 template <MKL_INT BRNG,
int Bits>
485 float *r,
float alpha,
float beta)
487 rng.
stream().beta(static_cast<MKL_INT>(n), r, alpha, beta, 0, 1);
490 template <MKL_INT BRNG,
int Bits>
492 double *r,
double alpha,
double beta)
494 rng.
stream().beta(static_cast<MKL_INT>(n), r, alpha, beta, 0, 1);
497 template <MKL_INT BRNG,
int Bits>
501 rng.
stream().cauchy(static_cast<MKL_INT>(n), r, a, b);
504 template <MKL_INT BRNG,
int Bits>
508 rng.
stream().cauchy(static_cast<MKL_INT>(n), r, a, b);
511 template <MKL_INT BRNG,
int Bits>
515 rng.
stream().exponential(static_cast<MKL_INT>(n), r, 0, 1 / lambda);
518 template <MKL_INT BRNG,
int Bits>
522 rng.
stream().exponential(static_cast<MKL_INT>(n), r, 0, 1 / lambda);
525 template <MKL_INT BRNG,
int Bits>
529 rng.
stream().gumbel(static_cast<MKL_INT>(n), r, a, b);
533 template <MKL_INT BRNG,
int Bits>
537 rng.
stream().gumbel(static_cast<MKL_INT>(n), r, a, b);
541 template <MKL_INT BRNG,
int Bits>
543 float *r,
float alpha,
float beta)
545 rng.
stream().gamma(static_cast<MKL_INT>(n), r, alpha, 0, beta);
548 template <MKL_INT BRNG,
int Bits>
550 double *r,
double alpha,
double beta)
552 rng.
stream().gamma(static_cast<MKL_INT>(n), r, alpha, 0, beta);
555 template <MKL_INT BRNG,
int Bits>
557 float *r,
float location,
float scale)
559 rng.
stream().laplace(static_cast<MKL_INT>(n), r, location, scale);
562 template <MKL_INT BRNG,
int Bits>
564 double *r,
double location,
double scale)
566 rng.
stream().laplace(static_cast<MKL_INT>(n), r, location, scale);
569 template <MKL_INT BRNG,
int Bits>
573 rng.
stream().lognormal(static_cast<MKL_INT>(n), r, m, s, 0, 1);
576 template <MKL_INT BRNG,
int Bits>
580 rng.
stream().lognormal(static_cast<MKL_INT>(n), r, m, s, 0, 1);
583 template <MKL_INT BRNG,
int Bits>
585 float *r,
float mean,
float stddev)
587 rng.
stream().gaussian(static_cast<MKL_INT>(n), r, mean, stddev);
590 template <MKL_INT BRNG,
int Bits>
592 double *r,
double mean,
double stddev)
594 rng.
stream().gaussian(static_cast<MKL_INT>(n), r, mean, stddev);
597 template <MKL_INT BRNG,
int Bits>
599 float *r, std::size_t m,
const float *mean,
const float *chol)
601 rng.
stream().gaussian_mv(static_cast<MKL_INT>(n), r,
602 static_cast<MKL_INT>(m), VSL_MATRIX_STORAGE_PACKED, mean, chol);
605 template <MKL_INT BRNG,
int Bits>
607 double *r, std::size_t m,
const double *mean,
const double *chol)
609 rng.
stream().gaussian_mv(static_cast<MKL_INT>(n), r,
610 static_cast<MKL_INT>(m), VSL_MATRIX_STORAGE_PACKED, mean, chol);
613 template <MKL_INT BRNG,
int Bits>
621 template <MKL_INT BRNG,
int Bits>
629 template <MKL_INT BRNG,
int Bits>
633 rng.
stream().uniform(static_cast<MKL_INT>(n), r, 0, 1);
636 template <MKL_INT BRNG,
int Bits>
640 rng.
stream().uniform(static_cast<MKL_INT>(n), r, 0, 1);
643 template <MKL_INT BRNG,
int Bits>
647 rng.
stream().uniform(static_cast<MKL_INT>(n), r, a, b);
650 template <MKL_INT BRNG,
int Bits>
654 rng.
stream().uniform(static_cast<MKL_INT>(n), r, a, b);
657 template <MKL_INT BRNG,
int Bits>
661 rng.
stream().weibull(static_cast<MKL_INT>(n), r, a, 0, b);
664 template <MKL_INT BRNG,
int Bits>
668 rng.
stream().weibull(static_cast<MKL_INT>(n), r, a, 0, b);
673 #endif // VSMC_RNG_MKL_HPP
static constexpr MKL_INT max()
int uniform_bits32(MKL_INT n, unsigned *r, MKL_INT method=VSL_RNG_METHOD_UNIFORMBITS32_STD)
viRngUniform32
void seed(MKL_UINT s, MKL_INT offset)
typename std::conditional< std::is_scalar< T >::value, AlignedVector< T >, std::vector< T >>::type Vector
AlignedVector for scalar type and std::vector for others.
void laplace_distribution(RNGType &, std::size_t, RealType *, RealType, RealType)
Generating laplace random variates.
void normal_mv_distribution(RNGType &, std::size_t, RealType *, std::size_t, const RealType *, const RealType *)
Generating multivariate Normal random varaites.
constexpr double const_sqrt_2< double >() noexcept
void cauchy_distribution(RNGType &rng, std::size_t n, RealType *r, RealType a, RealType b)
Generating cauchy random variates.
void lognormal_distribution(RNGType &, std::size_t, RealType *, RealType, RealType)
Generating lognormal random variates.
void rng_rand(RNGType &rng, BetaDistribution< RealType > &dist, std::size_t n, RealType *r)
friend bool operator==(const MKLEngine< BRNG, Bits > &eng1, const MKLEngine< BRNG, Bits > &eng2)
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)
void discard(long long nskip)
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)
void rayleigh_distribution(RNGType &, std::size_t, RealType *, RealType)
Generating rayleigh random variates.
static constexpr result_type min()
static constexpr MKL_INT get()
void seed(SeedSeq &seq, typename std::enable_if< internal::is_seed_seq< SeedSeq, MKL_UINT >::value >::type *=nullptr)
void weibull_distribution(RNGType &, std::size_t, RealType *, RealType, RealType)
Generating weibull random variates.
int reset(MKL_INT brng, MKL_UINT seed)
vslNewStream
const MKLStream & stream() const
int skip_ahead(long long nskip)
vslSkipAheadStream
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, MKLEngine< BRNG, Bits > &eng)
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
int uniform_bits64(MKL_INT n, unsigned MKL_INT64 *r, MKL_INT method=VSL_RNG_METHOD_UNIFORMBITS64_STD)
viRngUniform64
static constexpr MKL_INT min()
constexpr float const_sqrt_2< float >() noexcept
friend bool operator!=(const MKLEngine< BRNG, Bits > &eng1, const MKLEngine< BRNG, Bits > &eng2)
void sub(std::size_t n, const float *a, const float *b, float *y)
static constexpr MKL_INT min()
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const MKLEngine< BRNG, Bits > &eng)
#define VSMC_RUNTIME_ASSERT_RNG_MKL_OFFSET(offset)
void beta_distribution(RNGType &rng, std::size_t n, RealType *r, RealType alpha, RealType beta)
Generating beta random variates.
static constexpr result_type max()
static constexpr MKL_INT max()
void uniform_real_distribution(RNGType &, std::size_t, RealType *, RealType, RealType)
Generate uniform real random variates with open/closed variants.
void operator()(std::size_t n, result_type *r)
void gamma_distribution(RNGType &rng, std::size_t n, RealType *r, RealType alpha, RealType beta)
Generating gamma random variates.
internal::MKLResultType< Bits > result_type
typename MKLResultTypeTrait< Bits >::type MKLResultType
static void eval(MKLStream &stream, long long nskip)
static void eval(MKLStream &stream, long long nskip)