Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:31:31

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2023-2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file celeritas/track/ExtendFromSecondariesAction.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "celeritas/global/ActionInterface.hh"
0011 
0012 namespace celeritas
0013 {
0014 //---------------------------------------------------------------------------//
0015 /*!
0016  * Create track initializers on device from secondary particles.
0017  *
0018  * Secondaries produced by each track are ordered arbitrarily in memory, and
0019  * the memory may be fragmented if not all secondaries survived cutoffs. For
0020  * example, after the interactions have been processed and cutoffs applied, the
0021  * track states and their secondaries might look like the following (where 'X'
0022  * indicates a track or secondary that did not survive):
0023  * \verbatim
0024 
0025    thread ID   | 0   1 2           3       4   5 6           7       8   9
0026    track ID    | 10  X 8           7       X   5 4           X       2   1
0027    secondaries | [X]   [X, 11, 12] [13, X] [X]   [14, X, 15] [X, 16] [X]
0028 
0029    \endverbatim
0030  *
0031  * Because the order in which threads receive a chunk of memory from the
0032  * secondary allocator is nondeterministic, the actual ordering of the
0033  * secondaries in memory is unpredictable; for instance:
0034  * \verbatim
0035 
0036   secondary storage | [X, 13, X, X, 11, 12, X, X, 16, 14, X, 15, X]
0037 
0038   \endverbatim
0039  *
0040  * When track initializers are created from secondaries, they are ordered by
0041  * thread ID to ensure reproducibility. If a track that produced secondaries
0042  * has died (e.g., thread ID 7 in the example above), one of its secondaries is
0043  * immediately used to fill that track slot:
0044  * \verbatim
0045 
0046    thread ID   | 0   1 2           3       4   5 6           7       8   9
0047    track ID    | 10  X 8           7       X   5 4           16      2   1
0048    secondaries | [X]   [X, 11, 12] [13, X] [X]   [14, X, 15] [X, X]  [X]
0049 
0050    \endverbatim
0051  *
0052  * This way, the geometry state is reused rather than initialized from the
0053  * position (which is expensive). This also prevents the geometry state from
0054  * being overwritten by another track's secondary, so if the track produced
0055  * multiple secondaries, the rest are still able to copy the parent's state.
0056  *
0057  * Track initializers are created from the remaining secondaries and are added
0058  * to the back of the vector. The thread ID of each secondary's parent is also
0059  * stored, so any new tracks initialized from secondaries produced in this
0060  * step can copy the geometry state from the parent. The indices of the empty
0061  * slots in the track vector are identified and stored as a sorted vector of
0062  * vacancies.
0063  * \verbatim
0064 
0065    track initializers | 11 12 13 14 15
0066    parent             | 2  2  3  6  6
0067    vacancies          | 1  4
0068 
0069    \endverbatim
0070  */
0071 class ExtendFromSecondariesAction final : public CoreStepActionInterface,
0072                                           public CoreBeginRunActionInterface
0073 {
0074   public:
0075     //! Construct with explicit Id
0076     explicit ExtendFromSecondariesAction(ActionId id) : id_(id) {}
0077 
0078     //!@{
0079     //! \name Action interface
0080     //! ID of the action
0081     ActionId action_id() const final { return id_; }
0082     //! Short name for the action
0083     std::string_view label() const final { return "extend-from-secondaries"; }
0084     // Description of the action for user interaction
0085     std::string_view description() const final;
0086     //! Dependency ordering of the action
0087     StepActionOrder order() const final { return StepActionOrder::end; }
0088     //!@}
0089 
0090     //!@{
0091     //! \name ExplicitAction interface
0092     // Launch kernel with host data
0093     void step(CoreParams const&, CoreStateHost&) const final;
0094     // Launch kernel with device data
0095     void step(CoreParams const&, CoreStateDevice&) const final;
0096     //!@}
0097 
0098     //!@{
0099     //! \name BeginRunAction interface
0100     // No action necessary for host data
0101     void begin_run(CoreParams const&, CoreStateHost&) final {}
0102     // Warm up asynchronous allocation at beginning of run
0103     void begin_run(CoreParams const&, CoreStateDevice&) final;
0104     //!@}
0105 
0106   private:
0107     ActionId id_;
0108 
0109     template<MemSpace M>
0110     void step_impl(CoreParams const&, CoreState<M>&) const;
0111 
0112     void locate_alive(CoreParams const&, CoreStateHost&) const;
0113     void locate_alive(CoreParams const&, CoreStateDevice&) const;
0114 
0115     void process_secondaries(CoreParams const&, CoreStateHost&) const;
0116     void process_secondaries(CoreParams const&, CoreStateDevice&) const;
0117 };
0118 
0119 //---------------------------------------------------------------------------//
0120 }  // namespace celeritas