Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:53:48

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/user/detail/StepScratchCopyExecutor.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Macros.hh"
0010 #include "corecel/data/Collection.hh"
0011 #include "corecel/sys/ThreadId.hh"
0012 
0013 #include "../StepData.hh"
0014 
0015 namespace celeritas
0016 {
0017 namespace detail
0018 {
0019 //---------------------------------------------------------------------------//
0020 /*!
0021  * Equivalent to `CONT[tid]` but without debug checking.
0022  *
0023  * Debug checking causes the StepScratchCopyExecutor to grow large enough to
0024  * emit warnings.
0025  */
0026 template<class C, class O>
0027 CELER_FORCEINLINE_FUNCTION decltype(auto) fast_get(C&& cont, OpaqueId<O> tid)
0028 {
0029     static_assert(std::remove_reference_t<C>::memspace == MemSpace::native);
0030     return cont.data().get()[tid.unchecked_get()];
0031 }
0032 
0033 //---------------------------------------------------------------------------//
0034 /*!
0035  * In the CUDA implementation, "compress" by copying from scratch.
0036  */
0037 struct StepScratchCopyExecutor
0038 {
0039     NativeRef<StepStateData> state;
0040     size_type num_valid{};
0041 
0042     // Gather results from active tracks that are in a detector
0043     inline CELER_FUNCTION void operator()(ThreadId id);
0044 };
0045 
0046 //---------------------------------------------------------------------------//
0047 /*!
0048  * Gather results from active tracks that are in a detector.
0049  */
0050 CELER_FUNCTION void StepScratchCopyExecutor::operator()(ThreadId dst_id)
0051 {
0052     CELER_EXPECT(state.size() == state.scratch.size()
0053                  && num_valid <= state.size()
0054                  && dst_id < state.valid_id.size());
0055 
0056     // Indirect from thread to compressed track slot
0057     TrackSlotId src_id{fast_get(state.valid_id, dst_id)};
0058     CELER_ASSERT(src_id < state.size());
0059 
0060 #define DS_COPY_IF_SELECTED(FIELD)                    \
0061     do                                                \
0062     {                                                 \
0063         if (!state.data.FIELD.empty())                \
0064         {                                             \
0065             fast_get(state.scratch.FIELD, dst_id)     \
0066                 = fast_get(state.data.FIELD, src_id); \
0067         }                                             \
0068     } while (0)
0069 
0070     DS_COPY_IF_SELECTED(detector);
0071     DS_COPY_IF_SELECTED(track_id);
0072 
0073     for (auto sp : range(StepPoint::size_))
0074     {
0075         DS_COPY_IF_SELECTED(points[sp].time);
0076         DS_COPY_IF_SELECTED(points[sp].pos);
0077         DS_COPY_IF_SELECTED(points[sp].dir);
0078         DS_COPY_IF_SELECTED(points[sp].energy);
0079 
0080         if (auto const& data_vids = state.data.points[sp].volume_instance_ids;
0081             !data_vids.empty())
0082         {
0083             auto& scratch_vids = state.scratch.points[sp].volume_instance_ids;
0084             for (auto i : range(state.volume_instance_depth))
0085             {
0086                 using ViId = ItemId<VolumeInstanceId>;
0087 
0088                 ViId dst_vi_id{
0089                     dst_id.unchecked_get() * state.volume_instance_depth + i};
0090                 ViId src_vi_id{
0091                     src_id.unchecked_get() * state.volume_instance_depth + i};
0092                 fast_get(scratch_vids, dst_vi_id)
0093                     = fast_get(data_vids, src_vi_id);
0094             }
0095         }
0096     }
0097 
0098     DS_COPY_IF_SELECTED(event_id);
0099     DS_COPY_IF_SELECTED(parent_id);
0100     DS_COPY_IF_SELECTED(track_step_count);
0101     DS_COPY_IF_SELECTED(step_length);
0102     DS_COPY_IF_SELECTED(particle);
0103     DS_COPY_IF_SELECTED(energy_deposition);
0104 #undef DS_COPY_IF_SELECTED
0105 }
0106 
0107 //---------------------------------------------------------------------------//
0108 }  // namespace detail
0109 }  // namespace celeritas