BioCMAMC-ST
prng.hpp
1#ifndef __MC_PRNG_HPP__
2#define __MC_PRNG_HPP__
3
4#include "Kokkos_Macros.hpp"
5#include <Kokkos_Random.hpp>
6#include <common/common.hpp>
7#include <common/traits.hpp>
8#include <cstdint>
9#include <mc/alias.hpp>
10namespace MC
11{
12
13 pool_type get_pool(std::size_t seed = 0);
14
15 uint64_t master_seed();
16 uint64_t next_splitmix64(uint64_t& x) noexcept;
17
46
47 KOKKOS_INLINE_FUNCTION auto
48 sample_random_variables(const pool_type& pool, auto&& functor)
49 {
50 // Be sure that generator is passed to functor as reference
51 // As functor can be lambda usually [](auto gen){return gen.rand();};
52 // If auto is passed as value, value generated is UB. Need auto& to avoid
53 // any problem
54 using gen_t = typename pool_type::generator_type;
55 using Functor = decltype(functor);
56 static_assert(std::is_invocable_v<Functor, gen_t&>
57 && !std::is_invocable_v<Functor, gen_t>,
58 "Functor must accept generator by reference only");
59
60 auto gen = pool.get_state();
61 const auto result = functor(gen);
62 pool.free_state(gen);
63
64 return result;
65 }
66
67#define SAMPLE_RANDOM_VARIABLES(_random_pool_, ...) \
68 auto _generator_state_ = _random_pool_.get_state(); \
69 __VA_ARGS__; \
70 _random_pool_.free_state(_generator_state_);
71
75 class KPRNG // TODO remove deprecated
76 {
77 public:
79 using generator_type = pool_type::generator_type;
80
81 KPRNG() = default;
82
83 explicit KPRNG(uint64_t seed);
84
88 template <class Archive>
89 void
90 save(Archive& ar) const
91 {
92 ar(this->seed);
93 }
94
98 template <class Archive>
99 void
100 load(Archive& ar)
101 {
102 uint64_t _seed = 0;
103 ar(_seed);
104 this->random_pool = get_pool(_seed);
105 }
106
107 template <FloatingPointType T>
108 KOKKOS_INLINE_FUNCTION T
109 uniform() const
110 {
111 return this->uniform<T>(0, 1);
112 }
113
114 template <FloatingPointType T>
115 KOKKOS_INLINE_FUNCTION T
116 uniform(T a, T b) const
117 {
120 [a, b](auto gen)
121 {
122 T x;
123 if constexpr (std::is_same_v<T, float>)
124 {
125 x = gen.frand(a, b);
126 }
127 else if constexpr (std::is_same_v<T, double>)
128 {
129 x = gen.drand(a, b);
130 }
131 return x;
132 });
133 }
134
135 [[deprecated]] [[nodiscard]] Kokkos::View<double*, ComputeSpace>
136 double_uniform(size_t n_sample, double a = 0., double b = 1.) const;
137
138 template <FloatingPointType T, size_t n_r>
139 Kokkos::View<T[n_r], ComputeSpace>
141 {
142 Kokkos::View<T[n_r], ComputeSpace> A("random");
143 Kokkos::fill_random(A, random_pool, 0., 1.);
144 return A;
145 }
146
147 template <size_t n_r>
148 [[deprecated]] KOKKOS_INLINE_FUNCTION std::array<double, n_r>
150 {
152 random_pool, std::make_index_sequence<n_r>{});
153 }
154
155 [[nodiscard]] KOKKOS_INLINE_FUNCTION uint64_t
156 uniform_u(uint64_t a, uint64_t b) const
157 {
158
160 random_pool, [a, b](auto& gen) { return gen.urand64(a, b); });
161 }
162
164
165 [[nodiscard]] auto
166 get_seed() const
167 {
168 return seed;
169 } // TODO export this to result file
170
171 private:
172 std::size_t seed{};
173 template <typename random_pool_t, size_t n_r, size_t... I>
174 KOKKOS_INLINE_FUNCTION std::array<double, n_r>
175 generate_uniform_impl(random_pool_t pool,
176 std::index_sequence<I...> /*unused*/) const
177 {
178 // Constexpr loopunrolling to fill the array
179 auto generator = pool.get_state();
180 std::array<double, n_r> res
181 = { { (static_cast<void>(I), generator.drand(0., 1.))... } };
182 pool.free_state(generator);
183 return res;
184 }
185 };
186
187 template <class ExecutionSpace,
188 class ViewType,
189 class RandomPool,
190 class IndexType = int64_t,
191 const std::size_t CHUNK_SIZE>
192 void
193 fill_random(const ExecutionSpace& exec,
194 ViewType a,
195 RandomPool g,
196 typename ViewType::const_value_type begin,
197 typename ViewType::const_value_type end)
198 {
199 int64_t LDA = a.extent(0);
200
201 if (LDA > 0)
202 {
203 Kokkos::parallel_for(
204 "Kokkos::fill_random",
205 Kokkos::RangePolicy<ExecutionSpace>(
206 exec, 0, (LDA + (CHUNK_SIZE - 1)) / CHUNK_SIZE),
207 Kokkos::Impl::fill_random_functor_begin_end<ViewType,
208 RandomPool,
209 CHUNK_SIZE,
210 ViewType::rank,
211 IndexType>(
212 a, g, begin, end));
213 }
214 }
215
216} // namespace MC
217
218#endif //__MC_PRNG_HPP__
KOKKOS_INLINE_FUNCTION uint64_t uniform_u(uint64_t a, uint64_t b) const
Definition prng.hpp:156
KOKKOS_INLINE_FUNCTION T uniform() const
Definition prng.hpp:109
KOKKOS_INLINE_FUNCTION T uniform(T a, T b) const
Definition prng.hpp:116
KOKKOS_INLINE_FUNCTION std::array< double, n_r > generate_uniform_impl(random_pool_t pool, std::index_sequence< I... >) const
Definition prng.hpp:175
auto get_seed() const
Definition prng.hpp:166
MC::pool_type pool_type
Definition prng.hpp:78
void load(Archive &ar)
Load data from ar for deserialization.
Definition prng.hpp:100
KPRNG()=default
pool_type::generator_type generator_type
Definition prng.hpp:79
KPRNG(uint64_t seed)
KOKKOS_INLINE_FUNCTION std::array< double, n_r > double_uniform() const
Definition prng.hpp:149
pool_type random_pool
Definition prng.hpp:163
void save(Archive &ar) const
Save data into ar for serialization.
Definition prng.hpp:90
Kokkos::View< T[n_r], ComputeSpace > random_view() const
Definition prng.hpp:140
std::size_t seed
Definition prng.hpp:172
Namespace that contains classes and structures related to Monte Carlo (MC) simulations.
Definition alias.hpp:16
void fill_random(const ExecutionSpace &exec, ViewType a, RandomPool g, typename ViewType::const_value_type begin, typename ViewType::const_value_type end)
Definition prng.hpp:193
KOKKOS_INLINE_FUNCTION auto sample_random_variables(const pool_type &pool, auto &&functor)
Definition prng.hpp:48
pool_type get_pool(std::size_t seed=0)
Definition prng.cpp:29
gen_pool_type< Kokkos::DefaultExecutionSpace > pool_type
Definition alias.hpp:100
uint64_t master_seed()
Definition prng.cpp:23
uint64_t next_splitmix64(uint64_t &x) noexcept
Definition prng.cpp:13