File indexing completed on 2024-09-08 23:51:35
0001 #ifndef DataFormats_Portable_interface_PortableHostCollection_h
0002 #define DataFormats_Portable_interface_PortableHostCollection_h
0003
0004 #include <cassert>
0005 #include <optional>
0006
0007 #include <alpaka/alpaka.hpp>
0008
0009 #include "HeterogeneousCore/AlpakaInterface/interface/config.h"
0010 #include "HeterogeneousCore/AlpakaInterface/interface/host.h"
0011 #include "HeterogeneousCore/AlpakaInterface/interface/memory.h"
0012 #include "DataFormats/Portable/interface/PortableCollectionCommon.h"
0013
0014
0015 template <typename T>
0016 class PortableHostCollection {
0017 public:
0018 using Layout = T;
0019 using View = typename Layout::View;
0020 using ConstView = typename Layout::ConstView;
0021 using Buffer = cms::alpakatools::host_buffer<std::byte[]>;
0022 using ConstBuffer = cms::alpakatools::const_host_buffer<std::byte[]>;
0023
0024 PortableHostCollection() = default;
0025
0026 PortableHostCollection(int32_t elements, alpaka_common::DevHost const& host)
0027
0028 : buffer_{cms::alpakatools::make_host_buffer<std::byte[]>(Layout::computeDataSize(elements))},
0029 layout_{buffer_->data(), elements},
0030 view_{layout_} {
0031
0032 assert(reinterpret_cast<uintptr_t>(buffer_->data()) % Layout::alignment == 0);
0033 }
0034
0035 template <typename TQueue, typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
0036 PortableHostCollection(int32_t elements, TQueue const& queue)
0037
0038 : buffer_{cms::alpakatools::make_host_buffer<std::byte[]>(queue, Layout::computeDataSize(elements))},
0039 layout_{buffer_->data(), elements},
0040 view_{layout_} {
0041
0042 assert(reinterpret_cast<uintptr_t>(buffer_->data()) % Layout::alignment == 0);
0043 }
0044
0045
0046 PortableHostCollection(PortableHostCollection const&) = delete;
0047 PortableHostCollection& operator=(PortableHostCollection const&) = delete;
0048
0049
0050 PortableHostCollection(PortableHostCollection&&) = default;
0051 PortableHostCollection& operator=(PortableHostCollection&&) = default;
0052
0053
0054 ~PortableHostCollection() = default;
0055
0056
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
0068 Buffer buffer() { return *buffer_; }
0069 ConstBuffer buffer() const { return *buffer_; }
0070 ConstBuffer const_buffer() const { return *buffer_; }
0071
0072
0073 void zeroInitialise() {
0074 std::memset(std::data(*buffer_), 0x00, alpaka::getExtentProduct(*buffer_) * sizeof(std::byte));
0075 }
0076
0077 template <typename TQueue, typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
0078 void zeroInitialise(TQueue&& queue) {
0079 alpaka::memset(std::forward<TQueue>(queue), *buffer_, 0x00);
0080 }
0081
0082
0083 static void ROOTReadStreamer(PortableHostCollection* newObj, Layout& layout) {
0084
0085 newObj->~PortableHostCollection();
0086
0087 new (newObj) PortableHostCollection(layout.metadata().size(), cms::alpakatools::host());
0088
0089 newObj->layout_.ROOTReadStreamer(layout);
0090
0091 layout.ROOTStreamerCleaner();
0092 }
0093
0094 private:
0095 std::optional<Buffer> buffer_;
0096 Layout layout_;
0097 View view_;
0098 };
0099
0100
0101 template <typename T0, typename... Args>
0102 class PortableHostMultiCollection {
0103 template <typename T>
0104 static constexpr std::size_t count_t_ = portablecollection::typeCount<T, T0, Args...>;
0105
0106 template <typename T>
0107 static constexpr std::size_t index_t_ = portablecollection::typeIndex<T, T0, Args...>;
0108
0109 static constexpr std::size_t members_ = portablecollection::membersCount<T0, Args...>;
0110
0111 public:
0112 using Buffer = cms::alpakatools::host_buffer<std::byte[]>;
0113 using ConstBuffer = cms::alpakatools::const_host_buffer<std::byte[]>;
0114 using Implementation = portablecollection::CollectionImpl<0, T0, Args...>;
0115
0116 using SizesArray = std::array<int32_t, members_>;
0117
0118 template <std::size_t Idx = 0, typename = std::enable_if_t<(members_ > Idx)>>
0119 using Layout = portablecollection::TypeResolver<Idx, T0, Args...>;
0120 template <std::size_t Idx = 0, typename = std::enable_if_t<(members_ > Idx)>>
0121 using View = typename Layout<Idx>::View;
0122 template <std::size_t Idx = 0, typename = std::enable_if_t<(members_ > Idx)>>
0123 using ConstView = typename Layout<Idx>::ConstView;
0124
0125 private:
0126 template <std::size_t Idx>
0127 using Leaf = portablecollection::CollectionLeaf<Idx, Layout<Idx>>;
0128
0129 template <std::size_t Idx>
0130 Leaf<Idx>& get() {
0131 return static_cast<Leaf<Idx>&>(impl_);
0132 }
0133
0134 template <std::size_t Idx>
0135 Leaf<Idx> const& get() const {
0136 return static_cast<Leaf<Idx> const&>(impl_);
0137 }
0138
0139 template <typename T>
0140 portablecollection::CollectionLeaf<index_t_<T>, T>& get() {
0141 return static_cast<portablecollection::CollectionLeaf<index_t_<T>, T>&>(impl_);
0142 }
0143
0144 template <typename T>
0145 const portablecollection::CollectionLeaf<index_t_<T>, T>& get() const {
0146 return static_cast<const portablecollection::CollectionLeaf<index_t_<T>, T>&>(impl_);
0147 }
0148
0149 static int32_t computeDataSize(const std::array<int32_t, members_>& sizes) {
0150 int32_t ret = 0;
0151 portablecollection::constexpr_for<0, members_>(
0152 [&sizes, &ret](auto i) { ret += Layout<i>::computeDataSize(sizes[i]); });
0153 return ret;
0154 }
0155
0156 public:
0157 PortableHostMultiCollection() = default;
0158
0159 PortableHostMultiCollection(int32_t elements, alpaka_common::DevHost const& host)
0160
0161 : buffer_{cms::alpakatools::make_host_buffer<std::byte[]>(Layout<>::computeDataSize(elements))},
0162 impl_{buffer_->data(), elements} {
0163
0164 assert(reinterpret_cast<uintptr_t>(buffer_->data()) % Layout<>::alignment == 0);
0165 static_assert(members_ == 1);
0166 }
0167
0168 template <typename TQueue, typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
0169 PortableHostMultiCollection(int32_t elements, TQueue const& queue)
0170
0171 : buffer_{cms::alpakatools::make_host_buffer<std::byte[]>(queue, Layout<>::computeDataSize(elements))},
0172 impl_{buffer_->data(), elements} {
0173
0174 assert(reinterpret_cast<uintptr_t>(buffer_->data()) % Layout<>::alignment == 0);
0175 static_assert(members_ == 1);
0176 }
0177
0178 PortableHostMultiCollection(const std::array<int32_t, members_>& sizes, alpaka_common::DevHost const& host)
0179
0180 : buffer_{cms::alpakatools::make_host_buffer<std::byte[]>(computeDataSize(sizes))},
0181 impl_{buffer_->data(), sizes} {
0182
0183 portablecollection::constexpr_for<0, members_>(
0184 [&](auto i) { assert(reinterpret_cast<uintptr_t>(buffer_->data()) % Layout<i>::alignment == 0); });
0185 constexpr auto alignment = Layout<0>::alignment;
0186 portablecollection::constexpr_for<1, members_>(
0187 [&alignment](auto i) { static_assert(alignment == Layout<i>::alignment); });
0188 }
0189
0190 template <typename TQueue, typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
0191 PortableHostMultiCollection(const std::array<int32_t, members_>& sizes, TQueue const& queue)
0192
0193 : buffer_{cms::alpakatools::make_host_buffer<std::byte[]>(queue, computeDataSize(sizes))},
0194 impl_{buffer_->data(), sizes} {
0195
0196 portablecollection::constexpr_for<0, members_>(
0197 [&](auto i) { assert(reinterpret_cast<uintptr_t>(buffer_->data()) % Layout<i>::alignment == 0); });
0198 constexpr auto alignment = Layout<0>::alignment;
0199 portablecollection::constexpr_for<1, members_>(
0200 [&alignment](auto i) { static_assert(alignment == Layout<i>::alignment); });
0201 }
0202
0203
0204 PortableHostMultiCollection(PortableHostMultiCollection const&) = delete;
0205 PortableHostMultiCollection& operator=(PortableHostMultiCollection const&) = delete;
0206
0207
0208 PortableHostMultiCollection(PortableHostMultiCollection&&) = default;
0209 PortableHostMultiCollection& operator=(PortableHostMultiCollection&&) = default;
0210
0211
0212 ~PortableHostMultiCollection() = default;
0213
0214
0215 template <std::size_t Idx = 0, typename = std::enable_if_t<(members_ > Idx)>>
0216 View<Idx>& view() {
0217 return get<Idx>().view_;
0218 }
0219
0220 template <std::size_t Idx = 0, typename = std::enable_if_t<(members_ > Idx)>>
0221 ConstView<Idx> const& view() const {
0222 return get<Idx>().view_;
0223 }
0224
0225 template <std::size_t Idx = 0, typename = std::enable_if_t<(members_ > Idx)>>
0226 ConstView<Idx> const& const_view() const {
0227 return get<Idx>().view_;
0228 }
0229
0230 template <std::size_t Idx = 0, typename = std::enable_if_t<(members_ > Idx)>>
0231 View<Idx>& operator*() {
0232 return get<Idx>().view_;
0233 }
0234
0235 template <std::size_t Idx = 0, typename = std::enable_if_t<(members_ > Idx)>>
0236 ConstView<Idx> const& operator*() const {
0237 return get<Idx>().view_;
0238 }
0239
0240 template <std::size_t Idx = 0, typename = std::enable_if_t<(members_ > Idx)>>
0241 View<Idx>* operator->() {
0242 return &get<Idx>().view_;
0243 }
0244
0245 template <std::size_t Idx = 0, typename = std::enable_if_t<(members_ > Idx)>>
0246 ConstView<Idx> const* operator->() const {
0247 return &get<Idx>().view_;
0248 }
0249
0250
0251 template <typename T>
0252 typename T::View& view() {
0253 return get<T>().view_;
0254 }
0255
0256 template <typename T>
0257 typename T::ConstView const& view() const {
0258 return get<T>().view_;
0259 }
0260
0261 template <typename T>
0262 typename T::ConstView const& const_view() const {
0263 return get<T>().view_;
0264 }
0265
0266 template <typename T>
0267 typename T::View& operator*() {
0268 return get<T>().view_;
0269 }
0270
0271 template <typename T>
0272 typename T::ConstView const& operator*() const {
0273 return get<T>().view_;
0274 }
0275
0276 template <typename T>
0277 typename T::View* operator->() {
0278 return &get<T>().view_;
0279 }
0280
0281 template <typename T>
0282 typename T::ConstView const* operator->() const {
0283 return &get<T>().view_;
0284 }
0285
0286
0287 Buffer buffer() { return *buffer_; }
0288 ConstBuffer buffer() const { return *buffer_; }
0289 ConstBuffer const_buffer() const { return *buffer_; }
0290
0291
0292 void zeroInitialise() {
0293 std::memset(std::data(*buffer_), 0x00, alpaka::getExtentProduct(*buffer_) * sizeof(std::byte));
0294 }
0295
0296 template <typename TQueue, typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
0297 void zeroInitialise(TQueue&& queue) {
0298 alpaka::memset(std::forward<TQueue>(queue), *buffer_, 0x00);
0299 }
0300
0301
0302 SizesArray sizes() const {
0303 SizesArray ret;
0304 portablecollection::constexpr_for<0, members_>([&](auto i) { ret[i] = get<i>().layout_.metadata().size(); });
0305 return ret;
0306 }
0307
0308
0309 static void ROOTReadStreamer(PortableHostMultiCollection* newObj, Implementation& onfileImpl) {
0310 newObj->~PortableHostMultiCollection();
0311
0312 std::array<int32_t, members_> sizes;
0313 portablecollection::constexpr_for<0, members_>([&sizes, &onfileImpl](auto i) {
0314 sizes[i] = static_cast<Leaf<i> const&>(onfileImpl).layout_.metadata().size();
0315 });
0316 new (newObj) PortableHostMultiCollection(sizes, cms::alpakatools::host());
0317 portablecollection::constexpr_for<0, members_>([&newObj, &onfileImpl](auto i) {
0318 static_cast<Leaf<i>&>(newObj->impl_).layout_.ROOTReadStreamer(static_cast<Leaf<i> const&>(onfileImpl).layout_);
0319 static_cast<Leaf<i>&>(onfileImpl).layout_.ROOTStreamerCleaner();
0320 });
0321 }
0322
0323 private:
0324 std::optional<Buffer> buffer_;
0325 Implementation impl_;
0326 };
0327
0328
0329
0330
0331 template <typename T0, typename T1>
0332 using PortableHostCollection2 = ::PortableHostMultiCollection<T0, T1>;
0333
0334 template <typename T0, typename T1, typename T2>
0335 using PortableHostCollection3 = ::PortableHostMultiCollection<T0, T1, T2>;
0336
0337 template <typename T0, typename T1, typename T2, typename T3>
0338 using PortableHostCollection4 = ::PortableHostMultiCollection<T0, T1, T2, T3>;
0339
0340 template <typename T0, typename T1, typename T2, typename T3, typename T4>
0341 using PortableHostCollection5 = ::PortableHostMultiCollection<T0, T1, T2, T3, T4>;
0342
0343 #endif