BioCMAMC-ST
first_touch.hpp
1#ifndef __MC_FIRST_TOUCH_HPP__
2#define __MC_FIRST_TOUCH_HPP__
3
4#include <Kokkos_Core.hpp>
5#include <algorithm>
6#include <biocma_cst_config.hpp>
7#include <common/common.hpp>
8#include <common/execinfo.hpp>
9#include <common/kokkos_getpolicy.hpp>
10#include <cstddef>
11#include <utility>
12
24namespace MC
25{
26 namespace Impl
27 {
28 template <typename ViewType> struct FirstTouchFunctor
29 {
30 using TeamMember = typename Kokkos::TeamPolicy<ComputeSpace>::member_type;
31 using value_type = typename ViewType::non_const_value_type;
32
33 ViewType view;
34 std::size_t begin;
35 std::size_t end;
36 std::size_t per_team;
37
38 KOKKOS_INLINE_FUNCTION void
39 operator()(const TeamMember& team) const
40 {
41 const std::size_t p0 = begin + (team.league_rank() * per_team);
42 const std::size_t upper = (p0 + per_team > end) ? end - p0 : per_team;
43
44 Kokkos::parallel_for(Kokkos::TeamThreadRange(team, 0, upper),
45 [&](const std::size_t idx)
46 {
47 const std::size_t i = p0 + idx;
48 if constexpr (ViewType::rank == 1)
49 {
50 view(i) = value_type{};
51 }
52 else
53 {
54 for (std::size_t j = 0; j < view.extent(1);
55 ++j)
56 {
57 view(i, j) = value_type{};
58 }
59 }
60 });
61 }
62 };
63 } // namespace Impl
64
66 template <typename ViewType>
67 void
68 first_touch(const ViewType& view,
69 std::size_t begin,
70 std::size_t end,
71 std::size_t npt)
72 {
73 end = std::min(end, static_cast<std::size_t>(view.extent(0)));
74 if (begin >= end || npt == 0)
75 {
76 return;
77 }
78
79 const std::size_t league = Common::c_league_size(end - begin, npt);
80
81 Kokkos::parallel_for(
82 "first_touch",
83 Kokkos::TeamPolicy<ComputeSpace>(
84 static_cast<int>(league), Kokkos::AUTO(), Kokkos::AUTO()),
85 Impl::FirstTouchFunctor<ViewType>{ view, begin, end, npt });
86 }
87
104 template <typename ViewType, typename... Extents>
105 void
106 resize_first_touch(ViewType& view,
107 std::size_t n_alloc,
108 std::size_t n_live,
109 std::size_t npt,
110 Extents... rest)
111 {
112 if (view.extent(0) == n_alloc)
113 {
114 return;
115 }
116
117 ViewType next(Kokkos::view_alloc(Kokkos::WithoutInitializing, view.label()),
118 n_alloc,
119 rest...);
120
121 const std::size_t live = std::min(n_live, n_alloc);
122 first_touch(next, 0, live, npt); // placed with the compute partition
123 first_touch(next, live, n_alloc, npt); // must exist; placement not yet
124 // relevant
125
126 const std::size_t n_copy
127 = std::min(static_cast<std::size_t>(view.extent(0)), n_alloc);
128 if (n_copy != 0)
129 {
130 const auto range = Kokkos::make_pair(std::size_t{ 0 }, n_copy);
131 if constexpr (ViewType::rank == 1)
132 {
133 Kokkos::deep_copy(Kokkos::subview(next, range),
134 Kokkos::subview(view, range));
135 }
136 else
137 {
138 Kokkos::deep_copy(Kokkos::subview(next, range, Kokkos::ALL),
139 Kokkos::subview(view, range, Kokkos::ALL));
140 }
141 }
142
143 view = next;
144 }
145} // namespace MC
146
147#endif //__MC_FIRST_TOUCH_HPP__
std::size_t c_league_size(std::size_t n_tot, std::size_t n_per_team) noexcept
Definition common.cpp:17
Definition first_touch.hpp:27
Namespace that contains classes and structures related to Monte Carlo (MC) simulations.
Definition alias.hpp:16
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
void first_touch(const ViewType &view, std::size_t begin, std::size_t end, std::size_t npt)
Write-touch [begin, end) with the move kernel's team decomposition.
Definition first_touch.hpp:68
Definition first_touch.hpp:29
std::size_t per_team
Definition first_touch.hpp:36
ViewType view
Definition first_touch.hpp:33
std::size_t begin
Definition first_touch.hpp:34
KOKKOS_INLINE_FUNCTION void operator()(const TeamMember &team) const
Definition first_touch.hpp:39
typename Kokkos::TeamPolicy< ComputeSpace >::member_type TeamMember
Definition first_touch.hpp:30
std::size_t end
Definition first_touch.hpp:35
typename ViewType::non_const_value_type value_type
Definition first_touch.hpp:31