1#ifndef __PARTICLES_CONTAINER_HPP__
2#define __PARTICLES_CONTAINER_HPP__
4#include "Kokkos_Macros.hpp"
5#include "common/alg.hpp"
6#include <Kokkos_Core.hpp>
7#include <biocma_cst_config.hpp>
9#include <common/common.hpp>
10#include <common/env_var.hpp>
11#include <common/has_serialize.hpp>
13#include <mc/alias.hpp>
14#include <mc/prng/prng.hpp>
15#include <mc/traits.hpp>
17#include <Kokkos_Sort.hpp>
18#include <sorting/Kokkos_BinSortPublicAPI.hpp>
19#include <sorting/impl/Kokkos_CopyOpsForBinSortImpl.hpp>
20#include <sorting/impl/Kokkos_SortByKeyImpl.hpp>
33 template <
class Archive>
66 std::size_t n_particle,
67 std::size_t _n_samples);
92 KOKKOS_INLINE_FUNCTION
auto sample(std::size_t idx,
93 std::size_t i_sample)
const;
102 template <
typename CviewType>
103 KOKKOS_INLINE_FUNCTION
void
105 const CviewType& contributions)
const
110 "ModelType: Constapply_weight()");
114 auto access = contributions.access();
118 const int rel = i -
begin;
119 access(rel, pos) += weight *
model(idx, i);
137 [[nodiscard]] KOKKOS_INLINE_FUNCTION
bool
143 [[nodiscard]] KOKKOS_INLINE_FUNCTION
double
162 template <
class Archive>
void save(Archive& ar)
const;
167 template <
class Archive>
void load(Archive& ar);
179 [[nodiscard]] std::
size_t capacity() const noexcept;
199 [[nodiscard]] KOKKOS_INLINE_FUNCTION std::
size_t n_particles() const;
238 void _resize(std::size_t new_size,
bool force =
false);
256 using TeamPolicy = Kokkos::TeamPolicy<ComputeSpace>;
257 using TeamMember = TeamPolicy::member_type;
297 template <ModelType M>
struct CompactParticlesFunctor
301 M::SelfParticle _model,
304 std::size_t _to_remove,
305 std::size_t _last_used_index)
306 : status(std::move(_status)), model(std::move(_model)),
307 position(std::move(_position)), ages(std::move(_ages)),
308 offset(
"offset"), to_remove(_to_remove),
309 last_used_index(_last_used_index)
312 Kokkos::deep_copy(offset, 0);
315 KOKKOS_INLINE_FUNCTION
void
316 operator()(
const int i, std::size_t& update,
const bool final)
const
330 const std::size_t scan_index = update;
333 update += is_inactive ? 1 : 0;
336 if (
final && is_inactive && scan_index < to_remove)
339 const auto inactive_slot = i;
345 auto replacement_index
346 = last_used_index - Kokkos::atomic_fetch_add(&offset(), 1);
349 ==
static_cast<std::size_t
>(inactive_slot))
352 = last_used_index - Kokkos::atomic_fetch_add(&offset(), 1);
360 Kokkos::atomic_exchange(&position(inactive_slot),
361 position(replacement_index));
364 for (std::size_t i_properties = 0; i_properties < M::n_var;
367 model(inactive_slot, i_properties)
368 = model(replacement_index, i_properties);
370 ages(inactive_slot, 0) = ages(replacement_index, 0);
371 ages(inactive_slot, 1) = ages(replacement_index, 1);
376 M::SelfParticle model;
379 Kokkos::View<std::size_t, ComputeSpace> offset;
380 std::size_t to_remove;
381 std::size_t last_used_index;
400 template <ModelType M>
struct InsertFunctor
402 InsertFunctor(std::size_t _original_size,
403 M::SelfParticle _model,
406 M::SelfParticle _buffer_model,
408 : original_size(_original_size), model(std::move(_model)),
409 ages(std::move(_ages)), position(std::move(_position)),
410 buffer_model(std::move(_buffer_model)),
411 buffer_position(std::move(_buffer_position))
428 KOKKOS_INLINE_FUNCTION
430 operator()(
const TeamMember& team)
const
432 auto range = M::n_var;
433 const int i = team.league_rank();
435 Kokkos::parallel_for(
436 Kokkos::TeamVectorRange(team, range),
438 { model(original_size + i, j) = buffer_model(i, j); });
439 position(original_size + i) = buffer_position(i);
444 ages(original_size + i, 0) = 0;
445 ages(original_size + i, 1) = 0;
448 std::size_t original_size;
449 M::SelfParticle model;
452 M::SelfParticle buffer_model;
458 template <ModelType Model>
459 [[nodiscard]] KOKKOS_INLINE_FUNCTION std::size_t
465 template <ModelType Model>
466 [[nodiscard]] std::size_t
472 template <ModelType Model>
480 template <ModelType Model>
481 [[maybe_unused]] [[nodiscard]]
auto
488 template <ModelType Model>
495 template <ModelType Model>
496 [[nodiscard]] std::size_t
502 template <ModelType Model>
503 KOKKOS_INLINE_FUNCTION
auto
508 template <ModelType Model>
509 KOKKOS_INLINE_FUNCTION
auto
511 const std::size_t i_sample)
const
513 return random(idx, i_sample);
516 template <ModelType Model>
517 template <
class Archive>
527 deserialize_view(ar,
status);
528 deserialize_view(ar,
model);
529 deserialize_view(ar,
ages);
531 Kokkos::printf(
"ParticlesContainer::load: Check if load_tuning_constant "
532 "works with different value");
538 template <ModelType Model>
539 template <
class Archive>
548 serialize_view(ar,
status);
549 serialize_view(ar,
model);
550 serialize_view(ar,
ages);
553 template <ModelType Model>
564 template <ModelType Model>
567 const std::size_t dead)
573 const auto _threshold = std::max(
576 *
rt_params.dead_particle_ratio_threshold));
585 template <ModelType Model>
586 KOKKOS_INLINE_FUNCTION
bool
588 std::size_t idx1)
const
592 const auto idx2 = Kokkos::atomic_fetch_add(&
buffer_index(), 1);
601 template <ModelType Model>
605 PROFILE_SECTION(
"ParticlesContainer::merge_buffer")
612 _resize(original_size + n_add_item);
613 Kokkos::parallel_for(
"insert_merge",
614 TeamPolicy(n_add_item, Kokkos::AUTO, Model::n_var),
615 InsertFunctor<Model>(original_size,
627 template <ModelType Model>
631 PROFILE_SECTION(
"ParticlesContainer::_resize")
640 const auto new_allocated_size =
static_cast<std::size_t
>(std::ceil(
641 static_cast<double>(new_size) *
rt_params.allocation_factor));
648 Kokkos::resize(
model,
673 template <ModelType Model>
677 PROFILE_SECTION(
"ParticlesContainer::__allocate_buffer__")
679 const auto buffer_ratio =
rt_params.buffer_ratio;
680 if (
static_cast<double>(buffer_size)
684 buffer_size =
static_cast<std::size_t
>(
696 template <ModelType M>
698 std::size_t n_particle,
699 std::size_t _n_samples)
700 :
model(Kokkos::view_alloc(Kokkos::WithoutInitializing,
"particle_model"),
703 position(Kokkos::view_alloc(Kokkos::WithoutInitializing,
704 "particle_position"),
707 Kokkos::view_alloc(Kokkos::WithoutInitializing,
"particle_status"),
710 Kokkos::view_alloc(Kokkos::WithoutInitializing,
"particle_weigth"),
712 ages(Kokkos::view_alloc(Kokkos::WithoutInitializing,
"particle_age"),
715 Kokkos::view_alloc(Kokkos::WithoutInitializing,
"particle_random"),
733 const auto bounds = M::get_bounds();
734 begin = bounds.begin;
738 template <ModelType M>
744 template <ModelType M>
749 PROFILE_SECTION(
"ParticlesContainer::remove_inactive_particles")
763 throw std::runtime_error(
764 "remove_inactive_particles: Error in kernel cannot remove more "
765 "element than existing");
773 Kokkos::parallel_scan(
776 CompactParticlesFunctor<M>(
802 template <ModelType M>
803 [[nodiscard]] KOKKOS_INLINE_FUNCTION
double
816 template <ModelType M>
823 template <ModelType M>
RuntimeParameters rt_params
Definition particles_container.hpp:240
void update_and_remove_inactive(std::size_t out, std::size_t dead)
Definition particles_container.hpp:566
double get_allocation_factor() const noexcept
Get the allocation factor.
Definition particles_container.hpp:490
~ParticlesContainer()=default
Default destructor.
void force_remove_dead()
Clean all the non-idle particle even if number smaller than threshold.
Definition particles_container.hpp:474
Model::SelfParticle model
Definition particles_container.hpp:83
KOKKOS_INLINE_FUNCTION std::size_t n_particles() const
Definition particles_container.hpp:460
ParticleWeigths weights
Definition particles_container.hpp:86
int end
Definition particles_container.hpp:243
KOKKOS_INLINE_FUNCTION bool handle_division(const MC::pool_type &random_pool, std::size_t idx1) const
Attempts to spawn a new particle by performing division on the specified particle.
Definition particles_container.hpp:587
ParticleSamples random
Definition particles_container.hpp:88
Kokkos::View< uint64_t, Kokkos::SharedSpace > buffer_index
Definition particles_container.hpp:232
void _resize(std::size_t new_size, bool force=false)
Definition particles_container.hpp:629
void change_nsample(std::size_t new_n_sample)
Definition particles_container.hpp:555
void remove_inactive_particles(std::size_t to_remove)
Definition particles_container.hpp:746
void __allocate_buffer__()
Definition particles_container.hpp:675
ParticlesContainer()
Definition particles_container.hpp:739
ParticlesContainer & operator=(ParticlesContainer &&)=default
std::size_t get_inactive() const noexcept
Definition particles_container.hpp:467
std::size_t capacity() const noexcept
Definition particles_container.hpp:497
uint64_t n_used_elements
Definition particles_container.hpp:234
auto get_buffer_index() const
Definition particles_container.hpp:482
KOKKOS_INLINE_FUNCTION void get_contributions(const std::size_t idx, const CviewType &contributions) const
Get the contribution if particle at index idx.
Definition particles_container.hpp:104
void merge_buffer()
Insert particle buffer into the main container.
Definition particles_container.hpp:603
Model::SelfParticle buffer_model
Definition particles_container.hpp:230
KOKKOS_INLINE_FUNCTION double get_weight(std::size_t idx) const
Return the particle weight.
Definition particles_container.hpp:804
std::size_t n_samples
Definition particles_container.hpp:239
KOKKOS_INLINE_FUNCTION auto sample(std::size_t idx, std::size_t i_sample) const
get the sample at idx/i_sample position
Definition particles_container.hpp:510
ParticlesContainer(RuntimeParameters rt_param, std::size_t n_particle, std::size_t _n_samples)
Alias for the model used by the container.
Definition particles_container.hpp:697
ParticlePositions buffer_position
Definition particles_container.hpp:231
MC::ParticlePositions position
Definition particles_container.hpp:84
void save(Archive &ar) const
Save data into ar for serialization.
Definition particles_container.hpp:541
std::size_t inactive_counter
Definition particles_container.hpp:235
ParticleAges ages
Definition particles_container.hpp:87
Model UsedModel
Definition particles_container.hpp:59
ParticlesContainer & operator=(const ParticlesContainer &)=default
void _sort(size_t n_c)
Definition particles_container.hpp:825
ParticlesContainer(const ParticlesContainer &)=default
Default copy and move constructors and assignment operators.
void load(Archive &ar)
Load data from ar for deserialization.
Definition particles_container.hpp:519
ParticlesContainer(ParticlesContainer &&)=default
std::size_t n_allocated_elements
Definition particles_container.hpp:233
void change_runtime(RuntimeParameters &¶meters) noexcept
Definition particles_container.hpp:818
int begin
Definition particles_container.hpp:242
KOKKOS_INLINE_FUNCTION auto samples()
get the sample view
Definition particles_container.hpp:504
MC::ParticleStatus status
Definition particles_container.hpp:85
Concept to check if a model type has uniform_weight
Definition traits.hpp:204
Namespace that contains classes and structures related to Monte Carlo (MC) simulations.
Definition alias.hpp:15
Kokkos::View< double *, ComputeSpace > ParticleWeigths
Definition alias.hpp:75
Kokkos::View< Status *, ComputeSpace > ParticleStatus
Definition alias.hpp:74
Kokkos::View< uint64_t *, ComputeSpace > ParticlePositions
Definition alias.hpp:73
@ Idle
Definition alias.hpp:59
ParticleAgesBase< ComputeSpace > ParticleAges
Definition alias.hpp:76
gen_pool_type< Kokkos::DefaultExecutionSpace > pool_type
Definition alias.hpp:39
Kokkos:: View< Kokkos::Experimental::half_t **, Kokkos::LayoutRight, ComputeSpace > ParticleSamples
Definition alias.hpp:78
void sort_soa(std::size_t n0, std::size_t nn, std::size_t n_e, std::size_t n_max, RefView ref_sorting, ViewType... views)
Definition alg.hpp:65
Definition particles_container.hpp:26
double shink_ratio
Definition particles_container.hpp:30
void serialize(Archive &ar)
Definition particles_container.hpp:35
double buffer_ratio
Definition particles_container.hpp:28
double dead_particle_ratio_threshold
Definition particles_container.hpp:31
uint64_t minimum_dead_particle_removal
Definition particles_container.hpp:27
double allocation_factor
Definition particles_container.hpp:29