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