21 #ifndef ROCRAND_LFSR113_H_
22 #define ROCRAND_LFSR113_H_
24 #include "rocrand/rocrand_common.h"
25 #include "rocrand/rocrand_lfsr113_precomputed.h"
33 #define ROCRAND_LFSR113_DEFAULT_SEED_X 2
36 #define ROCRAND_LFSR113_DEFAULT_SEED_Y 8
39 #define ROCRAND_LFSR113_DEFAULT_SEED_Z 16
42 #define ROCRAND_LFSR113_DEFAULT_SEED_W 128
45 namespace rocrand_device
50 __forceinline__ __device__ __host__
void mul_mat_vec_inplace(
const unsigned int* m, uint4* z)
52 unsigned int v[4] = {z->x, z->y, z->z, z->w};
53 unsigned int r[LFSR113_N] = {0};
54 for(
int ij = 0; ij < LFSR113_N * LFSR113_M; ij++)
56 const int i = ij / LFSR113_M;
57 const int j = ij % LFSR113_M;
58 const unsigned int b = (v[i] & (1U << j)) ? 0xffffffff : 0x0;
59 for(
int k = 0; k < LFSR113_N; k++)
61 r[k] ^= b & m[i * LFSR113_M * LFSR113_N + j * LFSR113_N + k];
86 __forceinline__ __device__ __host__ lfsr113_engine(
const uint4 seed
91 const unsigned int subsequence = 0,
92 const unsigned long long offset = 0)
94 this->seed(seed, subsequence, offset);
102 __forceinline__ __device__ __host__
void seed(uint4 seed_value,
103 const unsigned long long subsequence,
104 const unsigned long long offset = 0)
106 m_state.subsequence = seed_value;
108 reset_start_subsequence();
109 discard_subsequence(subsequence);
114 __forceinline__ __device__ __host__
void discard()
120 __forceinline__ __device__ __host__
void discard(
unsigned long long offset)
122 #ifdef __HIP_DEVICE_COMPILE__
123 jump(offset, d_lfsr113_jump_matrices);
125 jump(offset, h_lfsr113_jump_matrices);
131 __forceinline__ __device__ __host__
void discard_subsequence(
unsigned int subsequence)
134 #ifdef __HIP_DEVICE_COMPILE__
135 jump(subsequence, d_lfsr113_sequence_jump_matrices);
137 jump(subsequence, h_lfsr113_sequence_jump_matrices);
141 __forceinline__ __device__ __host__
unsigned int operator()()
146 __forceinline__ __device__ __host__
unsigned int next()
150 b = (((m_state.z.x << 6) ^ m_state.z.x) >> 13);
151 m_state.z.x = (((m_state.z.x & 4294967294U) << 18) ^ b);
153 b = (((m_state.z.y << 2) ^ m_state.z.y) >> 27);
154 m_state.z.y = (((m_state.z.y & 4294967288U) << 2) ^ b);
156 b = (((m_state.z.z << 13) ^ m_state.z.z) >> 21);
157 m_state.z.z = (((m_state.z.z & 4294967280U) << 7) ^ b);
159 b = (((m_state.z.w << 3) ^ m_state.z.w) >> 12);
160 m_state.z.w = (((m_state.z.w & 4294967168U) << 13) ^ b);
162 return (m_state.z.x ^ m_state.z.y ^ m_state.z.z ^ m_state.z.w);
167 __forceinline__ __device__ __host__
void reset_start_subsequence()
169 m_state.z.x = m_state.subsequence.x;
170 m_state.z.y = m_state.subsequence.y;
171 m_state.z.z = m_state.subsequence.z;
172 m_state.z.w = m_state.subsequence.w;
176 __forceinline__ __device__ __host__
void discard_state()
181 __forceinline__ __device__ __host__
void
182 jump(
unsigned long long v,
183 const unsigned int (&jump_matrices)[LFSR113_JUMP_MATRICES][LFSR113_SIZE])
201 const unsigned int is =
static_cast<unsigned int>(v) & ((1 << LFSR113_JUMP_LOG2) - 1);
202 for(
unsigned int i = 0; i < is; i++)
204 detail::mul_mat_vec_inplace(jump_matrices[mi], &m_state.z);
207 v >>= LFSR113_JUMP_LOG2;
212 lfsr113_state m_state;
224 typedef rocrand_device::lfsr113_engine rocrand_state_lfsr113;
237 __forceinline__ __device__ __host__
void
238 rocrand_init(
const uint4 seed,
const unsigned int subsequence, rocrand_state_lfsr113* state)
240 *state = rocrand_state_lfsr113(seed, subsequence);
254 __forceinline__ __device__ __host__
void rocrand_init(
const uint4 seed,
255 const unsigned int subsequence,
256 const unsigned long long offset,
257 rocrand_state_lfsr113* state)
259 *state = rocrand_state_lfsr113(seed, subsequence, offset);
274 __forceinline__ __device__ __host__
unsigned int rocrand(rocrand_state_lfsr113* state)
276 return state->next();
287 __forceinline__ __device__ __host__
void skipahead(
unsigned long long offset,
288 rocrand_state_lfsr113* state)
290 return state->discard(offset);
303 rocrand_state_lfsr113* state)
305 return state->discard_subsequence(subsequence);
318 rocrand_state_lfsr113* state)
320 return state->discard_subsequence(sequence);
__forceinline__ __device__ __host__ void rocrand_init(const uint4 seed, const unsigned int subsequence, rocrand_state_lfsr113 *state)
Initializes LFSR113 state.
Definition: rocrand_lfsr113.h:238
__forceinline__ __device__ __host__ void skipahead(unsigned long long offset, rocrand_state_lfsr113 *state)
Updates LFSR113 state to skip ahead by offset elements.
Definition: rocrand_lfsr113.h:287
#define ROCRAND_LFSR113_DEFAULT_SEED_Y
Default Y seed for LFSR113 PRNG.
Definition: rocrand_lfsr113.h:36
__forceinline__ __device__ __host__ void skipahead_sequence(unsigned int sequence, rocrand_state_lfsr113 *state)
Updates LFSR113 state to skip ahead by sequence sequences.
Definition: rocrand_lfsr113.h:317
#define ROCRAND_LFSR113_DEFAULT_SEED_W
Default W seed for LFSR113 PRNG.
Definition: rocrand_lfsr113.h:42
__forceinline__ __device__ __host__ void skipahead_subsequence(unsigned int subsequence, rocrand_state_lfsr113 *state)
Updates LFSR113 state to skip ahead by subsequence subsequences.
Definition: rocrand_lfsr113.h:302
#define ROCRAND_LFSR113_DEFAULT_SEED_Z
Default Z seed for LFSR113 PRNG.
Definition: rocrand_lfsr113.h:39
#define ROCRAND_LFSR113_DEFAULT_SEED_X
Default X seed for LFSR113 PRNG.
Definition: rocrand_lfsr113.h:33
__forceinline__ __device__ __host__ unsigned int rocrand(rocrand_state_lfsr113 *state)
Returns uniformly distributed random unsigned int value from [0; 2^32 - 1] range.
Definition: rocrand_lfsr113.h:274