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,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_ARS_HPP
33 #define VSMC_RNG_ARS_HPP
34 
36 #include <vsmc/rng/aes_ni.hpp>
37 
40 #ifndef VSMC_RNG_ARS_BLOCKS
41 #define VSMC_RNG_ARS_BLOCKS 1
42 #endif
43 
46 #ifndef VSMC_RNG_ARS_ROUNDS
47 #define VSMC_RNG_ARS_ROUNDS 7
48 #endif
49 
50 namespace vsmc {
51 
52 namespace traits {
53 
54 namespace internal {
55 
56 template <std::size_t> struct ARSWeylConstantValue;
57 
58 template <> struct ARSWeylConstantValue<0> :
59  public cxx11::integral_constant<uint64_t, UINT64_C(0xBB67AE8584CAA73B)> {};
60 
61 template <> struct ARSWeylConstantValue<1> :
62  public cxx11::integral_constant<uint64_t, UINT64_C(0x9E3779B97F4A7C15)> {};
63 
64 } // namespace vsmc::traits::internal
65 
72 template <std::size_t I> struct ARSWeylConstantTrait :
73  public internal::ARSWeylConstantValue<I> {};
74 
75 } // namespace vsmc::traits
76 
79 template <typename ResultType>
80 class ARSKeySeq
81 {
82  public :
83 
84  typedef Array<ResultType, 16 / sizeof(ResultType)> key_type;
85 
86  ARSKeySeq () : weyl_(_mm_set_epi64x(
87  static_cast<int64_t>(traits::ARSWeylConstantTrait<0>::value),
88  static_cast<int64_t>(traits::ARSWeylConstantTrait<1>::value)))
89  {}
90 
91  template <std::size_t Rp1>
92  void generate (const key_type &key, Array<__m128i, Rp1> &key_seq)
93  {
94  m128i_pack<0>(key, key_seq.front());
95  generate_seq<1>(key_seq, cxx11::integral_constant<bool, 1 < Rp1>());
96  }
97 
98  private :
99 
100  const __m128i weyl_;
101 
102  template <std::size_t, std::size_t Rp1>
103  void generate_seq (Array<__m128i, Rp1> &, cxx11::false_type) {}
104 
105  template <std::size_t N, std::size_t Rp1>
106  void generate_seq (Array<__m128i, Rp1> &key_seq, cxx11::true_type)
107  {
108  key_seq[Position<N>()] = _mm_add_epi64(
109  key_seq[Position<N - 1>()], weyl_);
110  generate_seq<N + 1>(key_seq,
111  cxx11::integral_constant<bool, N + 1 < Rp1>());
112  }
113 }; // class ARSKeySeq
114 
128 template <typename ResultType,
129  std::size_t Rounds = VSMC_RNG_ARS_ROUNDS,
130  std::size_t Blocks = VSMC_RNG_ARS_BLOCKS>
131 class ARSEngine :
132  public AESNIEngine<ResultType, ARSKeySeq<ResultType>,
133  false, Rounds, Blocks>
134 {
135  public :
136 
138  false, Rounds, Blocks> base_eng_type;
139 
140  explicit ARSEngine (ResultType s = 0) : base_eng_type(s) {}
141 
142  template <typename SeedSeq>
143  explicit ARSEngine (SeedSeq &seq, typename cxx11::enable_if<
144  internal::is_seed_seq<SeedSeq,
146  typename base_eng_type::key_type,
148  >::value>::type * = VSMC_NULLPTR) : base_eng_type(seq) {}
149 
150  ARSEngine (const typename base_eng_type::key_type &k) : base_eng_type(k) {}
151 }; // class ARSEngine
152 
157 
162 
167 
172 
177 
182 
187 
192 
197 
202 
203 } // namespace vsmc
204 
205 #endif // VSMC_RNG_ARS_HPP
Definition: adapter.hpp:37
ARSEngine< uint64_t, 7, 8 > ARS_8x64
ARS RNG engine with 64-bits integers output, 8 blocks and default rounds.
Definition: ars.hpp:201
ARSEngine< uint32_t, 7, 1 > ARS_1x32
ARS RNG engine with 32-bits integers output, 1 block and default rounds.
Definition: ars.hpp:161
ARSEngine(const typename base_eng_type::key_type &k)
Definition: ars.hpp:150
ARSEngine< uint32_t, 7, 8 > ARS_8x32
ARS RNG engine with 32-bits integers output, 8 blocks and default rounds.
Definition: ars.hpp:176
ARSEngine Weyl sequence constants.
Definition: ars.hpp:72
ARSEngine< uint32_t, 7, 2 > ARS_2x32
ARS RNG engine with 32-bits integers output, 2 blocks and default rounds.
Definition: ars.hpp:166
reference front()
Definition: array.hpp:119
void generate(const key_type &key, Array< __m128i, Rp1 > &key_seq)
Definition: ars.hpp:92
ARSEngine< uint64_t > ARS_64
ARS RNG engine with 64-bits integers output, default blocks and default rounds.
Definition: ars.hpp:181
ARSEngine< uint64_t, 7, 2 > ARS_2x64
ARS RNG engine with 64-bits integers output, 2 blocks and default rounds.
Definition: ars.hpp:191
ARSEngine(SeedSeq &seq, typename cxx11::enable_if< internal::is_seed_seq< SeedSeq, typename base_eng_type::result_type, typename base_eng_type::key_type, ARSEngine< ResultType, Rounds, Blocks > >::value >::type *=nullptr)
Definition: ars.hpp:143
ARSEngine< uint64_t, 7, 1 > ARS_1x64
ARS RNG engine with 64-bits integers output, 1 block and default rounds.
Definition: ars.hpp:186
RNG engine using AES-NI instructions.
Definition: aes_ni.hpp:213
#define VSMC_RNG_ARS_ROUNDS
ARSEngine default rounds.
Definition: ars.hpp:47
#define VSMC_NULLPTR
nullptr
Definition: defines.hpp:79
integral_constant< bool, true > true_type
ARS RNG engine.
Definition: ars.hpp:131
ARSEngine(ResultType s=0)
Definition: ars.hpp:140
ARSEngine< uint32_t > ARS_32
ARS RNG engine with 32-bits integers output, default blocks and default rounds.
Definition: ars.hpp:156
ARSEngine< uint64_t, 7, 4 > ARS_4x64
ARS RNG engine with 64-bits integers output, 4 blocks and default rounds.
Definition: ars.hpp:196
#define VSMC_RNG_ARS_BLOCKS
ARSEngine default blocks.
Definition: ars.hpp:41
Static array.
Definition: array.hpp:79
Default ARSEngine key sequence generator.
Definition: ars.hpp:80
ARSEngine< uint32_t, 7, 4 > ARS_4x32
ARS RNG engine with 32-bits integers output, 4 blocks and default rounds.
Definition: ars.hpp:171
AESNIEngine< ResultType, ARSKeySeq< ResultType >, false, Rounds, Blocks > base_eng_type
Definition: ars.hpp:138