1#ifndef __SIMULATION_MOVE_KERNEL_HPP__
2#define __SIMULATION_MOVE_KERNEL_HPP__
4#include "Kokkos_Macros.hpp"
5#include <Kokkos_Assert.hpp>
6#include <Kokkos_Core.hpp>
7#include <Kokkos_Printf.hpp>
8#include <Kokkos_Random.hpp>
9#include <biocma_cst_config.hpp>
11#include <common/common.hpp>
12#include <mc/alias.hpp>
13#include <mc/domain.hpp>
14#include <mc/events.hpp>
15#include <mc/prng/prng.hpp>
16#include <mc/traits.hpp>
17#include <simulation/probability_leaving.hpp>
18#include <simulation/probe.hpp>
71 KOKKOS_INLINE_FUNCTION std::size_t
75 cumulative_probability,
76 const std::size_t i_compartment,
77 const double random_number)
79 const int max_neighbor =
static_cast<int>(neighbors.extent(1));
81 KOKKOS_ASSERT(max_neighbor >= 1);
82 KOKKOS_ASSERT(random_number <= 1. && random_number >= 0.);
83 KOKKOS_ASSERT(neighbors.extent(1) == cumulative_probability.extent(1));
98 int right = max_neighbor - 1;
101 const int mid = (left + right) >> 1;
102 const auto pm = cumulative_probability(i_compartment, mid);
103 const int mask =
static_cast<int>(random_number > pm);
104 left = mask * (mid + 1) + (1 - mask) * left;
105 right = mask * right + (1 - mask) * mid;
107 KOKKOS_ASSERT(left >= 0 &&
static_cast<size_t>(left) < neighbors.extent(1));
108 return neighbors(i_compartment, left);
111 template <
typename ViewType1>
112 KOKKOS_INLINE_FUNCTION
void
114 const std::size_t position,
118 std::size_t i_flow = 0;
119 const std::size_t n_flow = leaving_flow.size();
125 const auto& [index, flow, liquid_volume] = leaving_flow(i_flow++);
126 if (position == index)
129 _liquid_volume = liquid_volume;
132 }
while (i_flow < n_flow);
141 std::size_t p_team_leave,
156 std::
move(_random_pool),
164 std::size_t p_team_leave,
198 this->
move = std::move(move_i);
200 this->
status = std::move(_status);
201 this->
ages = std::move(_ages);
210 KOKKOS_INLINE_FUNCTION
void
212 const Kokkos::TeamPolicy<ComputeSpace>::member_type& team,
216 const std::size_t p0 = team.league_rank() * N;
219 KOKKOS_ASSERT(upper_bound > 0 && upper_bound <=
n_particles);
222 const auto& proba =
move.move_probability;
223 const std::size_t p = team.team_size();
224 const std::size_t m = (upper_bound + p - 1) / p;
226 std::size_t team_move_count = 0;
227 Kokkos::parallel_reduce(
228 Kokkos::TeamThreadRange(team, 0, p),
229 [&](
const std::size_t tid, std::size_t& moved_count)
231 auto gen = rp.get_state();
233 for (std::size_t k = 0; k < m; ++k)
235 const std::size_t idx = tid + k * p;
237 if (idx >= upper_bound)
241 const std::size_t flat_index = p0 + idx;
249 const std::size_t next
263 Kokkos::single(Kokkos::PerTeam(team),
264 [&]() { local_tally.
moved += team_move_count; });
267 KOKKOS_INLINE_FUNCTION
void
269 const Kokkos::TeamPolicy<ComputeSpace>::member_type& team_handle,
270 std::size_t& local_dead_count)
const
274 const std::size_t p0 = team_handle.league_rank() * count;
277 const auto upper_bound
278 = ((p0 + count) >= n_particle) ? n_particle - p0 : count;
280 KOKKOS_ASSERT(upper_bound > 0 && upper_bound <= n_particle);
281 std::size_t team_dead_count = 0;
282 const auto& lf =
move.leaving_flow;
283 Kokkos::parallel_reduce(
284 Kokkos::TeamThreadRange(team_handle, 0, upper_bound),
285 [&](
const std::size_t idx, std::size_t& thread_dead_count)
287 const auto flat_index = p0 + idx;
293 team_handle.team_barrier();
295 Kokkos::PerTeam(team_handle),
298 if constexpr (AutoGenerated::FlagCompileTime::enable_event_counter)
302 local_dead_count += team_dead_count;
311 KOKKOS_INLINE_FUNCTION
void
313 const Kokkos::TeamPolicy<ComputeSpace>::member_type& team,
317 const std::size_t p0 = team.league_rank() * N;
320 KOKKOS_ASSERT(upper_bound > 0 && upper_bound <=
n_particles);
323 const auto& lf =
move.leaving_flow;
324 const auto& proba =
move.move_probability;
326 const std::size_t p = team.team_size();
327 const std::size_t m = (upper_bound + p - 1) / p;
331 Kokkos::parallel_reduce(
332 Kokkos::TeamThreadRange(team, 0, p),
335 auto gen = rp.get_state();
337 for (std::size_t k = 0; k < m; ++k)
339 const std::size_t idx = tid + k * p;
341 if (idx >= upper_bound)
345 const std::size_t flat_index = p0 + idx;
348 std::size_t position =
positions(flat_index);
353 const std::size_t next
383 Kokkos::single(Kokkos::PerTeam(team),
384 [&]() { local_tally += team_tally; });
399 KOKKOS_INLINE_FUNCTION
void
401 const Kokkos::TeamPolicy<ComputeSpace>::member_type& team_handle,
407 const auto& lf =
move.leaving_flow;
414 Kokkos::PerTeam(team_handle),
415 [&lf, dt = this->
d_t](
double& local_lambda)
417 const auto& [_, flow_value, liquid_volume] = lf(0);
419 local_lambda = dt * flow_value / liquid_volume;
423 team_handle.team_barrier();
433 const std::size_t p0 = team_handle.league_rank() * N;
436 KOKKOS_ASSERT(upper_bound > 0 && upper_bound <=
n_particles);
440 const std::size_t p = team_handle.team_size();
442 const std::size_t m = (upper_bound + p - 1) / p;
444 std::size_t team_dead_count = 0;
450 Kokkos::parallel_reduce(
451 Kokkos::TeamThreadRange(team_handle, 0, p),
452 [&](
const std::size_t tid, std::size_t& dead_count)
454 auto gen = rp.get_state();
456 for (std::size_t k = 0; k < m; ++k)
458 const std::size_t idx = tid + k * p;
460 if (idx >= upper_bound)
464 const std::size_t flat_index = p0 + idx;
470 const double r = gen.drand(0., 1.);
481 team_handle.team_barrier();
483 Kokkos::single(Kokkos::PerTeam(team_handle),
484 [&]() { local_tally.
dead += team_dead_count; });
491 template <
typename GenType>
492 KOKKOS_FORCEINLINE_FUNCTION std::size_t
494 const std::size_t i_current_compartment,
500 i_current_compartment <
move.liquid_volume.extent(0)
501 &&
"Particle position is incorect (greater than compartment number)");
503 moved = move_probability(i_current_compartment) > gen.frand(0.F, 1.F);
507 return i_current_compartment;
511 move.cumulative_probability,
512 i_current_compartment,
513 gen.frand(0.F, 1.F));
515 next <
move.liquid_volume.extent(0)
516 &&
" Position after move is greater than compartment number");
523 template <
typename ExecSpace,
typename GenType>
524 KOKKOS_FORCEINLINE_FUNCTION
void
526 const std::size_t idx,
527 const Kokkos::View<const MC::LeavingFlow*, ExecSpace>& leaving_flow,
528 const std::size_t position,
530 std::size_t& dead_count)
const
534 find_flow(leaving_flow, position, found_flow_value, found_liquid_volume);
537 if (found_flow_value != 0.)
539 const auto r = gen.frand(0., 1.);
540 KOKKOS_ASSERT(found_liquid_volume > 0.);
541 KOKKOS_ASSERT(found_flow_value > 0.);
543 r, found_liquid_volume, found_flow_value,
d_t),
549 template <
typename ExecSpace>
550 KOKKOS_FORCEINLINE_FUNCTION std::size_t
552 const std::size_t idx,
553 const Kokkos::View<const MC::LeavingFlow*, ExecSpace>& leaving_flow,
554 std::size_t& dead_count)
const
557 const std::size_t position =
positions(idx);
565 find_flow(leaving_flow, position, found_flow_value, found_liquid_volume);
569 if (found_flow_value != 0.)
573 const auto r = gen.frand(0., 1.);
576 KOKKOS_ASSERT(found_liquid_volume > 0.);
577 KOKKOS_ASSERT(found_flow_value > 0.);
579 r, found_liquid_volume, found_flow_value,
d_t);
586 KOKKOS_INLINE_FUNCTION
void
588 const std::size_t idx,
589 std::size_t& dead_count)
const
596 if constexpr (AutoGenerated::FlagCompileTime::use_probe)
598 using mem_space = ComputeSpace::memory_space;
600 const auto _ =
probes.set<mem_space>(
ages(idx, 0));
632 struct reduction_identity<
Simulation::KernelInline::MoveLeaveTally>
Definition move_kernel.hpp:630
std::conditional_t< is_const, Kokkos::View< const std::size_t **, Kokkos::LayoutRight, ExecSpace, Kokkos::MemoryTraits< Kokkos::RandomAccess > >, Kokkos::View< std::size_t **, Kokkos::LayoutRight, ExecSpace > > NeighborsView
Definition alias.hpp:215
std::conditional_t< is_const, Kokkos::View< const double *, ExecSpace, Kokkos::MemoryTraits< Kokkos::RandomAccess > >, Kokkos::View< double *, ExecSpace > > MoveProbabilityView
d_t * flow / volume per compartment. Owned by ReactorDomain
Definition alias.hpp:182
Kokkos::View< Status *, ComputeSpace > ParticleStatus
Definition alias.hpp:141
Kokkos::View< uint64_t *, ComputeSpace > ParticlePositions
Definition alias.hpp:140
@ Exit
Remove particle from list due to move in domain.
Definition events.hpp:22
@ Idle
Definition alias.hpp:126
@ Exit
Definition alias.hpp:128
ParticleAgesBase< ComputeSpace > ParticleAges
Definition alias.hpp:144
gen_pool_type< Kokkos::DefaultExecutionSpace > pool_type
Definition alias.hpp:100
std::conditional_t< is_const, Kokkos::View< const double **, Kokkos::LayoutRight, ExecSpace, Kokkos::MemoryTraits< Kokkos::RandomAccess > >, Kokkos::View< double **, Kokkos::LayoutRight, ExecSpace > > CumulativeProbabilityView
Definition alias.hpp:206
Definition cycle_reducer.hpp:13
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 bool probability_leaving(const T random_number, const double lambda)
Definition probability_leaving.hpp:26
KOKKOS_INLINE_FUNCTION std::size_t __find_next_compartment(const MC::NeighborsView< ComputeSpace, true > &neighbors, const MC::CumulativeProbabilityView< ComputeSpace, true > &cumulative_probability, const std::size_t i_compartment, const double random_number)
probably overkill binary search to find next compartment
Definition move_kernel.hpp:72
KOKKOS_INLINE_FUNCTION void find_flow(const ViewType1 &leaving_flow, const std::size_t position, MC::LeavingFlow::float_type &val_flow, MC::LeavingFlow::float_type &_liquid_volume)
Definition move_kernel.hpp:113
int precision_tag
Definition probability_leaving.hpp:12
constexpr bool disable_move
Definition move_kernel.hpp:25
Namespace that contains classes and structures related to simulation handling.
Definition host_specific.hpp:12
Probes< AutoGenerated::probe_buffer_size > ProbeAutogeneratedBuffer
Definition probe.hpp:150
static KOKKOS_FORCEINLINE_FUNCTION Simulation::KernelInline::MoveLeaveTally sum()
Definition move_kernel.hpp:635
Structure to store information about domain needed during MC cycle data is likely to change between e...
Definition domain.hpp:29
Use to count events that occurs during Monte-Carlo processing cycles.
Definition events.hpp:168
double float_type
Definition domain.hpp:19
MoveFunctor(std::size_t p_team_move, std::size_t p_team_leave, double _d_t, MC::ParticlePositions p, MC::ParticleStatus _status, std::size_t n_p, MC::DomainState< ComputeSpace > m, MC::pool_type _random_pool, MC::EventContainer _events, ProbeAutogeneratedBuffer _probes, MC::ParticleAges _ages, bool b_move, bool b_leave)
Definition move_kernel.hpp:163
bool do_move() const
Definition move_kernel.hpp:388
KOKKOS_FORCEINLINE_FUNCTION std::size_t next_compartment(const std::size_t i_current_compartment, const MC::MoveProbabilityView< ComputeSpace, true > &move_probability, GenType &gen, bool &moved) const
Definition move_kernel.hpp:493
bool m_enable_leave
Definition move_kernel.hpp:625
MoveFunctor(std::size_t p_team_move, std::size_t p_team_leave, MC::ParticlePositions p, MC::ParticleStatus _status, MC::DomainState< ComputeSpace > m, MC::pool_type _random_pool, MC::EventContainer _events, ProbeAutogeneratedBuffer _probes, MC::ParticleAges _ages)
Definition move_kernel.hpp:140
KOKKOS_INLINE_FUNCTION void operator()(TagLeave _tag, const Kokkos::TeamPolicy< ComputeSpace >::member_type &team_handle, std::size_t &local_dead_count) const
Definition move_kernel.hpp:268
KOKKOS_INLINE_FUNCTION void operator()(TagMove, const Kokkos::TeamPolicy< ComputeSpace >::member_type &team, MoveLeaveTally &local_tally) const
Definition move_kernel.hpp:211
bool need_launch() const
Definition move_kernel.hpp:205
Kokkos::TeamPolicy< ComputeSpace > TeamPolicy
Definition move_kernel.hpp:137
TeamPolicy::member_type TeamMember
Definition move_kernel.hpp:138
MC::ParticlePositions positions
Definition move_kernel.hpp:613
std::size_t m_p_team_move
Definition move_kernel.hpp:622
double d_t
Definition move_kernel.hpp:612
MC::DomainState< ComputeSpace, true > move
Definition move_kernel.hpp:615
KOKKOS_FORCEINLINE_FUNCTION std::size_t handle_exit(const std::size_t idx, const Kokkos::View< const MC::LeavingFlow *, ExecSpace > &leaving_flow, std::size_t &dead_count) const
Definition move_kernel.hpp:551
KOKKOS_FORCEINLINE_FUNCTION void handle_exit_at(const std::size_t idx, const Kokkos::View< const MC::LeavingFlow *, ExecSpace > &leaving_flow, const std::size_t position, GenType &gen, std::size_t &dead_count) const
Definition move_kernel.hpp:525
std::size_t n_particles
Definition move_kernel.hpp:614
MC::EventContainer events
Definition move_kernel.hpp:618
ProbeAutogeneratedBuffer probes
Definition move_kernel.hpp:619
KOKKOS_INLINE_FUNCTION void perform_exit(const bool proba, const std::size_t idx, std::size_t &dead_count) const
Definition move_kernel.hpp:587
KOKKOS_INLINE_FUNCTION void operator()(TagMoveLeave, const Kokkos::TeamPolicy< ComputeSpace >::member_type &team, MoveLeaveTally &local_tally) const
Definition move_kernel.hpp:312
void update(double _d_t, std::size_t n_p, MC::DomainState< ComputeSpace > move_i, MC::ParticlePositions _positions, MC::ParticleStatus _status, MC::ParticleAges _ages, bool b_move, bool b_leave)
Definition move_kernel.hpp:184
MC::ParticleStatus status
Definition move_kernel.hpp:617
MC::ParticleAges ages
Definition move_kernel.hpp:620
bool m_enable_move
Definition move_kernel.hpp:624
std::size_t m_p_team_leave
Definition move_kernel.hpp:621
KOKKOS_INLINE_FUNCTION void operator()(TagLeaveB0D _tag, const Kokkos::TeamPolicy< ComputeSpace >::member_type &team_handle, MoveLeaveTally &local_tally) const
Definition move_kernel.hpp:400
MC::pool_type random_pool
Definition move_kernel.hpp:616
bool do_leave() const
Definition move_kernel.hpp:394
Definition move_kernel.hpp:51
std::size_t dead
Definition move_kernel.hpp:53
std::size_t moved
Definition move_kernel.hpp:52
KOKKOS_INLINE_FUNCTION MoveLeaveTally & operator+=(const MoveLeaveTally &other)
Definition move_kernel.hpp:56
Definition move_kernel.hpp:37
Definition move_kernel.hpp:33
Definition move_kernel.hpp:44
Definition move_kernel.hpp:29