forked from celeritas-project/celeritas
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ExtendFromSecondariesAction.cc
147 lines (129 loc) · 5.69 KB
/
ExtendFromSecondariesAction.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//----------------------------------*-C++-*----------------------------------//
// Copyright 2021-2024 UT-Battelle, LLC, and other Celeritas developers.
// See the top-level COPYRIGHT file for details.
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
//---------------------------------------------------------------------------//
//! \file celeritas/track/ExtendFromSecondariesAction.cc
//---------------------------------------------------------------------------//
#include "ExtendFromSecondariesAction.hh"
#include "corecel/Assert.hh"
#include "corecel/Macros.hh"
#include "celeritas/global/ActionLauncher.hh"
#include "celeritas/global/CoreParams.hh"
#include "celeritas/global/CoreState.hh"
#include "detail/LocateAliveExecutor.hh" // IWYU pragma: associated
#include "detail/ProcessSecondariesExecutor.hh" // IWYU pragma: associated
#include "detail/TrackInitAlgorithms.hh" // IWYU pragma: associated
namespace celeritas
{
//---------------------------------------------------------------------------//
/*!
* Get a long description of the action.
*/
std::string_view ExtendFromSecondariesAction::description() const
{
return "create track initializers from secondaries";
}
//---------------------------------------------------------------------------//
/*!
* Execute the action with host data.
*/
void ExtendFromSecondariesAction::execute(CoreParams const& params,
CoreStateHost& state) const
{
return this->execute_impl(params, state);
}
//---------------------------------------------------------------------------//
/*!
* Execute the action with device data.
*/
void ExtendFromSecondariesAction::execute(CoreParams const& params,
CoreStateDevice& state) const
{
return this->execute_impl(params, state);
}
//---------------------------------------------------------------------------//
/*!
* Initialize track states.
*/
template<MemSpace M>
void ExtendFromSecondariesAction::execute_impl(CoreParams const& core_params,
CoreState<M>& core_state) const
{
TrackInitStateData<Ownership::reference, M>& init = core_state.ref().init;
CoreStateCounters& counters = core_state.counters();
// Launch a kernel to identify which track slots are still alive and count
// the number of surviving secondaries per track
this->locate_alive(core_params, core_state);
// Remove all elements in the vacancy vector that were flagged as active
// tracks, leaving the (sorted) indices of the empty slots
counters.num_vacancies
= detail::remove_if_alive(init.vacancies, core_state.stream_id());
// The exclusive prefix sum of the number of secondaries produced by each
// track is used to get the start index in the vector of track initializers
// for each thread. Starting at that index, each thread creates track
// initializers from all surviving secondaries produced in its
// interaction.
counters.num_secondaries = detail::exclusive_scan_counts(
init.secondary_counts, core_state.stream_id());
// TODO: if we don't have space for all the secondaries, we will need to
// buffer the current track initializers to create room
counters.num_initializers += counters.num_secondaries;
CELER_VALIDATE(counters.num_initializers <= init.initializers.size(),
<< "insufficient capacity (" << init.initializers.size()
<< ") for track initializers (created "
<< counters.num_secondaries
<< " new secondaries for a total capacity requirement of "
<< counters.num_initializers << ")");
// Launch a kernel to create track initializers from secondaries
counters.num_alive = core_state.size() - counters.num_vacancies;
this->process_secondaries(core_params, core_state);
}
//---------------------------------------------------------------------------//
/*!
* Launch a (host) kernel to locate alive particles.
*
* This fills the TrackInit \c vacancies and \c secondary_counts arrays.
*/
void ExtendFromSecondariesAction::locate_alive(CoreParams const& core_params,
CoreStateHost& core_state) const
{
detail::LocateAliveExecutor execute{core_params.ptr<MemSpace::native>(),
core_state.ptr()};
launch_action(*this, core_params, core_state, execute);
}
//---------------------------------------------------------------------------//
/*!
* Launch a (host) kernel to create track initializers from secondary
* particles.
*/
void ExtendFromSecondariesAction::process_secondaries(
CoreParams const& core_params, CoreStateHost& core_state) const
{
detail::ProcessSecondariesExecutor execute{
core_params.ptr<MemSpace::native>(),
core_state.ptr(),
core_state.counters()};
launch_action(*this, core_params, core_state, execute);
}
//---------------------------------------------------------------------------//
// DEVICE-DISABLED IMPLEMENTATION
//---------------------------------------------------------------------------//
#if !CELER_USE_DEVICE
void ExtendFromSecondariesAction::begin_run(CoreParams const&, CoreStateDevice&)
{
CELER_NOT_CONFIGURED("CUDA OR HIP");
}
void ExtendFromSecondariesAction::locate_alive(CoreParams const&,
CoreStateDevice&) const
{
CELER_NOT_CONFIGURED("CUDA OR HIP");
}
void ExtendFromSecondariesAction::process_secondaries(CoreParams const&,
CoreStateDevice&) const
{
CELER_NOT_CONFIGURED("CUDA OR HIP");
}
#endif
//---------------------------------------------------------------------------//
} // namespace celeritas