Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:51:04

0001 #ifndef DataFormats_Portable_interface_PortableDeviceCollection_h
0002 #define DataFormats_Portable_interface_PortableDeviceCollection_h
0003 
0004 #include <cassert>
0005 #include <optional>
0006 #include <type_traits>
0007 
0008 #include <alpaka/alpaka.hpp>
0009 
0010 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
0011 #include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
0012 
0013 // generic SoA-based product in device memory
0014 template <typename T, typename TDev, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
0015 class PortableDeviceCollection {
0016   static_assert(not std::is_same_v<TDev, alpaka_common::DevHost>,
0017                 "Use PortableHostCollection<T> instead of PortableDeviceCollection<T, DevHost>");
0018 
0019 public:
0020   using Layout = T;
0021   using View = typename Layout::View;
0022   using ConstView = typename Layout::ConstView;
0023   using Buffer = cms::alpakatools::device_buffer<TDev, std::byte[]>;
0024   using ConstBuffer = cms::alpakatools::const_device_buffer<TDev, std::byte[]>;
0025 
0026   PortableDeviceCollection() = default;
0027 
0028   PortableDeviceCollection(int32_t elements, TDev const& device)
0029       : buffer_{cms::alpakatools::make_device_buffer<std::byte[]>(device, Layout::computeDataSize(elements))},
0030         layout_{buffer_->data(), elements},
0031         view_{layout_} {
0032     // Alpaka set to a default alignment of 128 bytes defining ALPAKA_DEFAULT_HOST_MEMORY_ALIGNMENT=128
0033     assert(reinterpret_cast<uintptr_t>(buffer_->data()) % Layout::alignment == 0);
0034   }
0035 
0036   template <typename TQueue, typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
0037   PortableDeviceCollection(int32_t elements, TQueue const& queue)
0038       : buffer_{cms::alpakatools::make_device_buffer<std::byte[]>(queue, Layout::computeDataSize(elements))},
0039         layout_{buffer_->data(), elements},
0040         view_{layout_} {
0041     // Alpaka set to a default alignment of 128 bytes defining ALPAKA_DEFAULT_HOST_MEMORY_ALIGNMENT=128
0042     assert(reinterpret_cast<uintptr_t>(buffer_->data()) % Layout::alignment == 0);
0043   }
0044 
0045   // non-copyable
0046   PortableDeviceCollection(PortableDeviceCollection const&) = delete;
0047   PortableDeviceCollection& operator=(PortableDeviceCollection const&) = delete;
0048 
0049   // movable
0050   PortableDeviceCollection(PortableDeviceCollection&&) = default;
0051   PortableDeviceCollection& operator=(PortableDeviceCollection&&) = default;
0052 
0053   // default destructor
0054   ~PortableDeviceCollection() = default;
0055 
0056   // access the View
0057   View& view() { return view_; }
0058   ConstView const& view() const { return view_; }
0059   ConstView const& const_view() const { return view_; }
0060 
0061   View& operator*() { return view_; }
0062   ConstView const& operator*() const { return view_; }
0063 
0064   View* operator->() { return &view_; }
0065   ConstView const* operator->() const { return &view_; }
0066 
0067   // access the Buffer
0068   Buffer buffer() { return *buffer_; }
0069   ConstBuffer buffer() const { return *buffer_; }
0070   ConstBuffer const_buffer() const { return *buffer_; }
0071 
0072 private:
0073   std::optional<Buffer> buffer_;  //!
0074   Layout layout_;                 //
0075   View view_;                     //!
0076 };
0077 
0078 #endif  // DataFormats_Portable_interface_PortableDeviceCollection_h