File indexing completed on 2026-01-10 10:05:47
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Macros.hh"
0010 #include "corecel/Types.hh"
0011 #include "corecel/math/Algorithms.hh"
0012 #include "celeritas/optical/CoreTrackView.hh"
0013 #include "celeritas/optical/MaterialData.hh"
0014 #include "celeritas/track/CoreStateCounters.hh"
0015 #include "celeritas/track/detail/Utils.hh"
0016
0017 #include "GeneratorTraits.hh"
0018 #include "OpticalGenAlgorithms.hh"
0019 #include "../OffloadData.hh"
0020
0021 namespace celeritas
0022 {
0023 namespace detail
0024 {
0025
0026
0027
0028
0029
0030
0031 template<GeneratorType G>
0032 struct GeneratorExecutor
0033 {
0034
0035
0036 template<Ownership W, MemSpace M>
0037 using Data = typename GeneratorTraits<G>::template Data<W, M>;
0038 using Generator = typename GeneratorTraits<G>::Generator;
0039
0040
0041
0042 CRefPtr<celeritas::optical::CoreParamsData, MemSpace::native> params;
0043 RefPtr<celeritas::optical::CoreStateData, MemSpace::native> state;
0044 NativeCRef<celeritas::optical::MaterialParamsData> const material;
0045 NativeCRef<Data> const shared;
0046 NativeRef<GeneratorStateData> const offload;
0047 size_type buffer_size{};
0048 CoreStateCounters counters;
0049
0050
0051
0052
0053 inline CELER_FUNCTION void operator()(TrackSlotId tid) const;
0054 CELER_FORCEINLINE_FUNCTION void operator()(ThreadId tid) const
0055 {
0056 return (*this)(TrackSlotId{tid.unchecked_get()});
0057 }
0058 };
0059
0060
0061
0062
0063
0064
0065
0066 template<GeneratorType G>
0067 CELER_FUNCTION void GeneratorExecutor<G>::operator()(TrackSlotId tid) const
0068 {
0069 CELER_EXPECT(state);
0070 CELER_EXPECT(shared);
0071 CELER_EXPECT(material);
0072 CELER_EXPECT(offload);
0073
0074 using DistId = ItemId<GeneratorDistributionData>;
0075
0076 celeritas::optical::CoreTrackView track(*params, *state, tid);
0077
0078
0079
0080 auto all_offsets = offload.offsets[ItemRange<size_type>(
0081 ItemId<size_type>(0), ItemId<size_type>(buffer_size))];
0082 auto buffer_start = celeritas::upper_bound(
0083 all_offsets.begin(), all_offsets.end(), size_type(0));
0084 CELER_ASSERT(buffer_start != all_offsets.end());
0085
0086
0087
0088
0089 Span<size_type> offsets{buffer_start, all_offsets.end()};
0090
0091
0092 size_type dist_idx = find_distribution_index(offsets, tid.get());
0093 CELER_ASSERT(dist_idx < offload.distributions.size());
0094 auto const& dist = offload.distributions[DistId(dist_idx)];
0095 CELER_ASSERT(dist);
0096
0097
0098 celeritas::optical::CoreTrackView vacancy{
0099 *params, *state, [&] {
0100
0101
0102 TrackSlotId idx{
0103 index_before(counters.num_vacancies, ThreadId(tid.get()))};
0104 return state->init.vacancies[idx];
0105 }()};
0106
0107
0108 auto rng = track.rng();
0109 optical::MaterialView opt_mat{material, dist.material};
0110 vacancy = Generator(opt_mat, shared, dist)(rng);
0111 }
0112
0113
0114 }
0115 }