Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/bits/random.hfa

    r4020f09 r261e107  
    1010// Created On       : Fri Jan 14 07:18:11 2022
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Dec  5 13:13:14 2022
    13 // Update Count     : 128
     12// Last Modified On : Fri Dec  9 17:08:30 2022
     13// Update Count     : 169
    1414//
    1515
     
    2323// Set default PRNG for architecture size.
    2424#ifdef __x86_64__                                                                               // 64-bit architecture
    25 #define LEHMER64
    26 #define XORSHIFT_6_21_7
    27 //#define XOSHIRO256PP
    28 //#define XOSHIRO128PP
     25        // 64-bit generators
     26        #define LEHMER64
     27        //#define XORSHIFT_12_25_27
     28        //#define XOSHIRO256PP
     29        //#define KISS_64
     30
     31        // 32-bit generators
     32        #define XORSHIFT_6_21_7
     33        //#define XOSHIRO128PP
    2934#else                                                                                                   // 32-bit architecture
    30 #define XORSHIFT_13_7_17
    31 #define XORSHIFT_6_21_7
     35        // 64-bit generators
     36        #define XORSHIFT_13_7_17
     37
     38        // 32-bit generators
     39        #define XORSHIFT_6_21_7
    3240#endif // __x86_64__
    3341
     
    3543
    3644// SKULLDUGGERY: typedefs name struct and typedef with the same name to deal with CFA typedef numbering problem.
    37 
    38 #ifdef LEHMER64
    39 #define PRNG_NAME_64 lehmer64
    40 #define PRNG_STATE_64_T __uint128_t
    41 #endif // LEHMER64
    42 
    43 #ifdef XORSHIFT_13_7_17
    44 #define PRNG_NAME_64 xorshift_13_7_17
    45 #define PRNG_STATE_64_T uint64_t
    46 #endif // XORSHIFT_13_7_17
    47 
    48 #ifdef XORSHIFT_6_21_7
    49 #define PRNG_NAME_32 xorshift_6_21_7
    50 #define PRNG_STATE_32_T uint32_t
    51 #endif // XORSHIFT_6_21_7
    5245
    5346#ifdef XOSHIRO256PP
     
    6255typedef struct PRNG_STATE_32_T { uint32_t s[4]; } PRNG_STATE_32_T;
    6356#endif // XOSHIRO128PP
     57
     58#ifdef LEHMER64
     59#define PRNG_NAME_64 lehmer64
     60#define PRNG_STATE_64_T __uint128_t
     61#endif // LEHMER64
     62
     63#ifdef WYHASH64
     64#define PRNG_NAME_64 wyhash64
     65#define PRNG_STATE_64_T uint64_t
     66#endif // LEHMER64
     67
     68#ifdef XORSHIFT_13_7_17
     69#define PRNG_NAME_64 xorshift_13_7_17
     70#define PRNG_STATE_64_T uint64_t
     71#endif // XORSHIFT_13_7_17
     72
     73#ifdef XORSHIFT_6_21_7
     74#define PRNG_NAME_32 xorshift_6_21_7
     75#define PRNG_STATE_32_T uint32_t
     76#endif // XORSHIFT_6_21_7
     77
     78#ifdef XORSHIFT_12_25_27
     79#define PRNG_NAME_64 xorshift_12_25_27
     80#define PRNG_STATE_64_T uint64_t
     81#endif // XORSHIFT_12_25_27
     82
     83#ifdef KISS_64
     84#define PRNG_NAME_64 kiss_64
     85#define PRNG_STATE_64_T GLUE(PRNG_NAME_64,_t)
     86typedef struct PRNG_STATE_64_T { uint64_t z, w, jsr, jcong; } PRNG_STATE_64_T;
     87#endif // KISS_^64
    6488
    6589#ifdef XORWOW
     
    85109
    86110
     111// ALL PRNG ALGORITHMS ARE OPTIMIZED SO THAT THE PRNG LOGIC CAN HAPPEN IN PARALLEL WITH THE USE OF THE RESULT.
     112// Therefore, the set_seed routine primes the state by calling the PRNG with the state so the seed is not return as the
     113// first random value.
     114
    87115#ifdef __cforall                                                                                // don't include in C code (invoke.h)
    88116
     
    120148static inline void xoshiro256pp_set_seed( xoshiro256pp_t & state,  uint64_t seed ) {
    121149        state = (xoshiro256pp_t){ {seed, seed, seed, seed} };
     150        xoshiro256pp( state );
    122151} // xoshiro256pp_set_seed
    123152
     
    154183static inline void xoshiro128pp_set_seed( xoshiro128pp_t & state, uint32_t seed ) {
    155184        state = (xoshiro128pp_t){ {seed, seed, seed, seed} };
     185        xoshiro128pp( state );                                                          // prime
    156186} // xoshiro128pp_set_seed
    157187
     
    168198        static inline void lehmer64_set_seed( __uint128_t & state, uint64_t seed ) {
    169199                state = seed;
     200                lehmer64( state );
    170201        } // lehmer64_set_seed
    171202
    172203        //--------------------------------------------------
    173204        static inline uint64_t wyhash64( uint64_t & state ) {
    174                 state += 0x60bee2bee120fc15;
     205                uint64_t ret = state;
     206                state += 0x_60be_e2be_e120_fc15;
    175207                __uint128_t tmp;
    176                 tmp = (__uint128_t) state * 0xa3b195354a39b70d;
     208                tmp = (__uint128_t) ret * 0x_a3b1_9535_4a39_b70d;
    177209                uint64_t m1 = (tmp >> 64) ^ tmp;
    178                 tmp = (__uint128_t)m1 * 0x1b03738712fad5c9;
     210                tmp = (__uint128_t)m1 * 0x_1b03_7387_12fa_d5c9;
    179211                uint64_t m2 = (tmp >> 64) ^ tmp;
    180212                return m2;
    181         }
    182 
    183         static inline void wyhash64_set_seed( __uint128_t & state, uint64_t seed ) {
     213        } // wyhash64
     214
     215        static inline void wyhash64_set_seed( uint64_t & state, uint64_t seed ) {
    184216                state = seed;
    185         } // lehmer64_set_seed
     217                wyhash64( state );                                                              // prime
     218        } // wyhash64_set_seed
    186219#endif // __SIZEOF_INT128__
    187220
     
    195228} // xorshift_13_7_17
    196229
    197 static inline void xorshift_13_7_17_set_seed( uint64_t & state, uint32_t seed ) {
     230static inline void xorshift_13_7_17_set_seed( uint64_t & state, uint64_t seed ) {
    198231        state = seed;
     232        xorshift_13_7_17( state );                                                      // prime
    199233} // xorshift_13_7_17_set_seed
    200234
     
    214248static inline void xorshift_6_21_7_set_seed( uint32_t & state, uint32_t seed ) {
    215249        state = seed;
     250        xorshift_6_21_7( state );                                                       // prime
    216251} // xorshift_6_21_7_set_seed
     252
     253//--------------------------------------------------
     254// The state must be seeded with a nonzero value.
     255static inline uint64_t xorshift_12_25_27( uint64_t & state ) {
     256        uint64_t ret = state;
     257        state ^= state >> 12;
     258        state ^= state << 25;
     259        state ^= state >> 27;
     260        return ret * 0x_2545_F491_4F6C_DD1D;
     261} // xorshift_12_25_27
     262
     263static inline void xorshift_12_25_27_set_seed( uint64_t & state, uint64_t seed ) {
     264        state = seed;
     265        xorshift_12_25_27( state );                                                     // prime
     266} // xorshift_12_25_27_set_seed
     267
     268//--------------------------------------------------
     269// The state must be seeded with a nonzero value.
     270#ifndef KISS_64
     271typedef struct kiss_64_t { uint64_t z, w, jsr, jcong; } kiss_64_t;
     272#endif // ! KISS_64
     273
     274static inline uint64_t kiss_64( kiss_64_t & state ) with(state) {
     275        kiss_64_t ret = state;
     276        z = 36969 * (z & 65535) + (z >> 16);
     277        w = 18000 * (w & 65535) + (w >> 16);
     278        jsr ^= (jsr << 17);
     279        jsr ^= (jsr << 13);
     280        jsr ^= (jsr << 5);
     281        jcong = 69069 * jcong + 1234567;
     282        return ((ret.z << 16 + ret.w) ^ ret.jcong) + ret.jsr;
     283} // kiss_64
     284
     285static inline void kiss_64_set_seed( kiss_64_t & state, uint64_t seed ) with(state) {
     286        z = 1; w = 1; jsr = 4; jcong = seed;
     287        kiss_64( state );                                                                       // prime
     288} // kiss_64_set_seed
    217289
    218290//--------------------------------------------------
     
    222294#endif // ! XORWOW
    223295
    224 static inline uint32_t xorwow( xorwow_t & state ) {
     296static inline uint32_t xorwow( xorwow_t & state ) with(state) {
    225297        // Algorithm "xorwow" from p. 5 of Marsaglia, "Xorshift RNGs".
    226         uint32_t ret = state.a + state.counter;
    227         uint32_t t = state.d;
    228 
    229         uint32_t const s = state.a;
    230         state.d = state.c;
    231         state.c = state.b;
    232         state.b = s;
     298        uint32_t ret = a + counter;
     299        uint32_t t = d;
     300
     301        uint32_t const s = a;
     302        d = c;
     303        c = b;
     304        b = s;
    233305
    234306        t ^= t >> 2;
    235307        t ^= t << 1;
    236308        t ^= s ^ (s << 4);
    237         state.a = t;
    238 
    239         state.counter += 362437;
     309        a = t;
     310        counter += 362437;
    240311        return ret;
    241312} // xorwow
     
    243314static inline void xorwow_set_seed( xorwow_t & state, uint32_t seed ) {
    244315        state = (xorwow_t){ seed, seed, seed, seed, 0 };
     316        xorwow( state );                                                                        // prime
    245317} // xorwow_set_seed
    246318
Note: See TracChangeset for help on using the changeset viewer.