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_Printf.hpp"
6#include "mc/alias.hpp"
7#include <Kokkos_Core.hpp>
8#include <Kokkos_Random.hpp>
9#include <biocma_cst_config.hpp>
10#include <cassert>
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 <type_traits>
19#include <utility>
20
22{
23 constexpr bool enable_leave = true;
24 constexpr bool disable_leave = false;
25 constexpr bool disable_move = false;
26 constexpr bool enable_move = true;
27
28 template <typename ExecSpace> struct MoveInfo
29 {
30 ConstNeighborsView<ExecSpace> neighbors;
35 Kokkos::View<double*, ExecSpace> liquid_volume;
36
38 : diag_transition("diag_transition", 0), leaving_flow("leaving_flow", 0),
39 index_leaving_flow("index_leaving_flow", 0), liquid_volume("liquid_volume")
40 {
41 }
42 };
43
44 KOKKOS_INLINE_FUNCTION std::size_t
45 __find_next_compartment(const ConstNeighborsView<ComputeSpace>& neighbors,
46 const CumulativeProbabilityView<ComputeSpace>& cumulative_probability,
47 const std::size_t i_compartment,
48 const double random_number)
49 {
50 const int max_neighbor = static_cast<int>(neighbors.extent(1));
51
52 std::size_t next = neighbors(i_compartment, 0); // Default to the first neighbor
53
54 // Iterate through the neighbors to find the appropriate next compartment
55 for (int k_neighbor = 0; k_neighbor < max_neighbor - 1; ++k_neighbor)
56 {
57
58 // Get the cumulative probability range for the current neighbor
59 const auto pi = cumulative_probability(i_compartment, k_neighbor);
60 const auto pn = cumulative_probability(i_compartment, k_neighbor + 1);
61
62 // Use of a Condition mask to avoid branching.
63 next = (random_number <= pn && pi <= random_number) ? neighbors(i_compartment, k_neighbor + 1)
64 : next;
65 }
66
67 return next; // Return the index of the chosen next compartment
68 }
69
70 template <bool enable_leave, bool enable_move> struct MoveFunctor
71 {
72 MoveFunctor(double _d_t,
74 MC::ParticleStatus _status,
75 std::size_t n_p,
77 MC::KPRNG::pool_type _random_pool,
78 MC::EventContainer _events,
80 MC::ParticleAges _ages)
81 : d_t(_d_t), positions(std::move(p)), n_particles(n_p), move(std::move(m)),
82 random_pool(_random_pool), status(std::move(_status)), events(std::move(_events)),
83 probes(std::move(_probes)) ,ages(std::move(_ages)) {};
84
85 KOKKOS_INLINE_FUNCTION void
86 operator()(const Kokkos::TeamPolicy<ComputeSpace>::member_type& team_handle,
87 std::size_t& dead_count) const
88 {
89 GET_INDEX(n_particles);
90 if (status(idx) != MC::Status::Idle) [[unlikely]]
91 {
92 // Kokkos::printf("Skip %ld", idx);
93 return;
94 }
95 ages(idx,0)+=d_t;
96
97 if constexpr (enable_move)
98 {
99 handle_move(idx);
100 }
101
102 if constexpr (enable_leave)
103 {
104 handle_exit(idx, dead_count);
105 }
106
107 }
108
109 KOKKOS_FUNCTION void handle_move(const std::size_t idx) const
110 {
111 auto generator = random_pool.get_state();
112 const float rng1 = generator.frand(0., 1.);
113 const double rng2 = generator.drand(0., 1.);
114 random_pool.free_state(generator);
115
116 const std::size_t i_current_compartment = positions(idx);
117
118 const bool mask_next = probability_leaving(rng1,
119 move.liquid_volume(i_current_compartment),
120 move.diag_transition(i_current_compartment),
121 d_t);
122
123 positions(idx) =
124 (mask_next)
126 move.neighbors, move.cumulative_probability, i_current_compartment, rng2)
127 : i_current_compartment;
128
129 KOKKOS_ASSERT(positions(idx) < move.liquid_volume.extent(0));
130
131 if constexpr (AutoGenerated::FlagCompileTime::enable_event_counter)
132 {
133 if (mask_next)
134 {
136 }
137 }
138 }
139
140 KOKKOS_FUNCTION void handle_exit(std::size_t idx, std::size_t& dead_count) const
141 {
142
143 for (size_t i = 0LU; i < move.index_leaving_flow.size(); ++i)
144 {
145 const auto position = positions(idx);
146 auto generator = random_pool.get_state();
147 const float random_number = generator.frand(0., 1.);
148 random_pool.free_state(generator);
149
150 const auto& index = move.index_leaving_flow(i);
151 const auto& flow = move.leaving_flow(i);
152 if (position != index)
153 {
154 return;
155 }
156
157 if (probability_leaving(random_number, move.liquid_volume(position), flow, d_t))
158 {
159 dead_count += 1;
162 if constexpr (AutoGenerated::FlagCompileTime::use_probe)
163 {
164 // Ignore ret value, if probe is full we´re gonna miss events which is not really
165 // important
166 if (!probes.set(ages(idx,0))){
167 Kokkos::printf("PROBES OVERFLOW\r\n");
168 };
169 ages(idx,0)=0;
170
171 }
172 }
173 }
174 }
175
176 double d_t;
178 std::size_t n_particles;
185 };
186} // namespace Simulation::KernelInline
187
188#endif
Kokkos::Random_XorShift1024_Pool< Kokkos::DefaultExecutionSpace > pool_type
Definition prng.hpp:17
KOKKOS_INLINE_FUNCTION bool set(double val) const
Definition probe.hpp:80
Kokkos::View< Status *, ComputeSpace > ParticleStatus
Definition alias.hpp:20
Kokkos::View< double *[2], Kokkos::LayoutLeft, ComputeSpace > ParticleAges
Definition alias.hpp:22
Kokkos::View< uint64_t *, ComputeSpace > ParticlePositions
Definition alias.hpp:19
@ Move
Move in domain.
@ Exit
Remove particle from list due to move in domain.
Definition move_kernel.hpp:22
constexpr bool enable_leave
Definition move_kernel.hpp:23
constexpr bool enable_move
Definition move_kernel.hpp:26
constexpr bool disable_leave
Definition move_kernel.hpp:24
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:45
KOKKOS_INLINE_FUNCTION bool probability_leaving(float random_number, double volume, double flow, double dt)
Definition probability_leaving.hpp:31
constexpr bool disable_move
Definition move_kernel.hpp:25
Kokkos::View< std::size_t *, Kokkos::SharedHostPinnedSpace > LeavingFlowIndexType
Definition alias.hpp:25
Kokkos:: View< double *, Kokkos::LayoutLeft, ExecSpace, Kokkos::MemoryTraits< Kokkos::RandomAccess > > DiagonalView
Definition alias.hpp:14
Kokkos::View< double *, Kokkos::SharedHostPinnedSpace > LeavingFlowType
Definition alias.hpp:26
Kokkos:: View< const double **, Kokkos::LayoutRight, Space, Kokkos::MemoryTraits< Kokkos::RandomAccess > > CumulativeProbabilityView
Definition alias.hpp:20
Use to count events that occurs during Monte-Carlo processing cycles.
Definition events.hpp:43
KOKKOS_FORCEINLINE_FUNCTION constexpr void wrap_incr() const
Definition events.hpp:109
Definition move_kernel.hpp:71
MC::ParticleAges ages
Definition move_kernel.hpp:184
KOKKOS_INLINE_FUNCTION void operator()(const Kokkos::TeamPolicy< ComputeSpace >::member_type &team_handle, std::size_t &dead_count) const
Definition move_kernel.hpp:86
MC::ParticleStatus status
Definition move_kernel.hpp:181
ProbeAutogeneratedBuffer probes
Definition move_kernel.hpp:183
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)
Definition move_kernel.hpp:72
MC::ParticlePositions positions
Definition move_kernel.hpp:177
MC::EventContainer events
Definition move_kernel.hpp:182
std::size_t n_particles
Definition move_kernel.hpp:178
MoveInfo< ComputeSpace > move
Definition move_kernel.hpp:179
KOKKOS_FUNCTION void handle_move(const std::size_t idx) const
Definition move_kernel.hpp:109
double d_t
Definition move_kernel.hpp:176
MC::KPRNG::pool_type random_pool
Definition move_kernel.hpp:180
KOKKOS_FUNCTION void handle_exit(std::size_t idx, std::size_t &dead_count) const
Definition move_kernel.hpp:140
Definition move_kernel.hpp:29
MoveInfo()
Definition move_kernel.hpp:37
DiagonalView< ExecSpace > diag_transition
Definition move_kernel.hpp:31
LeavingFlowType leaving_flow
Definition move_kernel.hpp:33
LeavingFlowIndexType index_leaving_flow
Definition move_kernel.hpp:34
CumulativeProbabilityView< ExecSpace > cumulative_probability
Definition move_kernel.hpp:32
ConstNeighborsView< ExecSpace > neighbors
Definition move_kernel.hpp:30
Kokkos::View< double *, ExecSpace > liquid_volume
Definition move_kernel.hpp:35