File indexing completed on 2024-12-19 04:04:30
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 "DataFormats/Common/interface/Uninitialized.h"
0011 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
0012 #include "HeterogeneousCore/AlpakaInterface/interface/host.h"
0013 #include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
0014
0015
0016 template <typename T>
0017 class PortableHostObject {
0018 public:
0019 using Product = T;
0020 using Buffer = cms::alpakatools::host_buffer<Product>;
0021 using ConstBuffer = cms::alpakatools::const_host_buffer<Product>;
0022
0023 static_assert(std::is_trivially_destructible_v<Product>);
0024
0025 PortableHostObject() = delete;
0026
0027 PortableHostObject(edm::Uninitialized) noexcept {}
0028
0029
0030
0031 PortableHostObject(alpaka_common::DevHost const& host)
0032
0033 : buffer_{cms::alpakatools::make_host_buffer<Product>()}, product_{buffer_->data()} {
0034 assert(reinterpret_cast<uintptr_t>(product_) % alignof(Product) == 0);
0035 }
0036
0037 template <typename... Args>
0038 PortableHostObject(alpaka_common::DevHost const& host, Args&&... args)
0039
0040 : buffer_{cms::alpakatools::make_host_buffer<Product>()},
0041 product_{new(buffer_->data()) Product(std::forward<Args>(args)...)} {
0042 assert(reinterpret_cast<uintptr_t>(product_) % alignof(Product) == 0);
0043 }
0044
0045
0046
0047 template <typename TQueue, typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
0048 PortableHostObject(TQueue const& queue)
0049
0050 : buffer_{cms::alpakatools::make_host_buffer<Product>(queue)}, product_{buffer_->data()} {
0051 assert(reinterpret_cast<uintptr_t>(product_) % alignof(Product) == 0);
0052 }
0053
0054 template <typename TQueue, typename... Args, typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
0055 PortableHostObject(TQueue const& queue, Args&&... args)
0056
0057 : buffer_{cms::alpakatools::make_host_buffer<Product>(queue)},
0058 product_{new(buffer_->data()) Product(std::forward<Args>(args)...)} {
0059 assert(reinterpret_cast<uintptr_t>(product_) % alignof(Product) == 0);
0060 }
0061
0062
0063 PortableHostObject(PortableHostObject const&) = delete;
0064 PortableHostObject& operator=(PortableHostObject const&) = delete;
0065
0066
0067 PortableHostObject(PortableHostObject&&) = default;
0068 PortableHostObject& operator=(PortableHostObject&&) = default;
0069
0070
0071 ~PortableHostObject() = default;
0072
0073
0074 Product& value() { return *product_; }
0075 Product const& value() const { return *product_; }
0076 Product const& const_value() const { return *product_; }
0077
0078 Product* data() { return product_; }
0079 Product const* data() const { return product_; }
0080 Product const* const_data() const { return product_; }
0081
0082 Product& operator*() { return *product_; }
0083 Product const& operator*() const { return *product_; }
0084
0085 Product* operator->() { return product_; }
0086 Product const* operator->() const { return product_; }
0087
0088
0089 Buffer buffer() { return *buffer_; }
0090 ConstBuffer buffer() const { return *buffer_; }
0091 ConstBuffer const_buffer() const { return *buffer_; }
0092
0093
0094 void zeroInitialise() {
0095 std::memset(std::data(*buffer_), 0x00, alpaka::getExtentProduct(*buffer_) * sizeof(std::byte));
0096 }
0097
0098 template <typename TQueue, typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
0099 void zeroInitialise(TQueue&& queue) {
0100 alpaka::memset(std::forward<TQueue>(queue), *buffer_, 0x00);
0101 }
0102
0103
0104 static void ROOTReadStreamer(PortableHostObject* newObj, Product& product) {
0105
0106 newObj->~PortableHostObject();
0107
0108 new (newObj) PortableHostObject(cms::alpakatools::host());
0109
0110 std::memcpy(newObj->product_, &product, sizeof(Product));
0111 }
0112
0113 private:
0114 std::optional<Buffer> buffer_;
0115 Product* product_;
0116 };
0117
0118 #endif