imate
C++/CUDA Reference
xoshiro_256_star_star.cpp
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright 2021, Siavash Ameli <sameli@berkeley.edu>
3  * SPDX-License-Identifier: BSD-3-Clause
4  * SPDX-FileType: SOURCE
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the license found in the LICENSE.txt file in the root
8  * directory of this source tree.
9  */
10 
11 
12 // =======
13 // Headers
14 // =======
15 
17 #include <cstdlib> // NULL
18 #include "./split_mix_64.h" // SplitMix64
19 
20 // stdint.h in old compilers (e.g. gcc 4.4.7) does not declare UINT64_C macro.
21 #ifndef UINT64_C
22  #define UINT64_C(c) static_cast<uint64_t>(c)
23 #endif
24 
25 
26 // ===========
27 // Constructor
28 // ===========
29 
34  state(NULL)
35 {
36  // Allocate state
37  this->state = new uint64_t[4];
38 
39  // Initializing SplitMix64 random generator
40  SplitMix64 split_mix_64(seed);
41 
42  for (int i=0; i < 4; ++i)
43  {
44  this->state[i] = split_mix_64.next();
45  }
46 }
47 
48 
49 // ==========
50 // Destructor
51 // ==========
52 
55 
57 {
58  if (this->state != NULL)
59  {
60  delete[] this->state;
61  this->state = NULL;
62  }
63 }
64 
65 
66 // ====
67 // next
68 // ====
69 
72 
74 {
75  const uint64_t result = this->rotation_left(this->state[1] * 5, 7) * 9;
76 
77  const uint64_t t = this->state[1] << 17;
78 
79  this->state[2] ^= this->state[0];
80  this->state[3] ^= this->state[1];
81  this->state[1] ^= this->state[2];
82  this->state[0] ^= this->state[3];
83 
84  this->state[2] ^= t;
85 
86  this->state[3] = this->rotation_left(this->state[3], 45);
87 
88  return result;
89 }
90 
91 
92 // ====
93 // jump
94 // ====
95 
99 
101 {
102  static const uint64_t JUMP[] = {
103  0x180ec6d33cfd0aba,
104  0xd5a61266f0c9392c,
105  0xa9582618e03fc9aa,
106  0x39abdc4529b1661c};
107 
108  uint64_t s0 = 0;
109  uint64_t s1 = 0;
110  uint64_t s2 = 0;
111  uint64_t s3 = 0;
112 
113  for (unsigned int i = 0; i < sizeof(JUMP) / sizeof(*JUMP); ++i)
114  {
115  for (int b = 0; b < 64; ++b)
116  {
117  if (JUMP[i] & UINT64_C(1) << b)
118  {
119  s0 ^= this->state[0];
120  s1 ^= this->state[1];
121  s2 ^= this->state[2];
122  s3 ^= this->state[3];
123  }
124 
125  this->next();
126  }
127  }
128 
129  this->state[0] = s0;
130  this->state[1] = s1;
131  this->state[2] = s2;
132  this->state[3] = s3;
133 }
134 
135 
136 // =========
137 // long jump
138 // =========
139 
144 
146 {
147  static const uint64_t LONG_JUMP[] = {
148  0x76e15d3efefdcbbf,
149  0xc5004e441c522fb3,
150  0x77710069854ee241,
151  0x39109bb02acbe635};
152 
153  uint64_t s0 = 0;
154  uint64_t s1 = 0;
155  uint64_t s2 = 0;
156  uint64_t s3 = 0;
157 
158  for (unsigned int i = 0; i < sizeof(LONG_JUMP) / sizeof(*LONG_JUMP); ++i)
159  {
160  for (int b = 0; b < 64; ++b)
161  {
162  if (LONG_JUMP[i] & UINT64_C(1) << b)
163  {
164  s0 ^= this->state[0];
165  s1 ^= this->state[1];
166  s2 ^= this->state[2];
167  s3 ^= this->state[3];
168  }
169 
170  this->next();
171  }
172  }
173 
174  this->state[0] = s0;
175  this->state[1] = s1;
176  this->state[2] = s2;
177  this->state[3] = s3;
178 }
179 
180 
181 // ===========
182 // rotate left
183 // ===========
184 
191 
193  const uint64_t x,
194  int k)
195 {
196  return (x << k) | (x >> (64 - k));
197 }
Pseudo-random integer generator. This class generates 64-bit integer using SplitMix64 algorithm.
Definition: split_mix_64.h:43
uint64_t next()
Generates the next presudo-random number in the sequence.
Xoshiro256StarStar(const int64_t seed)
Constructor. It initializes the state variable with random integers using splitmix64 pseudo-random ge...
static uint64_t rotation_left(const uint64_t x, int k)
Rotates the bits of a 64 bit integer toward left.
void long_jump()
Long jump function for the generator. It is equivalent to 2^192 calls to next(). It can be used to ge...
uint64_t next()
Generates the next presudo-random number.
void jump()
Jump function for the generator. It is equivalent to 2^128 calls to next(); it can be used to generat...
#define UINT64_C(c)