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/execinfo.hpp>
11#include <common/has_serialize.hpp>
13#include <mc/alias.hpp>
14#include <mc/first_touch.hpp>
15#include <mc/prng/prng.hpp>
16#include <mc/traits.hpp>
18#include <Kokkos_Sort.hpp>
19#include <sorting/Kokkos_BinSortPublicAPI.hpp>
20#include <sorting/impl/Kokkos_CopyOpsForBinSortImpl.hpp>
21#include <sorting/impl/Kokkos_SortByKeyImpl.hpp>
35 template <
class Archive>
67 std::size_t n_particle,
132 [[nodiscard]] KOKKOS_INLINE_FUNCTION
bool
138 [[nodiscard]] KOKKOS_INLINE_FUNCTION Model::FloatType
157 template <
class Archive>
void save(Archive& ar)
const;
162 template <
class Archive>
void load(Archive& ar);
173 [[nodiscard]] std::
size_t capacity() const noexcept;
193 [[nodiscard]] KOKKOS_INLINE_FUNCTION std::
size_t n_particles() const;
235 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,
302 M::SelfContribs _contribs,
305 std::size_t _to_remove,
306 std::size_t _last_used_index)
307 : status(std::move(_status)), model(std::move(_model)),
308 contribs(std::move(_contribs)), position(std::move(_position)),
309 ages(std::move(_ages)), offset(
"offset"), to_remove(_to_remove),
310 last_used_index(_last_used_index)
313 Kokkos::deep_copy(offset, 0);
316 KOKKOS_INLINE_FUNCTION
void
317 operator()(
const int i, std::size_t& update,
const bool final)
const
331 const std::size_t scan_index = update;
334 update += is_inactive ? 1 : 0;
337 if (
final && is_inactive && scan_index < to_remove)
340 const auto inactive_slot = i;
346 auto replacement_index
347 = last_used_index - Kokkos::atomic_fetch_add(&offset(), 1);
350 ==
static_cast<std::size_t
>(inactive_slot))
353 = last_used_index - Kokkos::atomic_fetch_add(&offset(), 1);
361 Kokkos::atomic_exchange(&position(inactive_slot),
362 position(replacement_index));
365 for (std::size_t i_properties = 0; i_properties < M::n_var;
368 model(inactive_slot, i_properties)
369 = model(replacement_index, i_properties);
372 for (std::size_t i_c = 0; i_c < M::n_c; ++i_c)
374 contribs(inactive_slot, i_c) = contribs(replacement_index, i_c);
377 ages(inactive_slot, 0) = ages(replacement_index, 0);
378 ages(inactive_slot, 1) = ages(replacement_index, 1);
383 M::SelfParticle model;
384 M::SelfContribs contribs;
387 Kokkos::View<std::size_t, ComputeSpace> offset;
388 std::size_t to_remove;
389 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))
421 KOKKOS_INLINE_FUNCTION
423 operator()(TagRow,
const std::size_t i,
const std::size_t j)
const
425 model(original_size + i, j) = buffer_model(i, j);
428 KOKKOS_INLINE_FUNCTION
430 operator()(TagScalar,
const std::size_t i)
const
432 position(original_size + i) = buffer_position(i);
437 ages(original_size + i, 0) = 0;
438 ages(original_size + i, 1) = 0;
441 std::size_t original_size;
442 M::SelfParticle model;
445 M::SelfParticle buffer_model;
451 template <ModelType Model>
452 [[nodiscard]] KOKKOS_INLINE_FUNCTION std::size_t
458 template <ModelType Model>
459 [[nodiscard]] std::size_t
465 template <ModelType Model>
473 template <ModelType Model>
474 [[maybe_unused]] [[nodiscard]]
auto
481 template <ModelType Model>
488 template <ModelType Model>
489 [[nodiscard]] std::size_t
495 template <ModelType Model>
496 template <
class Archive>
506 deserialize_view(ar,
status);
507 deserialize_view(ar,
model);
508 deserialize_view(ar,
ages);
510 if (Model::n_var !=
model.extent(1))
512 throw std::runtime_error(
513 "Error when deserialze, model number of property mismatch");
520 Kokkos::printf(
"ParticlesContainer::load: Check if load_tuning_constant "
521 "works with different value");
527 template <ModelType Model>
528 template <
class Archive>
537 serialize_view(ar,
status);
538 serialize_view(ar,
model);
539 serialize_view(ar,
ages);
542 template <ModelType Model>
545 const std::size_t dead)
551 const auto _threshold = std::max(
554 *
rt_params.dead_particle_ratio_threshold));
562 template <ModelType Model>
563 KOKKOS_INLINE_FUNCTION
bool
565 std::size_t idx1)
const
569 const auto idx2 = Kokkos::atomic_fetch_add(&
buffer_index(), 1);
578 template <ModelType Model>
582 PROFILE_SECTION(
"ParticlesContainer::merge_buffer")
589 _resize(original_size + n_add_item);
591 using functor_type = InsertFunctor<Model>;
592 const functor_type functor(
595 Kokkos::parallel_for(
"insert_merge_rows",
596 Kokkos::MDRangePolicy<
typename functor_type::TagRow,
600 {
static_cast<int64_t
>(n_add_item),
601 static_cast<int64_t
>(Model::n_var) }),
604 Kokkos::parallel_for(
605 "insert_merge_scalars",
606 Kokkos::RangePolicy<typename functor_type::TagScalar, ComputeSpace>(
615 template <ModelType Model>
619 PROFILE_SECTION(
"ParticlesContainer::_resize")
628 const auto new_allocated_size =
static_cast<std::size_t
>(std::ceil(
629 static_cast<double>(new_size) *
rt_params.allocation_factor));
686 template <ModelType Model>
690 PROFILE_SECTION(
"ParticlesContainer::__allocate_buffer__")
692 const auto required_buffer_size =
static_cast<std::size_t
>(
704 required_buffer_size,
705 required_buffer_size,
713#define alloc_without_init(name) \
714 Kokkos::view_alloc(Kokkos::WithoutInitializing, name)
717 template <ModelType M>
719 std::size_t n_particle,
721 :
model(alloc_without_init(
"particle_model"), 0, 0),
723 contribs(alloc_without_init(
"particle_contribs"), 0),
724 position(alloc_without_init(
"particle_position"), 0),
725 status(alloc_without_init(
"particle_status"), 0),
726 weights(alloc_without_init(
"particle_weigth"), 0),
727 ages(alloc_without_init(
"particle_age"), 0),
754 template <ModelType M>
760 template <ModelType M>
765 PROFILE_SECTION(
"ParticlesContainer::remove_inactive_particles")
779 throw std::runtime_error(
780 "remove_inactive_particles: Error in kernel cannot remove more "
781 "element than existing");
789 Kokkos::parallel_scan(
792 CompactParticlesFunctor<M>(
status,
807 const bool do_shrink = n_used_elements <= static_cast<std::size_t>(
819 template <ModelType M>
820 [[nodiscard]] KOKKOS_INLINE_FUNCTION M::FloatType
833 template <ModelType M>
840 template <ModelType M>
848 const int bin_size = 2048;
853 using ExecSpace = Kokkos::DefaultExecutionSpace;
854 using view_type =
decltype(
position);
855 auto binop = Kokkos::BinOp1D<view_type>(bin_size, 0, n_c);
857 auto sorter = Kokkos::BinSort<view_type, decltype(binop)>(
858 ExecSpace(), sn, binop,
true);
RuntimeParameters rt_params
Definition particles_container.hpp:236
void update_and_remove_inactive(std::size_t out, std::size_t dead)
Definition particles_container.hpp:544
double get_allocation_factor() const noexcept
Get the allocation factor.
Definition particles_container.hpp:483
Model::SelfContribs contribs
Definition particles_container.hpp:85
~ParticlesContainer()=default
Default destructor.
void force_remove_dead()
Clean all the non-idle particle even if number smaller than threshold.
Definition particles_container.hpp:467
Model::SelfParticle model
Definition particles_container.hpp:84
KOKKOS_INLINE_FUNCTION std::size_t n_particles() const
Definition particles_container.hpp:453
KOKKOS_INLINE_FUNCTION bool handle_division(const MC::pool_type &random_pool, std::size_t idx1) const
Get the contribution if particle at index idx.
Definition particles_container.hpp:564
KernelDispatchOptions kernel_options
Definition particles_container.hpp:232
Kokkos::View< uint64_t, Kokkos::SharedSpace > buffer_index
Definition particles_container.hpp:226
void _resize(std::size_t new_size, bool force=false)
Definition particles_container.hpp:617
void remove_inactive_particles(std::size_t to_remove)
Definition particles_container.hpp:762
void __allocate_buffer__()
Definition particles_container.hpp:688
ParticlesContainer()
Definition particles_container.hpp:755
ParticlesContainer & operator=(ParticlesContainer &&)=default
std::size_t get_inactive() const noexcept
Definition particles_container.hpp:460
std::size_t capacity() const noexcept
Definition particles_container.hpp:490
uint64_t n_used_elements
Definition particles_container.hpp:228
auto get_buffer_index() const
Definition particles_container.hpp:475
KOKKOS_INLINE_FUNCTION Model::FloatType get_weight(std::size_t idx) const
Return the particle weight.
Definition particles_container.hpp:821
void merge_buffer()
Insert particle buffer into the main container.
Definition particles_container.hpp:580
Model::SelfParticle buffer_model
Definition particles_container.hpp:224
ParticlePositions buffer_position
Definition particles_container.hpp:225
MC::ParticlePositions position
Definition particles_container.hpp:87
void save(Archive &ar) const
Save data into ar for serialization.
Definition particles_container.hpp:530
std::size_t inactive_counter
Definition particles_container.hpp:229
ParticleAges ages
Definition particles_container.hpp:90
Model UsedModel
Definition particles_container.hpp:61
ParticleWeigths< typename Model::FloatType > weights
Definition particles_container.hpp:89
ParticlesContainer & operator=(const ParticlesContainer &)=default
void _sort(size_t n_c)
Definition particles_container.hpp:842
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:498
ParticlesContainer(RuntimeParameters rt_param, std::size_t n_particle, KernelDispatchOptions kernel_opts={})
Alias for the model used by the container.
Definition particles_container.hpp:718
ParticlesContainer(ParticlesContainer &&)=default
std::size_t n_allocated_elements
Definition particles_container.hpp:227
void change_runtime(RuntimeParameters &¶meters) noexcept
Definition particles_container.hpp:835
MC::ParticleStatus status
Definition particles_container.hpp:88
Concept to check if a model type has uniform_weight
Definition traits.hpp:203
Namespace that contains classes and structures related to Monte Carlo (MC) simulations.
Definition alias.hpp:16
Kokkos::View< Status *, ComputeSpace > ParticleStatus
Definition alias.hpp:141
Kokkos::View< uint64_t *, ComputeSpace > ParticlePositions
Definition alias.hpp:140
@ Idle
Definition alias.hpp:126
ParticleAgesBase< ComputeSpace > ParticleAges
Definition alias.hpp:144
gen_pool_type< Kokkos::DefaultExecutionSpace > pool_type
Definition alias.hpp:100
Kokkos::View< ftype *, ComputeSpace > ParticleWeigths
Definition alias.hpp:143
Kokkos::DefaultExecutionSpace ComputeSpace
Definition alias.hpp:17
void resize_first_touch(ViewType &view, std::size_t n_alloc, std::size_t n_live, std::size_t npt, Extents... rest)
Kokkos::resize, but with the first touch placed by us.
Definition first_touch.hpp:106
Definition execinfo.hpp:13
Definition particles_container.hpp:28
void serialize(Archive &ar)
Definition particles_container.hpp:37
double buffer_ratio
Definition particles_container.hpp:30
double dead_particle_ratio_threshold
Definition particles_container.hpp:33
uint64_t minimum_dead_particle_removal
Definition particles_container.hpp:29
double shrink_ratio
Definition particles_container.hpp:32
double allocation_factor
Definition particles_container.hpp:31