Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-01 10:04:13

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/data/Copier.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <cstddef>
0010 #include <type_traits>
0011 
0012 #include "corecel/Assert.hh"
0013 #include "corecel/Types.hh"
0014 #include "corecel/cont/Span.hh"
0015 #include "corecel/sys/ThreadId.hh"
0016 
0017 namespace celeritas
0018 {
0019 //---------------------------------------------------------------------------//
0020 /*!
0021  * Copy spans of data.
0022  *
0023  * The destination (which can be a reusable buffer) is the constructor
0024  * argument, and the source of the data to copy is the function argument.
0025  *
0026  * Example of copying data from device to host:
0027  * \code
0028     Copier<int, MemSpace::host> copy_to_host{host_ints};
0029     copy_to_host(MemSpace::device, device_ints);
0030  * \endcode
0031  */
0032 template<class T, MemSpace M>
0033 class Copier
0034 {
0035     static_assert(is_trivially_copyable_v<T>, "Data is not trivially copyable");
0036 
0037   public:
0038     //! Construct with the destination and the class's memspace
0039     explicit Copier(Span<T> dst) : dst_{dst} {}
0040 
0041     //! Also construct with a stream ID to use for async copy
0042     Copier(Span<T> dst, StreamId stream) : dst_{dst}, stream_{stream} {}
0043 
0044     inline void operator()(MemSpace srcmem, Span<T const> src) const;
0045 
0046   private:
0047     Span<T> dst_;
0048     StreamId stream_;
0049     static constexpr auto dstmem = M;
0050 };
0051 
0052 //---------------------------------------------------------------------------//
0053 /*!
0054  * Copy a single value from device to host.
0055  *
0056  * The source of the data to copy is the function argument.
0057  */
0058 template<class T>
0059 class ItemCopier
0060 {
0061     static_assert(is_trivially_copyable_v<T>, "Data is not trivially copyable");
0062 
0063   public:
0064     //! Default constructor
0065     ItemCopier() = default;
0066 
0067     //! Also construct with a stream ID to use for async copy
0068     explicit ItemCopier(StreamId stream) : stream_{stream} {}
0069 
0070     inline T operator()(T const* src) const;
0071 
0072   private:
0073     StreamId stream_;
0074 };
0075 
0076 //---------------------------------------------------------------------------//
0077 // Copy bytes between two memory spaces
0078 void copy_bytes(MemSpace dstmem,
0079                 void* dst,
0080                 MemSpace srcmem,
0081                 void const* src,
0082                 std::size_t count);
0083 
0084 // Asynchronously copy bytes between two memory spaces
0085 void copy_bytes(MemSpace dstmem,
0086                 void* dst,
0087                 MemSpace srcmem,
0088                 void const* src,
0089                 std::size_t count,
0090                 StreamId stream);
0091 
0092 //---------------------------------------------------------------------------//
0093 /*!
0094  * Copy data from the given source and memory space.
0095  */
0096 template<class T, MemSpace M>
0097 void Copier<T, M>::operator()(MemSpace srcmem, Span<T const> src) const
0098 {
0099     CELER_EXPECT(src.size() == dst_.size());
0100     if (stream_)
0101     {
0102         copy_bytes(dstmem,
0103                    dst_.data(),
0104                    srcmem,
0105                    src.data(),
0106                    src.size() * sizeof(T),
0107                    stream_);
0108     }
0109     else
0110     {
0111         copy_bytes(
0112             dstmem, dst_.data(), srcmem, src.data(), src.size() * sizeof(T));
0113     }
0114 }
0115 
0116 //---------------------------------------------------------------------------//
0117 /*!
0118  * Copy a value from device to host.
0119  */
0120 template<class T>
0121 T ItemCopier<T>::operator()(T const* src) const
0122 {
0123     T dst;
0124     if (stream_)
0125     {
0126         copy_bytes(
0127             MemSpace::host, &dst, MemSpace::device, src, sizeof(T), stream_);
0128     }
0129     else
0130     {
0131         copy_bytes(MemSpace::host, &dst, MemSpace::device, src, sizeof(T));
0132     }
0133     return dst;
0134 }
0135 
0136 //---------------------------------------------------------------------------//
0137 }  // namespace celeritas