Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 08:55:04

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(std::is_trivially_copyable<T>::value,
0036                   "Data is not trivially copyable");
0037 
0038   public:
0039     //! Construct with the destination and the class's memspace
0040     explicit Copier(Span<T> dst) : dst_{dst} {}
0041 
0042     //! Also construct with a stream ID to use for async copy
0043     Copier(Span<T> dst, StreamId stream) : dst_{dst}, stream_{stream} {}
0044 
0045     inline void operator()(MemSpace srcmem, Span<T const> src) const;
0046 
0047   private:
0048     Span<T> dst_;
0049     StreamId stream_;
0050     static constexpr auto dstmem = M;
0051 };
0052 
0053 //---------------------------------------------------------------------------//
0054 /*!
0055  * Copy a single value from device to host.
0056  *
0057  * The source of the data to copy is the function argument.
0058  */
0059 template<class T>
0060 class ItemCopier
0061 {
0062     static_assert(std::is_trivially_copyable<T>::value,
0063                   "Data is not trivially copyable");
0064 
0065   public:
0066     //! Default constructor
0067     ItemCopier() = default;
0068 
0069     //! Also construct with a stream ID to use for async copy
0070     explicit ItemCopier(StreamId stream) : stream_{stream} {}
0071 
0072     inline T operator()(T const* src) const;
0073 
0074   private:
0075     StreamId stream_;
0076 };
0077 
0078 //---------------------------------------------------------------------------//
0079 // Copy bytes between two memory spaces
0080 void copy_bytes(MemSpace dstmem,
0081                 void* dst,
0082                 MemSpace srcmem,
0083                 void const* src,
0084                 std::size_t count);
0085 
0086 // Asynchronously copy bytes between two memory spaces
0087 void copy_bytes(MemSpace dstmem,
0088                 void* dst,
0089                 MemSpace srcmem,
0090                 void const* src,
0091                 std::size_t count,
0092                 StreamId stream);
0093 
0094 //---------------------------------------------------------------------------//
0095 /*!
0096  * Copy data from the given source and memory space.
0097  */
0098 template<class T, MemSpace M>
0099 void Copier<T, M>::operator()(MemSpace srcmem, Span<T const> src) const
0100 {
0101     CELER_EXPECT(src.size() == dst_.size());
0102     if (stream_)
0103     {
0104         copy_bytes(dstmem,
0105                    dst_.data(),
0106                    srcmem,
0107                    src.data(),
0108                    src.size() * sizeof(T),
0109                    stream_);
0110     }
0111     else
0112     {
0113         copy_bytes(
0114             dstmem, dst_.data(), srcmem, src.data(), src.size() * sizeof(T));
0115     }
0116 }
0117 
0118 //---------------------------------------------------------------------------//
0119 /*!
0120  * Copy a value from device to host.
0121  */
0122 template<class T>
0123 T ItemCopier<T>::operator()(T const* src) const
0124 {
0125     T dst;
0126     if (stream_)
0127     {
0128         copy_bytes(
0129             MemSpace::host, &dst, MemSpace::device, src, sizeof(T), stream_);
0130     }
0131     else
0132     {
0133         copy_bytes(MemSpace::host, &dst, MemSpace::device, src, sizeof(T));
0134     }
0135     return dst;
0136 }
0137 
0138 //---------------------------------------------------------------------------//
0139 }  // namespace celeritas