Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:54:10

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/sys/Stream.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <cstddef>
0010 #include <memory>
0011 
0012 #include "corecel/Config.hh"
0013 
0014 #include "corecel/Macros.hh"  // IWYU pragma: keep
0015 
0016 #if CELER_DEVICE_SOURCE
0017 #    include "corecel/DeviceRuntimeApi.hh"
0018 #endif
0019 
0020 #if CELERITAS_USE_CUDA
0021 #    define CELER_STREAM_SUPPORTS_ASYNC 1
0022 #elif CELERITAS_USE_HIP       \
0023     && (HIP_VERSION_MAJOR > 5 \
0024         || (HIP_VERSION_MAJOR == 5 && HIP_VERSION_MINOR >= 2))
0025 #    define CELER_STREAM_SUPPORTS_ASYNC 1
0026 #else
0027 //! Whether CUDA/HIP is enabled and new enough to support async operations
0028 #    define CELER_STREAM_SUPPORTS_ASYNC 0
0029 #endif
0030 
0031 namespace celeritas
0032 {
0033 //---------------------------------------------------------------------------//
0034 namespace detail
0035 {
0036 class AsyncMemoryResource;
0037 }
0038 
0039 //---------------------------------------------------------------------------//
0040 /*!
0041  * PIMPL class for CUDA or HIP stream.
0042  *
0043  * This creates/destroys a stream on construction/destruction and provides
0044  * accessors to low-level stream-related functionality. This class will
0045  * typically be accessed only by low-level device implementations or advanced
0046  * kernels that need to interact with the device stream.
0047  *
0048  * \warning This class interface changes based on available headers.
0049  * Because the CUDA/HIP stream type are only defined when those paths are
0050  * included and available (which isn't true for all Celeritas code) we hide the
0051  * stream unless DeviceRuntimeApi has been included or the file is being
0052  * compiled by a CUDA/HIP compiler. Worse, our stream class has to manage a
0053  * Thrust memory resource, and in newer versions of rocthrust, its headers
0054  * cannot be included at all by a non-HIP compiler. Because this class forward
0055  * declares the memory resource, downstream uses must include \c
0056  * corecel/sys/detail/AsyncMemoryResource.device.hh .
0057  */
0058 class Stream
0059 {
0060   public:
0061     //!@{
0062     //! \name Type aliases
0063 #ifdef CELER_DEVICE_RUNTIME_INCLUDED
0064     using StreamT = CELER_DEVICE_API_SYMBOL(Stream_t);
0065 #else
0066     using MissingDeviceRuntime = void;
0067 #endif
0068     using ResourceT = detail::AsyncMemoryResource;
0069     //!@}
0070 
0071   public:
0072     // Construct by creating a stream
0073     Stream();
0074     CELER_DEFAULT_MOVE_DELETE_COPY(Stream);
0075     ~Stream() = default;
0076 
0077 #ifdef CELER_DEVICE_RUNTIME_INCLUDED
0078     // Access the stream
0079     StreamT get() const;
0080 #else
0081     // Since CUDA/HIP declarations are unavailable, this function cannot be
0082     // used. Include "corecel/DeviceRuntimeApi.hh" to fix.
0083     MissingDeviceRuntime get() const {}
0084 #endif
0085 
0086     // Access the thrust resource allocator associated with the stream
0087     ResourceT& memory_resource();
0088 
0089     // Synchronize this stream
0090     void sync() const;
0091 
0092     // Allocate memory asynchronously on this stream if possible
0093     void* malloc_async(std::size_t bytes) const;
0094 
0095     // Free memory asynchronously on this stream if possible
0096     void free_async(void* ptr) const;
0097 
0098   private:
0099     struct Impl;
0100     struct ImplDeleter
0101     {
0102         void operator()(Impl*) noexcept;
0103     };
0104     std::unique_ptr<Impl, ImplDeleter> impl_;
0105 };
0106 
0107 //---------------------------------------------------------------------------//
0108 #if !CELER_USE_DEVICE
0109 inline Stream::Stream()
0110 {
0111     CELER_NOT_CONFIGURED("CUDA OR HIP");
0112 }
0113 
0114 #    ifdef CELER_DEVICE_RUNTIME_INCLUDED
0115 inline Stream::StreamT Stream::get() const
0116 {
0117     CELER_ASSERT_UNREACHABLE();
0118 }
0119 #    endif
0120 
0121 inline Stream::ResourceT& Stream::memory_resource()
0122 {
0123     CELER_ASSERT_UNREACHABLE();
0124 }
0125 
0126 inline void Stream::sync() const
0127 {
0128     CELER_ASSERT_UNREACHABLE();
0129 }
0130 inline void* Stream::malloc_async(std::size_t) const
0131 {
0132     CELER_ASSERT_UNREACHABLE();
0133 }
0134 
0135 inline void Stream::free_async(void*) const
0136 {
0137     CELER_ASSERT_UNREACHABLE();
0138 }
0139 
0140 inline void Stream::ImplDeleter::operator()(Impl*) noexcept
0141 {
0142     CELER_UNREACHABLE;
0143 }
0144 
0145 #endif
0146 //---------------------------------------------------------------------------//
0147 }  // namespace celeritas