vSMC
vSMC: Scalable Monte Carlo
ars.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/rng/ars.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2016, 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_ARS_HPP
33 #define VSMC_RNG_ARS_HPP
34 
36 #include <vsmc/rng/aes_ni.hpp>
37 
40 #ifndef VSMC_RNG_ARS_ROUNDS
41 #define VSMC_RNG_ARS_ROUNDS 5
42 #endif
43 
46 #ifndef VSMC_RNG_ARS_BLOCKS
47 #define VSMC_RNG_ARS_BLOCKS 4
48 #endif
49 
50 namespace vsmc
51 {
52 
53 namespace internal
54 {
55 
56 template <std::size_t>
58 
59 template <>
60 class ARSWeylConstant<0> : public std::integral_constant<std::uint64_t,
61  UINT64_C(0x9E3779B97F4A7C15)>
62 {
63 }; // class ARSWeylConstant
64 
65 template <>
66 class ARSWeylConstant<1> : public std::integral_constant<std::uint64_t,
67  UINT64_C(0xBB67AE8584CAA73B)>
68 {
69 }; // class ARSWeylConstant
70 
71 } // namespace vsmc::internal
72 
79 template <std::size_t I>
81 {
82 }; // class ARSWeylConstantTrait
83 
86 template <typename T>
87 class ARSKeySeq
88 {
89  public:
90  using key_type = std::array<T, M128I<T>::size()>;
91 
92  void reset(const key_type &) {}
93 
94  template <typename U, std::size_t Rp1>
95  void operator()(const key_type &key, std::array<M128I<U>, Rp1> &rk) const
96  {
98  weyl.set(
100  std::get<0>(rk).load(key.data());
101  generate<1>(rk, weyl, std::integral_constant<bool, 1 < Rp1>());
102  }
103 
104  private:
105  template <std::size_t, typename U, std::size_t Rp1>
106  void generate(std::array<M128I<U>, Rp1> &, const M128I<std::uint64_t> &,
107  std::false_type) const
108  {
109  }
110 
111  template <std::size_t N, typename U, std::size_t Rp1>
112  void generate(std::array<M128I<U>, Rp1> &rk,
113  const M128I<std::uint64_t> &weyl, std::true_type) const
114  {
115  std::get<N>(rk) =
116  _mm_add_epi64(std::get<N - 1>(rk).value(), weyl.value());
117  generate<N + 1>(rk, weyl, std::integral_constant<bool, N + 1 < Rp1>());
118  }
119 }; // class ARSKeySeq
120 
123 template <typename ResultType, std::size_t Rounds = VSMC_RNG_ARS_ROUNDS,
124  std::size_t Blocks = VSMC_RNG_ARS_BLOCKS>
125 using ARSEngine =
127 
132 
137 
142 
147 
152 
157 
162 
167 
172 
177 
178 } // namespace vsmc
179 
180 #endif // VSMC_RNG_ARS_HPP
Definition: monitor.hpp:49
Using __m128i as integer vector.
Definition: simd.hpp:113
Counter based RNG engine.
Definition: counter.hpp:289
__m128i & value()
Definition: simd.hpp:140
void set(T e1, T e0)
Definition: simd.hpp:193
std::array< T, M128I< T >::size()> key_type
Definition: ars.hpp:90
#define VSMC_RNG_ARS_ROUNDS
ARSEngine default rounds.
Definition: ars.hpp:41
ARSEngine Weyl sequence constants.
Definition: ars.hpp:80
void operator()(const key_type &key, std::array< M128I< U >, Rp1 > &rk) const
Definition: ars.hpp:95
void reset(const key_type &)
Definition: ars.hpp:92
#define VSMC_RNG_ARS_BLOCKS
ARSEngine default blocks.
Definition: ars.hpp:47
Default ARSEngine key sequence generator.
Definition: ars.hpp:87