BioCMAMC-ST
contribution_kernel.hpp
1#ifndef __CONTRIBUTION_KERNEL_HPP__
2#define __CONTRIBUTION_KERNEL_HPP__
3#include "Kokkos_Assert.hpp"
4#include <Kokkos_Core.hpp>
5#include <mc/particles_container.hpp>
6#include <mc/traits.hpp>
7
8template <ModelType M> struct ContributionFunctor
9{
10 struct Tag0D
11 {
12 };
13 struct Tag3D
14 {
15 };
16
17 using TeamPolicy = Kokkos::TeamPolicy<ComputeSpace>;
18 using TeamMember = TeamPolicy::member_type;
19 using float_type = float;
21 = Kokkos::View<float_type*,
22 TeamPolicy::execution_space::scratch_memory_space>;
24 ContributionFunctor(std::size_t particle_per_team,
25 MC::ContributionView contribution_scatter,
27 : m_particle_per_team(particle_per_team),
28 m_contribution_scatter(std::move(contribution_scatter)),
29 m_particles(std::move(particles))
30 {
31 }
33 size_t np{};
34
35 void
37
38 {
39 this->m_particles = std::move(_particles);
40 np = m_particles.n_particles();
41 }
43 std::size_t m_particle_per_team;
47
48 KOKKOS_INLINE_FUNCTION
49 void
50 operator()(Tag0D _tag, const TeamMember& team) const
51 {
52 (void)_tag;
53 const std::size_t p0 = team.league_rank() * m_particle_per_team;
54 const std::size_t n_particle = m_particles.n_particles();
55 const auto& status = m_particles.status;
56 const auto& contribs = m_particles.contribs;
57 static const auto n_c = M::n_c;
58
59 ScratchView scratch(team.team_scratch(0), n_c);
60
61 Kokkos::parallel_for(Kokkos::TeamVectorRange(team, n_c),
62 [&](const std::size_t j)
63 { scratch(j) = float_type{ 0 }; });
64
65 const auto upper_bound = ((p0 + m_particle_per_team) >= n_particle)
66 ? n_particle - p0
68
69 KOKKOS_ASSERT(upper_bound > 0 && upper_bound <= m_particle_per_team
70 && (p0 + upper_bound) <= n_particle);
71
72 team.team_barrier();
73
74 Kokkos::parallel_for(
75 Kokkos::TeamThreadRange(team, 0, upper_bound),
76 [&](const std::size_t relative_index)
77 {
78 const std::size_t flatten_index = p0 + relative_index;
79 if (status(flatten_index) != MC::Status::Idle)
80 {
81 return;
82 }
83 const auto weight = m_particles.get_weight(flatten_index);
84 for (std::size_t j = 0; j < n_c; ++j)
85 {
86 Kokkos::atomic_add(&scratch(j),
87 weight * contribs(flatten_index, j));
88 }
89 });
90
91 team.team_barrier();
92 const auto& cs = m_contribution_scatter;
93 Kokkos::single(Kokkos::PerTeam(team),
94 [=]()
95 {
96 auto access = cs.access();
97 for (std::size_t j = 0; j < M::n_c; ++j)
98 {
99 access(j, 0) += scratch(j);
100 }
101 });
102 }
103
104 // KOKKOS_INLINE_FUNCTION
105 // void
106 // operator()(const Tag3D _tag, const TeamMember& team) const
107 // {
108 // (void)_tag;
109
110 // const std::size_t p0 = team.league_rank() * m_particle_per_team;
111 // const auto& c = m_particles.contribs;
112 // const auto& status = m_particles.status;
113 // const auto n_particle = m_particles.n_particles();
114 // const auto& positions = m_particles.position;
115
116 // const auto upper_bound = ((p0 + m_particle_per_team) >= n_particle)
117 // ? n_particle - p0 - 1
118 // : m_particle_per_team;
119 // KOKKOS_ASSERT(upper_bound >= 0 && upper_bound < n_particle);
120
121 // constexpr std::size_t work_per_thread = 32;
122 // KOKKOS_ASSERT(m_particle_per_team%work_per_thread==0);
123
124 // Kokkos::parallel_for(Kokkos::TeamThreadRange(team, 0, upper_bound),
125 // [&](const std::size_t i)
126 // {
127 // const std::size_t p = p0 + i;
128 // if (status(p) != MC::Status::Idle)
129 // {
130 // return;
131 // }
132 // auto access = m_contribution_scatter.access();
133 // const double weight = m_particles.get_weight(p);
134 // const auto pos = positions(p);
135
136 // Kokkos::parallel_for(
137 // Kokkos::ThreadVectorRange(team, 0, M::n_c),
138 // [&](const int j)
139 // { access(j, pos) += weight * c(p, j); });
140 // });
141
142 // }
143
144 KOKKOS_INLINE_FUNCTION
145 void
146 operator()(const Tag3D _tag, const TeamMember& team) const
147 {
148 (void)_tag;
149
150 const std::size_t p0 = team.league_rank() * m_particle_per_team;
151 const auto& c = m_particles.contribs;
152 const auto& status = m_particles.status;
153 const auto n_particle = m_particles.n_particles();
154 const auto& positions = m_particles.position;
155 constexpr std::size_t work_per_thread = 32;
156
157 const auto upper_bound = ((p0 + m_particle_per_team) >= n_particle)
158 ? n_particle - p0
160 // KOKKOS_ASSERT(upper_bound >= 0 && upper_bound < n_particle);
161 KOKKOS_ASSERT(upper_bound < n_particle);
162
163 const auto range = (upper_bound + work_per_thread - 1) / work_per_thread;
164
165 KOKKOS_ASSERT(m_particle_per_team % work_per_thread == 0);
166
167 Kokkos::parallel_for(
168 Kokkos::TeamThreadRange(team, 0, range),
169 [&](const std::size_t i)
170 {
171 auto access = m_contribution_scatter.access();
172 for (std::size_t k = 0; k < work_per_thread; ++k)
173 {
174 const std::size_t p = p0 + i * work_per_thread + k;
175 if (status(p) != MC::Status::Idle || i >= n_particle)
176 {
177 return;
178 }
179 const double weight = m_particles.get_weight(p);
180 const auto pos = positions(p);
181 Kokkos::parallel_for(Kokkos::ThreadVectorRange(team, 0, M::n_c),
182 [&](const int j)
183 { access(j, pos) += weight * c(p, j); });
184 }
185 });
186 }
187};
188
189#endif
Main owning object for Monte-Carlo particles.
Definition particles_container.hpp:57
decltype(Kokkos::Experimental::create_scatter_view( kernelContribution())) ContributionView
Definition alias.hpp:162
@ Idle
Definition alias.hpp:126
Definition contribution_kernel.hpp:11
Definition contribution_kernel.hpp:14
Kokkos::View< float_type *, TeamPolicy::execution_space::scratch_memory_space > ScratchView
Definition contribution_kernel.hpp:20
TeamPolicy::member_type TeamMember
Definition contribution_kernel.hpp:18
KOKKOS_INLINE_FUNCTION void operator()(Tag0D _tag, const TeamMember &team) const
Definition contribution_kernel.hpp:49
ContributionFunctor(std::size_t particle_per_team, MC::ContributionView contribution_scatter, MC::ParticlesContainer< M > particles)
Definition contribution_kernel.hpp:23
Kokkos::TeamPolicy< ComputeSpace > TeamPolicy
Definition contribution_kernel.hpp:17
void update(MC::ParticlesContainer< M > _particles)
Definition contribution_kernel.hpp:35
size_t np
Definition contribution_kernel.hpp:32
MC::ParticlesContainer< M > m_particles
Definition contribution_kernel.hpp:45
float float_type
Definition contribution_kernel.hpp:19
MC::ContributionView m_contribution_scatter
Definition contribution_kernel.hpp:44
std::size_t m_particle_per_team
Definition contribution_kernel.hpp:42