vSMC
vSMC: Scalable Monte Carlo
rdrand.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/rng/rdrand.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013,2014, 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_RDRAND_HPP
33 #define VSMC_RNG_RDRAND_HPP
34 
37 #include <immintrin.h>
38 
39 #ifndef VSMC_RDRAND_NTRIAL_MAX
40 #define VSMC_RDRAND_NTRIAL_MAX 10
41 #endif
42 
43 #define VSMC_STATIC_ASSERT_RNG_RDRAND_GENERATOR_RESULT_TYPE(ResultType) \
44  VSMC_STATIC_ASSERT(( \
45  cxx11::is_same<ResultType, uint16_t>::value || \
46  cxx11::is_same<ResultType, uint32_t>::value || \
47  cxx11::is_same<ResultType, uint64_t>::value), \
48  USE_RDRANDGenerator_WITH_RESULT_TYPE_OTHER_THAN_uint16_t_OR_uint32_t_OR_uint64_t)
49 
50 #define VSMC_STATIC_ASSERT_RNG_RDRAND_GENERATOR \
51  VSMC_STATIC_ASSERT_RNG_RDRAND_GENERATOR_RESULT_TYPE(ResultType);
52 
53 #define VSMC_RUNTIME_WARNING_RNG_RDRAND_GENERATOR_NTRIAL(ntrial, NTrialMax) \
54  VSMC_RUNTIME_WARNING((ntrial < NTrialMax), \
55  ("**RDRAND::generate** MAXIMUM NUMBER OF TRIALS EXCEEDED"))
56 
57 namespace vsmc {
58 
61 template <typename UIntType> inline bool rdrand (UIntType *);
62 
65 template <> inline bool rdrand<uint16_t> (uint16_t *rand)
66 {
67  unsigned short r;
68  int cf = _rdrand16_step(&r);
69  *rand = static_cast<uint16_t>(r);
70 
71  return cf != 0;
72 }
73 
76 template <> inline bool rdrand<uint32_t> (uint32_t *rand)
77 {
78  unsigned r;
79  int cf = _rdrand32_step(&r);
80  *rand = static_cast<uint32_t>(r);
81 
82  return cf != 0;
83 }
84 
87 template <> inline bool rdrand<uint64_t> (uint64_t *rand)
88 {
89  unsigned VSMC_INT64 r;
90  int cf = _rdrand64_step(&r);
91  *rand = static_cast<uint64_t>(r);
92 
93  return cf != 0;
94 }
95 
98 template <typename ResultType, std::size_t NTrialMax = VSMC_RDRAND_NTRIAL_MAX>
100 {
101  public :
102 
103  typedef ResultType result_type;
104 
105  static result_type generate ()
106  {
108 
109  result_type r;
110  std::size_t ntrial = 0;
111  while (!rdrand<result_type>(&r) && ntrial != NTrialMax)
112  ++ntrial;
114 
115  return r;
116  }
117 }; // class RDRANDGenertor
118 
122 
126 
130 
131 } // namespace vsmc
132 
133 #endif// VSMC_RNG_RDRAND_HPP
Definition: adapter.hpp:37
GeneratorWrapper< uint64_t, RDRANDGenerator< uint64_t > > RDRAND64
C++11 Engine using 64-bits RDRAND instruction.
Definition: rdrand.hpp:129
bool rdrand< uint64_t >(uint64_t *rand)
Invoke the 64-bits RDRAND instruction and return the carry flag.
Definition: rdrand.hpp:87
bool rdrand< uint32_t >(uint32_t *rand)
Invoke the 32-bits RDRAND instruction and return the carry flag.
Definition: rdrand.hpp:76
#define VSMC_STATIC_ASSERT_RNG_RDRAND_GENERATOR
Definition: rdrand.hpp:50
bool rdrand< uint16_t >(uint16_t *rand)
Invoke the 16-bits RDRAND instruction and return the carry flag.
Definition: rdrand.hpp:65
GeneratorWrapper< uint32_t, RDRANDGenerator< uint32_t > > RDRAND32
C++11 Engine using 32-bits RDRAND instruction.
Definition: rdrand.hpp:125
A thin wrapper over any RNG Generator for use with C++11 API.
GeneratorWrapper< uint16_t, RDRANDGenerator< uint16_t > > RDRAND16
C++11 Engine using 16-bits RDRAND instruction.
Definition: rdrand.hpp:121
RDRAND generator.
Definition: rdrand.hpp:99
ResultType result_type
Definition: rdrand.hpp:103
#define VSMC_RUNTIME_WARNING_RNG_RDRAND_GENERATOR_NTRIAL(ntrial, NTrialMax)
Definition: rdrand.hpp:53
bool rdrand(UIntType *)
Invoke the RDRAND instruction and return the carry flag.
#define VSMC_INT64
Definition: clang.hpp:405
static result_type generate()
Definition: rdrand.hpp:105