1#ifndef __PARTICLES_CONTAINER_HPP__
2#define __PARTICLES_CONTAINER_HPP__
4#include "Kokkos_Macros.hpp"
5#include <Kokkos_Core.hpp>
6#include <biocma_cst_config.hpp>
8#include <common/common.hpp>
9#include <common/env_var.hpp>
10#include <common/has_serialize.hpp>
12#include <mc/alias.hpp>
13#include <mc/prng/prng.hpp>
14#include <mc/traits.hpp>
16#include <Kokkos_Sort.hpp>
17#include <sorting/Kokkos_BinSortPublicAPI.hpp>
18#include <sorting/impl/Kokkos_CopyOpsForBinSortImpl.hpp>
19#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);
260 using TeamPolicy = Kokkos::TeamPolicy<ComputeSpace>;
261 using TeamMember = TeamPolicy::member_type;
301 template <ModelType M>
struct CompactParticlesFunctor
305 M::SelfParticle _model,
308 std::size_t _to_remove,
309 std::size_t _last_used_index)
310 : status(std::move(_status)), model(std::move(_model)),
311 position(std::move(_position)), ages(std::move(_ages)),
312 offset(
"offset"), to_remove(_to_remove),
313 last_used_index(_last_used_index)
316 Kokkos::deep_copy(offset, 0);
319 KOKKOS_INLINE_FUNCTION
void
320 operator()(
const int i, std::size_t& update,
const bool final)
const
334 const std::size_t scan_index = update;
337 update += is_inactive ? 1 : 0;
340 if (
final && is_inactive && scan_index < to_remove)
343 const auto inactive_slot = i;
349 auto replacement_index
350 = last_used_index - Kokkos::atomic_fetch_add(&offset(), 1);
353 ==
static_cast<std::size_t
>(inactive_slot))
356 = last_used_index - Kokkos::atomic_fetch_add(&offset(), 1);
364 Kokkos::atomic_exchange(&position(inactive_slot),
365 position(replacement_index));
368 for (std::size_t i_properties = 0; i_properties < M::n_var;
371 model(inactive_slot, i_properties)
372 = model(replacement_index, i_properties);
374 ages(inactive_slot, 0) = ages(replacement_index, 0);
375 ages(inactive_slot, 1) = ages(replacement_index, 1);
380 M::SelfParticle model;
383 Kokkos::View<std::size_t, ComputeSpace> offset;
384 std::size_t to_remove;
385 std::size_t last_used_index;
404 template <ModelType M>
struct InsertFunctor
406 InsertFunctor(std::size_t _original_size,
407 M::SelfParticle _model,
410 M::SelfParticle _buffer_model,
412 : original_size(_original_size), model(std::move(_model)),
413 ages(std::move(_ages)), position(std::move(_position)),
414 buffer_model(std::move(_buffer_model)),
415 buffer_position(std::move(_buffer_position))
418 KOKKOS_INLINE_FUNCTION
420 operator()(
const TeamMember& team)
const
422 auto range = M::n_var;
423 const int i = team.league_rank();
425 Kokkos::parallel_for(
426 Kokkos::TeamVectorRange(team, range),
428 { model(original_size + i, j) = buffer_model(i, j); });
429 position(original_size + i) = buffer_position(i);
434 ages(original_size + i, 0) = 0;
435 ages(original_size + i, 1) = 0;
438 std::size_t original_size;
439 M::SelfParticle model;
442 M::SelfParticle buffer_model;
448 template <ModelType Model>
449 [[nodiscard]] KOKKOS_INLINE_FUNCTION std::size_t
455 template <ModelType Model>
456 [[nodiscard]] std::size_t
462 template <ModelType Model>
470 template <ModelType Model>
471 [[maybe_unused]] [[nodiscard]]
auto
478 template <ModelType Model>
485 template <ModelType Model>
486 [[nodiscard]] std::size_t
492 template <ModelType Model>
493 KOKKOS_INLINE_FUNCTION
auto
498 template <ModelType Model>
499 KOKKOS_INLINE_FUNCTION
auto
501 const std::size_t i_sample)
const
503 return random(idx, i_sample);
506 template <ModelType Model>
507 template <
class Archive>
517 deserialize_view(ar,
status);
518 deserialize_view(ar,
model);
519 deserialize_view(ar,
ages);
521 Kokkos::printf(
"ParticlesContainer::load: Check if load_tuning_constant "
522 "works with different value");
528 template <ModelType Model>
529 template <
class Archive>
538 serialize_view(ar,
status);
539 serialize_view(ar,
model);
540 serialize_view(ar,
ages);
543 template <ModelType Model>
554 template <ModelType Model>
557 const std::size_t dead)
563 const auto _threshold = std::max(
566 *
rt_params.dead_particle_ratio_threshold));
574 template <ModelType Model>
575 KOKKOS_INLINE_FUNCTION
bool
577 std::size_t idx1)
const
581 const auto idx2 = Kokkos::atomic_fetch_add(&
buffer_index(), 1);
590 template <ModelType Model>
594 PROFILE_SECTION(
"ParticlesContainer::merge_buffer")
601 _resize(original_size + n_add_item);
602 Kokkos::parallel_for(
"insert_merge",
603 TeamPolicy(n_add_item, Kokkos::AUTO, Model::n_var),
604 InsertFunctor<Model>(original_size,
616 template <ModelType Model>
620 PROFILE_SECTION(
"ParticlesContainer::_resize")
629 const auto new_allocated_size =
static_cast<std::size_t
>(std::ceil(
630 static_cast<double>(new_size) *
rt_params.allocation_factor));
637 Kokkos::resize(
model,
686 template <ModelType Model>
690 PROFILE_SECTION(
"ParticlesContainer::__allocate_buffer__")
692 const auto required_buffer_size =
static_cast<std::size_t
>(
699 Kokkos::realloc(
buffer_model, required_buffer_size, Model::n_var);
705#define alloc_without_init(name) \
706 Kokkos::view_alloc(Kokkos::WithoutInitializing, name)
709 template <ModelType M>
711 std::size_t n_particle,
712 std::size_t _n_samples)
713 :
model(alloc_without_init(
"particle_model"), 0, 0),
714 position(alloc_without_init(
"particle_position"), 0),
715 status(alloc_without_init(
"particle_status"), 0),
716 weights(alloc_without_init(
"particle_weigth"), 0),
717 ages(alloc_without_init(
"particle_age"), 0),
718 random(alloc_without_init(
"particle_random"), 0, 0),
734 const auto bounds = M::get_bounds();
738 throw std::invalid_argument(
"Model begin should be > end");
741 begin = bounds.begin;
745 template <ModelType M>
751 template <ModelType M>
756 PROFILE_SECTION(
"ParticlesContainer::remove_inactive_particles")
770 throw std::runtime_error(
771 "remove_inactive_particles: Error in kernel cannot remove more "
772 "element than existing");
780 Kokkos::parallel_scan(
783 CompactParticlesFunctor<M>(
799 const bool do_shrink = n_used_elements <= static_cast<std::size_t>(
815 template <ModelType M>
816 [[nodiscard]] KOKKOS_INLINE_FUNCTION
double
829 template <ModelType M>
836 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:556
double get_allocation_factor() const noexcept
Get the allocation factor.
Definition particles_container.hpp:480
~ParticlesContainer()=default
Default destructor.
void force_remove_dead()
Clean all the non-idle particle even if number smaller than threshold.
Definition particles_container.hpp:464
Model::SelfParticle model
Definition particles_container.hpp:83
KOKKOS_INLINE_FUNCTION std::size_t n_particles() const
Definition particles_container.hpp:450
ParticleWeigths weights
Definition particles_container.hpp:86
int end
Definition particles_container.hpp:244
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:576
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:618
void change_nsample(std::size_t new_n_sample)
Definition particles_container.hpp:545
void remove_inactive_particles(std::size_t to_remove)
Definition particles_container.hpp:753
void __allocate_buffer__()
Definition particles_container.hpp:688
ParticlesContainer()
Definition particles_container.hpp:746
ParticlesContainer & operator=(ParticlesContainer &&)=default
std::size_t get_inactive() const noexcept
Definition particles_container.hpp:457
std::size_t capacity() const noexcept
Definition particles_container.hpp:487
uint64_t n_used_elements
Definition particles_container.hpp:234
auto get_buffer_index() const
Definition particles_container.hpp:472
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:592
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:817
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:500
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:710
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:531
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:838
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:509
ParticlesContainer(ParticlesContainer &&)=default
std::size_t n_allocated_elements
Definition particles_container.hpp:233
void change_runtime(RuntimeParameters &¶meters) noexcept
Definition particles_container.hpp:831
int begin
Definition particles_container.hpp:243
KOKKOS_INLINE_FUNCTION auto samples()
get the sample view
Definition particles_container.hpp:494
MC::ParticleStatus status
Definition particles_container.hpp:85
Concept to check if a model type has uniform_weight
Definition traits.hpp:183
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< float **, Kokkos::LayoutRight, ComputeSpace > ParticleSamples
Definition alias.hpp:81
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
Definition particles_container.hpp:26
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 shrink_ratio
Definition particles_container.hpp:30
double allocation_factor
Definition particles_container.hpp:29