vSMC  v3.0.0
Scalable Monte Carlo
philox.h
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/rngc/philox.h
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013-2016, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef VSMC_RNGC_PHILOX_H
33 #define VSMC_RNGC_PHILOX_H
34 
35 #include <vsmc/internal/config.h>
36 
39 typedef struct {
40  uint32_t v[2];
42 
45 typedef struct {
46  uint32_t v[4];
48 
51 typedef struct {
52  uint32_t v[1];
54 
57 typedef struct {
58  uint32_t v[2];
60 
61 typedef struct {
62  uint32_t v[1];
64 
65 typedef struct {
66  uint32_t v[2];
68 
71 typedef struct {
77 
80 typedef struct {
86 
88 {
89  if (++ctr->v[0] != 0)
90  return;
91  if (++ctr->v[1] != 0)
92  return;
93 }
94 
96 {
97  if (++ctr->v[0] != 0)
98  return;
99  if (++ctr->v[1] != 0)
100  return;
101  if (++ctr->v[2] != 0)
102  return;
103  if (++ctr->v[3] != 0)
104  return;
105 }
106 
107 static inline void vsmc_philox2x32_initpar(
109 {
110  par->v[0] = key->v[0];
111 }
112 
113 static inline void vsmc_philox4x32_initpar(
115 {
116  par->v[0] = key->v[0];
117  par->v[1] = key->v[1];
118 }
119 
121 {
122  par->v[0] += UINT32_C(0x9E3779B9);
123 }
124 
126 {
127  par->v[0] += UINT32_C(0x9E3779B9);
128  par->v[1] += UINT32_C(0xBB67AE85);
129 }
130 
131 static inline void vsmc_philox2x32_round(
132  vsmc_philox2x32_ctr_t *state, const vsmc_philox2x32_par_t *par)
133 {
134 #ifdef __cplusplus
135  uint64_t p = static_cast<uint64_t>(state->v[0]) * UINT64_C(0xD256D193);
136  uint32_t hi = static_cast<uint32_t>(p >> 32);
137  uint32_t lo = static_cast<uint32_t>(p);
138 #else
139  uint64_t p = ((uint64_t)(state->v[0])) * UINT64_C(0xD256D193);
140  uint32_t hi = (uint32_t)(p >> 32);
141  uint32_t lo = (uint32_t)(p);
142 #endif
143  hi ^= par->v[0];
144  state->v[0] = hi ^ (state->v[1]);
145  state->v[1] = lo;
146 }
147 
148 static inline void vsmc_philox4x32_round(
149  vsmc_philox4x32_ctr_t *state, const vsmc_philox4x32_par_t *par)
150 {
151 #ifdef __cplusplus
152  uint64_t p0 = static_cast<uint64_t>(state->v[0]) * UINT64_C(0xD2511F53);
153  uint64_t p2 = static_cast<uint64_t>(state->v[2]) * UINT64_C(0xCD9E8D57);
154  uint32_t hi0 = static_cast<uint32_t>(p2 >> 32);
155  uint32_t lo1 = static_cast<uint32_t>(p2);
156  uint32_t hi2 = static_cast<uint32_t>(p0 >> 32);
157  uint32_t lo3 = static_cast<uint32_t>(p0);
158 #else
159  uint64_t p0 = ((uint64_t)(state->v[0])) * UINT64_C(0xD2511F53);
160  uint64_t p2 = ((uint64_t)(state->v[2])) * UINT64_C(0xCD9E8D57);
161  uint32_t hi0 = (uint32_t)(p2 >> 32);
162  uint32_t lo1 = (uint32_t)(p2);
163  uint32_t hi2 = (uint32_t)(p0 >> 32);
164  uint32_t lo3 = (uint32_t)(p0);
165 #endif
166  hi0 ^= par->v[0];
167  hi2 ^= par->v[1];
168  state->v[0] = hi0 ^ (state->v[1]);
169  state->v[1] = lo1;
170  state->v[2] = hi2 ^ (state->v[3]);
171  state->v[3] = lo3;
172 }
173 
176 static inline void vsmc_philox2x32_gen(const vsmc_philox2x32_ctr_t *ctr,
177  const vsmc_philox2x32_key_t *key, vsmc_philox2x32_ctr_t *state)
178 {
179  *state = *ctr;
181  vsmc_philox2x32_initpar(key, &par);
182 
183  vsmc_philox2x32_round(state, &par); // N = 1
184  vsmc_philox2x32_bumpkey(&par); // N = 2
185  vsmc_philox2x32_round(state, &par); // N = 2
186  vsmc_philox2x32_bumpkey(&par); // N = 3
187  vsmc_philox2x32_round(state, &par); // N = 3
188  vsmc_philox2x32_bumpkey(&par); // N = 4
189  vsmc_philox2x32_round(state, &par); // N = 4
190  vsmc_philox2x32_bumpkey(&par); // N = 5
191  vsmc_philox2x32_round(state, &par); // N = 5
192  vsmc_philox2x32_bumpkey(&par); // N = 6
193  vsmc_philox2x32_round(state, &par); // N = 6
194  vsmc_philox2x32_bumpkey(&par); // N = 7
195  vsmc_philox2x32_round(state, &par); // N = 7
196  vsmc_philox2x32_bumpkey(&par); // N = 8
197  vsmc_philox2x32_round(state, &par); // N = 8
198  vsmc_philox2x32_bumpkey(&par); // N = 9
199  vsmc_philox2x32_round(state, &par); // N = 9
200  vsmc_philox2x32_bumpkey(&par); // N = 10
201  vsmc_philox2x32_round(state, &par); // N = 10
202 }
203 
206 static inline void vsmc_philox4x32_gen(const vsmc_philox4x32_ctr_t *ctr,
207  const vsmc_philox4x32_key_t *key, vsmc_philox4x32_ctr_t *state)
208 {
209  *state = *ctr;
211  vsmc_philox4x32_initpar(key, &par);
212 
213  vsmc_philox4x32_round(state, &par); // N = 1
214  vsmc_philox4x32_bumpkey(&par); // N = 2
215  vsmc_philox4x32_round(state, &par); // N = 2
216  vsmc_philox4x32_bumpkey(&par); // N = 3
217  vsmc_philox4x32_round(state, &par); // N = 3
218  vsmc_philox4x32_bumpkey(&par); // N = 4
219  vsmc_philox4x32_round(state, &par); // N = 4
220  vsmc_philox4x32_bumpkey(&par); // N = 5
221  vsmc_philox4x32_round(state, &par); // N = 5
222  vsmc_philox4x32_bumpkey(&par); // N = 6
223  vsmc_philox4x32_round(state, &par); // N = 6
224  vsmc_philox4x32_bumpkey(&par); // N = 7
225  vsmc_philox4x32_round(state, &par); // N = 7
226  vsmc_philox4x32_bumpkey(&par); // N = 8
227  vsmc_philox4x32_round(state, &par); // N = 8
228  vsmc_philox4x32_bumpkey(&par); // N = 9
229  vsmc_philox4x32_round(state, &par); // N = 9
230  vsmc_philox4x32_bumpkey(&par); // N = 10
231  vsmc_philox4x32_round(state, &par); // N = 10
232 }
233 
236 static inline void vsmc_philox2x32_init(vsmc_philox2x32 *rng, uint32_t seed)
237 {
238  rng->ctr.v[0] = 0;
239  rng->ctr.v[1] = 0;
240  rng->key.v[0] = seed;
241  rng->index = 2;
242 }
243 
246 static inline void vsmc_philox4x32_init(vsmc_philox4x32 *rng, uint32_t seed)
247 {
248  rng->ctr.v[0] = 0;
249  rng->ctr.v[1] = 0;
250  rng->ctr.v[2] = 0;
251  rng->ctr.v[3] = 0;
252  rng->key.v[0] = seed;
253  rng->key.v[1] = 0;
254  rng->index = 4;
255 }
256 
260 {
261  if (rng->index == 2) {
262  vsmc_philox2x32_inc(&rng->ctr);
263  vsmc_philox2x32_gen(&rng->ctr, &rng->key, &rng->state);
264  rng->index = 0;
265  }
266 
267  return rng->state.v[rng->index++];
268 }
269 
273 {
274  if (rng->index == 4) {
275  vsmc_philox4x32_inc(&rng->ctr);
276  vsmc_philox4x32_gen(&rng->ctr, &rng->key, &rng->state);
277  rng->index = 0;
278  }
279 
280  return rng->state.v[rng->index++];
281 }
282 
283 #endif // VSMC_RNGC_PHILOX_H
#define UINT64_C(x)
Definition: opencl.h:44
Philox4x32 counter type.
Definition: philox.h:45
uint32_t v[2]
Definition: philox.h:40
uint32_t v[4]
Definition: philox.h:46
static void vsmc_philox2x32_round(vsmc_philox2x32_ctr_t *state, const vsmc_philox2x32_par_t *par)
Definition: philox.h:131
vsmc_philox2x32_ctr_t ctr
Definition: philox.h:73
Philox2x32 counter type.
Definition: philox.h:39
vsmc_philox4x32_ctr_t ctr
Definition: philox.h:82
Philox4x32 RNG state structure.
Definition: philox.h:80
static void vsmc_philox2x32_initpar(const vsmc_philox2x32_key_t *key, vsmc_philox2x32_par_t *par)
Definition: philox.h:107
uint32_t v[1]
Definition: philox.h:52
Philox2x32 RNG state structure.
Definition: philox.h:71
uint uint32_t
Definition: opencl.h:41
static void vsmc_philox4x32_initpar(const vsmc_philox4x32_key_t *key, vsmc_philox4x32_par_t *par)
Definition: philox.h:113
ulong uint64_t
Definition: opencl.h:42
static void vsmc_philox4x32_bumpkey(vsmc_philox4x32_par_t *par)
Definition: philox.h:125
static void vsmc_philox4x32_gen(const vsmc_philox4x32_ctr_t *ctr, const vsmc_philox4x32_key_t *key, vsmc_philox4x32_ctr_t *state)
Generate Philox4x32 RNG state.
Definition: philox.h:206
uint32_t v[2]
Definition: philox.h:58
vsmc_philox2x32_ctr_t state
Definition: philox.h:72
Philox2x32 key type.
Definition: philox.h:51
static void vsmc_philox2x32_init(vsmc_philox2x32 *rng, uint32_t seed)
Initialize Philox2x32 RNG state.
Definition: philox.h:236
Philox4x32 key type.
Definition: philox.h:57
static uint32_t vsmc_philox2x32_rand(vsmc_philox2x32 *rng)
Generate random 32-bit integers from Philox2x32 RNG.
Definition: philox.h:259
uint32_t index
Definition: philox.h:75
static void vsmc_philox2x32_gen(const vsmc_philox2x32_ctr_t *ctr, const vsmc_philox2x32_key_t *key, vsmc_philox2x32_ctr_t *state)
Generate Philox2x32 RNG state.
Definition: philox.h:176
static void vsmc_philox2x32_bumpkey(vsmc_philox2x32_par_t *par)
Definition: philox.h:120
vsmc_philox4x32_ctr_t state
Definition: philox.h:81
uint32_t v[2]
Definition: philox.h:66
uint32_t v[1]
Definition: philox.h:62
static uint32_t vsmc_philox4x32_rand(vsmc_philox4x32 *rng)
Generate random 32-bit integers from Philox4x32 RNG.
Definition: philox.h:272
vsmc_philox2x32_key_t key
Definition: philox.h:74
static void vsmc_philox4x32_init(vsmc_philox4x32 *rng, uint32_t seed)
Initialize Philox4x32 RNG state.
Definition: philox.h:246
static void vsmc_philox4x32_round(vsmc_philox4x32_ctr_t *state, const vsmc_philox4x32_par_t *par)
Definition: philox.h:148
#define UINT32_C(x)
Definition: opencl.h:43
vsmc_philox4x32_key_t key
Definition: philox.h:83
static void vsmc_philox4x32_inc(vsmc_philox4x32_ctr_t *ctr)
Definition: philox.h:95
uint32_t index
Definition: philox.h:84
static void vsmc_philox2x32_inc(vsmc_philox2x32_ctr_t *ctr)
Definition: philox.h:87