diff --git a/DataFormats/SoATemplate/interface/SoACommon.h b/DataFormats/SoATemplate/interface/SoACommon.h index a0f598048b0c4..c9b14930f8ae3 100644 --- a/DataFormats/SoATemplate/interface/SoACommon.h +++ b/DataFormats/SoATemplate/interface/SoACommon.h @@ -813,4 +813,222 @@ SOA_HOST_ONLY std::ostream& operator<<(std::ostream& os, const SOA& soa) { return os; } +namespace cms::soa::detail { + // Helper function for streaming column + template + void printColumn(std::ostream& soa_impl_os, + const cms::soa::SoAConstParametersImpl& column, + std::string_view name, + cms::soa::byte_size_type& soa_impl_offset, + cms::soa::size_type, + cms::soa::byte_size_type alignment) { + soa_impl_os << " Scalar " << name << " at offset " << soa_impl_offset << " has size " << sizeof(T) + << " and padding " << ((sizeof(T) - 1) / alignment + 1) * alignment - sizeof(T) << std::endl; + soa_impl_offset += ((sizeof(T) - 1) / alignment + 1) * alignment; + } + + template + void printColumn(std::ostream& soa_impl_os, + const cms::soa::SoAConstParametersImpl& column, + std::string_view name, + cms::soa::byte_size_type& soa_impl_offset, + cms::soa::size_type elements, + cms::soa::byte_size_type alignment) { + soa_impl_os << " Column " << name << " at offset " << soa_impl_offset << " has size " << sizeof(T) * elements + << " and padding " << cms::soa::alignSize(elements * sizeof(T), alignment) - (elements * sizeof(T)) + << std::endl; + soa_impl_offset += cms::soa::alignSize(elements * sizeof(T), alignment); + } + + template + void printColumn(std::ostream& soa_impl_os, + const cms::soa::SoAConstParametersImpl& column, + std::string_view name, + cms::soa::byte_size_type& soa_impl_offset, + cms::soa::size_type elements, + cms::soa::byte_size_type alignment) { + soa_impl_os << " Eigen value " << name << " at offset " << soa_impl_offset << " has dimension " + << "(" << T::RowsAtCompileTime << " x " << T::ColsAtCompileTime << ")" + << " and per column size " << sizeof(T::Scalar) * elements << " and padding " + << cms::soa::alignSize(elements * sizeof(T::Scalar), alignment) - (elements * sizeof(T::Scalar)) + << std::endl; + soa_impl_offset += + cms::soa::alignSize(elements * sizeof(T::Scalar), alignment) * T::RowsAtCompileTime * T::ColsAtCompileTime; + } + + // Helper functions for accumulating column elements + template + struct AccumulateColumnByteSizes; + + template + struct AccumulateColumnByteSizes> { + cms::soa::byte_size_type operator()(cms::soa::size_type, cms::soa::byte_size_type alignment) const { + return cms::soa::alignSize(sizeof(T), alignment); + } + }; + + template + struct AccumulateColumnByteSizes> { + cms::soa::byte_size_type operator()(cms::soa::size_type elements, cms::soa::byte_size_type alignment) const { + return cms::soa::alignSize(elements * sizeof(T), alignment); + } + }; + + template + struct AccumulateColumnByteSizes> { + cms::soa::byte_size_type operator()(cms::soa::size_type elements, cms::soa::byte_size_type alignment) const { + return cms::soa::alignSize(elements * sizeof(typename T::Scalar), alignment) * T::RowsAtCompileTime * + T::ColsAtCompileTime; + } + }; + + // Helper functions for computing the pitch of each column + template + SOA_HOST_DEVICE constexpr cms::soa::byte_size_type computePitch( + const cms::soa::SoAParametersImpl& column, + cms::soa::byte_size_type alignment, + cms::soa::size_type elements) { + return cms::soa::alignSize(sizeof(T), alignment); + } + + template + SOA_HOST_DEVICE constexpr cms::soa::byte_size_type computePitch( + const cms::soa::SoAParametersImpl& column, + cms::soa::byte_size_type alignment, + cms::soa::size_type elements) { + return cms::soa::alignSize(elements * sizeof(T), alignment); + } + + template + SOA_HOST_DEVICE constexpr cms::soa::byte_size_type computePitch( + const cms::soa::SoAParametersImpl& column, + cms::soa::byte_size_type alignment, + cms::soa::size_type elements) { + return cms::soa::alignSize(elements * sizeof(typename T::Scalar), alignment) * T::RowsAtCompileTime * + T::ColsAtCompileTime; + } + + // Helper type trait for obtaining a span type for a column + template + struct GetSpanType; + + template + struct GetSpanType> { + using type = std::span; + }; + + template + struct GetSpanType> { + using type = std::span; + }; + + template + struct GetSpanType> { + using type = std::span; + }; + + template + struct GetSpanType> { + using type = std::span; + }; + + template + struct GetSpanType> { + using type = std::span; + }; + + template + struct GetSpanType> { + using type = std::span; + }; + + template + using SpanType = GetSpanType::type; + + // Helper type trait for obtaining a const-span type for a column + template + struct GetConstSpanType; + + template + struct GetConstSpanType> { + using type = std::span, 1>; + }; + + template + struct GetConstSpanType> { + using type = std::span>; + }; + + template + struct GetConstSpanType> { + using type = std::span>; + }; + + template + struct GetConstSpanType> { + using type = std::span, 1>; + }; + + template + struct GetConstSpanType> { + using type = std::span>; + }; + + template + struct GetConstSpanType> { + using type = std::span>; + }; + + template + using ConstSpanType = GetConstSpanType::type; + + // Helper functions for constructing a span from a column + template + auto getSpanToColumn(const cms::soa::SoAParametersImpl& column, + cms::soa::size_type, + cms::soa::byte_size_type alignment) { + return std::span(column.addr_, 1); + } + + template + auto getSpanToColumn(const cms::soa::SoAParametersImpl& column, + cms::soa::size_type elements, + cms::soa::byte_size_type alignment) { + return std::span(column.addr_, elements); + } + + template + auto getSpanToColumn(const cms::soa::SoAParametersImpl& 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)); + } + + template + auto getSpanToColumn(const cms::soa::SoAConstParametersImpl& column, + cms::soa::size_type elements, + cms::soa::byte_size_type alignment) { + return std::span(column.addr_, 1); + } + + template + auto getSpanToColumn(const cms::soa::SoAConstParametersImpl& column, + cms::soa::size_type elements, + cms::soa::byte_size_type alignment) { + return std::span(column.addr_, elements); + } + + template + auto getSpanToColumn(const cms::soa::SoAConstParametersImpl& 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)); + } + +} // namespace cms::soa::detail + #endif // DataFormats_SoATemplate_interface_SoACommon_h diff --git a/DataFormats/SoATemplate/interface/SoALayout.h b/DataFormats/SoATemplate/interface/SoALayout.h index d157e555ecb4b..01fda57d53099 100644 --- a/DataFormats/SoATemplate/interface/SoALayout.h +++ b/DataFormats/SoATemplate/interface/SoALayout.h @@ -105,34 +105,7 @@ namespace cms::soa { // clang-format off #define _DECLARE_SOA_STREAM_INFO_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \ - _SWITCH_ON_TYPE( \ - VALUE_TYPE, \ - /* Dump scalar */ \ - _soa_impl_os << " Scalar " BOOST_PP_STRINGIZE(NAME) " at offset " << _soa_impl_offset \ - << " has size " << sizeof(CPP_TYPE) \ - << " and padding " << ((sizeof(CPP_TYPE) - 1) / alignment + 1) * alignment - sizeof(CPP_TYPE) \ - << std::endl; \ - _soa_impl_offset += ((sizeof(CPP_TYPE) - 1) / alignment + 1) * alignment; \ - , \ - /* Dump column */ \ - _soa_impl_os << " Column " BOOST_PP_STRINGIZE(NAME) " at offset " << _soa_impl_offset << " has size " \ - << sizeof(CPP_TYPE) * elements_ << " and padding " \ - << cms::soa::alignSize(elements_ * sizeof(CPP_TYPE), alignment) - (elements_ * sizeof(CPP_TYPE)) \ - << std::endl; \ - _soa_impl_offset += cms::soa::alignSize(elements_ * sizeof(CPP_TYPE), alignment); \ - , \ - /* Dump Eigen column */ \ - _soa_impl_os << " Eigen value " BOOST_PP_STRINGIZE(NAME) " at offset " << _soa_impl_offset << " has dimension " \ - << "(" << CPP_TYPE::RowsAtCompileTime << " x " << CPP_TYPE::ColsAtCompileTime << ")" \ - << " and per column size " \ - << sizeof(CPP_TYPE::Scalar) * elements_ \ - << " and padding " \ - << cms::soa::alignSize(elements_ * sizeof(CPP_TYPE::Scalar), alignment) \ - - (elements_ * sizeof(CPP_TYPE::Scalar)) \ - << std::endl; \ - _soa_impl_offset += cms::soa::alignSize(elements_ * sizeof(CPP_TYPE::Scalar), alignment) \ - * CPP_TYPE::RowsAtCompileTime * CPP_TYPE::ColsAtCompileTime; \ - ) + cms::soa::detail::printColumn(_soa_impl_os, ConstView::BOOST_PP_CAT(NAME, Parameters_), BOOST_PP_STRINGIZE(NAME), _soa_impl_offset, elements_, alignment); // clang-format on #define _DECLARE_SOA_STREAM_INFO(R, DATA, TYPE_NAME) \ @@ -147,23 +120,12 @@ namespace cms::soa { #define _DEFINE_METADATA_MEMBERS_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \ _SWITCH_ON_TYPE(VALUE_TYPE, \ /* Scalar */ \ - byte_size_type BOOST_PP_CAT(NAME, Pitch()) const { \ - return cms::soa::alignSize(sizeof(CPP_TYPE), ParentClass::alignment); \ - } \ constexpr static cms::soa::SoAColumnType BOOST_PP_CAT(ColumnTypeOf_, NAME) = cms::soa::SoAColumnType::scalar; \ - SOA_HOST_DEVICE SOA_INLINE \ - CPP_TYPE const* BOOST_PP_CAT(addressOf_, NAME)() const { \ - return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \ - } \ using BOOST_PP_CAT(ParametersTypeOf_, NAME) = \ cms::soa::SoAParameters_ColumnType::DataType; \ SOA_HOST_DEVICE SOA_INLINE \ BOOST_PP_CAT(ParametersTypeOf_, NAME) BOOST_PP_CAT(parametersOf_, NAME)() const { \ return BOOST_PP_CAT(ParametersTypeOf_, NAME) (parent_.BOOST_PP_CAT(NAME, _)); \ - } \ - SOA_HOST_DEVICE SOA_INLINE \ - CPP_TYPE* BOOST_PP_CAT(addressOf_, NAME)() { \ - return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \ }, \ /* Column */ \ using BOOST_PP_CAT(ParametersTypeOf_, NAME) = \ @@ -172,18 +134,6 @@ namespace cms::soa { BOOST_PP_CAT(ParametersTypeOf_, NAME) BOOST_PP_CAT(parametersOf_, NAME)() const { \ return BOOST_PP_CAT(ParametersTypeOf_, NAME) (parent_.BOOST_PP_CAT(NAME, _)); \ } \ - SOA_HOST_DEVICE SOA_INLINE \ - CPP_TYPE const* BOOST_PP_CAT(addressOf_, NAME)() const { \ - return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \ - } \ - SOA_HOST_DEVICE SOA_INLINE \ - CPP_TYPE* BOOST_PP_CAT(addressOf_, NAME)() { \ - return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \ - } \ - SOA_HOST_DEVICE SOA_INLINE \ - byte_size_type BOOST_PP_CAT(NAME, Pitch()) const { \ - return cms::soa::alignSize(parent_.elements_ * sizeof(CPP_TYPE), ParentClass::alignment); \ - } \ constexpr static cms::soa::SoAColumnType BOOST_PP_CAT(ColumnTypeOf_, NAME) = cms::soa::SoAColumnType::column;, \ /* Eigen column */ \ using BOOST_PP_CAT(ParametersTypeOf_, NAME) = \ @@ -194,21 +144,20 @@ namespace cms::soa { parent_.BOOST_PP_CAT(NAME, _), \ parent_.BOOST_PP_CAT(NAME, Stride_)); \ } \ - SOA_HOST_DEVICE SOA_INLINE \ - byte_size_type BOOST_PP_CAT(NAME, Pitch()) const { \ - return cms::soa::alignSize(parent_.elements_ * sizeof(CPP_TYPE::Scalar), ParentClass::alignment) \ - * CPP_TYPE::RowsAtCompileTime * CPP_TYPE::ColsAtCompileTime; \ - } \ constexpr static cms::soa::SoAColumnType BOOST_PP_CAT(ColumnTypeOf_, NAME) = cms::soa::SoAColumnType::eigen; \ - SOA_HOST_DEVICE SOA_INLINE \ - CPP_TYPE::Scalar const* BOOST_PP_CAT(addressOf_, NAME)() const { \ - return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \ - } \ - SOA_HOST_DEVICE SOA_INLINE \ - CPP_TYPE::Scalar* BOOST_PP_CAT(addressOf_, NAME)() { \ - return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \ - } \ - ) + ) \ + SOA_HOST_DEVICE SOA_INLINE \ + auto* BOOST_PP_CAT(addressOf_, NAME)() { \ + return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \ + } \ + SOA_HOST_DEVICE SOA_INLINE \ + const auto* BOOST_PP_CAT(addressOf_, NAME)() const { \ + return parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)().addr_; \ + } \ + SOA_HOST_DEVICE SOA_INLINE byte_size_type BOOST_PP_CAT(NAME, Pitch()) const { \ + return cms::soa::detail::computePitch(parent_.metadata().BOOST_PP_CAT(parametersOf_, NAME)(), \ + ParentClass::alignment, parent_.elements_); \ + } // clang-format on #define _DEFINE_METADATA_MEMBERS(R, DATA, TYPE_NAME) \ @@ -221,16 +170,7 @@ namespace cms::soa { */ // clang-format off #define _DECLARE_CONST_DESCRIPTOR_SPANS_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \ - _SWITCH_ON_TYPE(VALUE_TYPE, \ - /* Scalar */ \ - (std::span>) \ - , \ - /* Column */ \ - (std::span>) \ - , \ - /* Eigen column*/ \ - (std::span>) \ - ) + (cms::soa::detail::ConstSpanType) // clang-format on #define _DECLARE_CONST_DESCRIPTOR_SPANS(R, DATA, TYPE_NAME) \ @@ -243,16 +183,7 @@ namespace cms::soa { */ // clang-format off #define _DECLARE_DESCRIPTOR_SPANS_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \ - _SWITCH_ON_TYPE(VALUE_TYPE, \ - /* Scalar */ \ - (std::span) \ - , \ - /* Column */ \ - (std::span) \ - , \ - /* Eigen column */ \ - (std::span) \ - ) + (cms::soa::detail::SpanType) // clang-format on #define _DECLARE_DESCRIPTOR_SPANS(R, DATA, TYPE_NAME) \ @@ -264,21 +195,8 @@ namespace cms::soa { * Build the spans of the (const) descriptor from a (const) view */ // clang-format off -#define _ASSIGN_SPAN_TO_COLUMNS_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \ - _SWITCH_ON_TYPE(VALUE_TYPE, \ - /* Scalar */ \ - (std::span(view.metadata().BOOST_PP_CAT(addressOf_, NAME)(), \ - cms::soa::alignSize(sizeof(CPP_TYPE), alignment) / sizeof(CPP_TYPE))) \ - , \ - /* Column */ \ - (std::span(view.metadata().BOOST_PP_CAT(addressOf_, NAME)(), \ - cms::soa::alignSize(view.metadata().size() * sizeof(CPP_TYPE), alignment) / sizeof(CPP_TYPE))) \ - , \ - /* Eigen column */ \ - (std::span(view.metadata().BOOST_PP_CAT(addressOf_, NAME)(), \ - cms::soa::alignSize(view.metadata().size() * sizeof(CPP_TYPE::Scalar), alignment) * \ - CPP_TYPE::RowsAtCompileTime * CPP_TYPE::ColsAtCompileTime / sizeof(CPP_TYPE::Scalar))) \ - ) +#define _ASSIGN_SPAN_TO_COLUMNS_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \ + (cms::soa::detail::getSpanToColumn(view.metadata().BOOST_PP_CAT(parametersOf_, NAME)(), view.metadata().size(), alignment)) // clang-format on #define _ASSIGN_SPAN_TO_COLUMNS(R, DATA, TYPE_NAME) \ @@ -456,17 +374,7 @@ namespace cms::soa { */ // clang-format off #define _ACCUMULATE_SOA_ELEMENT_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \ - _SWITCH_ON_TYPE(VALUE_TYPE, \ - /* Scalar */ \ - _soa_impl_ret += cms::soa::alignSize(sizeof(CPP_TYPE), alignment); \ - , \ - /* Column */ \ - _soa_impl_ret += cms::soa::alignSize(elements * sizeof(CPP_TYPE), alignment); \ - , \ - /* Eigen column */ \ - _soa_impl_ret += cms::soa::alignSize(elements * sizeof(CPP_TYPE::Scalar), alignment) \ - * CPP_TYPE::RowsAtCompileTime * CPP_TYPE::ColsAtCompileTime; \ - ) + _soa_impl_ret += cms::soa::detail::AccumulateColumnByteSizes{}(elements, alignment); // clang-format on #define _ACCUMULATE_SOA_ELEMENT(R, DATA, TYPE_NAME) \ @@ -531,7 +439,7 @@ namespace cms::soa { */ // clang-format off #define _STREAMER_READ_SOA_DATA_MEMBER_IMPL(VALUE_TYPE, CPP_TYPE, NAME, ARGS) \ - _SWITCH_ON_TYPE(VALUE_TYPE, \ + _SWITCH_ON_TYPE(VALUE_TYPE, \ /* Scalar */ \ memcpy(BOOST_PP_CAT(NAME, _), onfile.BOOST_PP_CAT(NAME, _), sizeof(CPP_TYPE)); \ , \ @@ -541,7 +449,7 @@ namespace cms::soa { /* Eigen column */ \ memcpy(BOOST_PP_CAT(NAME, _), onfile.BOOST_PP_CAT(NAME, _), \ sizeof(CPP_TYPE::Scalar) * BOOST_PP_CAT(NAME, ElementsWithPadding_)); \ - ) + ) // clang-format on #define _STREAMER_READ_SOA_DATA_MEMBER(R, DATA, TYPE_NAME) \ @@ -1744,6 +1652,8 @@ _SWITCH_ON_TYPE(VALUE_TYPE, size_type elements_; \ size_type const scalar_ = 1; \ byte_size_type byteSize_ EDM_REFLEX_TRANSIENT; \ + /* TODO: The layout will contain SoAParametersImpl as members for the columns, which will allow the use of \ + * more template helper functions. */ \ _ITERATE_ON_ALL(_DECLARE_SOA_DATA_MEMBER, ~, __VA_ARGS__) \ /* Making the code conditional is problematic in macros as the commas will interfere with parameter lisings */ \ /* So instead we make the code unconditional with paceholder names which are protected by a private protection. */ \