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
59namespace 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
80 discrete_alias(
const double x,
const rocrand_discrete_distribution_st& dis)
85__forceinline__ __device__ __host__
unsigned int
86 discrete_alias(
const unsigned int r,
const rocrand_discrete_distribution_st& dis)
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
95 discrete_alias(
const unsigned long r,
const rocrand_discrete_distribution_st& dis)
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
103 discrete_alias(
const unsigned long long int r,
const rocrand_discrete_distribution_st& dis)
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
138 discrete_cdf(
const double x,
const rocrand_discrete_distribution_st& dis)
143__forceinline__ __device__ __host__
unsigned int
144 discrete_cdf(
const unsigned int r,
const rocrand_discrete_distribution_st& dis)
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
153 discrete_cdf(
const unsigned long r,
const rocrand_discrete_distribution_st& dis)
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
161 discrete_cdf(
const unsigned long long int r,
const rocrand_discrete_distribution_st& dis)
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__
190 const rocrand_discrete_distribution discrete_distribution)
192 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
207__forceinline__ __device__ __host__
209 const rocrand_discrete_distribution discrete_distribution)
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__
234 const rocrand_discrete_distribution discrete_distribution)
236 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
251__forceinline__ __device__ __host__
253 const rocrand_discrete_distribution discrete_distribution)
255 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
270__forceinline__ __device__ __host__
272 const rocrand_discrete_distribution discrete_distribution)
274 return rocrand_device::detail::discrete_alias(
rocrand(state), *discrete_distribution);
289__forceinline__ __device__
291 const rocrand_discrete_distribution discrete_distribution)
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__
314 const rocrand_discrete_distribution discrete_distribution)
316 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
331__forceinline__ __device__ __host__
333 const rocrand_discrete_distribution discrete_distribution)
335 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
350__forceinline__ __device__ __host__
352 const rocrand_discrete_distribution discrete_distribution)
354 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
369__forceinline__ __device__ __host__
371 const rocrand_discrete_distribution discrete_distribution)
373 return rocrand_device::detail::discrete_cdf(
rocrand(state), *discrete_distribution);
388__forceinline__ __device__ __host__
390 const rocrand_discrete_distribution discrete_distribution)
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__
413 const rocrand_discrete_distribution discrete_distribution)
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__
436 const rocrand_discrete_distribution discrete_distribution)
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__
459 const rocrand_discrete_distribution discrete_distribution)
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__
482 const rocrand_discrete_distribution discrete_distribution)
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
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