Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-09-11 22:29:16

0001 #ifndef CUDADataFormats_Common_interface_PortableHostCollection_h
0002 #define CUDADataFormats_Common_interface_PortableHostCollection_h
0003 
0004 #include <cassert>
0005 #include <cstdlib>
0006 
0007 #include "HeterogeneousCore/CUDAUtilities/interface/host_unique_ptr.h"
0008 
0009 namespace cms::cuda {
0010 
0011   // generic SoA-based product in host memory
0012   template <typename T>
0013   class PortableHostCollection {
0014   public:
0015     using Layout = T;
0016     using View = typename Layout::View;
0017     using ConstView = typename Layout::ConstView;
0018     using Buffer = cms::cuda::host::unique_ptr<std::byte[]>;
0019 
0020     PortableHostCollection() = default;
0021 
0022     PortableHostCollection(int32_t elements)
0023         // allocate pageable host memory
0024         : buffer_{cms::cuda::make_host_unique<std::byte[]>(Layout::computeDataSize(elements))},
0025           layout_{buffer_.get(), elements},
0026           view_{layout_} {
0027       // make_host_unique for pageable host memory uses a default alignment of 128 bytes
0028       assert(reinterpret_cast<uintptr_t>(buffer_.get()) % Layout::alignment == 0);
0029     }
0030 
0031     PortableHostCollection(int32_t elements, cudaStream_t stream)
0032         // allocate pinned host memory, accessible by the current device
0033         : buffer_{cms::cuda::make_host_unique<std::byte[]>(Layout::computeDataSize(elements), stream)},
0034           layout_{buffer_.get(), elements},
0035           view_{layout_} {
0036       // CUDA pinned host memory uses a default alignment of at least 128 bytes
0037       assert(reinterpret_cast<uintptr_t>(buffer_.get()) % Layout::alignment == 0);
0038     }
0039 
0040     // non-copyable
0041     PortableHostCollection(PortableHostCollection const&) = delete;
0042     PortableHostCollection& operator=(PortableHostCollection const&) = delete;
0043 
0044     // movable
0045     PortableHostCollection(PortableHostCollection&&) = default;
0046     PortableHostCollection& operator=(PortableHostCollection&&) = default;
0047 
0048     // default destructor
0049     ~PortableHostCollection() = default;
0050 
0051     // access the View
0052     View& view() { return view_; }
0053     ConstView const& view() const { return view_; }
0054     ConstView const& const_view() const { return view_; }
0055 
0056     View& operator*() { return view_; }
0057     ConstView const& operator*() const { return view_; }
0058 
0059     View* operator->() { return &view_; }
0060     ConstView const* operator->() const { return &view_; }
0061 
0062     // access the Buffer
0063     Buffer& buffer() { return buffer_; }
0064     Buffer const& buffer() const { return buffer_; }
0065     Buffer const& const_buffer() const { return buffer_; }
0066 
0067     size_t bufferSize() const { return layout_.metadata().byteSize(); }
0068 
0069     // part of the ROOT read streamer
0070     static void ROOTReadStreamer(PortableHostCollection* newObj, Layout const& layout) {
0071       newObj->~PortableHostCollection();
0072       // allocate pinned host memory using the legacy stream, that synchronises with all (blocking) streams
0073       new (newObj) PortableHostCollection(layout.metadata().size());
0074       newObj->layout_.ROOTReadStreamer(layout);
0075     }
0076 
0077   private:
0078     Buffer buffer_;  //!
0079     Layout layout_;  //
0080     View view_;      //!
0081   };
0082 
0083 }  // namespace cms::cuda
0084 
0085 #endif  // CUDADataFormats_Common_interface_PortableHostCollection_h