Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE {
}

auto geom = iRecord.getTransientHandle(geometryToken_);
SiPixelMappingHost product(pixelgpudetails::MAX_SIZE, cms::alpakatools::host());
SiPixelMappingHost product(cms::alpakatools::host(), pixelgpudetails::MAX_SIZE);
std::vector<unsigned int> const& fedIds = cablingMap->fedIds();
std::unique_ptr<SiPixelFedCablingTree> const& cabling = cablingMap->cablingTree();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ namespace ALPAKA_ACCELERATOR_NAMESPACE {
auto const& gains = iRecord.get(gainsToken_);
auto const& geom = iRecord.get(geometryToken_);

auto product = std::make_unique<SiPixelGainCalibrationForHLTHost>(gains.data().size(), cms::alpakatools::host());
auto product = std::make_unique<SiPixelGainCalibrationForHLTHost>(cms::alpakatools::host(), gains.data().size());

// bizzarre logic (looking for fist strip-det) don't ask
auto const& dus = geom.detUnits();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ namespace hcal {
template <typename TDev>
class HcalRecoParamWithPulseShapeT {
public:
using RecoParamCollection = PortableCollection<HcalRecoParamSoA, TDev>;
using PulseShapeCollection = PortableCollection<HcalPulseShapeSoA, TDev>;
using RecoParamCollection = PortableCollection<TDev, HcalRecoParamSoA>;
using PulseShapeCollection = PortableCollection<TDev, HcalPulseShapeSoA>;

using PulseShapeConstElement = typename PulseShapeCollection::ConstView::const_element;

Expand All @@ -34,10 +34,10 @@ namespace hcal {
};

HcalRecoParamWithPulseShapeT(size_t recoSize, size_t pulseSize, TDev const& dev)
: recoParam_(recoSize, dev), pulseShape_(pulseSize, dev) {}
: recoParam_(dev, recoSize), pulseShape_(dev, pulseSize) {}
template <typename TQueue, typename = std::enable_if_t<alpaka::isQueue<TQueue>>>
HcalRecoParamWithPulseShapeT(size_t recoSize, size_t pulseSize, TQueue const& queue)
: recoParam_(recoSize, queue), pulseShape_(pulseSize, queue) {}
: recoParam_(queue, recoSize), pulseShape_(queue, pulseSize) {}
HcalRecoParamWithPulseShapeT(RecoParamCollection reco, PulseShapeCollection pulse)
: recoParam_(std::move(reco)), pulseShape_(std::move(pulse)) {}

Expand Down
38 changes: 10 additions & 28 deletions DataFormats/Portable/interface/PortableCollection.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,31 @@
namespace traits {

// trait for a generic SoA-based product
template <typename T, typename TDev, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
struct PortableCollectionTrait {
using CollectionType = PortableDeviceCollection<T, TDev>;
using CollectionType = PortableDeviceCollection<TDev, T>;
};

// specialise for host device
template <typename T>
struct PortableCollectionTrait<T, alpaka_common::DevHost> {
struct PortableCollectionTrait<alpaka_common::DevHost, T> {
using CollectionType = PortableHostCollection<T>;
};

} // namespace traits

// type alias for a generic SoA-based product
template <typename T, typename TDev, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
using PortableCollection = typename traits::PortableCollectionTrait<T, TDev>::CollectionType;
template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
using PortableCollection = typename traits::PortableCollectionTrait<TDev, T>::CollectionType;

// define how to copy PortableCollection between host and device
namespace cms::alpakatools {
template <typename TLayout, typename TDevice>
template <typename TDevice, typename TLayout>
requires alpaka::isDevice<TDevice>
struct CopyToHost<PortableDeviceCollection<TLayout, TDevice>> {
struct CopyToHost<PortableDeviceCollection<TDevice, TLayout>> {
template <typename TQueue>
requires alpaka::isQueue<TQueue> && (!portablecollection::hasBlocksNumber<TLayout>)
static auto copyAsync(TQueue& queue, PortableDeviceCollection<TLayout, TDevice> const& srcData) {
PortableHostCollection<TLayout> dstData(srcData->metadata().size(), queue);
alpaka::memcpy(queue, dstData.buffer(), srcData.buffer());
return dstData;
}

template <typename TQueue>
requires alpaka::isQueue<TQueue> && portablecollection::hasBlocksNumber<TLayout>
static auto copyAsync(TQueue& queue, PortableDeviceCollection<TLayout, TDevice> const& srcData) {
requires alpaka::isQueue<TQueue>
static auto copyAsync(TQueue& queue, PortableDeviceCollection<TDevice, TLayout> const& srcData) {
PortableHostCollection<TLayout> dstData(queue, srcData->metadata().size());
alpaka::memcpy(queue, dstData.buffer(), srcData.buffer());
return dstData;
Expand All @@ -56,19 +48,9 @@ namespace cms::alpakatools {
template <typename TLayout>
struct CopyToDevice<PortableHostCollection<TLayout>> {
template <cms::alpakatools::NonCPUQueue TQueue>
requires(!portablecollection::hasBlocksNumber<TLayout>)
static auto copyAsync(TQueue& queue, PortableHostCollection<TLayout> const& srcData) {
using TDevice = typename alpaka::trait::DevType<TQueue>::type;
PortableDeviceCollection<TLayout, TDevice> dstData(srcData->metadata().size(), queue);
alpaka::memcpy(queue, dstData.buffer(), srcData.buffer());
return dstData;
}

template <cms::alpakatools::NonCPUQueue TQueue>
requires portablecollection::hasBlocksNumber<TLayout>
static auto copyAsync(TQueue& queue, PortableHostCollection<TLayout> const& srcData) {
using TDevice = typename alpaka::trait::DevType<TQueue>::type;
PortableDeviceCollection<TLayout, TDevice> dstData(queue, srcData->metadata().size());
PortableDeviceCollection<TDevice, TLayout> dstData(queue, srcData->metadata().size());
alpaka::memcpy(queue, dstData.buffer(), srcData.buffer());
return dstData;
}
Expand Down
23 changes: 17 additions & 6 deletions DataFormats/Portable/interface/PortableCollectionCommon.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
#ifndef DataFormats_Portable_interface_PortableCollectionCommon_h
#define DataFormats_Portable_interface_PortableCollectionCommon_h

#include <array>
#include <cstddef>
#include <type_traits>
#include <format>
#include <limits>
#include <stdexcept>
#include <typeinfo>

#include "FWCore/Utilities/interface/TypeDemangler.h"

namespace portablecollection {

// concept to check if a Layout has a static member blocksNumber
template <class L>
concept hasBlocksNumber = requires { L::blocksNumber; };
template <std::integral Int>
constexpr int size_cast(Int input) {
if ((std::is_signed_v<Int> && input < 0) || input > std::numeric_limits<int>::max()) {
throw std::runtime_error(
std::format("Invalid input value for size of PortableCollection: cannot be narrowed to positive int32. "
"Source type: {}, value: {} ",
edm::typeDemangle(typeid(Int).name()),
input));
}
return static_cast<int>(input);
}

} // namespace portablecollection

Expand Down
65 changes: 33 additions & 32 deletions DataFormats/Portable/interface/PortableDeviceCollection.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include "HeterogeneousCore/AlpakaInterface/interface/memory.h"

// generic SoA-based product in device memory
template <typename T, typename TDev, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
class PortableDeviceCollection {
static_assert(not std::is_same_v<TDev, alpaka_common::DevHost>,
"Use PortableHostCollection<T> instead of PortableDeviceCollection<T, DevHost>");
Expand All @@ -34,59 +34,60 @@ class PortableDeviceCollection {

explicit PortableDeviceCollection(edm::Uninitialized) noexcept {}

PortableDeviceCollection(int32_t elements, TDev const& device)
requires(!portablecollection::hasBlocksNumber<Layout>)
: buffer_{cms::alpakatools::make_device_buffer<std::byte[]>(device, Layout::computeDataSize(elements))},
layout_{buffer_->data(), elements},
template <std::integral Int>
PortableDeviceCollection(TDev const& device, const Int size)
requires(!requires { Layout::blocksNumber; })
: buffer_{cms::alpakatools::make_device_buffer<std::byte[]>(
device, Layout::computeDataSize(portablecollection::size_cast(size)))},
layout_{buffer_->data(), portablecollection::size_cast(size)},
view_{layout_} {
// Alpaka set to a default alignment of 128 bytes defining ALPAKA_DEFAULT_HOST_MEMORY_ALIGNMENT=128
assert(reinterpret_cast<uintptr_t>(buffer_->data()) % Layout::alignment == 0);
}

template <typename TQueue>
requires(alpaka::isQueue<TQueue> && (!portablecollection::hasBlocksNumber<Layout>))
PortableDeviceCollection(int32_t elements, TQueue const& queue)
: buffer_{cms::alpakatools::make_device_buffer<std::byte[]>(queue, Layout::computeDataSize(elements))},
layout_{buffer_->data(), elements},
template <typename TQueue, std::integral Int>
requires(alpaka::isQueue<TQueue> && (!requires { Layout::blocksNumber; }))
PortableDeviceCollection(TQueue const& queue, const Int size)
: buffer_{cms::alpakatools::make_device_buffer<std::byte[]>(
queue, Layout::computeDataSize(portablecollection::size_cast(size)))},
layout_{buffer_->data(), portablecollection::size_cast(size)},
view_{layout_} {
// Alpaka set to a default alignment of 128 bytes defining ALPAKA_DEFAULT_HOST_MEMORY_ALIGNMENT=128
assert(reinterpret_cast<uintptr_t>(buffer_->data()) % Layout::alignment == 0);
}

// constructor for SoA by blocks with a variadic of sizes
// constructor for a SoABlocks-layout, taking per-block sizes as variadic integral arguments
template <std::integral... Ints>
requires(portablecollection::hasBlocksNumber<Layout>)
explicit PortableDeviceCollection(TDev const& device, Ints... sizes)
requires(sizeof...(sizes) == Layout::blocksNumber)
: PortableDeviceCollection(device, std::to_array({static_cast<int32_t>(sizes)...})) {}
explicit PortableDeviceCollection(TDev const& device, const Ints... sizes)
requires requires { Layout::blocksNumber; } && (sizeof...(Ints) == static_cast<std::size_t>(Layout::blocksNumber))
: PortableDeviceCollection(device, std::to_array({portablecollection::size_cast(sizes)...})) {}

// constructor for SoA by blocks with a variadic of sizes
// constructor for a SoABlocks-layout, taking per-block sizes as variadic integral arguments
template <typename TQueue, std::integral... Ints>
requires(alpaka::isQueue<TQueue> && portablecollection::hasBlocksNumber<Layout>)
explicit PortableDeviceCollection(TQueue const& queue, Ints... sizes)
requires(sizeof...(sizes) == Layout::blocksNumber)
: PortableDeviceCollection(queue, std::to_array({static_cast<int32_t>(sizes)...})) {}
requires(alpaka::isQueue<TQueue>)
explicit PortableDeviceCollection(TQueue const& queue, const Ints... sizes)
requires requires { Layout::blocksNumber; } && (sizeof...(Ints) == static_cast<std::size_t>(Layout::blocksNumber))
: PortableDeviceCollection(queue, std::to_array({portablecollection::size_cast(sizes)...})) {}

// constructor for SoA by blocks with an array of sizes
// constructor for a SoABlocks-layout, taking per-block sizes as a fixed-size array
template <std::size_t N>
requires(portablecollection::hasBlocksNumber<Layout>)
explicit PortableDeviceCollection(TDev const& device, std::array<int32_t, N> const& sizes)
requires requires { Layout::blocksNumber; } && (N == static_cast<std::size_t>(Layout::blocksNumber))
: buffer_{cms::alpakatools::make_device_buffer<std::byte[]>(device, Layout::computeDataSize(sizes))},
layout_{buffer_->data(), sizes},
view_{layout_} {
static_assert(Layout::blocksNumber == N, "Number of sizes must match the number of blocks in the Layout");
// Alpaka set to a default alignment of 128 bytes defining ALPAKA_DEFAULT_HOST_MEMORY_ALIGNMENT=128
assert(reinterpret_cast<uintptr_t>(buffer_->data()) % Layout::alignment == 0);
}

// constructor for SoA by blocks with an array of sizes
// constructor for a SoABlocks-layout, taking per-block sizes as a fixed-size array
template <typename TQueue, std::size_t N>
requires(alpaka::isQueue<TQueue> && portablecollection::hasBlocksNumber<Layout>)
requires(alpaka::isQueue<TQueue>)
explicit PortableDeviceCollection(TQueue const& queue, std::array<int32_t, N> const& sizes)
requires requires { Layout::blocksNumber; } && (N == static_cast<std::size_t>(Layout::blocksNumber))
: buffer_{cms::alpakatools::make_device_buffer<std::byte[]>(queue, Layout::computeDataSize(sizes))},
layout_{buffer_->data(), sizes},
view_{layout_} {
static_assert(Layout::blocksNumber == N, "Number of sizes must match the number of blocks in the Layout");
// Alpaka set to a default alignment of 128 bytes defining ALPAKA_DEFAULT_HOST_MEMORY_ALIGNMENT=128
assert(reinterpret_cast<uintptr_t>(buffer_->data()) % Layout::alignment == 0);
}
Expand Down Expand Up @@ -128,27 +129,27 @@ class PortableDeviceCollection {
// Copy column by column heterogeneously for device to host/device data transfer.
// TODO: implement heterogeneous deepCopy for SoA blocks
template <typename TQueue>
requires(alpaka::isQueue<TQueue> && (!portablecollection::hasBlocksNumber<Layout>))
void deepCopy(ConstView const& view, TQueue& queue) {
requires(alpaka::isQueue<TQueue> && (!requires { Layout::blocksNumber; }))
void deepCopy(TQueue& queue, ConstView const& view) {
ConstDescriptor desc{view};
Descriptor desc_{view_};
_deepCopy<0>(desc_, desc, queue);
_deepCopy<0>(queue, desc_, desc);
}

// Either int32_t for normal layouts or std::array<int32_t, N> for SoABlocks layouts
// Either Layout::size_type for normal layouts or std::array<Layout::size_type, N> for SoABlocks layouts
auto size() const { return layout_.metadata().size(); }

private:
// Helper function implementing the recursive deep copy
template <int I, typename TQueue>
void _deepCopy(Descriptor& dest, ConstDescriptor const& src, TQueue& queue) {
void _deepCopy(TQueue& queue, Descriptor& dest, ConstDescriptor const& src) {
if constexpr (I < ConstDescriptor::num_cols) {
assert(std::get<I>(dest.buff).size_bytes() == std::get<I>(src.buff).size_bytes());
alpaka::memcpy(
queue,
alpaka::createView(alpaka::getDev(queue), std::get<I>(dest.buff).data(), std::get<I>(dest.buff).size()),
alpaka::createView(alpaka::getDev(queue), std::get<I>(src.buff).data(), std::get<I>(src.buff).size()));
_deepCopy<I + 1>(dest, src, queue);
_deepCopy<I + 1>(queue, dest, src);
}
}

Expand Down
2 changes: 1 addition & 1 deletion DataFormats/Portable/interface/PortableDeviceObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "HeterogeneousCore/AlpakaInterface/interface/memory.h"

// generic object in device memory
template <typename T, typename TDev, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
template <typename TDev, typename T, typename = std::enable_if_t<alpaka::isDevice<TDev>>>
class PortableDeviceObject {
static_assert(not std::is_same_v<TDev, alpaka_common::DevHost>,
"Use PortableHostObject<T> instead of PortableDeviceObject<T, DevHost>");
Expand Down
Loading