28 #ifndef OPENRAND_Philox_H_
29 #define OPENRAND_Philox_H_
31 #include <openrand/base_state.h>
38 #define PHILOX_W0 0x9E3779B9
39 #define PHILOX_W1 0xBB67AE85
40 #define PHILOX_M0 0xD2511F53
41 #define PHILOX_M1 0xCD9E8D57
64 OPENRAND_DEVICE
Philox(uint64_t seed, uint32_t ctr,
65 uint32_t global_seed = openrand::DEFAULT_GLOBAL_SEED,
66 uint32_t ctr1 = 0x12345)
67 : seed_hi((uint32_t)(seed >> 32)),
68 seed_lo((uint32_t)(seed & 0xFFFFFFFF)),
74 template <
typename T = u
int32_t>
75 OPENRAND_DEVICE T draw() {
78 static_assert(std::is_same_v<T, uint32_t> || std::is_same_v<T, uint64_t>);
79 if constexpr (std::is_same_v<T, uint32_t>)
return _out[0];
83 uint64_t res = (
static_cast<uint64_t
>(_out[0]) << 32) |
84 static_cast<uint64_t
>(_out[1]);
85 return static_cast<uint64_t
>(res);
97 u01<float, uint32_t>(_out[0]), u01<float, uint32_t>(_out[1]),
98 u01<float, uint32_t>(_out[2]), u01<float, uint32_t>(_out[3])};
102 OPENRAND_DEVICE
void generate() {
103 uint32_t key[2] = {seed_hi, seed_lo};
118 for (
int r = 0; r < 10; r++) {
128 inline OPENRAND_DEVICE uint32_t mulhilo(uint32_t L, uint32_t R,
130 uint64_t product =
static_cast<uint64_t
>(L) *
static_cast<uint64_t
>(R);
131 *hip =
static_cast<uint32_t
>(product >> 32);
132 return static_cast<uint32_t
>(product);
135 inline OPENRAND_DEVICE
void round(
const uint32_t (&key)[2],
136 uint32_t (&ctr)[4]) {
139 uint32_t lo0 = mulhilo(PHILOX_M0, ctr[0], &hi0);
140 uint32_t lo1 = mulhilo(PHILOX_M1, ctr[2], &hi1);
141 ctr[0] = hi1 ^ ctr[1] ^ key[0];
143 ctr[2] = hi0 ^ ctr[3] ^ key[1];
149 const uint32_t seed_hi, seed_lo;
150 const uint32_t ctr0, ctr1, ctr2;
Base class for random number generators.
Definition: base_state.h:50
Philox generator.
Definition: philox.h:51
OPENRAND_DEVICE Philox(uint64_t seed, uint32_t ctr, uint32_t global_seed=openrand::DEFAULT_GLOBAL_SEED, uint32_t ctr1=0x12345)
Construct a new Philox generator.
Definition: philox.h:64