HILA
Loading...
Searching...
No Matches
random.h
1#ifndef HILA_RANDOM_H_
2#define HILA_RANDOM_H_
3
4namespace hila {
5
6constexpr bool device_rng_off = false;
7constexpr bool device_rng_on = true;
8
9
10/**
11 *@brief Seed random generators with 64-bit unsigned value.
12 * On MPI shuffles the seed so that different MPI ranks are seeded with different values.
13 */
14void seed_random(uint64_t seed, bool device_rng = true);
15
16/**
17 *@brief Check if RNG is seeded already
18 */
19bool is_rng_seeded();
20
21/**
22 *@brief Initialize host (CPU) random number generator separately, done implicitly by `seed_random()`
23 */
24void initialize_host_rng(uint64_t seed);
25
26/**
27 *@brief Initialize device random number generator on GPUs, if application run on GPU platform.
28 * No effect on other archs.
29 */
30void initialize_device_rng(uint64_t seed);
31
32/**
33 *@brief Free GPU RNG state, does nothing on non-GPU archs.
34 */
35void free_device_rng();
36
37/**
38 *@brief Check if the RNG on GPU is allocated and ready to use.
39 */
40bool is_device_rng_on();
41
42
43/////////////////////////////////////////////////////////////////////////////////////////////////
44
45// It is important that the random number generators random(), gaussrand() and gaussrand2()
46// are marked as "loop function" and "contains rng", because hilapp does not have a view
47// inside them from all compilation units - although hila::random() has special treatment
48
49
50/**
51 * @brief Real valued uniform random number generator.
52 * @details Returns an uniform double precision random number in interval \f$[0,1)\f$.
53 * This function can be called from outside or inside site loops (on GPU if the device rng is initialized).
54 *
55 * Uses
56 * [std::uniform_real_distribution](https://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution)
57 *
58 * @return double
59 */
60#pragma hila contains_rng loop_function
61double random();
62
63// alias for host (CPU) rng, used in GPU code generation. Must not be used inside onsites() {}. This
64// routine is not normally needed in user code, instead use standard hila::random().
65double host_random();
66
67
68/**
69 * @brief Gaussian random generation routine
70 */
71#pragma hila contains_rng loop_function
72double gaussrand();
73
74/**
75 *@brief `hila::gaussrand2` returns 2 Gaussian distributed random numbers with variance \f$1.0\f$.
76 *@details Useful because Box-Muller algorithm computes 2 values at the same time.
77 */
78#pragma hila contains_rng loop_function
79double gaussrand2(double &out2);
80
81/**
82 *@brief Check if RNG is initialized, do what the name says.
83 */
85
86/**
87 *@brief Template function `const T & hila::random(T & var)`
88 * sets the argument to a random value, and return a constant reference to it.
89 *@details For example
90 *\code{.cpp}
91 * Complex<double> c;
92 * auto n = hila::random(c).abs();
93 *\endcode
94 *sets the variable `c` to complex random value and calculates its absolute value.
95 *`c.real()` and `c.imag()` will be \f$\in [0,1)\f$.
96 *
97 *For hila classes relies on the existence of method `T::random()` (i.e. `var.random()`),
98 *this function typically sets the argument real numbers to interval \f$[0,1)\f$ if `type T` is arithmatic.
99 *if T is more commplicated classes such as `SU<N,T>`-matrix, this function sets the argument to
100 * valid random `SU<N,T>`.
101 *
102 * Advantage of this function over class function `T::random()` is that the argument can be
103 * of elementary arithmetic type.
104 */
105template <typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
106T random(out_only T &val) {
107 val = hila::random();
108 return val;
109}
110
111template <typename T, std::enable_if_t<!std::is_arithmetic<T>::value, int> = 0>
112T &random(out_only T &val) {
113 val.random();
114 return val;
115}
116
117/**
118 *@brief Template function `T hila::random<T>()` without argument.
119 *@details This is used to generate random value for `type T` without defined variable.
120 *Example:
121 *\code{.cpp}
122 * auto n = hila::random<Complex<double>>().abs();
123 *\endcode
124 * calculates the norm of a random complex value.
125 *`hila::random<double>()` is functionally equivalent to `hila::random()`
126 */
127template <typename T>
129 T val;
130 hila::random(val);
131 return val;
132}
133
134/**
135 * @brief Template function
136 * `const T & hila::gaussian_random(T & variable,double width=1)`
137 * @details Sets the argument to a gaussian random value, and return a constant reference to it.
138 * Optional second argument width sets the \f$variance=width^{2}\f$ (\f$default==1\f$)
139 *
140 * For example:
141 * \code {.cpp}
142 * Complex<double> c;
143 * auto n = sqr(hila::gaussian_random(c));
144 * \endcode
145 * sets the variable `c` to complex gaussian random value and stores its square in `n`.
146 *
147 * This function is for hila classes relies on the existence of method `T::gaussian_random()`.
148 * The advantage for this function over class function `T::random()` is that the argument can be
149 * of elementary arithmetic type.
150 * @return T by reference
151 */
152template <typename T, std::enable_if_t<std::is_arithmetic<T>::value, int> = 0>
153T gaussian_random(out_only T &val, double w = 1.0) {
154 val = hila::gaussrand() * w;
155 return val;
156}
157
158
159template <typename T, std::enable_if_t<!std::is_arithmetic<T>::value, int> = 0>
160T &gaussian_random(out_only T &val, double w = 1.0) {
161 val.gaussian_random(w);
162 return val;
163}
164
165
166/**
167 *@brief Template function
168 * `T hila::gaussian_random<T>()`,generates gaussian random value of `type T`, with variance \f$1\f$.
169 *@details For example,
170 *\code{.cpp}
171 * auto n = hila::gaussian_random<Complex<double>>().abs();
172 *\endcode
173 *calculates the norm of a gaussian random complex value.
174 *
175 *@note there is no width/variance parameter, because of danger of confusion
176 *with above `hila::gaussian_random(value)`
177 */
178template <typename T>
180 T val;
182 return val;
183}
184
185
186} // namespace hila
187
188
189#endif
Implement hila::swap for gauge fields.
Definition array.h:982
T gaussian_random()
Template function T hila::gaussian_random<T>(),generates gaussian random value of type T,...
Definition random.h:179
void initialize_device_rng(uint64_t seed)
Initialize device random number generator on GPUs, if application run on GPU platform....
Definition hila_gpu.cpp:71
void free_device_rng()
Free GPU RNG state, does nothing on non-GPU archs.
Definition hila_gpu.cpp:107
double random()
Real valued uniform random number generator.
Definition hila_gpu.cpp:121
bool is_device_rng_on()
Check if the RNG on GPU is allocated and ready to use.
Definition hila_gpu.cpp:58
double gaussrand()
Gaussian random generation routine.
Definition random.cpp:240
void seed_random(uint64_t seed, bool device_rng=true)
Seed random generators with 64-bit unsigned value. On MPI shuffles the seed so that different MPI ran...
Definition random.cpp:86
bool is_rng_seeded()
Check if RNG is seeded already.
Definition random.cpp:250
void initialize_host_rng(uint64_t seed)
Initialize host (CPU) random number generator separately, done implicitly by seed_random()
Definition random.cpp:61
double gaussrand2(double &out2)
hila::gaussrand2 returns 2 Gaussian distributed random numbers with variance .
Definition random.cpp:188
void check_that_rng_is_initialized()
Check if RNG is initialized, do what the name says.
Definition random.cpp:263