MCKL
Monte Carlo Kernel Library
rdrand.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/rdrand.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_RANDOM_RDRAND_HPP
33 #define MCKL_RANDOM_RDRAND_HPP
34 
36 
37 #ifndef MCKL_RDRAND_NTRIAL_MAX
38 #define MCKL_RDRAND_NTRIAL_MAX 0
39 #endif
40 
41 namespace mckl {
42 
45 template <typename UIntType, std::size_t W>
46 inline bool rdrand(UIntType *, std::integral_constant<int, W>);
47 
50 template <typename UIntType>
51 inline bool rdrand(UIntType *rand, std::integral_constant<int, 16>)
52 {
53  unsigned short r;
54  int cf = _rdrand16_step(&r);
55  *rand = static_cast<UIntType>(r);
56 
57  return cf != 0;
58 }
59 
62 template <typename UIntType>
63 inline bool rdrand(UIntType *rand, std::integral_constant<int, 32>)
64 {
65  unsigned r;
66  int cf = _rdrand32_step(&r);
67  *rand = static_cast<UIntType>(r);
68 
69  return cf != 0;
70 }
71 
74 template <typename UIntType>
75 inline bool rdrand(UIntType *rand, std::integral_constant<int, 64>)
76 {
77 #if defined(MCKL_INTEL) && MCKL_INTEL_VERSION < 1600
78  unsigned __int64 r;
79 #else
80  unsigned long long r;
81 #endif
82  int cf = _rdrand64_step(&r);
83  *rand = static_cast<UIntType>(r);
84 
85  return cf != 0;
86 }
87 
90 template <typename ResultType, std::size_t NTrialMax = MCKL_RDRAND_NTRIAL_MAX>
92 {
93  static_assert(std::is_unsigned<ResultType>::value,
94  "**RDRANDEngine** used with ResultType other than unsigned integer "
95  "types");
96 
97  static_assert(std::numeric_limits<ResultType>::digits == 16 ||
98  std::numeric_limits<ResultType>::digits == 32 ||
99  std::numeric_limits<ResultType>::digits == 64,
100  "**RDRANDEngine** used with ResultType of size other than 16, 32 or "
101  "64 bits");
102 
103  public:
104  using result_type = ResultType;
105 
106  RDRANDEngine() = default;
107 
108  template <typename Seed>
109  explicit RDRANDEngine(const Seed &)
110  {
111  }
112 
113  template <typename Seed>
114  void seed(const Seed &)
115  {
116  }
117 
119  {
120  return generate(std::integral_constant<bool, NTrialMax != 0>());
121  }
122 
123  void discard(std::size_t) {}
124 
125  static constexpr result_type min()
126  {
127  return std::numeric_limits<result_type>::min();
128  }
129 
130  static constexpr result_type max()
131  {
132  return std::numeric_limits<result_type>::max();
133  }
134 
137  {
138  return false;
139  }
140 
143  {
144  return true;
145  }
146 
147  template <typename CharT, typename CharTraits>
148  friend std::basic_ostream<CharT, CharTraits> &operator<<(
149  std::basic_ostream<CharT, CharTraits> &os,
151  {
152  return os;
153  }
154 
155  template <typename CharT, typename CharTraits>
156  friend std::basic_istream<CharT, CharTraits> &operator>>(
157  std::basic_istream<CharT, CharTraits> &is,
159  {
160  return is;
161  }
162 
163  private:
164  result_type generate(std::true_type)
165  {
166  result_type r;
167  std::size_t ntrial = 0;
168  while (true) {
169  ++ntrial;
170  bool success = rdrand<result_type>(&r,
171  std::integral_constant<int,
172  std::numeric_limits<result_type>::digits>());
173  if (success || ntrial > NTrialMax) {
174  break;
175  }
176  }
177  runtime_assert(ntrial < NTrialMax,
178  "**RDRAND::generator** maximum number of trials exceeded", true);
179 
180  return r;
181  }
182 
183  result_type generate(std::false_type)
184  {
185  result_type r;
186  while (true) {
187  bool success = rdrand<result_type>(&r,
188  std::integral_constant<int,
189  std::numeric_limits<result_type>::digits>());
190  if (success) {
191  break;
192  }
193  }
194 
195  return r;
196  }
197 }; // class RDRANDEngine
198 
202 
206 
210 
211 } // namespace mckl
212 
213 #endif // MCKL_RANDOM_RDRAND_HPP
result_type operator()()
Definition: rdrand.hpp:118
ResultType result_type
Definition: rdrand.hpp:104
RDRAND generator.
Definition: rdrand.hpp:91
RDRANDEngine()=default
bool rdrand(UIntType *, std::integral_constant< int, W >)
Invoke the RDRAND instruction and return the carry flag.
static constexpr result_type min()
Definition: rdrand.hpp:125
static constexpr result_type max()
Definition: rdrand.hpp:130
friend std::basic_istream< CharT, CharTraits > & operator>>(std::basic_istream< CharT, CharTraits > &is, RDRANDEngine< ResultType, NTrialMax > &)
Definition: rdrand.hpp:156
friend std::basic_ostream< CharT, CharTraits > & operator<<(std::basic_ostream< CharT, CharTraits > &os, const RDRANDEngine< ResultType, NTrialMax > &)
Definition: rdrand.hpp:148
RDRANDEngine(const Seed &)
Definition: rdrand.hpp:109
Definition: mcmc.hpp:40
void rand(RNGType &rng, ArcsineDistribution< RealType > &distribution, std::size_t N, RealType *r)
void seed(const Seed &)
Definition: rdrand.hpp:114
friend bool operator!=(const RDRANDEngine< ResultType, NTrialMax > &, const RDRANDEngine< ResultType, NTrialMax > &)
Definition: rdrand.hpp:141
void discard(std::size_t)
Definition: rdrand.hpp:123
RNG default seed generator.
Definition: seed.hpp:339
void runtime_assert(bool cond, const char *msg, bool soft=false)
Definition: assert.hpp:65
friend bool operator==(const RDRANDEngine< ResultType, NTrialMax > &, const RDRANDEngine< ResultType, NTrialMax > &)
Definition: rdrand.hpp:135