Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-11 08:37:23

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file celeritas/track/TrackInitData.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Types.hh"
0010 #include "corecel/cont/Range.hh"
0011 #include "corecel/data/Collection.hh"
0012 #include "corecel/data/CollectionAlgorithms.hh"
0013 #include "corecel/data/CollectionBuilder.hh"
0014 #include "corecel/sys/Device.hh"
0015 #include "corecel/sys/ThreadId.hh"
0016 #include "geocel/Types.hh"
0017 #include "celeritas/Types.hh"
0018 #include "celeritas/phys/ParticleData.hh"
0019 #include "celeritas/phys/Primary.hh"
0020 
0021 #include "SimData.hh"
0022 
0023 namespace celeritas
0024 {
0025 //---------------------------------------------------------------------------//
0026 /*!
0027  * Persistent data for track initialization.
0028  *
0029  * TODO: change \c max_events to be the maximum number of events in flight at
0030  * once rather than the maximum number of events that can be run over the
0031  * entire simulation
0032  */
0033 template<Ownership W, MemSpace M>
0034 struct TrackInitParamsData
0035 {
0036     size_type capacity{0};  //!< Track initializer storage size
0037     size_type max_events{0};  //!< Maximum number of events that can be run
0038     TrackOrder track_order{TrackOrder::none};  //!< How to sort tracks on
0039                                                //!< gpu
0040 
0041     //// METHODS ////
0042 
0043     //! Whether the data are assigned
0044     explicit CELER_FUNCTION operator bool() const
0045     {
0046         return capacity > 0 && max_events > 0;
0047     }
0048 
0049     //! Assign from another set of data
0050     template<Ownership W2, MemSpace M2>
0051     TrackInitParamsData& operator=(TrackInitParamsData<W2, M2> const& other)
0052     {
0053         CELER_EXPECT(other);
0054         capacity = other.capacity;
0055         max_events = other.max_events;
0056         track_order = other.track_order;
0057         return *this;
0058     }
0059 };
0060 
0061 //---------------------------------------------------------------------------//
0062 /*!
0063  * Lightweight version of a track used to initialize new tracks from primaries
0064  * or secondaries.
0065  */
0066 struct TrackInitializer
0067 {
0068     SimTrackInitializer sim;
0069     GeoTrackInitializer geo;
0070     ParticleTrackInitializer particle;
0071 
0072     //! True if assigned and valid
0073     explicit CELER_FUNCTION operator bool() const
0074     {
0075         return sim && geo && particle;
0076     }
0077 };
0078 
0079 //---------------------------------------------------------------------------//
0080 /*!
0081  * Storage for dynamic data used to initialize new tracks.
0082  *
0083  * Not all of this is technically "state" data, though it is all mutable and in
0084  * most cases accessed by \c TrackSlotId. Specifically, \c initializers and \c
0085  * vacancies are resizable, and \c track_counters has size
0086  * \c max_events.
0087  * - \c initializers stores the data for primaries and secondaries waiting to
0088  *   be turned into new tracks and can be any size up to \c capacity.
0089  * - \c vacancies stores the \c TrackSlotid of the tracks that have been
0090  *   killed; the size will be <= the number of track states.
0091  * - \c track_counters stores the total number of particles that have been
0092  *   created per event.
0093  * - \c secondary_counts stores the number of secondaries created by each track
0094  *   (with one remainder at the end for storing the accumulated number of
0095  *   secondaries)
0096  */
0097 template<Ownership W, MemSpace M>
0098 struct TrackInitStateData
0099 {
0100     //// TYPES ////
0101 
0102     template<class T>
0103     using StateItems = StateCollection<T, W, M>;
0104     template<class T>
0105     using EventItems = Collection<T, W, M, EventId>;
0106     template<class T>
0107     using Items = Collection<T, W, M>;
0108 
0109     //// DATA ////
0110 
0111     StateItems<size_type> indices;
0112     StateItems<size_type> secondary_counts;
0113     StateItems<TrackSlotId> vacancies;
0114     EventItems<TrackId::size_type> track_counters;
0115 
0116     // Storage (size is "capacity", not "currently used": see
0117     // CoreStateCounters)
0118     Items<TrackInitializer> initializers;
0119 
0120     //// METHODS ////
0121 
0122     //! Whether the data are assigned
0123     explicit CELER_FUNCTION operator bool() const
0124     {
0125         return (indices.size() == vacancies.size() || indices.empty())
0126                && secondary_counts.size() == vacancies.size() + 1
0127                && !track_counters.empty() && !initializers.empty();
0128     }
0129 
0130     //! Assign from another set of data
0131     template<Ownership W2, MemSpace M2>
0132     TrackInitStateData& operator=(TrackInitStateData<W2, M2>& other)
0133     {
0134         CELER_EXPECT(other);
0135 
0136         indices = other.indices;
0137         secondary_counts = other.secondary_counts;
0138         track_counters = other.track_counters;
0139 
0140         vacancies = other.vacancies;
0141         initializers = other.initializers;
0142 
0143         return *this;
0144     }
0145 };
0146 
0147 //---------------------------------------------------------------------------//
0148 /*!
0149  * Resize and initialize track initializer data.
0150  *
0151  * Here \c size is the number of track states, and the "capacity" is the
0152  * maximum number of track initializers (inactive/pending tracks) that we can
0153  * hold.
0154  *
0155  * \note It's likely that for GPU runs, the capacity should be greater than
0156  * the size, but that might not be the case universally, so it is not asserted.
0157  */
0158 template<MemSpace M>
0159 void resize(TrackInitStateData<Ownership::value, M>* data,
0160             HostCRef<TrackInitParamsData> const& params,
0161             StreamId stream,
0162             size_type size)
0163 {
0164     CELER_EXPECT(params);
0165     CELER_EXPECT(size > 0);
0166     CELER_EXPECT(M == MemSpace::host || celeritas::device());
0167 
0168     // Allocate device data
0169     resize(&data->secondary_counts, size + 1);
0170     resize(&data->track_counters, params.max_events);
0171     if (params.track_order == TrackOrder::init_charge)
0172     {
0173         resize(&data->indices, size);
0174     }
0175 
0176     // Initialize the track counter for each event to zero
0177     fill(size_type(0), &data->track_counters);
0178 
0179     // Initialize vacancies to mark all track slots as empty
0180     resize(&data->vacancies, size);
0181     fill_sequence(&data->vacancies, stream);
0182 
0183     // Reserve space for initializers
0184     resize(&data->initializers, params.capacity);
0185 
0186     CELER_ENSURE(*data);
0187 }
0188 
0189 //---------------------------------------------------------------------------//
0190 
0191 }  // namespace celeritas