/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-rocrand/checkouts/latest/library/include/rocrand/rocrand_lfsr113.h Source File

/home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-rocrand/checkouts/latest/library/include/rocrand/rocrand_lfsr113.h Source File#

API library: /home/docs/checkouts/readthedocs.org/user_builds/advanced-micro-devices-rocrand/checkouts/latest/library/include/rocrand/rocrand_lfsr113.h Source File
API library
rocrand_lfsr113.h
1 // Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
20 
21 #ifndef ROCRAND_LFSR113_H_
22 #define ROCRAND_LFSR113_H_
23 
24 #ifndef FQUALIFIERS
25  #define FQUALIFIERS __forceinline__ __device__
26 #endif // FQUALIFIERS
27 
28 #include "rocrand/rocrand_common.h"
29 
36 #define ROCRAND_LFSR113_DEFAULT_SEED_X 2
39 #define ROCRAND_LFSR113_DEFAULT_SEED_Y 8
42 #define ROCRAND_LFSR113_DEFAULT_SEED_Z 16
45 #define ROCRAND_LFSR113_DEFAULT_SEED_W 128 // end of group rocranddevice
47 
48 namespace rocrand_device
49 {
50 
51 class lfsr113_engine
52 {
53 public:
54  struct lfsr113_state
55  {
56  uint4 z;
57  uint4 subsequence;
58  };
59 
65  lfsr113_engine(const uint4 seed = {ROCRAND_LFSR113_DEFAULT_SEED_X,
69  const unsigned int subsequence = 0)
70  {
71  this->seed(seed, subsequence);
72  }
73 
79  void seed(uint4 seed_value, const unsigned long long subsequence)
80  {
81  m_state.subsequence = seed_value;
82 
83  reset_start_subsequence();
84  discard_subsequence(subsequence);
85  }
86 
89  void discard()
90  {
91  discard_state();
92  }
93 
97  void discard_subsequence(unsigned int subsequence)
98  {
99  for(unsigned int i = 0; i < subsequence; i++)
100  {
101  reset_next_subsequence();
102  }
103  }
104 
106  unsigned int operator()()
107  {
108  return next();
109  }
110 
112  unsigned int next()
113  {
114  unsigned int b;
115 
116  b = (((m_state.z.x << 6) ^ m_state.z.x) >> 13);
117  m_state.z.x = (((m_state.z.x & 4294967294U) << 18) ^ b);
118 
119  b = (((m_state.z.y << 2) ^ m_state.z.y) >> 27);
120  m_state.z.y = (((m_state.z.y & 4294967288U) << 2) ^ b);
121 
122  b = (((m_state.z.z << 13) ^ m_state.z.z) >> 21);
123  m_state.z.z = (((m_state.z.z & 4294967280U) << 7) ^ b);
124 
125  b = (((m_state.z.w << 3) ^ m_state.z.w) >> 12);
126  m_state.z.w = (((m_state.z.w & 4294967168U) << 13) ^ b);
127 
128  return (m_state.z.x ^ m_state.z.y ^ m_state.z.z ^ m_state.z.w);
129  }
130 
131 protected:
134  void reset_start_subsequence()
135  {
136  m_state.z.x = m_state.subsequence.x;
137  m_state.z.y = m_state.subsequence.y;
138  m_state.z.z = m_state.subsequence.z;
139  m_state.z.w = m_state.subsequence.w;
140  }
141 
144  void reset_next_subsequence()
145  {
146  /* The following operations make the jump ahead with
147  2 ^ 55 iterations for every component of the generator.
148  The internal state after the jump, however, is slightly different
149  from 2 ^ 55 iterations since it ignores the state in
150  which are found the first bits of each components,
151  since they are ignored in the recurrence.The state becomes
152  identical to what one would with normal iterations
153  after a call nextValue().*/
154  int z, b;
155 
156  z = m_state.subsequence.x & 0xFFFFFFFE;
157  b = (z << 6) ^ z;
158 
159  z = (z) ^ (z << 3) ^ (z << 4) ^ (z << 6) ^ (z << 7) ^ (z << 8) ^ (z << 10) ^ (z << 11)
160  ^ (z << 13) ^ (z << 14) ^ (z << 16) ^ (z << 17) ^ (z << 18) ^ (z << 22) ^ (z << 24)
161  ^ (z << 25) ^ (z << 26) ^ (z << 28) ^ (z << 30);
162 
163  z ^= ((b >> 1) & 0x7FFFFFFF) ^ ((b >> 3) & 0x1FFFFFFF) ^ ((b >> 5) & 0x07FFFFFF)
164  ^ ((b >> 6) & 0x03FFFFFF) ^ ((b >> 7) & 0x01FFFFFF) ^ ((b >> 9) & 0x007FFFFF)
165  ^ ((b >> 13) & 0x0007FFFF) ^ ((b >> 14) & 0x0003FFFF) ^ ((b >> 15) & 0x0001FFFF)
166  ^ ((b >> 17) & 0x00007FFF) ^ ((b >> 18) & 0x00003FFF) ^ ((b >> 20) & 0x00000FFF)
167  ^ ((b >> 21) & 0x000007FF) ^ ((b >> 23) & 0x000001FF) ^ ((b >> 24) & 0x000000FF)
168  ^ ((b >> 25) & 0x0000007F) ^ ((b >> 26) & 0x0000003F) ^ ((b >> 27) & 0x0000001F)
169  ^ ((b >> 30) & 0x00000003);
170  m_state.subsequence.x = z;
171 
172  z = m_state.subsequence.y & 0xFFFFFFF8;
173  b = z ^ (z << 1);
174  b ^= (b << 2);
175  b ^= (b << 4);
176  b ^= (b << 8);
177 
178  b <<= 8;
179  b ^= (z << 22) ^ (z << 25) ^ (z << 27);
180  if((z & 0x80000000) != 0)
181  b ^= 0xABFFF000;
182  if((z & 0x40000000) != 0)
183  b ^= 0x55FFF800;
184  z = b ^ ((z >> 7) & 0x01FFFFFF) ^ ((z >> 20) & 0x00000FFF) ^ ((z >> 21) & 0x000007FF);
185  m_state.subsequence.y = z;
186 
187  z = m_state.subsequence.z & 0xFFFFFFF0;
188  b = (z << 13) ^ z;
189  z = ((b >> 3) & 0x1FFFFFFF) ^ ((b >> 17) & 0x00007FFF) ^ (z << 10) ^ (z << 11) ^ (z << 25);
190  m_state.subsequence.z = z;
191 
192  z = m_state.subsequence.w & 0xFFFFFF80;
193  b = (z << 3) ^ z;
194  z = (z << 14) ^ (z << 16) ^ (z << 20) ^ ((b >> 5) & 0x07FFFFFF) ^ ((b >> 9) & 0x007FFFFF)
195  ^ ((b >> 11) & 0x001FFFFF);
196  m_state.subsequence.w = z;
197 
198  reset_start_subsequence();
199  }
200 
201  // Advances the internal state to the next state.
203  void discard_state()
204  {
205  this->next();
206  }
207 
208 protected:
209  lfsr113_state m_state;
210 
211 }; // lfsr113_engine class
212 
213 } // end namespace rocrand_device
214 
221 typedef rocrand_device::lfsr113_engine rocrand_state_lfsr113;
223 
235 void rocrand_init(const uint4 seed, const unsigned int subsequence, rocrand_state_lfsr113* state)
236 {
237  *state = rocrand_state_lfsr113(seed, subsequence);
238 }
239 
253 unsigned int rocrand(rocrand_state_lfsr113* state)
254 {
255  return state->next();
256 }
257  // end of group rocranddevice
259 
260 #endif // ROCRAND_LFSR113_H_
#define ROCRAND_LFSR113_DEFAULT_SEED_Y
Default Y seed for LFSR113 PRNG.
Definition: rocrand_lfsr113.h:39
FQUALIFIERS unsigned int rocrand(rocrand_state_lfsr113 *state)
Returns uniformly distributed random unsigned int value from [0; 2^32 - 1] range.
Definition: rocrand_lfsr113.h:253
#define ROCRAND_LFSR113_DEFAULT_SEED_W
Default W seed for LFSR113 PRNG.
Definition: rocrand_lfsr113.h:45
FQUALIFIERS void rocrand_init(const uint4 seed, const unsigned int subsequence, rocrand_state_lfsr113 *state)
Initializes LFSR113 state.
Definition: rocrand_lfsr113.h:235
#define ROCRAND_LFSR113_DEFAULT_SEED_Z
Default Z seed for LFSR113 PRNG.
Definition: rocrand_lfsr113.h:42
#define ROCRAND_LFSR113_DEFAULT_SEED_X
Default X seed for LFSR113 PRNG.
Definition: rocrand_lfsr113.h:36
#define FQUALIFIERS
Shorthand for commonly used function qualifiers.
Definition: rocrand_uniform.h:31