From f959fd57b2ac89b4886aa30a060b62740a52f1b5 Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Tue, 4 Feb 2025 10:33:14 +0100 Subject: [PATCH 1/6] DPL Analysis: reduce amount of base types for columns --- Framework/Core/include/Framework/ASoA.h | 415 ++++++++++++++++-------- 1 file changed, 273 insertions(+), 142 deletions(-) diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 4ed8e830fe137..65ac91f60f889 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -584,13 +584,6 @@ class ColumnIterator : ChunkingPolicy return *(mCurrent + (*mCurrentPos >> SCALE_FACTOR)); } - // Move to the chunk which containts element pos - ColumnIterator& moveToPos() - { - checkSkipChunk(); - return *this; - } - mutable unwrap_t const* mCurrent; int64_t const* mCurrentPos; mutable unwrap_t const* mLast; @@ -650,23 +643,30 @@ class ColumnIterator : ChunkingPolicy } }; -template -struct Column { - using inherited_t = INHERIT; - Column(ColumnIterator const& it) - : mColumnIterator{it} +template +struct BaseColumn { + using inherited_t = REC; + using type = T; + + static constexpr const char* const& columnLabel() { return inherited_t::mLabel; } +}; + +template +struct PersistentColumn : BaseColumn { + using inherited_t = BaseColumn::inherited_t; + using type = BaseColumn::type; + + PersistentColumn(ColumnIterator&& iterator) + : mColumnIterator{iterator} { } - Column() = default; - Column(Column const&) = default; - Column& operator=(Column const&) = default; - - Column(Column&&) = default; - Column& operator=(Column&&) = default; + PersistentColumn() = default; + PersistentColumn(PersistentColumn const&) = default; + PersistentColumn(PersistentColumn&&) = default; + PersistentColumn& operator=(PersistentColumn const&) = default; + PersistentColumn& operator=(PersistentColumn&&) = default; - using type = T; - static constexpr const char* const& columnLabel() { return INHERIT::mLabel; } ColumnIterator const& getIterator() const { return mColumnIterator; @@ -677,38 +677,18 @@ struct Column { return std::make_shared(inherited_t::mLabel, framework::expressions::concreteArrowType(framework::expressions::selectArrowType())); } - /// FIXME: rather than keeping this public we should have a protected - /// non-const getter and mark this private. ColumnIterator mColumnIterator; }; -/// The purpose of this class is to store the lambda which is associated to the -/// method call. -template -struct DynamicColumn { - using inherited_t = INHERIT; - - static constexpr const char* const& columnLabel() { return INHERIT::mLabel; } -}; - -template -struct IndexColumn { - using inherited_t = INHERIT; - - static constexpr const char* const& columnLabel() { return INHERIT::mLabel; } -}; - -template -struct MarkerColumn { - using inherited_t = INHERIT; - - static constexpr const char* const& columnLabel() { return INHERIT::mLabel; } +template +struct TransientColumn : BaseColumn { + using inherited_t = BaseColumn::inherited_t; + using type = BaseColumn::type; }; template -struct Marker : o2::soa::MarkerColumn> { - using type = size_t; - using base = o2::soa::MarkerColumn>; +struct Marker : o2::soa::TransientColumn> { + using base = o2::soa::TransientColumn>; constexpr inline static auto value = M; Marker() = default; @@ -728,8 +708,8 @@ struct Marker : o2::soa::MarkerColumn> { }; template -struct Index : o2::soa::IndexColumn> { - using base = o2::soa::IndexColumn>; +struct Index : o2::soa::TransientColumn> { + using base = o2::soa::TransientColumn>; constexpr inline static int64_t start = START; constexpr inline static int64_t end = END; @@ -2292,14 +2272,14 @@ O2HASH("TEST/0"); } #define DECLARE_SOA_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) \ - struct _Name_ : o2::soa::Column<_Type_, _Name_> { \ + struct _Name_ : o2::soa::PersistentColumn<_Type_, _Name_> { \ static constexpr const char* mLabel = _Label_; \ static_assert(!((*(mLabel + 1) == 'I' && *(mLabel + 2) == 'n' && *(mLabel + 3) == 'd' && *(mLabel + 4) == 'e' && *(mLabel + 5) == 'x')), "Index is not a valid column name"); \ - using base = o2::soa::Column<_Type_, _Name_>; \ + using base = o2::soa::PersistentColumn<_Type_, _Name_>; \ using type = _Type_; \ using column_t = _Name_; \ _Name_(arrow::ChunkedArray const* column) \ - : o2::soa::Column<_Type_, _Name_>(o2::soa::ColumnIterator(column)) \ + : o2::soa::PersistentColumn<_Type_, _Name_>(o2::soa::ColumnIterator(column)) \ { \ } \ \ @@ -2328,13 +2308,13 @@ O2HASH("TEST/0"); #define MAKEINT(_Size_) uint##_Size_##_t #define DECLARE_SOA_BITMAP_COLUMN_FULL(_Name_, _Getter_, _Size_, _Label_) \ - struct _Name_ : o2::soa::Column { \ + struct _Name_ : o2::soa::PersistentColumn { \ static constexpr const char* mLabel = _Label_; \ static_assert(!((*(mLabel + 1) == 'I' && *(mLabel + 2) == 'n' && *(mLabel + 3) == 'd' && *(mLabel + 4) == 'e' && *(mLabel + 5) == 'x')), "Index is not a valid column name"); \ - using base = o2::soa::Column; \ + using base = o2::soa::PersistentColumn; \ using type = MAKEINT(_Size_); \ _Name_(arrow::ChunkedArray const* column) \ - : o2::soa::Column(o2::soa::ColumnIterator(column)) \ + : o2::soa::PersistentColumn(o2::soa::ColumnIterator(column)) \ { \ } \ \ @@ -2361,14 +2341,14 @@ O2HASH("TEST/0"); /// An 'expression' column. i.e. a column that can be calculated from other /// columns with gandiva based on static C++ expression. #define DECLARE_SOA_EXPRESSION_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_, _Expression_) \ - struct _Name_ : o2::soa::Column<_Type_, _Name_> { \ + struct _Name_ : o2::soa::PersistentColumn<_Type_, _Name_> { \ static constexpr const char* mLabel = _Label_; \ - using base = o2::soa::Column<_Type_, _Name_>; \ + using base = o2::soa::PersistentColumn<_Type_, _Name_>; \ using type = _Type_; \ using column_t = _Name_; \ using spawnable_t = std::true_type; \ _Name_(arrow::ChunkedArray const* column) \ - : o2::soa::Column<_Type_, _Name_>(o2::soa::ColumnIterator(column)) \ + : o2::soa::PersistentColumn<_Type_, _Name_>(o2::soa::ColumnIterator(column)) \ { \ } \ \ @@ -2457,17 +2437,17 @@ consteval auto getIndexTargets() } #define DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \ - struct _Name_##IdSlice : o2::soa::Column<_Type_[2], _Name_##IdSlice> { \ + struct _Name_##IdSlice : o2::soa::PersistentColumn<_Type_[2], _Name_##IdSlice> { \ static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \ static constexpr const char* mLabel = "fIndexSlice" _Label_ _Suffix_; \ - using base = o2::soa::Column<_Type_[2], _Name_##IdSlice>; \ + using base = o2::soa::PersistentColumn<_Type_[2], _Name_##IdSlice>; \ using type = _Type_[2]; \ using column_t = _Name_##IdSlice; \ using binding_t = _Table_; \ static constexpr auto index_targets = getIndexTargets<_Table_>(); \ _Name_##IdSlice(arrow::ChunkedArray const* column) \ - : o2::soa::Column<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator(column)) \ + : o2::soa::PersistentColumn<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator(column)) \ { \ } \ \ @@ -2542,6 +2522,7 @@ consteval auto getIndexTargets() #define DECLARE_SOA_SLICE_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "") /// ARRAY +<<<<<<< HEAD #define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \ struct _Name_##Ids : o2::soa::Column, _Name_##Ids> { \ static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ @@ -2690,6 +2671,156 @@ consteval auto getIndexTargets() binding_t const* getCurrent() const { return mBinding.get(); } \ o2::soa::Binding getCurrentRaw() const { return mBinding; } \ o2::soa::Binding mBinding; \ +======= +#define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \ + struct _Name_##Ids : o2::soa::PersistentColumn, _Name_##Ids> { \ + static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ + static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \ + static constexpr const char* mLabel = "fIndexArray" _Label_ _Suffix_; \ + using base = o2::soa::PersistentColumn, _Name_##Ids>; \ + using type = std::vector<_Type_>; \ + using column_t = _Name_##Ids; \ + using binding_t = _Table_; \ + static constexpr auto index_targets = getIndexTargets<_Table_>(); \ + _Name_##Ids(arrow::ChunkedArray const* column) \ + : o2::soa::PersistentColumn, _Name_##Ids>(o2::soa::ColumnIterator(column)) \ + { \ + } \ + \ + _Name_##Ids() = default; \ + _Name_##Ids(_Name_##Ids const& other) = default; \ + _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ + \ + gsl::span inline getIds() const \ + { \ + return _Getter_##Ids(); \ + } \ + \ + gsl::span _Getter_##Ids() const \ + { \ + return *mColumnIterator; \ + } \ + \ + bool has_##_Getter_() const \ + { \ + return !(*mColumnIterator).empty(); \ + } \ + \ + template \ + auto _Getter_##_as() const \ + { \ + if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ + o2::soa::notBoundTable(#_Table_); \ + } \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(); \ + } \ + return getIterators(); \ + } \ + \ + template \ + auto filtered_##_Getter_##_as() const \ + { \ + if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ + o2::soa::notBoundTable(#_Table_); \ + } \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(); \ + } \ + return getFilteredIterators(); \ + } \ + \ + template \ + auto getIterators() const \ + { \ + auto result = std::vector(); \ + for (auto& i : *mColumnIterator) { \ + result.push_back(mBinding.get()->rawIteratorAt(i)); \ + } \ + return result; \ + } \ + \ + template \ + std::vector getFilteredIterators() const \ + { \ + if constexpr (o2::soa::is_filtered_table) { \ + auto result = std::vector(); \ + for (auto const& i : *mColumnIterator) { \ + auto pos = mBinding.get()->isInSelectedRows(i); \ + if (pos > 0) { \ + result.emplace_back(mBinding.get()->iteratorAt(pos)); \ + } \ + } \ + return result; \ + } else { \ + static_assert(o2::framework::always_static_assert_v, "T is not a Filtered type"); \ + } \ + return {}; \ + } \ + \ + auto _Getter_() const \ + { \ + return _Getter_##_as(); \ + } \ + \ + template \ + auto _Getter_##_first_as() const \ + { \ + if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ + o2::soa::notBoundTable(#_Table_); \ + } \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(); \ + } \ + return t->rawIteratorAt((*mColumnIterator)[0]); \ + } \ + \ + template \ + auto _Getter_##_last_as() const \ + { \ + if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ + o2::soa::notBoundTable(#_Table_); \ + } \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(); \ + } \ + return t->rawIteratorAt((*mColumnIterator).back()); \ + } \ + \ + auto _Getter_first() const \ + { \ + return _Getter_##_first_as(); \ + } \ + \ + auto _Getter_last() const \ + { \ + return _Getter_##_last_as(); \ + } \ + \ + template \ + bool setCurrent(T const* current) \ + { \ + if constexpr (o2::soa::is_binding_compatible_v()) { \ + assert(current != nullptr); \ + this->mBinding.bind(current); \ + return true; \ + } \ + return false; \ + } \ + \ + bool setCurrentRaw(o2::soa::Binding current) \ + { \ + this->mBinding = current; \ + return true; \ + } \ + binding_t const* getCurrent() const { return mBinding.get(); } \ + o2::soa::Binding getCurrentRaw() const { return mBinding; } \ + o2::soa::Binding mBinding; \ +>>>>>>> d058635d65 (DPL Analysis: reduce amount of base types for columns) }; #define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_) @@ -2698,17 +2829,17 @@ consteval auto getIndexTargets() /// NORMAL #define DECLARE_SOA_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \ - struct _Name_##Id : o2::soa::Column<_Type_, _Name_##Id> { \ + struct _Name_##Id : o2::soa::PersistentColumn<_Type_, _Name_##Id> { \ static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \ static constexpr const char* mLabel = "fIndex" _Label_ _Suffix_; \ - using base = o2::soa::Column<_Type_, _Name_##Id>; \ + using base = o2::soa::PersistentColumn<_Type_, _Name_##Id>; \ using type = _Type_; \ using column_t = _Name_##Id; \ using binding_t = _Table_; \ static constexpr auto index_targets = getIndexTargets<_Table_>(); \ _Name_##Id(arrow::ChunkedArray const* column) \ - : o2::soa::Column<_Type_, _Name_##Id>(o2::soa::ColumnIterator(column)) \ + : o2::soa::PersistentColumn<_Type_, _Name_##Id>(o2::soa::ColumnIterator(column)) \ { \ } \ \ @@ -2780,16 +2911,16 @@ consteval auto getIndexTargets() /// SELF #define DECLARE_SOA_SELF_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \ - struct _Name_##Id : o2::soa::Column<_Type_, _Name_##Id> { \ + struct _Name_##Id : o2::soa::PersistentColumn<_Type_, _Name_##Id> { \ static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ static constexpr const char* mLabel = "fIndex" _Label_; \ - using base = o2::soa::Column<_Type_, _Name_##Id>; \ + using base = o2::soa::PersistentColumn<_Type_, _Name_##Id>; \ using type = _Type_; \ using column_t = _Name_##Id; \ using self_index_t = std::true_type; \ using compatible_signature = std::conditional, _IndexTarget_, void>; \ _Name_##Id(arrow::ChunkedArray const* column) \ - : o2::soa::Column<_Type_, _Name_##Id>(o2::soa::ColumnIterator(column)) \ + : o2::soa::PersistentColumn<_Type_, _Name_##Id>(o2::soa::ColumnIterator(column)) \ { \ } \ \ @@ -2839,16 +2970,16 @@ consteval auto getIndexTargets() #define DECLARE_SOA_SELF_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, #_Name_) /// SELF SLICE #define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \ - struct _Name_##IdSlice : o2::soa::Column<_Type_[2], _Name_##IdSlice> { \ + struct _Name_##IdSlice : o2::soa::PersistentColumn<_Type_[2], _Name_##IdSlice> { \ static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ static constexpr const char* mLabel = "fIndexSlice" _Label_; \ - using base = o2::soa::Column<_Type_[2], _Name_##IdSlice>; \ + using base = o2::soa::PersistentColumn<_Type_[2], _Name_##IdSlice>; \ using type = _Type_[2]; \ using column_t = _Name_##IdSlice; \ using self_index_t = std::true_type; \ using compatible_signature = std::conditional, _IndexTarget_, void>; \ _Name_##IdSlice(arrow::ChunkedArray const* column) \ - : o2::soa::Column<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator(column)) \ + : o2::soa::PersistentColumn<_Type_[2], _Name_##IdSlice>(o2::soa::ColumnIterator(column)) \ { \ } \ \ @@ -2901,77 +3032,77 @@ consteval auto getIndexTargets() #define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void) #define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, "_" #_Name_) /// SELF ARRAY -#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \ - struct _Name_##Ids : o2::soa::Column, _Name_##Ids> { \ - static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ - static constexpr const char* mLabel = "fIndexArray" _Label_; \ - using base = o2::soa::Column, _Name_##Ids>; \ - using type = std::vector<_Type_>; \ - using column_t = _Name_##Ids; \ - using self_index_t = std::true_type; \ - using compatible_signature = std::conditional, _IndexTarget_, void>; \ - _Name_##Ids(arrow::ChunkedArray const* column) \ - : o2::soa::Column, _Name_##Ids>(o2::soa::ColumnIterator(column)) \ - { \ - } \ - \ - _Name_##Ids() = default; \ - _Name_##Ids(_Name_##Ids const& other) = default; \ - _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ - gsl::span inline getIds() const \ - { \ - return _Getter_##Ids(); \ - } \ - \ - gsl::span _Getter_##Ids() const \ - { \ - return *mColumnIterator; \ - } \ - \ - bool has_##_Getter_() const \ - { \ - return !(*mColumnIterator).empty(); \ - } \ - \ - template \ - auto _Getter_##_as() const \ - { \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \ - } \ - return getIterators(); \ - } \ - \ - template \ - auto getIterators() const \ - { \ - auto result = std::vector(); \ - for (auto& i : *mColumnIterator) { \ - result.push_back(mBinding.get()->rawIteratorAt(i)); \ - } \ - return result; \ - } \ - \ - template \ - auto _Getter_##_first_as() const \ - { \ - return mBinding.get()->rawIteratorAt((*mColumnIterator)[0]); \ - } \ - \ - template \ - auto _Getter_##_last_as() const \ - { \ - return mBinding.get()->rawIteratorAt((*mColumnIterator).back()); \ - } \ - \ - bool setCurrentRaw(o2::soa::Binding current) \ - { \ - this->mBinding = current; \ - return true; \ - } \ - o2::soa::Binding getCurrentRaw() const { return mBinding; } \ - o2::soa::Binding mBinding; \ +#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \ + struct _Name_##Ids : o2::soa::PersistentColumn, _Name_##Ids> { \ + static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ + static constexpr const char* mLabel = "fIndexArray" _Label_; \ + using base = o2::soa::PersistentColumn, _Name_##Ids>; \ + using type = std::vector<_Type_>; \ + using column_t = _Name_##Ids; \ + using self_index_t = std::true_type; \ + using compatible_signature = std::conditional, _IndexTarget_, void>; \ + _Name_##Ids(arrow::ChunkedArray const* column) \ + : o2::soa::PersistentColumn, _Name_##Ids>(o2::soa::ColumnIterator(column)) \ + { \ + } \ + \ + _Name_##Ids() = default; \ + _Name_##Ids(_Name_##Ids const& other) = default; \ + _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ + gsl::span inline getIds() const \ + { \ + return _Getter_##Ids(); \ + } \ + \ + gsl::span _Getter_##Ids() const \ + { \ + return *mColumnIterator; \ + } \ + \ + bool has_##_Getter_() const \ + { \ + return !(*mColumnIterator).empty(); \ + } \ + \ + template \ + auto _Getter_##_as() const \ + { \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \ + } \ + return getIterators(); \ + } \ + \ + template \ + auto getIterators() const \ + { \ + auto result = std::vector(); \ + for (auto& i : *mColumnIterator) { \ + result.push_back(mBinding.get()->rawIteratorAt(i)); \ + } \ + return result; \ + } \ + \ + template \ + auto _Getter_##_first_as() const \ + { \ + return mBinding.get()->rawIteratorAt((*mColumnIterator)[0]); \ + } \ + \ + template \ + auto _Getter_##_last_as() const \ + { \ + return mBinding.get()->rawIteratorAt((*mColumnIterator).back()); \ + } \ + \ + bool setCurrentRaw(o2::soa::Binding current) \ + { \ + this->mBinding = current; \ + return true; \ + } \ + o2::soa::Binding getCurrentRaw() const { return mBinding; } \ + o2::soa::Binding mBinding; \ }; #define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void) @@ -3015,8 +3146,8 @@ consteval auto getIndexTargets() using return_type = typename callable_t::return_type; \ }; \ template \ - struct _Name_ : o2::soa::DynamicColumn> { \ - using base = o2::soa::DynamicColumn>; \ + struct _Name_ : o2::soa::TransientColumn> { \ + using base = o2::soa::TransientColumn>; \ using helper = _Name_##Helper; \ using callback_holder_t = _Name_##Callback; \ using callable_t = helper::callable_t; \ From 3ff00508234c286d7aa6563589f4c19befe25fad Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Tue, 4 Feb 2025 12:43:42 +0100 Subject: [PATCH 2/6] fixup! DPL Analysis: reduce amount of base types for columns --- Framework/Core/include/Framework/ASoA.h | 145 ++++++++++++------------ 1 file changed, 73 insertions(+), 72 deletions(-) diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 65ac91f60f889..8bff7bb53dba7 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -2821,7 +2821,8 @@ consteval auto getIndexTargets() o2::soa::Binding getCurrentRaw() const { return mBinding; } \ o2::soa::Binding mBinding; \ >>>>>>> d058635d65 (DPL Analysis: reduce amount of base types for columns) - }; +} +; #define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_) #define DECLARE_SOA_ARRAY_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "") @@ -3032,77 +3033,77 @@ consteval auto getIndexTargets() #define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void) #define DECLARE_SOA_SELF_SLICE_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_SELF_SLICE_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, "_" #_Name_) /// SELF ARRAY -#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \ - struct _Name_##Ids : o2::soa::PersistentColumn, _Name_##Ids> { \ - static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ - static constexpr const char* mLabel = "fIndexArray" _Label_; \ - using base = o2::soa::PersistentColumn, _Name_##Ids>; \ - using type = std::vector<_Type_>; \ - using column_t = _Name_##Ids; \ - using self_index_t = std::true_type; \ - using compatible_signature = std::conditional, _IndexTarget_, void>; \ - _Name_##Ids(arrow::ChunkedArray const* column) \ - : o2::soa::PersistentColumn, _Name_##Ids>(o2::soa::ColumnIterator(column)) \ - { \ - } \ - \ - _Name_##Ids() = default; \ - _Name_##Ids(_Name_##Ids const& other) = default; \ - _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ - gsl::span inline getIds() const \ - { \ - return _Getter_##Ids(); \ - } \ - \ - gsl::span _Getter_##Ids() const \ - { \ - return *mColumnIterator; \ - } \ - \ - bool has_##_Getter_() const \ - { \ - return !(*mColumnIterator).empty(); \ - } \ - \ - template \ - auto _Getter_##_as() const \ - { \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \ - } \ - return getIterators(); \ - } \ - \ - template \ - auto getIterators() const \ - { \ - auto result = std::vector(); \ - for (auto& i : *mColumnIterator) { \ - result.push_back(mBinding.get()->rawIteratorAt(i)); \ - } \ - return result; \ - } \ - \ - template \ - auto _Getter_##_first_as() const \ - { \ - return mBinding.get()->rawIteratorAt((*mColumnIterator)[0]); \ - } \ - \ - template \ - auto _Getter_##_last_as() const \ - { \ - return mBinding.get()->rawIteratorAt((*mColumnIterator).back()); \ - } \ - \ - bool setCurrentRaw(o2::soa::Binding current) \ - { \ - this->mBinding = current; \ - return true; \ - } \ - o2::soa::Binding getCurrentRaw() const { return mBinding; } \ - o2::soa::Binding mBinding; \ +#define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, _IndexTarget_) \ + struct _Name_##Ids : o2::soa::PersistentColumn, _Name_##Ids> { \ + static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ + static constexpr const char* mLabel = "fIndexArray" _Label_; \ + using base = o2::soa::PersistentColumn, _Name_##Ids>; \ + using type = std::vector<_Type_>; \ + using column_t = _Name_##Ids; \ + using self_index_t = std::true_type; \ + using compatible_signature = std::conditional, _IndexTarget_, void>; \ + _Name_##Ids(arrow::ChunkedArray const* column) \ + : o2::soa::PersistentColumn, _Name_##Ids>(o2::soa::ColumnIterator(column)) \ + { \ + } \ + \ + _Name_##Ids() = default; \ + _Name_##Ids(_Name_##Ids const& other) = default; \ + _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ + gsl::span inline getIds() const \ + { \ + return _Getter_##Ids(); \ + } \ + \ + gsl::span _Getter_##Ids() const \ + { \ + return *mColumnIterator; \ + } \ + \ + bool has_##_Getter_() const \ + { \ + return !(*mColumnIterator).empty(); \ + } \ + \ + template \ + auto _Getter_##_as() const \ + { \ + auto t = mBinding.get(); \ + if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ + o2::soa::dereferenceWithWrongType(#_Getter_, "self"); \ + } \ + return getIterators(); \ + } \ + \ + template \ + auto getIterators() const \ + { \ + auto result = std::vector(); \ + for (auto& i : *mColumnIterator) { \ + result.push_back(mBinding.get()->rawIteratorAt(i)); \ + } \ + return result; \ + } \ + \ + template \ + auto _Getter_##_first_as() const \ + { \ + return mBinding.get()->rawIteratorAt((*mColumnIterator)[0]); \ + } \ + \ + template \ + auto _Getter_##_last_as() const \ + { \ + return mBinding.get()->rawIteratorAt((*mColumnIterator).back()); \ + } \ + \ + bool setCurrentRaw(o2::soa::Binding current) \ + { \ + this->mBinding = current; \ + return true; \ + } \ + o2::soa::Binding getCurrentRaw() const { return mBinding; } \ + o2::soa::Binding mBinding; \ }; #define DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Label_) DECLARE_SOA_SELF_ARRAY_INDEX_COLUMN_COMPLETE(_Name_, _Getter_, _Type_, _Label_, void) From efc6ff256fc0f6715a24da009d296ea89abca23a Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Tue, 4 Feb 2025 13:33:05 +0100 Subject: [PATCH 3/6] fixup! DPL Analysis: reduce amount of base types for columns --- Framework/Core/include/Framework/ASoA.h | 162 +----------------------- 1 file changed, 5 insertions(+), 157 deletions(-) diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 8bff7bb53dba7..e2514debd6385 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -2522,156 +2522,6 @@ consteval auto getIndexTargets() #define DECLARE_SOA_SLICE_INDEX_COLUMN_CUSTOM(_Name_, _Getter_, _Label_) DECLARE_SOA_SLICE_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, int32_t, _Name_##s, _Label_, "") /// ARRAY -<<<<<<< HEAD -#define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \ - struct _Name_##Ids : o2::soa::Column, _Name_##Ids> { \ - static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ - static_assert((*_Suffix_ == '\0') || (*_Suffix_ == '_'), "Suffix has to begin with _"); \ - static constexpr const char* mLabel = "fIndexArray" _Label_ _Suffix_; \ - using base = o2::soa::Column, _Name_##Ids>; \ - using type = std::vector<_Type_>; \ - using column_t = _Name_##Ids; \ - using binding_t = _Table_; \ - static constexpr auto index_targets = getIndexTargets<_Table_>(); \ - _Name_##Ids(arrow::ChunkedArray const* column) \ - : o2::soa::Column, _Name_##Ids>(o2::soa::ColumnIterator(column)) \ - { \ - } \ - \ - _Name_##Ids() = default; \ - _Name_##Ids(_Name_##Ids const& other) = default; \ - _Name_##Ids& operator=(_Name_##Ids const& other) = default; \ - \ - gsl::span inline getIds() const \ - { \ - return _Getter_##Ids(); \ - } \ - \ - gsl::span _Getter_##Ids() const \ - { \ - return *mColumnIterator; \ - } \ - \ - bool has_##_Getter_() const \ - { \ - return !(*mColumnIterator).empty(); \ - } \ - \ - template \ - auto _Getter_##_as() const \ - { \ - if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ - o2::soa::notBoundTable(#_Table_); \ - } \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \ - } \ - return getIterators(); \ - } \ - \ - template \ - auto filtered_##_Getter_##_as() const \ - { \ - if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ - o2::soa::notBoundTable(#_Table_); \ - } \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \ - } \ - return getFilteredIterators(); \ - } \ - \ - template \ - auto getIterators() const \ - { \ - auto result = std::vector(); \ - for (auto& i : *mColumnIterator) { \ - result.push_back(mBinding.get()->rawIteratorAt(i)); \ - } \ - return result; \ - } \ - \ - template \ - std::vector getFilteredIterators() const \ - { \ - if constexpr (o2::soa::is_filtered_table) { \ - auto result = std::vector(); \ - for (auto const& i : *mColumnIterator) { \ - auto pos = mBinding.get()->isInSelectedRows(i); \ - if (pos > 0) { \ - result.emplace_back(mBinding.get()->iteratorAt(pos)); \ - } \ - } \ - return result; \ - } else { \ - static_assert(o2::framework::always_static_assert_v, "T is not a Filtered type"); \ - } \ - return {}; \ - } \ - \ - auto _Getter_() const \ - { \ - return _Getter_##_as(); \ - } \ - \ - template \ - auto _Getter_##_first_as() const \ - { \ - if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ - o2::soa::notBoundTable(#_Table_); \ - } \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \ - } \ - return t->rawIteratorAt((*mColumnIterator)[0]); \ - } \ - \ - template \ - auto _Getter_##_last_as() const \ - { \ - if (O2_BUILTIN_UNLIKELY(mBinding.ptr == nullptr)) { \ - o2::soa::notBoundTable(#_Table_); \ - } \ - auto t = mBinding.get(); \ - if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \ - } \ - return t->rawIteratorAt((*mColumnIterator).back()); \ - } \ - \ - auto _Getter_first() const \ - { \ - return _Getter_##_first_as(); \ - } \ - \ - auto _Getter_last() const \ - { \ - return _Getter_##_last_as(); \ - } \ - \ - template \ - bool setCurrent(T const* current) \ - { \ - if constexpr (o2::soa::is_binding_compatible_v()) { \ - assert(current != nullptr); \ - this->mBinding.bind(current); \ - return true; \ - } \ - return false; \ - } \ - \ - bool setCurrentRaw(o2::soa::Binding current) \ - { \ - this->mBinding = current; \ - return true; \ - } \ - binding_t const* getCurrent() const { return mBinding.get(); } \ - o2::soa::Binding getCurrentRaw() const { return mBinding; } \ - o2::soa::Binding mBinding; \ -======= #define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, _Label_, _Suffix_) \ struct _Name_##Ids : o2::soa::PersistentColumn, _Name_##Ids> { \ static_assert(std::is_integral_v<_Type_>, "Index type must be integral"); \ @@ -2714,7 +2564,7 @@ consteval auto getIndexTargets() } \ auto t = mBinding.get(); \ if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(); \ + o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \ } \ return getIterators(); \ } \ @@ -2727,7 +2577,7 @@ consteval auto getIndexTargets() } \ auto t = mBinding.get(); \ if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(); \ + o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \ } \ return getFilteredIterators(); \ } \ @@ -2773,7 +2623,7 @@ consteval auto getIndexTargets() } \ auto t = mBinding.get(); \ if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(); \ + o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \ } \ return t->rawIteratorAt((*mColumnIterator)[0]); \ } \ @@ -2786,7 +2636,7 @@ consteval auto getIndexTargets() } \ auto t = mBinding.get(); \ if (O2_BUILTIN_UNLIKELY(t == nullptr)) { \ - o2::soa::dereferenceWithWrongType(); \ + o2::soa::dereferenceWithWrongType(#_Getter_, #_Table_); \ } \ return t->rawIteratorAt((*mColumnIterator).back()); \ } \ @@ -2820,9 +2670,7 @@ consteval auto getIndexTargets() binding_t const* getCurrent() const { return mBinding.get(); } \ o2::soa::Binding getCurrentRaw() const { return mBinding; } \ o2::soa::Binding mBinding; \ ->>>>>>> d058635d65 (DPL Analysis: reduce amount of base types for columns) -} -; + }; #define DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, _Type_, _Table_, _Suffix_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL_CUSTOM(_Name_, _Getter_, _Type_, _Table_, #_Table_, _Suffix_) #define DECLARE_SOA_ARRAY_INDEX_COLUMN(_Name_, _Getter_) DECLARE_SOA_ARRAY_INDEX_COLUMN_FULL(_Name_, _Getter_, int32_t, _Name_##s, "") From f256c31a7f73d4c74a934c155620fb6249dee821 Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Mon, 2 Jun 2025 09:26:57 +0200 Subject: [PATCH 4/6] adapt --- Framework/Core/include/Framework/ASoA.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index e2514debd6385..7630c9399180d 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -2380,10 +2380,10 @@ O2HASH("TEST/0"); /// A configurable 'expression' column. i.e. a column that can be calculated from other /// columns with gandiva based on dynamically supplied C++ expression or a string definition. #define DECLARE_SOA_CONFIGURABLE_EXPRESSION_COLUMN(_Name_, _Getter_, _Type_, _Label_) \ - struct _Name_ : o2::soa::Column<_Type_, _Name_> { \ + struct _Name_ : o2::soa::PersistentColumn<_Type_, _Name_> { \ static constexpr const char* mLabel = _Label_; \ static constexpr const int32_t mHash = _Label_ ""_h; \ - using base = o2::soa::Column<_Type_, _Name_>; \ + using base = o2::soa::PersistentColumn<_Type_, _Name_>; \ using type = _Type_; \ using column_t = _Name_; \ using spawnable_t = std::true_type; \ From 63c8664de599b6ce675dd9b72b92540445c75900 Mon Sep 17 00:00:00 2001 From: Anton Alkin Date: Mon, 2 Jun 2025 09:36:50 +0200 Subject: [PATCH 5/6] fixup! adapt --- Framework/Core/include/Framework/ASoA.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index 7630c9399180d..d22775a75ab10 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -2388,7 +2388,7 @@ O2HASH("TEST/0"); using column_t = _Name_; \ using spawnable_t = std::true_type; \ _Name_(arrow::ChunkedArray const* column) \ - : o2::soa::Column<_Type_, _Name_>(o2::soa::ColumnIterator(column)) \ + : o2::soa::PersistentColumn<_Type_, _Name_>(o2::soa::ColumnIterator(column)) \ { \ } \ \ From 5d8c6eea64515c23d6f75df647d72c84b60afa07 Mon Sep 17 00:00:00 2001 From: ALICE Action Bot Date: Mon, 2 Jun 2025 07:41:03 +0000 Subject: [PATCH 6/6] Please consider the following formatting changes --- Framework/Core/include/Framework/ASoA.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Framework/Core/include/Framework/ASoA.h b/Framework/Core/include/Framework/ASoA.h index d22775a75ab10..a3c0cc57ce285 100644 --- a/Framework/Core/include/Framework/ASoA.h +++ b/Framework/Core/include/Framework/ASoA.h @@ -2380,15 +2380,15 @@ O2HASH("TEST/0"); /// A configurable 'expression' column. i.e. a column that can be calculated from other /// columns with gandiva based on dynamically supplied C++ expression or a string definition. #define DECLARE_SOA_CONFIGURABLE_EXPRESSION_COLUMN(_Name_, _Getter_, _Type_, _Label_) \ - struct _Name_ : o2::soa::PersistentColumn<_Type_, _Name_> { \ + struct _Name_ : o2::soa::PersistentColumn<_Type_, _Name_> { \ static constexpr const char* mLabel = _Label_; \ static constexpr const int32_t mHash = _Label_ ""_h; \ - using base = o2::soa::PersistentColumn<_Type_, _Name_>; \ + using base = o2::soa::PersistentColumn<_Type_, _Name_>; \ using type = _Type_; \ using column_t = _Name_; \ using spawnable_t = std::true_type; \ _Name_(arrow::ChunkedArray const* column) \ - : o2::soa::PersistentColumn<_Type_, _Name_>(o2::soa::ColumnIterator(column)) \ + : o2::soa::PersistentColumn<_Type_, _Name_>(o2::soa::ColumnIterator(column)) \ { \ } \ \