Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:09:15

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 parents is the \c TrackSlotId of the parent tracks of the initializers.
0090  * - \c vacancies stores the \c TrackSlotid of the tracks that have been
0091  *   killed; the size will be <= the number of track states.
0092  * - \c track_counters stores the total number of particles that have been
0093  *   created per event.
0094  * - \c secondary_counts stores the number of secondaries created by each track
0095  *   (with one remainder at the end for storing the accumulated number of
0096  *   secondaries)
0097  */
0098 template<Ownership W, MemSpace M>
0099 struct TrackInitStateData
0100 {
0101     //// TYPES ////
0102 
0103     template<class T>
0104     using StateItems = StateCollection<T, W, M>;
0105     template<class T>
0106     using EventItems = Collection<T, W, M, EventId>;
0107     template<class T>
0108     using Items = Collection<T, W, M>;
0109 
0110     //// DATA ////
0111 
0112     StateItems<TrackSlotId> parents;
0113     StateItems<size_type> indices;
0114     StateItems<size_type> secondary_counts;
0115     StateItems<TrackSlotId> vacancies;
0116     EventItems<TrackId::size_type> track_counters;
0117 
0118     // Storage (size is "capacity", not "currently used": see
0119     // CoreStateCounters)
0120     Items<TrackInitializer> initializers;
0121 
0122     //// METHODS ////
0123 
0124     //! Whether the data are assigned
0125     explicit CELER_FUNCTION operator bool() const
0126     {
0127         return parents.size() == vacancies.size()
0128                && (indices.size() == vacancies.size() || indices.empty())
0129                && secondary_counts.size() == vacancies.size() + 1
0130                && !track_counters.empty() && !initializers.empty();
0131     }
0132 
0133     //! Assign from another set of data
0134     template<Ownership W2, MemSpace M2>
0135     TrackInitStateData& operator=(TrackInitStateData<W2, M2>& other)
0136     {
0137         CELER_EXPECT(other);
0138 
0139         parents = other.parents;
0140         indices = other.indices;
0141         secondary_counts = other.secondary_counts;
0142         track_counters = other.track_counters;
0143 
0144         vacancies = other.vacancies;
0145         initializers = other.initializers;
0146 
0147         return *this;
0148     }
0149 };
0150 
0151 //---------------------------------------------------------------------------//
0152 /*!
0153  * Resize and initialize track initializer data.
0154  *
0155  * Here \c size is the number of track states, and the "capacity" is the
0156  * maximum number of track initializers (inactive/pending tracks) that we can
0157  * hold.
0158  *
0159  * \note It's likely that for GPU runs, the capacity should be greater than
0160  * the size, but that might not be the case universally, so it is not asserted.
0161  */
0162 template<MemSpace M>
0163 void resize(TrackInitStateData<Ownership::value, M>* data,
0164             HostCRef<TrackInitParamsData> const& params,
0165             StreamId stream,
0166             size_type size)
0167 {
0168     CELER_EXPECT(params);
0169     CELER_EXPECT(size > 0);
0170     CELER_EXPECT(M == MemSpace::host || celeritas::device());
0171 
0172     // Allocate device data
0173     resize(&data->parents, size);
0174     resize(&data->secondary_counts, size + 1);
0175     resize(&data->track_counters, params.max_events);
0176     if (params.track_order == TrackOrder::init_charge)
0177     {
0178         resize(&data->indices, size);
0179     }
0180 
0181     // Initialize the track counter for each event to zero
0182     fill(size_type(0), &data->track_counters);
0183 
0184     // Initialize vacancies to mark all track slots as empty
0185     resize(&data->vacancies, size);
0186     fill_sequence(&data->vacancies, stream);
0187 
0188     // Reserve space for initializers
0189     resize(&data->initializers, params.capacity);
0190 
0191     CELER_ENSURE(*data);
0192 }
0193 
0194 //---------------------------------------------------------------------------//
0195 
0196 }  // namespace celeritas