BioCMAMC-ST
kernels.hpp
1#ifndef __SIMULATION_KERNELS_HPP__
2#define __SIMULATION_KERNELS_HPP__
3
4#include "mc/alias.hpp"
5#include <Kokkos_Core_fwd.hpp>
6#include <common/common.hpp>
7#include <common/kokkos_getpolicy.hpp>
8#include <impl/Kokkos_Profiling.hpp>
9#include <mc/domain.hpp>
10#include <mc/unit.hpp>
11#include <simulation/kernels/contribution_kernel.hpp>
12#include <simulation/kernels/model_kernel.hpp>
13#include <simulation/kernels/move_kernel.hpp>
14
15#include <common/execinfo.hpp>
16#include <stdexcept>
17
19{
20
21 template <typename Space>
24 template <typename Space>
25 using move_reducer_view_type = Kokkos::View<MoveLeaveTally, Space>;
27 template <typename Space, ModelType Model> struct CycleFunctors
28 {
29 using FModel = Model;
34 ComputeSpace move_space;
36 ComputeSpace model_space;
45 CycleFunctors() = default;
50
51 void
52 update(const double d_t,
55 {
56 f_multi_compartment = new_move.liquid_volume.size() > 1;
58 const bool enable_leave = new_move.leaving_flow.size() != 0;
59
60 // FIXME: cycle_kernel: need to update container because we change:
61 // n_used_element counter which is size_t outside of kernel. As functor
62 // owns a copy of container this counter is not update between iterations.
63 // 1. Use n_used_element as a reference counter type
64 // 2. Manually update counter in update function (dirty way)
65
66 // launch_move is skipped entirely when need_launch() is false, and
67 // post_cycle tallies the reducer either way: clear it here so a step that
68 // launches nothing cannot re-count the previous step's events.
69 Kokkos::deep_copy(move_reducer, MoveLeaveTally{ 0, 0 });
70
71 cycle_kernel.update(d_t, container);
72
73 contribution_kernel.update(container, d_t);
74
75 // TODO: Why need to update all views (where did we lost the refcount ? )
76 move_kernel.update(d_t,
77 container.n_particles(),
78 std::move(new_move),
79 container.position,
80 container.status,
81 container.ages,
84 }
85
86 auto
88 {
89 const auto host_red
90 = Kokkos::create_mirror_view_and_copy(HostSpace(), cycle_reducer)();
91
92 const auto move_tally
93 = Kokkos::create_mirror_view_and_copy(HostSpace(), move_reducer)();
94
95 if constexpr (AutoGenerated::FlagCompileTime::enable_event_counter)
96 {
97 move_kernel.events.add<MC::EventType::Move>(move_tally.moved);
98 move_kernel.events.add<MC::EventType::Exit>(move_tally.dead);
99 }
100
101 return std::tuple(host_red, move_tally.dead);
102 }
106 MC::pool_type _random_pool,
107 MC::KernelConcentrationType _concentrations,
108 MC::ContributionView _contribs_scatter,
109 MC::EventContainer _event,
112 ProbeAutogeneratedBuffer _probes_div)
113 : cycle_reducer("cycle_reducer"), move_reducer("move_reducer"),
114 cycle_kernel(options.m_p_p_team_model,
115 container,
116 _random_pool,
117 _concentrations,
118 _event,
119 _probes_div),
120 move_kernel(options.m_p_p_team_move,
121 options.m_p_p_team_leave,
122 container.position,
123 container.status,
124 std::move(m),
125 _random_pool,
126 _event,
127 _probes,
128 container.ages),
129 // contribution_kernel(
130 // options.m_p_p_team_contribs, _contribs_scatter, container),
131 contribution_kernel(options.m_p_p_team_contribs,
132 _contribs_scatter,
133 container,
134 _random_pool,
135 _concentrations,
136 _event,
137 _probes_div),
138 m_options(options)
139
140 {
141 }
142
144 void
145 launch_move_3d(const std::size_t n_particle)
146 {
147 std::size_t npt = m_options.m_p_p_team_move;
148 if (n_particle <= npt)
149 {
150 move_kernel.m_p_team_move = 1;
151 npt = 1;
152 }
153 const std::size_t league_size = Common::c_league_size(n_particle, npt);
154
155 auto policy = Kokkos::TeamPolicy<TagMove>(move_space,
156 static_cast<int>(league_size),
157 Kokkos::AUTO(),
158 Kokkos::AUTO());
159
160 Kokkos::parallel_reduce("cycle_move", policy, move_kernel, move_reducer);
161 }
162
163 // Fused move + leave
164 void
165 launch_move_leave_3d(const std::size_t n_particle)
166 {
167 std::size_t npt = m_options.m_p_p_team_move;
168 if (n_particle <= npt)
169 {
170 move_kernel.m_p_team_move = 1;
171 npt = 1;
172 }
173 const std::size_t league_size = Common::c_league_size(n_particle, npt);
174
175 auto policy
176 = Kokkos::TeamPolicy<TagMoveLeave>(move_space,
177 static_cast<int>(league_size),
178 Kokkos::AUTO(),
179 Kokkos::AUTO());
180
181 Kokkos::parallel_reduce(
182 "cycle_move_leave", policy, move_kernel, move_reducer);
183 }
184
185 void
186 launch_leave_0d(const std::size_t n_particle)
187 {
188 std::size_t npt = move_kernel.m_p_team_leave;
189 if (n_particle <= npt)
190 {
191 move_kernel.m_p_team_leave = 1;
192 npt = 1;
193 }
194 const std::size_t league_size = Common::c_league_size(n_particle, npt);
195
196 auto policy
197 = Kokkos::TeamPolicy<TagLeaveB0D>(move_space,
198 static_cast<int>(league_size),
199 Kokkos::AUTO(),
200 Kokkos::AUTO());
201
202 Kokkos::parallel_reduce(
203 "cycle_leave_0D", policy, move_kernel, move_reducer);
204 }
205
206 void
207 launch_move(const std::size_t n_particle)
208 {
209 // The domain shape decides which kernels are legal:
210 // multi-compartment (3D) : move, or move + leave
211 // single compartment (0D): leave, or nothing
212 // do_move() is exactly "the domain has more than one compartment".
213 const bool is_multi_compartment = move_kernel.do_move();
214 const bool has_outlet = move_kernel.do_leave();
215
216 if (is_multi_compartment)
217 {
218 if (has_outlet)
219 {
220 launch_move_leave_3d(n_particle);
221 }
222 else
223 {
224 launch_move_3d(n_particle);
225 }
226 return;
227 }
228
229 if (has_outlet)
230 {
231 launch_leave_0d(n_particle);
232 }
233 }
234
235 void
236 launch_model(const std::size_t n_particle)
237 {
238
239 std::size_t npt = m_options.m_p_p_team_model;
240
241 if (n_particle <= npt)
242 {
243 cycle_kernel.m_p_team = 1;
244 npt = 1;
245 }
246
247 std::size_t league_size = Common::c_league_size(n_particle, npt);
248
249 // const auto cycle_policy
250 // = Kokkos::TeamPolicy<TagCycle, Kokkos::Schedule<Kokkos::Dynamic>>(
251 // model_space,
252 // static_cast<int>(league_size),
253 // Kokkos::AUTO(),
254 // Kokkos::AUTO());
255
256 // Kokkos::parallel_reduce(
257 // "cycle_model",
258 // cycle_policy,
259 // cycle_kernel,
260 // KernelInline::CycleReducer<ComputeSpace>(cycle_reducer));
261 // Kokkos::fence(); // TODO needed ?
262
263 // // Assumptions
264 // // Newborn cells do not contribte in current time step
265 // // Mother cell doesn´t exist but
266 // // Contribution array is not changed during division and
267
268 // if (cycle_kernel.do_contribs())
269 {
270
271 std::size_t npt = m_options.m_p_p_team_contribs;
272 if (n_particle <= npt)
273 {
274 contribution_kernel.m_particle_per_team = 1;
275 npt = 1;
276 }
277
278 league_size = Common::c_league_size(n_particle, npt);
279 static_assert(ConstWeightModelType<Model>,
280 "ModelType:Constapply_weight()");
283 {
284
285 const auto policy_contribs
286 = Kokkos::TeamPolicy<typename ContributionFunctor<Model>::Tag3D>(
287 model_space, league_size, Kokkos::AUTO(), Kokkos::AUTO());
288 Kokkos::parallel_reduce("cycle_model_contribs",
289 policy_contribs,
291 reducer);
292 }
293 else
294 {
295 auto policy_contribs
296 = Kokkos::TeamPolicy<typename ContributionFunctor<Model>::Tag0D>(
297 model_space, league_size, Kokkos::AUTO(), Kokkos::AUTO());
298 policy_contribs.set_scratch_size(
299 0, Kokkos::PerTeam(sizeof(float) * Model::n_c));
300 Kokkos::parallel_reduce("cycle_model_contribs_0d",
301 policy_contribs,
303 reducer);
304 }
305 }
306 }
307 };
308
309} // namespace Simulation::KernelInline
310
311#endif
Main owning object for Monte-Carlo particles.
Definition particles_container.hpp:59
KOKKOS_INLINE_FUNCTION std::size_t n_particles() const
Gets the number of particles in the container.
Definition particles_container.hpp:453
MC::ParticlePositions position
Definition particles_container.hpp:87
ParticleAges ages
Definition particles_container.hpp:90
MC::ParticleStatus status
Definition particles_container.hpp:88
Definition cycle_reducer.hpp:31
Kokkos::View< value_type, Space > result_view_type
Definition cycle_reducer.hpp:36
Concept to check if a model type has uniform_weight
Definition traits.hpp:203
std::size_t c_league_size(std::size_t n_tot, std::size_t n_per_team) noexcept
Definition common.cpp:23
@ Move
Move in domain.
Definition events.hpp:23
@ Exit
Remove particle from list due to move in domain.
Definition events.hpp:22
decltype(Kokkos::Experimental::create_scatter_view( kernelContribution())) ContributionView
Definition alias.hpp:162
gen_pool_type< Kokkos::DefaultExecutionSpace > pool_type
Definition alias.hpp:100
Kokkos::View< const double **, Kokkos::LayoutLeft, ComputeSpace, Kokkos::MemoryTraits< Kokkos::RandomAccess > > KernelConcentrationType
Definition alias.hpp:165
Definition cycle_reducer.hpp:13
constexpr bool enable_leave
Definition move_kernel.hpp:23
KernelInline::CycleReducer< Space >::result_view_type cycle_reducer_view_type
Definition kernels.hpp:22
constexpr bool enable_move
Definition move_kernel.hpp:26
Kokkos::View< MoveLeaveTally, Space > move_reducer_view_type
Definition kernels.hpp:24
Probes< AutoGenerated::probe_buffer_size > ProbeAutogeneratedBuffer
Definition probe.hpp:150
Definition contribution_kernel.hpp:12
Definition execinfo.hpp:13
Structure to store information about domain needed during MC cycle data is likely to change between e...
Definition domain.hpp:29
Use to count events that occurs during Monte-Carlo processing cycles.
Definition events.hpp:168
Definition model_kernel.hpp:42
void launch_leave_0d(const std::size_t n_particle)
Definition kernels.hpp:185
CycleFunctor< Model > cycle_kernel_type
Definition kernels.hpp:30
cycle_kernel_type cycle_kernel
Definition kernels.hpp:39
ComputeSpace model_space
Definition kernels.hpp:35
MoveFunctor move_kernel_type
Definition kernels.hpp:31
bool f_multi_compartment
Definition kernels.hpp:48
move_kernel_type move_kernel
Definition kernels.hpp:40
void launch_model(const std::size_t n_particle)
Definition kernels.hpp:235
void launch_move_3d(const std::size_t n_particle)
Move-only, multi-compartment domain.
Definition kernels.hpp:144
auto get_host_reduction()
Definition kernels.hpp:86
KernelDispatchOptions m_options
Definition kernels.hpp:46
ComputeSpace move_space
Definition kernels.hpp:33
cycle_reducer_view_type< Space > cycle_reducer
Definition kernels.hpp:37
move_reducer_view_type< Space > move_reducer
Definition kernels.hpp:38
void launch_move(const std::size_t n_particle)
Definition kernels.hpp:206
Model FModel
Definition kernels.hpp:28
ContributionFunctor< Model > contribution_kernel
Definition kernels.hpp:42
void launch_move_leave_3d(const std::size_t n_particle)
Definition kernels.hpp:164
void update(const double d_t, MC::ParticlesContainer< Model > container, MC::DomainState< ComputeSpace > &&new_move)
Definition kernels.hpp:51
Definition move_kernel.hpp:136
Definition move_kernel.hpp:51