Project
Loading...
Searching...
No Matches
GroupSlicer.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
12#ifndef FRAMEWORK_GROUP_SLICER_H_
13#define FRAMEWORK_GROUP_SLICER_H_
14
15#include "Framework/Pack.h"
16#include "Framework/ASoA.h"
18
19#include <arrow/util/config.h>
20#include <arrow/util/key_value_metadata.h>
21#include <type_traits>
22#include <string>
23namespace
24{
25template <typename T>
26auto getMatcherFor(std::string const& columnName, o2::header::DataOrigin newOrigin = o2::header::DataOrigin{"AOD"})
27{
28 auto matcher = o2::soa::getMatcherFromTypeForKey<std::decay_t<T>>(columnName);
29 if ((matcher.origin == o2::header::DataOrigin{"AOD"}) && (newOrigin != o2::header::DataOrigin{"AOD"})) {
30 matcher = o2::framework::replaceOrigin(matcher, newOrigin);
31 }
32 return matcher;
33}
34} // namespace
35
36namespace o2::framework
37{
38template <typename G, typename... A>
40 using grouping_t = std::decay_t<G>;
41 GroupSlicer(G& gt, std::tuple<A...>& at, ArrowTableSlicingCache& slices, header::DataOrigin newOrigin = header::DataOrigin{"AOD"})
42 : max{gt.size()},
43 mBegin{GroupSlicerIterator(gt, at, slices, newOrigin)}
44 {
45 }
46
48 int64_t position;
49 };
50
53
59
60 template <typename T>
62 {
63 }
64
65 template <soa::is_table T>
66 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<T>>() && !soa::is_smallgroups<T>)
67 auto splittingFunction(T&& table)
68 {
69 if (table.size() == 0) {
70 return;
71 }
72 sliceInfos[framework::has_type_at_v<std::decay_t<T>>(associated_pack_t{})] = mSlices->getCacheFor(Entry("", getMatcherFor<T>(mIndexColumnName, replacementOrigin), mIndexColumnName));
73 }
74
75 template <soa::is_smallgroups T>
76 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<T>>())
77 auto splittingFunction(T&& table)
78 {
79 if (table.tableSize() == 0) {
80 return;
81 }
82 sliceInfosUnsorted[framework::has_type_at_v<std::decay_t<T>>(associated_pack_t{})] = mSlices->getCacheUnsortedFor(Entry("", getMatcherFor<T>(mIndexColumnName, replacementOrigin), mIndexColumnName));
83 }
84
85 template <typename T>
87 {
88 }
89
90 template <soa::is_filtered_table T>
91 auto extractingFunction(T&& table)
92 {
93 constexpr auto index = framework::has_type_at_v<std::decay_t<T>>(associated_pack_t{});
94 selections[index] = &table.getSelectedRows();
95 starts[index] = selections[index]->begin();
96 }
97
98 GroupSlicerIterator(G& gt, std::tuple<A...>& at, ArrowTableSlicingCache& slices, header::DataOrigin newOrigin = header::DataOrigin{"AOD"})
99 : mIndexColumnName{std::string("fIndex") + o2::framework::cutString(o2::soa::getLabelFromType<G>())},
100 mGt{&gt},
101 mAt{&at},
103 position{0},
104 mSlices{&slices},
105 replacementOrigin{newOrigin}
106 {
108 groupSelection = mGt->getSelectedRows();
109 }
110
114
115 [this]<size_t... Is>(std::tuple<A...>& at, std::index_sequence<Is...>) {
116 (splittingFunction(std::get<Is>(at)), ...);
117 (extractingFunction(std::get<Is>(at)), ...);
118 }(*mAt, std::make_index_sequence<sizeof...(A)>());
119 }
120
122 {
123 ++position;
125 return *this;
126 }
127
129 {
130 GroupSlicerIterator copy = *this;
131 copy.position += inc;
132 copy.mGroupingElement = copy.mGroupingElement + inc;
133 return copy;
134 }
135
137 {
138 position += inc;
139 mGroupingElement += inc;
140 return *this;
141 }
142
144 {
145 return O2_BUILTIN_UNLIKELY(position == other.position);
146 }
147
149 {
150 return O2_BUILTIN_LIKELY(position != other.position);
151 }
152
154 {
155 return mGroupingElement;
156 }
157
159 {
160 return *this;
161 }
162
164 {
165 return std::make_tuple(prepareArgument<A>()...);
166 }
167
168 template <soa::is_smallgroups A1>
169 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<A1>>() && soa::is_filtered_table<A1>)
171 {
172 constexpr auto index = framework::has_type_at_v<A1>(associated_pack_t{});
173 auto& originalTable = std::get<A1>(*mAt);
177 } else {
178 pos = position;
179 }
180 // generic split
181 auto selection = sliceInfosUnsorted[index].getSliceFor(pos);
182 // intersect selections
184 if (selections[index]->empty()) {
185 if (!selection.empty()) {
186 std::copy(selection.begin(), selection.end(), std::back_inserter(s));
187 }
188 } else {
189 if (!selection.empty()) {
190 if constexpr (std::decay_t<A1>::applyFilters) {
191 std::set_intersection(selection.begin(), selection.end(), selections[index]->begin(), selections[index]->end(), std::back_inserter(s));
192 } else {
193 std::copy(selection.begin(), selection.end(), std::back_inserter(s));
194 }
195 }
196 }
197 std::decay_t<A1> typedTable{{originalTable.asArrowTableRef()}, std::move(s)};
198 typedTable.bindInternalIndicesTo(&originalTable);
199 return typedTable;
200 }
201
202 template <soa::is_filtered_table A1>
203 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<A1>>() && !soa::is_smallgroups<A1>)
205 {
206 constexpr auto index = framework::has_type_at_v<A1>(associated_pack_t{});
207 auto& originalTable = std::get<A1>(*mAt);
208 if (originalTable.size() == 0) {
209 return originalTable;
210 }
214 } else {
215 pos = position;
216 }
217 // optimized split
218 auto oc = sliceInfos[index].getSliceFor(pos);
219 uint64_t offset = oc.first;
220 auto count = oc.second;
221 auto groupedElementsTable = originalTable.asArrowTableRef().slice({offset, count});
222
223 // for each grouping element we need to slice the selection vector
224 auto start_iterator = std::lower_bound(starts[index], selections[index]->end(), offset);
225 auto stop_iterator = std::lower_bound(start_iterator, selections[index]->end(), offset + count);
226 starts[index] = stop_iterator;
227 soa::SelectionVector slicedSelection{start_iterator, stop_iterator};
228 std::transform(slicedSelection.begin(), slicedSelection.end(), slicedSelection.begin(),
229 [&offset](int64_t idx) {
230 return idx - static_cast<int64_t>(offset);
231 });
232
233 std::decay_t<A1> typedTable{{groupedElementsTable}, std::move(slicedSelection)};
234 typedTable.bindInternalIndicesTo(&originalTable);
235 return typedTable;
236 }
237
238 template <soa::is_table A1>
239 requires(o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<A1>>() && !soa::is_smallgroups<A1> && !soa::is_filtered_table<A1>)
241 {
242 constexpr auto index = framework::has_type_at_v<A1>(associated_pack_t{});
243 auto& originalTable = std::get<A1>(*mAt);
244 if (originalTable.size() == 0) {
245 return originalTable;
246 }
250 } else {
251 pos = position;
252 }
253 // optimized split
254 auto [offset, count] = sliceInfos[index].getSliceFor(pos);
255 auto groupedElementsTable = originalTable.rawSlice(offset, offset + count - 1);
256 groupedElementsTable.bindInternalIndicesTo(&originalTable);
257 return groupedElementsTable;
258 }
259
260 template <soa::is_table A1>
261 requires(!o2::soa::relatedByIndex<std::decay_t<G>, std::decay_t<A1>>() && !soa::is_smallgroups<A1>)
263 {
264 return std::get<A1>(*mAt);
265 }
266
267 std::string mIndexColumnName;
268 G const* mGt;
269 std::tuple<A...>* mAt;
270 typename grouping_t::iterator mGroupingElement;
272 std::span<int64_t const> groupSelection;
273 std::array<std::span<int64_t const> const*, sizeof...(A)> selections;
274 std::array<std::span<int64_t const>::iterator, sizeof...(A)> starts;
275
276 std::array<SliceInfoPtr, sizeof...(A)> sliceInfos;
277 std::array<SliceInfoUnsortedPtr, sizeof...(A)> sliceInfosUnsorted;
280 };
281
283 {
284 return mBegin;
285 }
286
288 {
289 return GroupSlicerSentinel{max};
290 }
291 int64_t max;
293};
294
295} // namespace o2::framework
296#endif // FRAMEWORK_GROUP_SLICER_H_
#define O2_BUILTIN_LIKELY(x)
#define O2_BUILTIN_UNLIKELY(x)
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
uint16_t pos
Definition RawData.h:3
Definition A.h:16
GLsizei const GLchar *const * string
Definition glcorearb.h:809
GLint GLsizei count
Definition glcorearb.h:399
GLsizeiptr size
Definition glcorearb.h:659
GLuint index
Definition glcorearb.h:781
GLintptr offset
Definition glcorearb.h:660
constexpr framework::ConcreteDataMatcher matcher()
Definition ASoA.h:388
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
ConfigParamSpec replaceOrigin(ConfigParamSpec &source, std::string const &originStr)
std::string cutString(std::string &&str)
Definition ASoA.cxx:322
std::vector< int64_t > SelectionVector
Definition ASoA.h:444
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
void empty(int)
SliceInfoUnsortedPtr getCacheUnsortedFor(Entry const &bindingKey) const
SliceInfoPtr getCacheFor(Entry const &bindingKey) const
std::array< SliceInfoUnsortedPtr, sizeof...(A)> sliceInfosUnsorted
GroupSlicerIterator operator+(int64_t inc) const
std::array< std::span< int64_t const >::iterator, sizeof...(A)> starts
std::array< SliceInfoPtr, sizeof...(A)> sliceInfos
GroupSlicerIterator & operator=(GroupSlicerIterator const &)=default
GroupSlicerIterator(GroupSlicerIterator &&)=default
bool operator!=(GroupSlicerSentinel const &other)
GroupSlicerIterator & operator=(GroupSlicerIterator &&)=default
GroupSlicerIterator operator+=(int64_t inc)
GroupSlicerIterator(GroupSlicerIterator const &)=default
std::array< std::span< int64_t const > const *, sizeof...(A)> selections
GroupSlicerIterator(G &gt, std::tuple< A... > &at, ArrowTableSlicingCache &slices, header::DataOrigin newOrigin=header::DataOrigin{"AOD"})
Definition GroupSlicer.h:98
bool operator==(GroupSlicerSentinel const &other)
GroupSlicerSentinel end()
GroupSlicer(G &gt, std::tuple< A... > &at, ArrowTableSlicingCache &slices, header::DataOrigin newOrigin=header::DataOrigin{"AOD"})
Definition GroupSlicer.h:41
GroupSlicerIterator mBegin
std::decay_t< G > grouping_t
Definition GroupSlicer.h:40
GroupSlicerIterator & begin()
VectorOfTObjectPtrs other