Block-Structured AMR Software Framework
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
AMReX_Random.H
Go to the documentation of this file.
1#ifndef AMREX_RAND_H
2#define AMREX_RAND_H
3#include <AMReX_Config.H>
4
5#include <AMReX.H>
9#include <limits>
10#include <cmath>
11#include <cstdint>
12
13namespace amrex
14{
22 Real Random ();
23
25 Real Random (RandomEngine const& random_engine)
26 {
27#if defined (__SYCL_DEVICE_ONLY__)
28 mkl::rng::device::uniform<Real> distr;
29 return mkl::rng::device::generate(distr, *random_engine.engine);
30#else
31#ifdef BL_USE_FLOAT
34 return 1.0f - hiprand_uniform(random_engine.rand_state); ,
35 return 1.0f - curand_uniform(random_engine.rand_state);
36 )
37 ))
38#else
41 return 1.0 - hiprand_uniform_double(random_engine.rand_state); ,
42 return 1.0 - curand_uniform_double(random_engine.rand_state);
43 )
44 ))
45#endif
47 amrex::ignore_unused(random_engine);
48 return Random();
49 ))
50#endif
51 }
52
60 Real RandomNormal (Real mean, Real stddev);
61
63 Real RandomNormal (Real mean, Real stddev, RandomEngine const& random_engine)
64 {
65#if defined (__SYCL_DEVICE_ONLY__)
66 mkl::rng::device::gaussian<Real> distr(mean, stddev);
67 return mkl::rng::device::generate(distr, *random_engine.engine);
68#else
69#ifdef BL_USE_FLOAT
72 return stddev * hiprand_normal(random_engine.rand_state) + mean; ,
73 return stddev * curand_normal(random_engine.rand_state) + mean;
74 )
75 ))
76#else
79 return stddev * hiprand_normal_double(random_engine.rand_state) + mean; ,
80 return stddev * curand_normal_double(random_engine.rand_state) + mean;
81 )
82 ))
83#endif
85 amrex::ignore_unused(random_engine);
86 return RandomNormal(mean, stddev);
87 ))
88#endif
89 }
90
100 unsigned int RandomPoisson (Real lambda);
101
103 unsigned int RandomPoisson (Real lambda, RandomEngine const& random_engine)
104 {
105#if defined (__SYCL_DEVICE_ONLY__)
106 mkl::rng::device::poisson<unsigned int> distr(lambda);
107 return mkl::rng::device::generate(distr, *random_engine.engine);
108#else
111 return hiprand_poisson(random_engine.rand_state, lambda); ,
112 return curand_poisson(random_engine.rand_state, lambda);
113 )
114 ))
116 amrex::ignore_unused(random_engine);
117 return RandomPoisson(lambda);
118 ))
119#endif
120 }
121
122 namespace random_util {
123
125 Real RandomGamma_alpha_ge_1 (Real alpha, Real beta, RandomEngine const& random_engine)
126 {
127 AMREX_ASSERT(alpha >= 1);
128 AMREX_ASSERT(beta > 0);
129
130 Real x, v, u;
131 Real d = alpha - 1.0_rt / 3.0_rt;
132 Real c = (1.0_rt / 3.0_rt) / std::sqrt(d);
133
134 while (true) {
135 do {
136 x = amrex::RandomNormal(0.0_rt, 1.0_rt, random_engine);
137 v = 1.0_rt + c * x;
138 } while (v <= 0.0_rt);
139
140 v = v * v * v;
141 u = amrex::Random(random_engine);
142
143 if (u < 1.0_rt - 0.0331_rt * x * x * x * x) {
144 break;
145 }
146
147 if (std::log(u) < 0.5_rt * x * x + d * (1.0_rt - v + std::log(v))) {
148 break;
149 }
150 }
151 return beta * d * v;
152 }
153 }
154
166 Real RandomGamma (Real alpha, Real beta);
167
169 Real RandomGamma (Real alpha, Real beta, RandomEngine const& random_engine)
170 {
171 AMREX_ASSERT(alpha > 0);
172 AMREX_ASSERT(beta > 0);
173
175 if (alpha < 1)
176 {
177 Real u = amrex::Random(random_engine);
178 return amrex::random_util::RandomGamma_alpha_ge_1(1.0_rt + alpha, beta, random_engine) * std::pow(u, 1.0_rt / alpha);
179 } else {
180 return amrex::random_util::RandomGamma_alpha_ge_1(alpha, beta, random_engine);
181 }
182 ))
183
185 amrex::ignore_unused(random_engine);
186 return RandomGamma(alpha, beta);
187 ))
188 }
189
197 unsigned int Random_int (unsigned int n); // [0,n-1]
198
200 unsigned int Random_int (unsigned int n, RandomEngine const& random_engine)
201 {
202#if defined(__SYCL_DEVICE_ONLY__)
203 mkl::rng::device::uniform<unsigned int> distr(0,n);
204 return mkl::rng::device::generate(distr, *random_engine.engine);
205#else
207 unsigned int rand;
208 constexpr unsigned int RAND_M = 4294967295; // 2**32-1
209 do {
210 AMREX_HIP_OR_CUDA( rand = hiprand(random_engine.rand_state);,
211 rand = curand(random_engine.rand_state) );
212 } while (rand > (RAND_M - RAND_M % n));
213 return rand % n;
214 ))
216 amrex::ignore_unused(random_engine);
217 return Random_int(n);
218 ))
219#endif
220 }
221
229 ULong Random_long (ULong n); // [0,n-1]
230
233 void FillRandom (Real* p, Long N);
234
236 void FillRandomNormal (Real* p, Long N, Real mean, Real stddev);
237
238 namespace detail {
239 inline ULong DefaultGpuSeed () {
240 return ParallelDescriptor::MyProc()*1234567ULL + 12345ULL;
241 }
242 }
243
256 void InitRandom (ULong cpu_seed, int nprocs=ParallelDescriptor::NProcs(),
257 ULong gpu_seed = detail::DefaultGpuSeed());
258
259 void ResetRandomSeed (ULong cpu_seed, ULong gpu_seed = detail::DefaultGpuSeed());
260
265 void SaveRandomState (std::ostream& os);
266
267 void RestoreRandomState (std::istream& is, int nthreads_old, int nstep_old);
268
278 void UniqueRandomSubset (Vector<int> &uSet, int setSize, int poolSize,
279 bool printSet = false);
280
282}
283
284#endif
#define AMREX_ASSERT(EX)
Definition AMReX_BLassert.H:38
#define AMREX_FORCE_INLINE
Definition AMReX_Extension.H:119
#define AMREX_HIP_OR_CUDA(a, b)
Definition AMReX_GpuControl.H:21
#define AMREX_IF_ON_DEVICE(CODE)
Definition AMReX_GpuQualifiers.H:56
#define AMREX_IF_ON_HOST(CODE)
Definition AMReX_GpuQualifiers.H:58
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
#define AMREX_GPU_HOST_DEVICE
Definition AMReX_GpuQualifiers.H:20
int MyProc() noexcept
return the rank number local to the current Parallel Context
Definition AMReX_ParallelDescriptor.H:125
int NProcs() noexcept
return the number of MPI ranks local to the current Parallel Context
Definition AMReX_ParallelDescriptor.H:243
ULong DefaultGpuSeed()
Definition AMReX_Random.H:239
AMREX_GPU_DEVICE AMREX_FORCE_INLINE Real RandomGamma_alpha_ge_1(Real alpha, Real beta, RandomEngine const &random_engine)
Definition AMReX_Random.H:125
Definition AMReX_Amr.cpp:49
void FillRandomNormal(MultiFab &mf, int scomp, int ncomp, Real mean, Real stddev)
Fill MultiFab with random numbers from normal distribution.
Definition AMReX_MultiFabUtil.cpp:1212
void FillRandom(MultiFab &mf, int scomp, int ncomp)
Fill MultiFab with random numbers from uniform distribution.
Definition AMReX_MultiFabUtil.cpp:1199
void InitRandom(ULong cpu_seed, int nprocs, ULong gpu_seed)
Set the seed of the random number generator.
Definition AMReX_Random.cpp:89
unsigned int Random_int(unsigned int n)
Generates one pseudorandom unsigned integer which is uniformly distributed on [0,n-1]-interval for ea...
Definition AMReX_Random.cpp:144
Real Random()
Generate a psuedo-random double from uniform distribution.
Definition AMReX_Random.cpp:123
void ResetRandomSeed(ULong cpu_seed, ULong gpu_seed)
Definition AMReX_Random.cpp:212
Real RandomNormal(Real mean, Real stddev)
Generate a psuedo-random double from a normal distribution.
Definition AMReX_Random.cpp:116
ULong Random_long(ULong n)
Generates one pseudorandom unsigned long which is uniformly distributed on [0,n-1]-interval for each ...
Definition AMReX_Random.cpp:151
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition AMReX.H:127
void UniqueRandomSubset(Vector< int > &uSet, int setSize, int poolSize, bool printSet)
Create a unique subset of random numbers from a pool of integers in the range [0, poolSize - 1] the s...
Definition AMReX_Random.cpp:190
unsigned int RandomPoisson(Real lambda)
Generate a psuedo-random integer from a Poisson distribution.
Definition AMReX_Random.cpp:130
void DeallocateRandomSeedDevArray()
Definition AMReX_Random.cpp:218
void SaveRandomState(std::ostream &os)
Save and restore random state.
Definition AMReX_Random.cpp:159
void RestoreRandomState(std::istream &is, int nthreads_old, int nstep_old)
Definition AMReX_Random.cpp:167
Real RandomGamma(Real alpha, Real beta)
Generate a psuedo-random floating point number from the Gamma distribution.
Definition AMReX_Random.cpp:137
Definition AMReX_FabArrayCommI.H:896
Definition AMReX_RandomEngine.H:57
randState_t * rand_state
Definition AMReX_RandomEngine.H:58