Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-11-03 09:43:44

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/global/TrackExecutor.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Types.hh"
0011 #include "corecel/math/Algorithms.hh"
0012 #include "corecel/sys/ThreadId.hh"
0013 #include "celeritas/track/TrackFunctors.hh"
0014 
0015 #include "CoreTrackData.hh"
0016 #include "CoreTrackDataFwd.hh"
0017 #include "CoreTrackView.hh"
0018 
0019 namespace celeritas
0020 {
0021 //---------------------------------------------------------------------------//
0022 /*!
0023  * Call a \c CoreTrackView executor for a given ThreadId.
0024  *
0025  * This class can be used to call a functor that applies to \c CoreTrackView
0026  * using a \c ThreadId, so that the tracks can be easily looped over as a
0027  * group on CPU or GPU. It applies a remapping from \em thread to \em slot if
0028  * the tracks are sorted. Otherwise, thread and track slot have the same
0029  * numerical value.
0030  *
0031  * This is primarily used by \c ActionLauncher .
0032  *
0033  * \code
0034 void foo_kernel(CoreParamsPtr const params,
0035                 CoreStatePtr const state)
0036 {
0037     TrackExecutor execute{params, state, MyTrackApplier{}};
0038 
0039     for (auto tid : range(ThreadID{123}))
0040     {
0041         step(tid);
0042     }
0043 }
0044 \endcode
0045  *
0046  * \todo Rename to ThreadExecutor. The template parameter, which must operate
0047  * on a core track view, is a track executor.
0048  */
0049 template<class T>
0050 class TrackExecutor
0051 {
0052   public:
0053     //!@{
0054     //! \name Type aliases
0055     using ParamsPtr = CoreParamsPtr<MemSpace::native>;
0056     using StatePtr = CoreStatePtr<MemSpace::native>;
0057     using Applier = T;
0058     //!@}
0059 
0060   public:
0061     //! Construct with core data and executor
0062     CELER_FUNCTION
0063     TrackExecutor(ParamsPtr params, StatePtr state, T&& execute_track)
0064         : params_{params}
0065         , state_{state}
0066         , execute_track_{celeritas::forward<T>(execute_track)}
0067     {
0068     }
0069 
0070     //! Call the underlying function, using indirection array if needed
0071     CELER_FUNCTION void operator()(ThreadId thread)
0072     {
0073         CELER_EXPECT(thread < state_->size());
0074         CoreTrackView track(*params_, *state_, thread);
0075         return execute_track_(track);
0076     }
0077 
0078   private:
0079     ParamsPtr const params_;
0080     StatePtr const state_;
0081     T execute_track_;
0082 };
0083 
0084 //---------------------------------------------------------------------------//
0085 /*!
0086  * Launch the track only when a certain condition applies to the sim state.
0087  *
0088  * The condition \c C must have the signature \code
0089  * (SimTrackView const&) -> bool
0090   \endcode
0091  *
0092  * see \c make_active_track_executor for an example where this is used to apply
0093  * only to active (or killed) tracks.
0094  */
0095 template<class C, class T>
0096 class ConditionalTrackExecutor
0097 {
0098   public:
0099     //!@{
0100     //! \name Type aliases
0101     using ParamsPtr = CoreParamsPtr<MemSpace::native>;
0102     using StatePtr = CoreStatePtr<MemSpace::native>;
0103     using Applier = T;
0104     //!@}
0105 
0106   public:
0107     //! Construct with condition and operator
0108     CELER_FUNCTION
0109     ConditionalTrackExecutor(ParamsPtr params,
0110                              StatePtr state,
0111                              C&& applies,
0112                              T&& execute_track)
0113         : params_{params}
0114         , state_{state}
0115         , applies_{celeritas::forward<C>(applies)}
0116         , execute_track_{celeritas::forward<T>(execute_track)}
0117     {
0118     }
0119 
0120     //! Launch the given thread if the track meets the condition
0121     CELER_FUNCTION void operator()(ThreadId thread)
0122     {
0123         CELER_EXPECT(thread < state_->size());
0124         CoreTrackView track(*params_, *state_, thread);
0125         if (!applies_(track))
0126         {
0127             return;
0128         }
0129 
0130         return execute_track_(track);
0131     }
0132 
0133   private:
0134     ParamsPtr const params_;
0135     StatePtr const state_;
0136     C applies_;
0137     T execute_track_;
0138 };
0139 
0140 //---------------------------------------------------------------------------//
0141 // DEDUCTION GUIDES
0142 //---------------------------------------------------------------------------//
0143 template<class T>
0144 CELER_FUNCTION TrackExecutor(CoreParamsPtr<MemSpace::native>,
0145                              CoreStatePtr<MemSpace::native>,
0146                              T&&) -> TrackExecutor<T>;
0147 
0148 template<class C, class T>
0149 CELER_FUNCTION ConditionalTrackExecutor(CoreParamsPtr<MemSpace::native>,
0150                                         CoreStatePtr<MemSpace::native>,
0151                                         C&&,
0152                                         T&&) -> ConditionalTrackExecutor<C, T>;
0153 
0154 //---------------------------------------------------------------------------//
0155 // FREE FUNCTIONS
0156 //---------------------------------------------------------------------------//
0157 /*!
0158  * Return a track executor that only applies to active, non-errored tracks.
0159  */
0160 template<class T>
0161 inline CELER_FUNCTION decltype(auto)
0162 make_active_track_executor(CoreParamsPtr<MemSpace::native> params,
0163                            CoreStatePtr<MemSpace::native> const& state,
0164                            T&& apply_track)
0165 {
0166     return ConditionalTrackExecutor{
0167         params, state, AppliesValid{}, celeritas::forward<T>(apply_track)};
0168 }
0169 
0170 //---------------------------------------------------------------------------//
0171 /*!
0172  * Return a track executor that only applies if the action ID matches.
0173  *
0174  * \note This should generally only be used for post-step actions and other
0175  * cases where the IDs *explicitly* are set. Many explicit actions apply to all
0176  * threads, active or not.
0177  */
0178 template<class T>
0179 inline CELER_FUNCTION decltype(auto)
0180 make_action_track_executor(CoreParamsPtr<MemSpace::native> params,
0181                            CoreStatePtr<MemSpace::native> state,
0182                            ActionId action,
0183                            T&& apply_track)
0184 {
0185     CELER_EXPECT(action);
0186     return ConditionalTrackExecutor{params,
0187                                     state,
0188                                     IsStepActionEqual{action},
0189                                     celeritas::forward<T>(apply_track)};
0190 }
0191 
0192 //---------------------------------------------------------------------------//
0193 /*!
0194  * Return a track executor that only applies for the given along-step action.
0195  */
0196 template<class T>
0197 inline CELER_FUNCTION decltype(auto)
0198 make_along_step_track_executor(CoreParamsPtr<MemSpace::native> params,
0199                                CoreStatePtr<MemSpace::native> state,
0200                                ActionId action,
0201                                T&& apply_track)
0202 {
0203     CELER_EXPECT(action);
0204     return ConditionalTrackExecutor{params,
0205                                     state,
0206                                     IsAlongStepActionEqual{action},
0207                                     celeritas::forward<T>(apply_track)};
0208 }
0209 
0210 //---------------------------------------------------------------------------//
0211 }  // namespace celeritas