MCKL
Monte Carlo Kernel Library
threefry.hpp
Go to the documentation of this file.
1 //============================================================================
2 // MCKL/include/mckl/random/threefry.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_THREEFRY_HPP
33 #define MCKL_RANDOM_THREEFRY_HPP
34 
38 #include <mckl/random/counter.hpp>
40 
41 #if MCKL_HAS_SSE2
43 #endif
44 
45 #if MCKL_HAS_AVX2
47 #endif
48 
51 #ifndef MCKL_THREEFRY_ROUNDS
52 #define MCKL_THREEFRY_ROUNDS 20
53 #endif
54 
55 namespace mckl {
56 
57 namespace internal {
58 
59 #if MCKL_USE_AVX2
60 template <typename T, std::size_t K, std::size_t Rounds, typename Constants>
63 #elif MCKL_USE_SSE2
64 template <typename T, std::size_t K, std::size_t Rounds, typename Constants>
65 using ThreefryGeneratorImpl =
67 #else // MCKL_USE_AVX2
68 template <typename T, std::size_t K, std::size_t Rounds, typename Constants>
69 using ThreefryGeneratorImpl =
71 #endif // MCKL_USE_AVX2
72 
73 } // namespace internal
74 
82 template <typename T, std::size_t K, std::size_t Rounds = MCKL_THREEFRY_ROUNDS,
83  typename Constants = ThreefryConstants<T, K>>
85 {
86  static_assert(std::is_unsigned<T>::value,
87  "**ThreefryGenerator** used with T other than unsigned integer types");
88 
89  static_assert(K != 0 && K % 2 == 0,
90  "**ThreefryGenerator** used with K other than multiples of 2");
91 
92  static_assert(
93  Rounds != 0, "**ThreefryGenerator** used with rounds equal to zero");
94 
95  public:
97  using key_type = std::array<T, K>;
98 
99  static constexpr std::size_t size() { return sizeof(T) * K; }
100 
101  key_type key() const
102  {
103  key_type key;
104  std::memcpy(key.data(), par_.data(), sizeof(T) * K);
105 
106  return key;
107  }
108 
109  void reset(const key_type &key)
110  {
111  constexpr T p = Constants::parity::value;
112 
113  std::memcpy(par_.data(), key.data(), sizeof(T) * K);
114  std::get<K>(par_) = p;
115  for (std::size_t i = 0; i != key.size(); ++i) {
116  std::get<K>(par_) ^= par_[i];
117  }
118  std::get<K + 1>(par_) = 0;
119  std::get<K + 2>(par_) = 0;
120  std::get<K + 3>(par_) = 0;
121  }
122 
123  std::pair<T, T> tweak() const
124  {
125  return std::make_pair(std::get<K + 1>(par_), std::get<K + 2>(par_));
126  }
127 
128  void tweak(T t0, T t1)
129  {
130  std::get<K + 1>(par_) = t0;
131  std::get<K + 2>(par_) = t1;
132  std::get<K + 3>(par_) = t0 ^ t1;
133  }
134 
135  void operator()(const void *plain, void *cipher) const
136  {
138  plain, cipher, par_);
139  }
140 
141  template <typename ResultType>
142  void operator()(ctr_type &ctr, ResultType *r) const
143  {
145  ctr, r, par_);
146  }
147 
148  template <typename ResultType>
149  void operator()(ctr_type &ctr, std::size_t n, ResultType *r) const
150  {
152  ctr, n, r, par_);
153  }
154 
155  friend bool operator==(
158  {
159  return gen1.par_ == gen2.par_;
160  }
161 
162  friend bool operator!=(
165  {
166  return !(gen1 == gen2);
167  }
168 
169  template <typename CharT, typename Traits>
170  friend std::basic_ostream<CharT, Traits> &operator<<(
171  std::basic_ostream<CharT, Traits> &os,
173  {
174  if (!os) {
175  return os;
176  }
177 
178  os << gen.par_;
179 
180  return os;
181  }
182 
183  template <typename CharT, typename Traits>
184  friend std::basic_istream<CharT, Traits> &operator>>(
185  std::basic_istream<CharT, Traits> &is,
187  {
188  if (!is) {
189  return is;
190  }
191 
193  gen_tmp.par_.fill(0);
194  is >> std::ws >> gen_tmp.par_;
195 
196  if (is) {
197  gen = std::move(gen_tmp);
198  }
199 
200  return is;
201  }
202 
203  private:
204  std::array<T, K + 4> par_;
205 }; // class ThreefryGenerator
206 
209 template <typename ResultType, typename T, std::size_t K,
210  std::size_t Rounds = MCKL_THREEFRY_ROUNDS,
211  typename Constants = ThreefryConstants<T, K>>
212 using ThreefryEngine =
214 
217 template <typename ResultType>
219 
222 template <typename ResultType>
224 
227 template <typename ResultType>
229 
232 template <typename ResultType>
234 
237 template <typename ResultType>
239 
242 template <typename ResultType>
244 
246 template <typename ResultType>
248 
250 template <typename ResultType>
252 
254 template <typename ResultType>
256 
260 
264 
268 
272 
276 
280 
284 
288 
292 
296 
300 
304 
308 
312 
316 
320 
324 
328 
329 } // namespace mckl
330 
331 #endif // MCKL_RANDOM_THREEFRY_HPP
Counter based RNG engine.
Definition: counter.hpp:62
void operator()(const void *plain, void *cipher) const
Definition: threefry.hpp:135
void operator()(ctr_type &ctr, std::size_t n, ResultType *r) const
Definition: threefry.hpp:149
static void eval(const void *plain, void *cipher, const std::array< T, K+4 > &par)
Counter< T, K > ctr_type
Definition: threefry.hpp:96
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, ThreefryGenerator< T, K, Rounds, Constants > &gen)
Definition: threefry.hpp:184
void reset(const key_type &key)
Definition: threefry.hpp:109
typename internal::CounterImpl< T, K >::type Counter
A counter type with the same width as std::array<T, K> but with possibly fewer elements.
Definition: increment.hpp:104
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const ThreefryGenerator< T, K, Rounds, Constants > &gen)
Definition: threefry.hpp:170
void operator()(ctr_type &ctr, ResultType *r) const
Definition: threefry.hpp:142
friend bool operator==(const ThreefryGenerator< T, K, Rounds, Constants > &gen1, const ThreefryGenerator< T, K, Rounds, Constants > &gen2)
Definition: threefry.hpp:155
key_type key() const
Definition: threefry.hpp:101
std::pair< T, T > tweak() const
Definition: threefry.hpp:123
Default Threefry constants.
ThreefryGeneratorAVX2Impl< T, K, Rounds, Constants > ThreefryGeneratorImpl
Definition: threefry.hpp:62
Threefry RNG generator.
Definition: threefry.hpp:84
Definition: mcmc.hpp:40
void tweak(T t0, T t1)
Definition: threefry.hpp:128
std::array< T, K > key_type
Definition: threefry.hpp:97
friend bool operator!=(const ThreefryGenerator< T, K, Rounds, Constants > &gen1, const ThreefryGenerator< T, K, Rounds, Constants > &gen2)
Definition: threefry.hpp:162
#define MCKL_THREEFRY_ROUNDS
ThreefryGenerator default rounds.
Definition: threefry.hpp:52
static constexpr std::size_t size()
Definition: threefry.hpp:99