Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-10-26 09:34:32

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 corecel/cont/LdgSpan.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <cstddef>
0010 #include <type_traits>
0011 
0012 #include "corecel/Types.hh"
0013 
0014 #include "Span.hh"
0015 
0016 #include "detail/LdgSpanImpl.hh"
0017 
0018 namespace celeritas
0019 {
0020 //---------------------------------------------------------------------------//
0021 /*!
0022  * Alias for a Span iterating over device const values read using \c ldg .
0023  *
0024  * This instantiates \c Span with a special wrapper class to optimize constant
0025  * data access in global device memory. In that case, data returned by \c
0026  * front, \c back, \c operator[] and \c begin / \c end iterators use value
0027  * semantics instead of reference.
0028  */
0029 template<class T, std::size_t Extent = dynamic_extent>
0030 using LdgSpan = Span<detail::LdgWrapper<T>, Extent>;
0031 
0032 //---------------------------------------------------------------------------//
0033 /*!
0034  * An LdgSpan when referencing compatible types, or Span otherwise.
0035  *
0036  * Note that T must be const.
0037  */
0038 template<class T, std::size_t Extent = dynamic_extent>
0039 using AutoLdgSpan
0040     = Span<std::conditional_t<is_auto_ldg_v<std::remove_const_t<T>>,
0041                               detail::LdgWrapper<T>,
0042                               T>,
0043            Extent>;
0044 
0045 //---------------------------------------------------------------------------//
0046 /*!
0047  * Construct an array from a fixed-size LdgSpan.
0048  *
0049  * Note: \code to_array(Span<T,N> const&) \endcode is not reused because:
0050  * 1. Using this overload reads input data using \c ldg
0051  * 2. \code return to_array<T, N>(s) \endcode results in segfault (gcc 11.3).
0052  *    This might be a compiler bug because temporary lifetime should be
0053  *    extended until the end of the expression and we return a copy...
0054  */
0055 template<class T, std::size_t N>
0056 CELER_CONSTEXPR_FUNCTION auto to_array(Span<detail::LdgWrapper<T const>, N> s)
0057 {
0058     Array<std::remove_cv_t<T>, N> result{};
0059     for (std::size_t i = 0; i < N; ++i)
0060     {
0061         result[i] = s[i];
0062     }
0063     return result;
0064 }
0065 
0066 //---------------------------------------------------------------------------//
0067 //! Make an LdgSpan directly from a container, primarily for testing
0068 template<class T>
0069 CELER_CONSTEXPR_FUNCTION auto make_ldg_span(T const& cont)
0070 {
0071     using pointer_type = decltype(cont.data());
0072     using value_type = std::add_const_t<std::remove_pointer_t<pointer_type>>;
0073     return LdgSpan<value_type>{cont.data(), cont.size()};
0074 }
0075 
0076 //! Make an LdgSpan directly from a C array, primarily for testing
0077 template<class T, std::size_t N>
0078 CELER_CONSTEXPR_FUNCTION LdgSpan<T const, N> make_ldg_span(T const (&arr)[N])
0079 {
0080     return {arr, N};
0081 }
0082 
0083 //---------------------------------------------------------------------------//
0084 //! Convert an LdgSpan to a regular Span, \em not using \c ldg
0085 template<class T, std::size_t N>
0086 CELER_CONSTEXPR_FUNCTION Span<T const, N> remove_ldg_wrapper(
0087     Span<detail::LdgWrapper<T const>, N> cont)
0088 {
0089     return {cont.data(), cont.size()};
0090 }
0091 
0092 //! Convert an LdgSpan to a regular Span, \em not using \c ldg
0093 template<class T, std::size_t N>
0094 CELER_CONSTEXPR_FUNCTION Span<T const, N> remove_ldg_wrapper(
0095     Span<T const, N> cont)
0096 {
0097     return cont;
0098 }
0099 
0100 //---------------------------------------------------------------------------//
0101 }  // namespace celeritas