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
145 changes: 21 additions & 124 deletions DataFormats/SoATemplate/interface/SoACommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,82 +162,15 @@ namespace cms::soa {
};
};

// Forward declarations
template <SoAColumnType COLUMN_TYPE, typename T>
struct SoAConstParametersImpl;

template <SoAColumnType COLUMN_TYPE, typename T>
struct SoAParametersImpl;

// Templated const parameter sets for scalars, columns and Eigen columns
template <SoAColumnType COLUMN_TYPE, typename T>
struct SoAConstParametersImpl {
static constexpr SoAColumnType columnType = COLUMN_TYPE;

using ValueType = T;
using ScalarType = T;

// default constructor
SoAConstParametersImpl() = default;

// constructor from address and size
SOA_HOST_DEVICE SOA_INLINE constexpr SoAConstParametersImpl(ScalarType const* addr) : addr_(addr) {}

// constructor from a non-const parameter set
SOA_HOST_DEVICE SOA_INLINE constexpr SoAConstParametersImpl(SoAParametersImpl<columnType, ValueType> const& o)
: addr_{o.addr_} {}

SOA_HOST_DEVICE SOA_INLINE ScalarType const* data() const { return addr_; }

public:
// scalar or column
ScalarType const* addr_ = nullptr;
};

// Templated const parameter specialisation for Eigen columns
template <typename T>
struct SoAConstParametersImpl<SoAColumnType::eigen, T> {
static constexpr SoAColumnType columnType = SoAColumnType::eigen;

using ValueType = T;
using ScalarType = typename T::Scalar;

// default constructor
SoAConstParametersImpl() = default;

// constructor from individual address, stride and size
SOA_HOST_DEVICE SOA_INLINE constexpr SoAConstParametersImpl(ScalarType const* addr, byte_size_type stride)
: addr_(addr), stride_(stride) {}

// constructor from a non-const parameter set
SOA_HOST_DEVICE SOA_INLINE constexpr SoAConstParametersImpl(SoAParametersImpl<columnType, ValueType> const& o)
: addr_{o.addr_}, stride_{o.stride_} {}

SOA_HOST_DEVICE SOA_INLINE ScalarType const* data() const { return addr_; }
SOA_HOST_DEVICE SOA_INLINE byte_size_type stride() const { return stride_; }

public:
// address, stride and size
ScalarType const* addr_ = nullptr;
byte_size_type stride_ = 0;
};

// Matryoshka template to avoid commas inside macros
template <SoAColumnType COLUMN_TYPE>
struct SoAConstParameters_ColumnType {
template <typename T>
using DataType = SoAConstParametersImpl<COLUMN_TYPE, T>;
};

// Templated parameter sets for scalars, columns and Eigen columns
template <SoAColumnType COLUMN_TYPE, typename T>
struct SoAParametersImpl {
static constexpr SoAColumnType columnType = COLUMN_TYPE;

using ValueType = T;
using ValueType = std::remove_cvref_t<T>;
using ScalarType = T;

using ConstType = SoAConstParametersImpl<columnType, ValueType>;
using ConstType = SoAParametersImpl<columnType, const ValueType>;
friend ConstType;

// default constructor
Expand All @@ -246,6 +179,9 @@ namespace cms::soa {
// constructor from address and size
SOA_HOST_DEVICE SOA_INLINE constexpr SoAParametersImpl(ScalarType* addr) : addr_(addr) {}

SOA_HOST_DEVICE SOA_INLINE constexpr SoAParametersImpl(SoAParametersImpl<COLUMN_TYPE, ValueType> const& params)
: addr_(const_cast<ScalarType*>(params.addr_)) {}

SOA_HOST_DEVICE SOA_INLINE ScalarType* data() const { return addr_; }

public:
Expand All @@ -258,10 +194,10 @@ namespace cms::soa {
struct SoAParametersImpl<SoAColumnType::eigen, T> {
static constexpr SoAColumnType columnType = SoAColumnType::eigen;

using ValueType = T;
using ValueType = std::remove_cvref_t<T>;
using ScalarType = typename T::Scalar;

using ConstType = SoAConstParametersImpl<columnType, ValueType>;
using ConstType = SoAParametersImpl<columnType, const ValueType>;
friend ConstType;

// default constructor
Expand All @@ -270,6 +206,9 @@ namespace cms::soa {
// constructor from individual address, stride and size
SOA_HOST_DEVICE SOA_INLINE constexpr SoAParametersImpl(ScalarType* addr, byte_size_type stride)
: addr_(addr), stride_(stride) {}
SOA_HOST_DEVICE SOA_INLINE constexpr SoAParametersImpl(
SoAParametersImpl<SoAColumnType::eigen, ValueType> const& params)
: addr_(const_cast<ScalarType*>(params.addr_)), stride_(params.stride_) {}

SOA_HOST_DEVICE SOA_INLINE ScalarType* data() const { return addr_; }
SOA_HOST_DEVICE SOA_INLINE byte_size_type stride() const { return stride_; }
Expand All @@ -280,6 +219,17 @@ namespace cms::soa {
byte_size_type stride_ = 0;
};

template <SoAColumnType COLUMN_TYPE, typename T>
requires std::same_as<std::remove_const_t<T>, T>
using SoAConstParametersImpl = SoAParametersImpl<COLUMN_TYPE, const T>;

// Matryoshka template to avoid commas inside macros
template <SoAColumnType COLUMN_TYPE>
struct SoAConstParameters_ColumnType {
template <typename T>
using DataType = SoAConstParametersImpl<COLUMN_TYPE, T>;
};

// Matryoshka template to avoid commas inside macros
template <SoAColumnType COLUMN_TYPE>
struct SoAParameters_ColumnType {
Expand Down Expand Up @@ -978,21 +928,6 @@ namespace cms::soa::detail {
template <typename ColumnType>
struct GetSpanType;

template <typename T>
struct GetSpanType<cms::soa::SoAConstParametersImpl<cms::soa::SoAColumnType::scalar, T>> {
using type = std::span<T, 1>;
};

template <typename T>
struct GetSpanType<cms::soa::SoAConstParametersImpl<cms::soa::SoAColumnType::column, T>> {
using type = std::span<T>;
};

template <typename T>
struct GetSpanType<cms::soa::SoAConstParametersImpl<cms::soa::SoAColumnType::eigen, T>> {
using type = std::span<typename T::Scalar>;
};

template <typename T>
struct GetSpanType<cms::soa::SoAParametersImpl<cms::soa::SoAColumnType::scalar, T>> {
using type = std::span<T, 1>;
Expand All @@ -1015,21 +950,6 @@ namespace cms::soa::detail {
template <typename ColumnType>
struct GetConstSpanType;

template <typename T>
struct GetConstSpanType<cms::soa::SoAConstParametersImpl<cms::soa::SoAColumnType::scalar, T>> {
using type = std::span<std::add_const_t<T>, 1>;
};

template <typename T>
struct GetConstSpanType<cms::soa::SoAConstParametersImpl<cms::soa::SoAColumnType::column, T>> {
using type = std::span<std::add_const_t<T>>;
};

template <typename T>
struct GetConstSpanType<cms::soa::SoAConstParametersImpl<cms::soa::SoAColumnType::eigen, T>> {
using type = std::span<std::add_const_t<typename T::Scalar>>;
};

template <typename T>
struct GetConstSpanType<cms::soa::SoAParametersImpl<cms::soa::SoAColumnType::scalar, T>> {
using type = std::span<std::add_const_t<T>, 1>;
Expand Down Expand Up @@ -1072,29 +992,6 @@ namespace cms::soa::detail {
T::ColsAtCompileTime / sizeof(typename T::Scalar));
}

template <typename T>
auto getSpanToColumn(const cms::soa::SoAConstParametersImpl<cms::soa::SoAColumnType::scalar, T>& column,
cms::soa::size_type elements,
cms::soa::byte_size_type alignment) {
return std::span(column.addr_, 1);
}

template <typename T>
auto getSpanToColumn(const cms::soa::SoAConstParametersImpl<cms::soa::SoAColumnType::column, T>& column,
cms::soa::size_type elements,
cms::soa::byte_size_type alignment) {
return std::span(column.addr_, elements);
}

template <typename T>
auto getSpanToColumn(const cms::soa::SoAConstParametersImpl<cms::soa::SoAColumnType::eigen, T>& column,
cms::soa::size_type elements,
cms::soa::byte_size_type alignment) {
return std::span(column.addr_,
cms::soa::alignSize(elements * sizeof(typename T::Scalar), alignment) * T::RowsAtCompileTime *
T::ColsAtCompileTime / sizeof(typename T::Scalar));
}

// Helper function for extracting the number of blocks of a layout. Falls back to 1 if the layout does not define a static member blocksNumber.
template <typename T>
constexpr size_type nBlocks() {
Expand Down
19 changes: 19 additions & 0 deletions DataFormats/SoATemplate/test/SoAUnitTests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ GENERATE_SOA_LAYOUT(SimpleLayoutTemplate,

using SimpleLayout = SimpleLayoutTemplate<>;

namespace {
template <typename TView>
concept Immutable = requires(TView view) { requires !requires { view[0] = decltype(view[0]){}; }; };
} // namespace

TEST_CASE("SoATemplate") {
// number of elements
const std::size_t slSize = 10;
Expand Down Expand Up @@ -166,4 +171,18 @@ TEST_CASE("SoATemplate") {
REQUIRE_THROWS_WITH(slcv.x(underflow), Catch::Matchers::ContainsSubstring("at file"));
REQUIRE_THROWS_WITH(slcv.x(overflow), Catch::Matchers::ContainsSubstring("at file"));
}

SECTION("Check immutability of ConstView") {
using ConstView =
SimpleLayout::ConstViewTemplate<cms::soa::RestrictQualify::Default, cms::soa::RangeChecking::extended>;
static_assert(Immutable<ConstView>);
}

SECTION("Check views conversions") {
using ConstView =
SimpleLayout::ConstViewTemplate<cms::soa::RestrictQualify::Default, cms::soa::RangeChecking::extended>;
using View = SimpleLayout::ViewTemplate<cms::soa::RestrictQualify::Default, cms::soa::RangeChecking::extended>;
static_assert(std::convertible_to<View, ConstView>);
static_assert(!std::convertible_to<ConstView, View>);
}
}