21 #ifndef ROCRAND_DISCRETE_H_
22 #define ROCRAND_DISCRETE_H_
24 #include "rocrand/rocrand_common.h"
25 #include "rocrand/rocrand_lfsr113.h"
26 #include "rocrand/rocrand_mrg31k3p.h"
27 #include "rocrand/rocrand_mrg32k3a.h"
28 #include "rocrand/rocrand_mtgp32.h"
29 #include "rocrand/rocrand_philox4x32_10.h"
30 #include "rocrand/rocrand_scrambled_sobol32.h"
31 #include "rocrand/rocrand_scrambled_sobol64.h"
32 #include "rocrand/rocrand_sobol32.h"
33 #include "rocrand/rocrand_sobol64.h"
34 #include "rocrand/rocrand_threefry2x32_20.h"
35 #include "rocrand/rocrand_threefry2x64_20.h"
36 #include "rocrand/rocrand_threefry4x32_20.h"
37 #include "rocrand/rocrand_threefry4x64_20.h"
38 #include "rocrand/rocrand_xorwow.h"
40 #include <hip/hip_runtime.h>
47 #if defined(__HIP_DEVICE_COMPILE__) && (defined(__GFX10__) || defined(__GFX11__))
48 #define ROCRAND_PREFER_CDF_OVER_ALIAS
59 namespace rocrand_device {
62 __forceinline__ __device__ __host__
unsigned int
63 discrete_alias(
const double x,
64 const unsigned int size,
65 const unsigned int offset,
66 const unsigned int* __restrict__ alias,
67 const double* __restrict__ probability)
72 const double nx = size * x;
73 const double fnx = floor(nx);
74 const double y = nx - fnx;
75 const unsigned int i =
static_cast<unsigned int>(fnx);
76 return offset + (y < probability[i] ? i : alias[i]);
79 __forceinline__ __device__ __host__
unsigned int
85 __forceinline__ __device__ __host__
unsigned int
88 constexpr
double inv_double_32 = ROCRAND_2POW32_INV_DOUBLE;
89 const double x = r * inv_double_32;
90 return discrete_alias(x, dis);
94 __forceinline__ __device__ __host__
unsigned int
97 constexpr
double inv_double_32 = ROCRAND_2POW32_INV_DOUBLE;
98 const double x = r * inv_double_32;
99 return discrete_alias(x, dis);
102 __forceinline__ __device__ __host__
unsigned int
105 constexpr
double inv_double_64 = ROCRAND_2POW64_INV_DOUBLE;
106 const double x = r * inv_double_64;
107 return discrete_alias(x, dis);
110 __forceinline__ __device__ __host__
unsigned int discrete_cdf(
const double x,
111 const unsigned int size,
112 const unsigned int offset,
113 const double* __restrict__ cdf)
117 unsigned int min = 0;
118 unsigned int max = size - 1;
121 const unsigned int center = (min + max) / 2;
122 const double p = cdf[center];
137 __forceinline__ __device__ __host__
unsigned int
143 __forceinline__ __device__ __host__
unsigned int
146 constexpr
double inv_double_32 = ROCRAND_2POW32_INV_DOUBLE;
147 const double x = r * inv_double_32;
148 return discrete_cdf(x, dis);
152 __forceinline__ __device__ __host__
unsigned int
155 constexpr
double inv_double_32 = ROCRAND_2POW32_INV_DOUBLE;
156 const double x = r * inv_double_32;
157 return discrete_cdf(x, dis);
160 __forceinline__ __device__ __host__
unsigned int
163 constexpr
double inv_double_64 = ROCRAND_2POW64_INV_DOUBLE;
164 const double x = r * inv_double_64;
165 return discrete_cdf(x, dis);
188 __forceinline__ __device__ __host__
192 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
207 __forceinline__ __device__ __host__
213 rocrand_device::detail::discrete_alias(u4.x, *discrete_distribution),
214 rocrand_device::detail::discrete_alias(u4.y, *discrete_distribution),
215 rocrand_device::detail::discrete_alias(u4.z, *discrete_distribution),
216 rocrand_device::detail::discrete_alias(u4.w, *discrete_distribution)
232 __forceinline__ __device__ __host__
236 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
251 __forceinline__ __device__ __host__
255 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
270 __forceinline__ __device__ __host__
274 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
289 __forceinline__ __device__
293 #ifdef ROCRAND_PREFER_CDF_OVER_ALIAS
294 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
296 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
312 __forceinline__ __device__ __host__
316 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
331 __forceinline__ __device__ __host__
335 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
350 __forceinline__ __device__ __host__
354 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
369 __forceinline__ __device__ __host__
373 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
388 __forceinline__ __device__ __host__
392 #ifdef ROCRAND_PREFER_CDF_OVER_ALIAS
393 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
395 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
411 __forceinline__ __device__ __host__
415 #ifdef ROCRAND_PREFER_CDF_OVER_ALIAS
416 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
418 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
434 __forceinline__ __device__ __host__
438 #ifdef ROCRAND_PREFER_CDF_OVER_ALIAS
439 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
441 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
457 __forceinline__ __device__ __host__
461 #ifdef ROCRAND_PREFER_CDF_OVER_ALIAS
462 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
464 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
480 __forceinline__ __device__ __host__
484 #ifdef ROCRAND_PREFER_CDF_OVER_ALIAS
485 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
487 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
494 #if defined(ROCRAND_PREFER_CDF_OVER_ALIAS)
495 #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:379
__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:208
__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:189
__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:277
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