Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-08 23:51:35

0001 #ifndef DataFormats_Portable_interface_PortableHostObject_h
0002 #define DataFormats_Portable_interface_PortableHostObject_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/host.h"
0012 #include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
0013 
0014 // generic object in host memory
0015 template <typename T>
0016 class PortableHostObject {
0017 public:
0018   using Product = T;
0019   using Buffer = cms::alpakatools::host_buffer<Product>;
0020   using ConstBuffer = cms::alpakatools::const_host_buffer<Product>;
0021 
0022   PortableHostObject() = default;
0023 
0024   PortableHostObject(alpaka_common::DevHost const& host)
0025       // allocate pageable host memory
0026       : buffer_{cms::alpakatools::make_host_buffer<Product>()}, product_{buffer_->data()} {
0027     assert(reinterpret_cast<uintptr_t>(product_) % alignof(Product) == 0);
0028   }
0029 
0030   template <typename TQueue, typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
0031   PortableHostObject(TQueue const& queue)
0032       // allocate pinned host memory associated to the given work queue, accessible by the queue's device
0033       : buffer_{cms::alpakatools::make_host_buffer<Product>(queue)}, product_{buffer_->data()} {
0034     assert(reinterpret_cast<uintptr_t>(product_) % alignof(Product) == 0);
0035   }
0036 
0037   // non-copyable
0038   PortableHostObject(PortableHostObject const&) = delete;
0039   PortableHostObject& operator=(PortableHostObject const&) = delete;
0040 
0041   // movable
0042   PortableHostObject(PortableHostObject&&) = default;
0043   PortableHostObject& operator=(PortableHostObject&&) = default;
0044 
0045   // default destructor
0046   ~PortableHostObject() = default;
0047 
0048   // access the product
0049   Product& value() { return *product_; }
0050   Product const& value() const { return *product_; }
0051   Product const& const_value() const { return *product_; }
0052 
0053   Product* data() { return product_; }
0054   Product const* data() const { return product_; }
0055   Product const* const_data() const { return product_; }
0056 
0057   Product& operator*() { return *product_; }
0058   Product const& operator*() const { return *product_; }
0059 
0060   Product* operator->() { return product_; }
0061   Product const* operator->() const { return product_; }
0062 
0063   // access the buffer
0064   Buffer buffer() { return *buffer_; }
0065   ConstBuffer buffer() const { return *buffer_; }
0066   ConstBuffer const_buffer() const { return *buffer_; }
0067 
0068   // erases the data in the Buffer by writing zeros (bytes containing '\0') to it
0069   void zeroInitialise() {
0070     std::memset(std::data(*buffer_), 0x00, alpaka::getExtentProduct(*buffer_) * sizeof(std::byte));
0071   }
0072 
0073   template <typename TQueue, typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
0074   void zeroInitialise(TQueue&& queue) {
0075     alpaka::memset(std::forward<TQueue>(queue), *buffer_, 0x00);
0076   }
0077 
0078   // part of the ROOT read streamer
0079   static void ROOTReadStreamer(PortableHostObject* newObj, Product& product) {
0080     // destroy the default-constructed object
0081     newObj->~PortableHostObject();
0082     // use the global "host" object returned by cms::alpakatools::host()
0083     new (newObj) PortableHostObject(cms::alpakatools::host());
0084     // copy the data from the on-file object to the new one
0085     std::memcpy(newObj->product_, &product, sizeof(Product));
0086   }
0087 
0088 private:
0089   std::optional<Buffer> buffer_;  //!
0090   Product* product_;
0091 };
0092 
0093 #endif  // DataFormats_Portable_interface_PortableHostObject_h