21 #ifndef ROCRAND_DISCRETE_H_
22 #define ROCRAND_DISCRETE_H_
26 #include "rocrand/rocrand_lfsr113.h"
27 #include "rocrand/rocrand_mrg31k3p.h"
28 #include "rocrand/rocrand_mrg32k3a.h"
29 #include "rocrand/rocrand_mtgp32.h"
30 #include "rocrand/rocrand_philox4x32_10.h"
31 #include "rocrand/rocrand_scrambled_sobol32.h"
32 #include "rocrand/rocrand_scrambled_sobol64.h"
33 #include "rocrand/rocrand_sobol32.h"
34 #include "rocrand/rocrand_sobol64.h"
35 #include "rocrand/rocrand_threefry2x32_20.h"
36 #include "rocrand/rocrand_threefry2x64_20.h"
37 #include "rocrand/rocrand_threefry4x32_20.h"
38 #include "rocrand/rocrand_threefry4x64_20.h"
39 #include "rocrand/rocrand_xorwow.h"
41 #include "rocrand/rocrand_discrete_types.h"
46 #if defined(__HIP_DEVICE_COMPILE__) && (defined(__GFX10__) || defined(__GFX11__))
47 #define ROCRAND_PREFER_CDF_OVER_ALIAS
58 namespace rocrand_device {
61 __forceinline__ __device__ __host__
unsigned int
62 discrete_alias(
const double x,
63 const unsigned int size,
64 const unsigned int offset,
65 const unsigned int* __restrict__ alias,
66 const double* __restrict__ probability)
71 const double nx = size * x;
72 const double fnx = floor(nx);
73 const double y = nx - fnx;
74 const unsigned int i =
static_cast<unsigned int>(fnx);
75 return offset + (y < probability[i] ? i : alias[i]);
78 __forceinline__ __device__ __host__
unsigned int
84 __forceinline__ __device__ __host__
unsigned int
87 constexpr
double inv_double_32 = ROCRAND_2POW32_INV_DOUBLE;
88 const double x = r * inv_double_32;
89 return discrete_alias(x, dis);
93 __forceinline__ __device__ __host__
unsigned int
96 constexpr
double inv_double_32 = ROCRAND_2POW32_INV_DOUBLE;
97 const double x = r * inv_double_32;
98 return discrete_alias(x, dis);
101 __forceinline__ __device__ __host__
unsigned int
104 constexpr
double inv_double_64 = ROCRAND_2POW64_INV_DOUBLE;
105 const double x = r * inv_double_64;
106 return discrete_alias(x, dis);
109 __forceinline__ __device__ __host__
unsigned int discrete_cdf(
const double x,
110 const unsigned int size,
111 const unsigned int offset,
112 const double* __restrict__ cdf)
116 unsigned int min = 0;
117 unsigned int max = size - 1;
120 const unsigned int center = (min + max) / 2;
121 const double p = cdf[center];
136 __forceinline__ __device__ __host__
unsigned int
142 __forceinline__ __device__ __host__
unsigned int
145 constexpr
double inv_double_32 = ROCRAND_2POW32_INV_DOUBLE;
146 const double x = r * inv_double_32;
147 return discrete_cdf(x, dis);
151 __forceinline__ __device__ __host__
unsigned int
154 constexpr
double inv_double_32 = ROCRAND_2POW32_INV_DOUBLE;
155 const double x = r * inv_double_32;
156 return discrete_cdf(x, dis);
159 __forceinline__ __device__ __host__
unsigned int
162 constexpr
double inv_double_64 = ROCRAND_2POW64_INV_DOUBLE;
163 const double x = r * inv_double_64;
164 return discrete_cdf(x, dis);
187 __forceinline__ __device__ __host__
unsigned int
191 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
211 rocrand_device::detail::discrete_alias(u4.x, *discrete_distribution),
212 rocrand_device::detail::discrete_alias(u4.y, *discrete_distribution),
213 rocrand_device::detail::discrete_alias(u4.z, *discrete_distribution),
214 rocrand_device::detail::discrete_alias(u4.w, *discrete_distribution)
230 __forceinline__ __device__ __host__
unsigned int
234 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
249 __forceinline__ __device__ __host__
unsigned int
253 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
268 __forceinline__ __device__ __host__
unsigned int
272 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
287 __forceinline__ __device__
unsigned int
291 #ifdef ROCRAND_PREFER_CDF_OVER_ALIAS
292 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
294 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
310 __forceinline__ __device__ __host__
unsigned int
314 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
329 __forceinline__ __device__ __host__
unsigned int
333 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
348 __forceinline__ __device__ __host__
unsigned int
352 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
367 __forceinline__ __device__ __host__
unsigned int
371 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
386 __forceinline__ __device__ __host__
unsigned int
390 #ifdef ROCRAND_PREFER_CDF_OVER_ALIAS
391 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
393 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
409 __forceinline__ __device__ __host__
unsigned int
413 #ifdef ROCRAND_PREFER_CDF_OVER_ALIAS
414 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
416 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
432 __forceinline__ __device__ __host__
unsigned int
436 #ifdef ROCRAND_PREFER_CDF_OVER_ALIAS
437 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
439 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
455 __forceinline__ __device__ __host__
unsigned int
459 #ifdef ROCRAND_PREFER_CDF_OVER_ALIAS
460 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
462 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
478 __forceinline__ __device__ __host__
unsigned int
482 #ifdef ROCRAND_PREFER_CDF_OVER_ALIAS
483 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
485 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
492 #if defined(ROCRAND_PREFER_CDF_OVER_ALIAS)
493 #undef ROCRAND_PREFER_CDF_OVER_ALIAS
__forceinline__ __device__ __host__ uint4 rocrand4(rocrand_state_philox4x32_10 *state)
Returns four uniformly distributed random unsigned int values from [0; 2^32 - 1] range.
Definition: rocrand_philox4x32_10.h:386
__forceinline__ __device__ __host__ uint4 rocrand_discrete4(rocrand_state_philox4x32_10 *state, const rocrand_discrete_distribution discrete_distribution)
Returns four discrete distributed unsigned int values.
Definition: rocrand_discrete.h:206
__forceinline__ __device__ __host__ unsigned int rocrand_discrete(rocrand_state_philox4x32_10 *state, const rocrand_discrete_distribution discrete_distribution)
Returns a discrete distributed unsigned int value.
Definition: rocrand_discrete.h:188
__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
Represents a discrete probability distribution.
Definition: rocrand_discrete_types.h:26
unsigned int size
Number of entries in the probability table.
Definition: rocrand_discrete_types.h:28
unsigned int * alias
Alias table.
Definition: rocrand_discrete_types.h:33
double * cdf
Cumulative distribution function.
Definition: rocrand_discrete_types.h:38
double * probability
Probability data for the alias table.
Definition: rocrand_discrete_types.h:35
unsigned int offset
The distribution can be offset.
Definition: rocrand_discrete_types.h:30