Block-Structured AMR Software Framework
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>
6 #include <AMReX_GpuQualifiers.H>
8 #include <AMReX_RandomEngine.H>
9 #include <limits>
10 #include <cmath>
11 #include <cstdint>
12 
13 namespace 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 
133  Real RandomGamma (Real alpha, Real beta);
134 
136  Real RandomGamma (Real alpha, Real beta, RandomEngine const& random_engine)
137  {
138  AMREX_ASSERT(alpha > 0);
139  AMREX_ASSERT(beta > 0);
140 
142  if (alpha < 1)
143  {
144  Real u = amrex::Random(random_engine);
145  return RandomGamma(1.0_rt + alpha, beta, random_engine) * std::pow(u, 1.0_rt / alpha);
146  }
147 
148  {
149  Real x, v, u;
150  Real d = alpha - 1.0_rt / 3.0_rt;
151  Real c = (1.0_rt / 3.0_rt) / std::sqrt(d);
152 
153  while (1) {
154  do {
155  x = amrex::RandomNormal(0.0_rt, 1.0_rt, random_engine);
156  v = 1.0_rt + c * x;
157  } while (v <= 0.0_rt);
158 
159  v = v * v * v;
160  u = amrex::Random(random_engine);
161 
162  if (u < 1.0_rt - 0.0331_rt * x * x * x * x) {
163  break;
164  }
165 
166  if (std::log(u) < 0.5_rt * x * x + d * (1.0_rt - v + std::log(v))) {
167  break;
168  }
169  }
170  return beta * d * v;
171  }
172  ))
173 
175  amrex::ignore_unused(random_engine);
176  return RandomGamma(alpha, beta);
177  ))
178 
179  }
180 
188  unsigned int Random_int (unsigned int n); // [0,n-1]
189 
191  unsigned int Random_int (unsigned int n, RandomEngine const& random_engine)
192  {
193 #if defined(__SYCL_DEVICE_ONLY__)
194  mkl::rng::device::uniform<unsigned int> distr(0,n);
195  return mkl::rng::device::generate(distr, *random_engine.engine);
196 #else
198  unsigned int rand;
199  constexpr unsigned int RAND_M = 4294967295; // 2**32-1
200  do {
201  AMREX_HIP_OR_CUDA( rand = hiprand(random_engine.rand_state);,
202  rand = curand(random_engine.rand_state) );
203  } while (rand > (RAND_M - RAND_M % n));
204  return rand % n;
205  ))
207  amrex::ignore_unused(random_engine);
208  return Random_int(n);
209  ))
210 #endif
211  }
212 
220  ULong Random_long (ULong n); // [0,n-1]
221 
224  void FillRandom (Real* p, Long N);
225 
227  void FillRandomNormal (Real* p, Long N, Real mean, Real stddev);
228 
229  namespace detail {
230  inline ULong DefaultGpuSeed () {
231  return ParallelDescriptor::MyProc()*1234567ULL + 12345ULL;
232  }
233  }
234 
247  void InitRandom (ULong cpu_seed, int nprocs=ParallelDescriptor::NProcs(),
248  ULong gpu_seed = detail::DefaultGpuSeed());
249 
250  void ResetRandomSeed (ULong cpu_seed, ULong gpu_seed = detail::DefaultGpuSeed());
251 
256  void SaveRandomState (std::ostream& os);
257 
258  void RestoreRandomState (std::istream& is, int nthreads_old, int nstep_old);
259 
269  void UniqueRandomSubset (Vector<int> &uSet, int setSize, int poolSize,
270  bool printSet = false);
271 
273 }
274 
275 #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_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:230
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
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > log(const GpuComplex< T > &a_z) noexcept
Complex natural logarithm function.
Definition: AMReX_GpuComplex.H:408
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:111
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
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > pow(const GpuComplex< T > &a_z, const T &a_y) noexcept
Raise a complex number to a (real) power.
Definition: AMReX_GpuComplex.H:418
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
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE GpuComplex< T > sqrt(const GpuComplex< T > &a_z) noexcept
Return the square root of a complex number.
Definition: AMReX_GpuComplex.H:373
Definition: AMReX_FabArrayCommI.H:896
Definition: AMReX_RandomEngine.H:57
randState_t * rand_state
Definition: AMReX_RandomEngine.H:58