|
||||
File indexing completed on 2025-01-18 09:54:49
0001 //----------------------------------*-C++-*----------------------------------// 0002 // Copyright 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 corecel/sys/ActionInterface.hh 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include <string> 0011 #include <string_view> 0012 0013 #include "corecel/cont/Span.hh" 0014 0015 #include "ThreadId.hh" 0016 0017 namespace celeritas 0018 { 0019 //---------------------------------------------------------------------------// 0020 /*! 0021 * Within-step ordering of explicit actions. 0022 * 0023 * Each "step iteration", wherein many tracks undergo a single step in 0024 * parallel, consists of an ordered series of actions. An action with an 0025 * earlier order always precedes an action with a later order. 0026 * 0027 * \sa StepActionInterface 0028 */ 0029 enum class StepActionOrder 0030 { 0031 generate, //!< Fill new track initializers 0032 start, //!< Initialize tracks 0033 user_start, //!< User initialization of new tracks 0034 sort_start, //!< Sort track slots after initialization 0035 pre, //!< Pre-step physics and setup 0036 user_pre, //!< User actions for querying pre-step data 0037 sort_pre, //!< Sort track slots after setting pre-step 0038 along, //!< Along-step 0039 sort_along, //!< Sort track slots after determining first step action 0040 pre_post, //!< Discrete selection kernel 0041 sort_pre_post, //! Sort track slots after selecting discrete interaction 0042 post, //!< After step 0043 user_post, //!< User actions after boundary crossing, collision 0044 end, //!< Processing secondaries, including replacing primaries 0045 size_ 0046 }; 0047 0048 //---------------------------------------------------------------------------// 0049 /*! 0050 * Pure abstract interface for an action that could happen to a track. 0051 * 0052 * An action represents a possible state point or state change for a track. 0053 * Explicit actions (see \c StepActionInterface ) call kernels that change 0054 * the state (discrete processes, geometry boundary), and *implicit* actions 0055 * (which do not inherit from the explicit interface) are placeholders for 0056 * different reasons to pause the state or mark it for future modification 0057 * (range limitation, propagation loop limit). 0058 * 0059 * The \c ActionInterface provides a clean virtual interface for 0060 * gathering metadata. The \c StepActionInterface provides additional 0061 * interfaces for launching kernels. The \c BeginRunActionInterface allows 0062 * actions to modify the state (or the class instance itself) at the beginning 0063 * of a stepping loop, and \c EndRunActionInterface allows actions to 0064 * gather and merge multiple state information at the end. 0065 * 0066 * Using multiple inheritance, you can create an action that inherits from 0067 * multiple of these classes. Note also that the function signatures are 0068 * similar to other high-level interfaces classes in Celeritas (e.g., \c 0069 * AuxParamsInterface, \c OutputInterface), so one "label" can be used to 0070 * satisfy multiple interfaces. 0071 * 0072 * The \c label should be a brief lowercase hyphen-separated string, usually a 0073 * noun, with perhaps some sort of category being the first token. 0074 * 0075 * The \c description should be a verb phrase (and not have a title-cased 0076 * start). 0077 */ 0078 class ActionInterface 0079 { 0080 public: 0081 // Default virtual destructor allows deletion by pointer-to-interface 0082 virtual ~ActionInterface() noexcept = 0; 0083 0084 //! ID of this action for verification and ordering 0085 virtual ActionId action_id() const = 0; 0086 0087 //! Short unique label of the action 0088 virtual std::string_view label() const = 0; 0089 0090 //! Description of the action 0091 virtual std::string_view description() const = 0; 0092 0093 protected: 0094 //!@{ 0095 //! Allow construction and assignment only through daughter classes 0096 ActionInterface() = default; 0097 CELER_DEFAULT_COPY_MOVE(ActionInterface); 0098 //!@} 0099 }; 0100 0101 //---------------------------------------------------------------------------// 0102 /*! 0103 * Interface that can modify the action's state. 0104 * 0105 * Most actions can modify \em only the local "state" being passed as an 0106 * argument. This one allows data to be allocated or initialized at the 0107 * beginning of the run. 0108 * 0109 * \todo Delete this to allow only stateless actions, since now 0110 * we have aux data? This will reduce overhead for virtual inheritance classes 0111 * too. 0112 */ 0113 class MutableActionInterface : public virtual ActionInterface 0114 { 0115 }; 0116 0117 //---------------------------------------------------------------------------// 0118 /*! 0119 * Traits class for actions that modify or access params/state. 0120 * 0121 * Using a single base class's typedefs is necessary for some compilers to 0122 * avoid an "ambiguous type alias" failure: "member 'CoreParams' found in 0123 * multiple base classes of different types". Note that adding this class to 0124 * the inheritance hierarchy (even multiple times) has no additional storage or 0125 * access cost. 0126 */ 0127 template<class P, template<MemSpace M> class S> 0128 struct ActionTypeTraits 0129 { 0130 //@{ 0131 //! \name Type aliases 0132 using CoreParams = P; 0133 using CoreStateHost = S<MemSpace::host>; 0134 using CoreStateDevice = S<MemSpace::device>; 0135 using SpanCoreStateHost = Span<S<MemSpace::host>* const>; 0136 using SpanCoreStateDevice = Span<S<MemSpace::device>* const>; 0137 //@} 0138 }; 0139 0140 //---------------------------------------------------------------------------// 0141 /*! 0142 * Interface for updating states at the beginning of the simulation. 0143 * 0144 * This is necessary for some classes that require deferred initialization 0145 * (either to the class itself or the state), for example because it needs the 0146 * number of total actions being run. 0147 * 0148 * If the class itself--rather than the state--needs initialization, try to 0149 * initialize in the constructor and avoid using this interface if possible. 0150 * 0151 * \todo This is currently called once per each state on each CPU thread, and 0152 * it would be more sensible to call a single with all cooperative states. 0153 * 0154 * \warning Because this is called once per thread, the inheriting class is 0155 * responsible for thread safety (e.g. adding mutexes). 0156 */ 0157 template<class P, template<MemSpace M> class S> 0158 class BeginRunActionInterface : public ActionTypeTraits<P, S>, 0159 public MutableActionInterface 0160 { 0161 public: 0162 //! Set host data at the beginning of a run 0163 virtual void begin_run(P const&, S<MemSpace::host>&) = 0; 0164 //! Set device data at the beginning of a run 0165 virtual void begin_run(P const&, S<MemSpace::device>&) = 0; 0166 }; 0167 0168 //---------------------------------------------------------------------------// 0169 /*! 0170 * Interface for kernel actions in a stepping loop. 0171 * 0172 * \tparam P Core param class 0173 * \tparam S Core state class 0174 */ 0175 template<class P, template<MemSpace M> class S> 0176 class StepActionInterface : public ActionTypeTraits<P, S>, 0177 virtual public ActionInterface 0178 { 0179 public: 0180 //! Dependency ordering of the action inside the step 0181 virtual StepActionOrder order() const = 0; 0182 //! Execute the action with host data 0183 virtual void step(P const&, S<MemSpace::host>&) const = 0; 0184 //! Execute the action with device data 0185 virtual void step(P const&, S<MemSpace::device>&) const = 0; 0186 }; 0187 0188 //---------------------------------------------------------------------------// 0189 /*! 0190 * Concrete mixin utility class for managing an action. 0191 * 0192 * Example: 0193 * \code 0194 class KernellyPhysicsAction final : public CoreStepActionInterface, 0195 public ConcreteAction 0196 { 0197 public: 0198 // Construct with ID and label 0199 using ConcreteAction::ConcreteAction; 0200 0201 void step(CoreParams const&, CoreStateHost&) const final; 0202 void step(CoreParams const&, CoreStateDevice&) const final; 0203 0204 StepActionOrder order() const final { return StepActionOrder::post; } 0205 }; 0206 0207 class PlaceholderPhysicsAction final : public ConcreteAction 0208 { 0209 public: 0210 // Construct with ID and label 0211 using ConcreteAction::ConcreteAction; 0212 }; 0213 * \endcode 0214 * 0215 * The \c noexcept declarations improve code generation for the 0216 * common use case of multiple inheritance. 0217 * 0218 * \note Use this class when multiple instances of the class may coexist in the 0219 * same stepping loop. 0220 */ 0221 class ConcreteAction : virtual public ActionInterface 0222 { 0223 public: 0224 // Construct from ID, unique label 0225 ConcreteAction(ActionId id, std::string label) noexcept(!CELERITAS_DEBUG); 0226 0227 // Construct from ID, unique label, and description 0228 ConcreteAction(ActionId id, 0229 std::string label, 0230 std::string description) noexcept(!CELERITAS_DEBUG); 0231 0232 // Default destructor 0233 ~ConcreteAction() noexcept; 0234 CELER_DELETE_COPY_MOVE(ConcreteAction); 0235 0236 //! ID of this action for verification 0237 ActionId action_id() const final { return id_; } 0238 0239 //! Short label 0240 std::string_view label() const final { return label_; } 0241 0242 //! Descriptive label 0243 std::string_view description() const final { return description_; } 0244 0245 private: 0246 ActionId id_; 0247 std::string label_; 0248 std::string description_; 0249 }; 0250 0251 //---------------------------------------------------------------------------// 0252 /*! 0253 * Concrete utility class for managing an action with static strings. 0254 * 0255 * This is an implementation detail of \c StaticConcreteAction, but it can be 0256 * used manually for classes that inherit from multiple \c label methods (e.g., 0257 * something that's both an action and has aux data) for which the mixin method 0258 * does not work. 0259 */ 0260 class StaticActionData 0261 { 0262 public: 0263 // Construct from ID, unique label 0264 StaticActionData(ActionId id, 0265 std::string_view label) noexcept(!CELERITAS_DEBUG); 0266 0267 // Construct from ID, unique label, and description 0268 StaticActionData(ActionId id, 0269 std::string_view label, 0270 std::string_view description) noexcept(!CELERITAS_DEBUG); 0271 0272 //! ID of this action for verification 0273 ActionId action_id() const { return id_; } 0274 0275 //! Short label 0276 std::string_view label() const { return label_; } 0277 0278 //! Descriptive label 0279 std::string_view description() const { return description_; } 0280 0281 private: 0282 ActionId id_; 0283 std::string_view label_; 0284 std::string_view description_; 0285 }; 0286 0287 //---------------------------------------------------------------------------// 0288 /*! 0289 * Concrete mixin utility class for managing an action with static strings. 0290 * 0291 * This is a typical use case for "singleton" actions where a maximum of one 0292 * can exist per stepping loop. The action ID still must be supplied at 0293 * runtime. 0294 * 0295 * \note Use this class when the label and description are compile-time 0296 * constants. 0297 */ 0298 class StaticConcreteAction : virtual public ActionInterface 0299 { 0300 public: 0301 // Construct from ID, unique label 0302 StaticConcreteAction(ActionId id, 0303 std::string_view label) noexcept(!CELERITAS_DEBUG); 0304 0305 // Construct from ID, unique label, and description 0306 StaticConcreteAction(ActionId id, 0307 std::string_view label, 0308 std::string_view description) noexcept(!CELERITAS_DEBUG); 0309 0310 // Default destructor 0311 ~StaticConcreteAction() = default; 0312 CELER_DELETE_COPY_MOVE(StaticConcreteAction); 0313 0314 //! ID of this action for verification 0315 ActionId action_id() const final { return sad_.action_id(); } 0316 0317 //! Short label 0318 std::string_view label() const final { return sad_.label(); } 0319 0320 //! Descriptive label 0321 std::string_view description() const final { return sad_.description(); } 0322 0323 private: 0324 StaticActionData sad_; 0325 }; 0326 0327 //---------------------------------------------------------------------------// 0328 0329 //! Action order/ID tuple for comparison in sorting 0330 struct OrderedAction 0331 { 0332 StepActionOrder order; 0333 ActionId id; 0334 0335 //! Ordering comparison for an action/ID 0336 CELER_CONSTEXPR_FUNCTION bool operator<(OrderedAction const& other) const 0337 { 0338 if (this->order < other.order) 0339 return true; 0340 if (this->order > other.order) 0341 return false; 0342 return this->id < other.id; 0343 } 0344 }; 0345 0346 //---------------------------------------------------------------------------// 0347 0348 // Get a string corresponding to a surface type 0349 char const* to_cstring(StepActionOrder); 0350 0351 //---------------------------------------------------------------------------// 0352 } // namespace celeritas
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |