BioCMAMC-ST
move_kernel.hpp
1#ifndef __SIMULATION_MOVE_KERNEL_HPP__
2#define __SIMULATION_MOVE_KERNEL_HPP__
3
4#include <Kokkos_Assert.hpp>
5#include <Kokkos_Core.hpp>
6#include <Kokkos_Printf.hpp>
7#include <Kokkos_Random.hpp>
8#include <biocma_cst_config.hpp>
9#include <cassert>
10#include <mc/alias.hpp>
11#include <mc/domain.hpp>
12#include <mc/events.hpp>
13#include <mc/prng/prng.hpp>
14#include <mc/traits.hpp>
15#include <simulation/alias.hpp>
16#include <simulation/probability_leaving.hpp>
17#include <simulation/probe.hpp>
18#include <utility>
19
21{
22 constexpr bool enable_leave = true;
23 constexpr bool disable_leave = false;
24 constexpr bool disable_move = false;
25 constexpr bool enable_move = true;
26
27 template <typename ExecSpace> struct MoveInfo
28 {
29 ConstNeighborsView<ExecSpace> neighbors;
34 Kokkos::View<double*, ExecSpace> liquid_volume;
35
37 : diag_transition("diag_transition", 0),
38 leaving_flow("leaving_flow", 0),
39 index_leaving_flow("index_leaving_flow", 0),
40 liquid_volume("liquid_volume", 0)
41 {
42 }
43
44 MoveInfo(const std::size_t n_compartments, const std::size_t n_flows)
45 : diag_transition("diag_transition", n_compartments),
46 leaving_flow("leaving_flow", n_flows),
47 index_leaving_flow("index_leaving_flow", n_flows),
48 liquid_volume("liquid_volume", n_compartments)
49
50 {
51 }
52 };
53
54 KOKKOS_INLINE_FUNCTION std::size_t __find_next_compartment(
55 const ConstNeighborsView<ComputeSpace>& neighbors,
56 const CumulativeProbabilityView<ComputeSpace>& cumulative_probability,
57 const std::size_t i_compartment,
58 const double random_number)
59 {
60 const int max_neighbor = static_cast<int>(neighbors.extent(1));
61
62 std::size_t next =
63 neighbors(i_compartment, 0); // Default to the first neighbor
64
65 // Iterate through the neighbors to find the appropriate next compartment
66 for (int k_neighbor = 0; k_neighbor < max_neighbor - 1; ++k_neighbor)
67 {
68
69 // Get the cumulative probability range for the current neighbor
70 const auto pi = cumulative_probability(i_compartment, k_neighbor);
71 const auto pn = cumulative_probability(i_compartment, k_neighbor + 1);
72
73 // Use of a Condition mask to avoid branching.
74 next = (random_number <= pn && pi <= random_number)
75 ? neighbors(i_compartment, k_neighbor + 1)
76 : next;
77 }
78
79 return next; // Return the index of the chosen next compartment
80 }
81
83 {
85 MC::ParticleStatus _status,
87 MC::KPRNG::pool_type _random_pool,
88 MC::EventContainer _events,
90 MC::ParticleAges _ages)
91 : d_t(0.), positions(std::move(p)), n_particles(0), move(std::move(m)),
92 random_pool(_random_pool), status(std::move(_status)),
93 events(std::move(_events)), probes(std::move(_probes)),
94 ages(std::move(_ages)), enable_move(false), enable_leave(false) {};
95
96 void update(double _d_t,
97 std::size_t n_p,
99 MC::ParticlePositions _positions,
100 MC::ParticleStatus _status,
101 MC::ParticleAges _ages,
102 bool b_move,
103 bool b_leave)
104 {
105 this->d_t = _d_t;
106 this->n_particles = n_p;
107 this->enable_leave = b_leave;
108 this->enable_move = b_move;
109 this->move = std::move(move_i);
110
111 this->positions = std::move(_positions);
112 this->status = std::move(_status);
113 this->ages = std::move(_ages);
114 }
115 MoveFunctor(double _d_t,
117 MC::ParticleStatus _status,
118 std::size_t n_p,
120 MC::KPRNG::pool_type _random_pool,
121 MC::EventContainer _events,
123 MC::ParticleAges _ages,
124 bool b_move,
125 bool b_leave)
126 : d_t(_d_t), positions(std::move(p)), n_particles(n_p),
127 move(std::move(m)), random_pool(_random_pool),
128 status(std::move(_status)), events(std::move(_events)),
129 probes(std::move(_probes)), ages(std::move(_ages)),
130 enable_move(b_move), enable_leave(b_leave) {};
131
132 KOKKOS_INLINE_FUNCTION void
133 operator()(const Kokkos::TeamPolicy<ComputeSpace>::member_type& team_handle,
134 std::size_t& dead_count) const
135 {
136
137 GET_INDEX(n_particles);
138 if (status(idx) != MC::Status::Idle) [[unlikely]]
139 {
140 return;
141 }
142
143 ages(idx, 0) += d_t;
144 if (enable_move)
145 {
146 handle_move(idx);
147 }
148 if (enable_leave)
149 {
150 handle_exit(idx, dead_count);
151 }
152 }
153
154 [[nodiscard]] bool need_launch() const
155 {
156 return enable_leave || enable_move;
157 }
158
159 KOKKOS_FUNCTION void handle_move(const std::size_t idx) const
160 {
161 auto generator = random_pool.get_state();
162 const float rng1 = generator.frand(0., 1.);
163 const double rng2 = generator.drand(0., 1.);
164 random_pool.free_state(generator);
165
166 const std::size_t i_current_compartment = positions(idx);
167
168 KOKKOS_ASSERT(i_current_compartment < move.liquid_volume.extent(0));
169
170 const bool mask_next =
172 move.liquid_volume(i_current_compartment),
173 move.diag_transition(i_current_compartment),
174 d_t);
175
176 positions(idx) =
177 (mask_next) ? __find_next_compartment(move.neighbors,
178 move.cumulative_probability,
179 i_current_compartment,
180 rng2)
181 : i_current_compartment;
182
183 KOKKOS_ASSERT(positions(idx) < move.liquid_volume.extent(0));
184
185 if constexpr (AutoGenerated::FlagCompileTime::enable_event_counter)
186 {
187 if (mask_next)
188 {
189 events.wrap_incr<MC::EventType::Move>();
190 }
191 }
192 }
193
194 KOKKOS_FUNCTION void handle_exit(std::size_t idx,
195 std::size_t& dead_count) const
196 {
197 const auto position = positions(idx);
198 for (size_t i = 0LU; i < move.index_leaving_flow.size(); ++i)
199 {
200
201 auto generator = random_pool.get_state();
202 const float random_number = generator.frand(0., 1.);
203 random_pool.free_state(generator);
204
205 const auto& index = move.index_leaving_flow(i);
206 const auto& flow = move.leaving_flow(i);
207 if (position != index)
208 {
209 return;
210 }
212 random_number, move.liquid_volume(position), flow, d_t))
213 {
214 dead_count += 1;
215 if constexpr (AutoGenerated::FlagCompileTime::use_probe)
216 {
217 // Ignore ret value, if probe is full we´re gonna miss events which
218 // is not really important
219 if (!probes.set(ages(idx, 0)))
220 {
221 Kokkos::printf("[Kernel]: PROBES OVERFLOW\r\n");
222 };
223 }
224 ages(idx, 0) = 0;
226 events.wrap_incr<MC::EventType::Exit>();
227 }
228 }
229 }
230
231 double d_t;
233 std::size_t n_particles;
240
243 };
244} // namespace Simulation::KernelInline
245
246#endif
Kokkos::Random_XorShift1024_Pool< Kokkos::DefaultExecutionSpace > pool_type
Definition prng.hpp:17
Kokkos::View< Status *, ComputeSpace, restrict_mt > ParticleStatus
Definition alias.hpp:53
@ Move
Move in domain.
Definition events.hpp:20
@ Exit
Remove particle from list due to move in domain.
Definition events.hpp:19
@ Idle
Definition alias.hpp:40
@ Exit
Definition alias.hpp:42
ParticleAgesBase< ComputeSpace > ParticleAges
Definition alias.hpp:56
Kokkos::View< uint64_t *, ComputeSpace, restrict_mt > ParticlePositions
Definition alias.hpp:52
Definition kernels.hpp:8
constexpr bool enable_leave
Definition move_kernel.hpp:22
constexpr bool enable_move
Definition move_kernel.hpp:25
constexpr bool disable_leave
Definition move_kernel.hpp:23
KOKKOS_INLINE_FUNCTION std::size_t __find_next_compartment(const ConstNeighborsView< ComputeSpace > &neighbors, const CumulativeProbabilityView< ComputeSpace > &cumulative_probability, const std::size_t i_compartment, const double random_number)
Definition move_kernel.hpp:54
KOKKOS_INLINE_FUNCTION bool probability_leaving(float random_number, double volume, double flow, double dt)
Definition probability_leaving.hpp:11
constexpr bool disable_move
Definition move_kernel.hpp:24
Kokkos::View< double *, Kokkos::LayoutLeft, ExecSpace, Kokkos::MemoryTraits< Kokkos::RandomAccess > > DiagonalView
Definition alias.hpp:14
Probes< AutoGenerated::probe_buffer_size > ProbeAutogeneratedBuffer
Definition probe.hpp:61
Kokkos::View< const double **, Kokkos::LayoutRight, Space, Kokkos::MemoryTraits< Kokkos::RandomAccess > > CumulativeProbabilityView
Definition alias.hpp:20
Kokkos::View< std::size_t *, Kokkos::SharedHostPinnedSpace > LeavingFlowIndexType
Definition alias.hpp:26
Kokkos::View< double *, Kokkos::SharedHostPinnedSpace > LeavingFlowType
Definition alias.hpp:28
Use to count events that occurs during Monte-Carlo processing cycles.
Definition events.hpp:44
MC::KPRNG::pool_type random_pool
Definition move_kernel.hpp:235
MoveFunctor(MC::ParticlePositions p, MC::ParticleStatus _status, MoveInfo< ComputeSpace > m, MC::KPRNG::pool_type _random_pool, MC::EventContainer _events, ProbeAutogeneratedBuffer _probes, MC::ParticleAges _ages)
Definition move_kernel.hpp:84
bool enable_leave
Definition move_kernel.hpp:242
MoveFunctor(double _d_t, MC::ParticlePositions p, MC::ParticleStatus _status, std::size_t n_p, MoveInfo< ComputeSpace > m, MC::KPRNG::pool_type _random_pool, MC::EventContainer _events, ProbeAutogeneratedBuffer _probes, MC::ParticleAges _ages, bool b_move, bool b_leave)
Definition move_kernel.hpp:115
KOKKOS_FUNCTION void handle_move(const std::size_t idx) const
Definition move_kernel.hpp:159
bool need_launch() const
Definition move_kernel.hpp:154
KOKKOS_INLINE_FUNCTION void operator()(const Kokkos::TeamPolicy< ComputeSpace >::member_type &team_handle, std::size_t &dead_count) const
Definition move_kernel.hpp:133
MC::ParticlePositions positions
Definition move_kernel.hpp:232
double d_t
Definition move_kernel.hpp:231
std::size_t n_particles
Definition move_kernel.hpp:233
MoveInfo< ComputeSpace > move
Definition move_kernel.hpp:234
MC::EventContainer events
Definition move_kernel.hpp:237
ProbeAutogeneratedBuffer probes
Definition move_kernel.hpp:238
void update(double _d_t, std::size_t n_p, MoveInfo< ComputeSpace > move_i, MC::ParticlePositions _positions, MC::ParticleStatus _status, MC::ParticleAges _ages, bool b_move, bool b_leave)
Definition move_kernel.hpp:96
MC::ParticleStatus status
Definition move_kernel.hpp:236
KOKKOS_FUNCTION void handle_exit(std::size_t idx, std::size_t &dead_count) const
Definition move_kernel.hpp:194
bool enable_move
Definition move_kernel.hpp:241
MC::ParticleAges ages
Definition move_kernel.hpp:239
Definition move_kernel.hpp:28
MoveInfo()
Definition move_kernel.hpp:36
DiagonalView< ExecSpace > diag_transition
Definition move_kernel.hpp:30
LeavingFlowType leaving_flow
Definition move_kernel.hpp:32
MoveInfo(const std::size_t n_compartments, const std::size_t n_flows)
Definition move_kernel.hpp:44
LeavingFlowIndexType index_leaving_flow
Definition move_kernel.hpp:33
CumulativeProbabilityView< ExecSpace > cumulative_probability
Definition move_kernel.hpp:31
ConstNeighborsView< ExecSpace > neighbors
Definition move_kernel.hpp:29
Kokkos::View< double *, ExecSpace > liquid_volume
Definition move_kernel.hpp:34