11 #ifndef ROOT_RDF_TINTERFACE_UTILS
12 #define ROOT_RDF_TINTERFACE_UTILS
37 #include <type_traits>
40 #include <unordered_map>
53 template<
typename T,
typename V>
79 class RIgnoreErrorLevelRAII {
84 RIgnoreErrorLevelRAII(
int errorIgnoreLevel) {
gErrorIgnoreLevel = errorIgnoreLevel; }
92 namespace ActionTags {
110 template <typename T, bool ISV6HISTO = std::is_base_of<TH1, T>::value>
113 static bool HasAxisLimits(
T &
h)
115 auto xaxis =
h.GetXaxis();
116 return !(xaxis->GetXmin() == 0. && xaxis->GetXmax() == 0.);
120 template <
typename T>
121 struct HistoUtils<
T, false> {
122 static void SetCanExtendAllAxes(
T &) {}
123 static bool HasAxisLimits(
T &) {
return true; }
127 template <
typename... ColTypes,
typename ActionTag,
typename ActionResultType,
typename PrevNodeType>
128 std::unique_ptr<RActionBase>
129 BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &
h,
const unsigned int nSlots,
132 using Helper_t = FillParHelper<ActionResultType>;
133 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<ColTypes...>>;
134 return std::make_unique<Action_t>(Helper_t(
h, nSlots), bl, std::move(prevNode), defines);
138 template <
typename... ColTypes,
typename PrevNodeType>
139 std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<::TH1D> &
h,
140 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
143 auto hasAxisLimits = HistoUtils<::TH1D>::HasAxisLimits(*
h);
146 using Helper_t = FillParHelper<::TH1D>;
147 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<ColTypes...>>;
148 return std::make_unique<Action_t>(Helper_t(
h, nSlots), bl, std::move(prevNode), defines);
150 using Helper_t = FillHelper;
151 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<ColTypes...>>;
152 return std::make_unique<Action_t>(Helper_t(
h, nSlots), bl, std::move(prevNode), defines);
156 template <
typename... ColTypes,
typename PrevNodeType>
157 std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<TGraph> &
g,
158 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
161 using Helper_t = FillTGraphHelper;
162 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<ColTypes...>>;
163 return std::make_unique<Action_t>(Helper_t(
g, nSlots), bl, std::move(prevNode), defines);
167 template <
typename ColType,
typename PrevNodeType,
typename ActionResultType>
168 std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &minV,
169 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
172 using Helper_t = MinHelper<ActionResultType>;
173 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
174 return std::make_unique<Action_t>(Helper_t(minV, nSlots), bl, std::move(prevNode), defines);
178 template <
typename ColType,
typename PrevNodeType,
typename ActionResultType>
179 std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &maxV,
180 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
183 using Helper_t = MaxHelper<ActionResultType>;
184 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
185 return std::make_unique<Action_t>(Helper_t(maxV, nSlots), bl, std::move(prevNode), defines);
189 template <
typename ColType,
typename PrevNodeType,
typename ActionResultType>
190 std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<ActionResultType> &sumV,
191 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
194 using Helper_t = SumHelper<ActionResultType>;
195 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
196 return std::make_unique<Action_t>(Helper_t(sumV, nSlots), bl, std::move(prevNode), defines);
200 template <
typename ColType,
typename PrevNodeType>
201 std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<double> &meanV,
202 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
205 using Helper_t = MeanHelper;
206 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
207 return std::make_unique<Action_t>(Helper_t(meanV, nSlots), bl, std::move(prevNode), defines);
211 template <
typename ColType,
typename PrevNodeType>
212 std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<double> &stdDeviationV,
213 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode,
216 using Helper_t = StdDevHelper;
217 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
218 return std::make_unique<Action_t>(Helper_t(stdDeviationV, nSlots), bl, prevNode, defines);
222 template <
typename... ColTypes,
typename PrevNodeType>
223 std::unique_ptr<RActionBase> BuildAction(
const ColumnNames_t &bl,
const std::shared_ptr<RDisplay> &
d,
224 const unsigned int, std::shared_ptr<PrevNodeType> prevNode,
227 using Helper_t = DisplayHelper<PrevNodeType>;
228 using Action_t = RAction<Helper_t, PrevNodeType,
TTraits::TypeList<ColTypes...>>;
229 return std::make_unique<Action_t>(Helper_t(
d, prevNode), bl, prevNode, defines);
232 struct SnapshotHelperArgs {
233 std::string fFileName;
234 std::string fDirName;
235 std::string fTreeName;
236 std::vector<std::string> fOutputColNames;
241 template <
typename... ColTypes,
typename PrevNodeType>
242 std::unique_ptr<RActionBase>
243 BuildAction(
const ColumnNames_t &colNames,
const std::shared_ptr<SnapshotHelperArgs> &snapHelperArgs,
244 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode, ActionTags::Snapshot,
247 const auto &filename = snapHelperArgs->fFileName;
248 const auto &dirname = snapHelperArgs->fDirName;
249 const auto &treename = snapHelperArgs->fTreeName;
250 const auto &outputColNames = snapHelperArgs->fOutputColNames;
251 const auto &options = snapHelperArgs->fOptions;
253 std::unique_ptr<RActionBase> actionPtr;
256 using Helper_t = SnapshotHelper<ColTypes...>;
257 using Action_t = RAction<Helper_t, PrevNodeType>;
258 actionPtr.reset(
new Action_t(Helper_t(filename, dirname, treename, colNames, outputColNames, options), colNames,
262 using Helper_t = SnapshotHelperMT<ColTypes...>;
263 using Action_t = RAction<Helper_t, PrevNodeType>;
264 actionPtr.reset(
new Action_t(Helper_t(nSlots, filename, dirname, treename, colNames, outputColNames, options),
265 colNames, prevNode, defines));
272 template <
typename Filter>
273 void CheckFilter(
Filter &)
275 using FilterRet_t =
typename RDF::CallableTraits<Filter>::ret_type;
276 static_assert(std::is_convertible<FilterRet_t, bool>::value,
277 "filter expression returns a type that is not convertible to bool");
281 const std::map<std::string, std::string> &aliasMap,
const ColumnNames_t &dataSourceColumns);
285 void BookFilterJit(
const std::shared_ptr<RJittedFilter> &jittedFilter, std::shared_ptr<RNodeBase> *prevNodeOnHeap,
287 const std::map<std::string, std::string> &aliasMap,
const ColumnNames_t &branches,
293 std::shared_ptr<RNodeBase> *prevNodeOnHeap);
296 const std::type_info &art,
const std::type_info &at,
void *rOnHeap,
TTree *
tree,
298 RDataSource *
ds, std::weak_ptr<RJittedAction> *jittedActionOnHeap);
306 template <
typename T>
307 std::weak_ptr<T> *MakeWeakOnHeap(
const std::shared_ptr<T> &shPtr)
309 return new std::weak_ptr<T>(shPtr);
313 template <
typename T>
314 std::shared_ptr<T> *MakeSharedOnHeap(
const std::shared_ptr<T> &shPtr)
316 return new std::shared_ptr<T>(shPtr);
323 std::shared_ptr<RNodeBase>
UpcastNode(std::shared_ptr<RNodeBase> ptr);
336 template <
typename T>
342 const auto valuePtrs =
ds.GetColumnReaders<
T>(colName);
343 if (!valuePtrs.empty()) {
345 std::vector<void*> typeErasedValuePtrs(valuePtrs.begin(), valuePtrs.end());
352 template <
typename... ColumnTypes>
357 using expander =
int[];
359 (
void)expander{(AddDSColumnsHelper<ColumnTypes>(requiredCols[i], lm,
ds), ++i)..., 0};
363 template <
typename F,
typename PrevNode>
365 std::weak_ptr<RJittedFilter> *wkJittedFilter, std::shared_ptr<PrevNode> *prevNodeOnHeap,
368 if (wkJittedFilter->expired()) {
371 delete wkJittedFilter;
375 delete prevNodeOnHeap;
379 const auto jittedFilter = wkJittedFilter->lock();
384 using ColTypes_t =
typename TTraits::CallableTraits<Callable_t>::arg_types;
385 constexpr
auto nColumns = ColTypes_t::list_size;
386 RDFInternal::CheckFilter(
f);
392 RDFInternal::AddDSColumns(cols, lm, *
ds, ColTypes_t());
394 jittedFilter->SetFilter(
395 std::unique_ptr<RFilterBase>(
new F_t(std::forward<F>(
f), cols, *prevNodeOnHeap, *defines,
name)));
399 delete prevNodeOnHeap;
400 delete wkJittedFilter;
403 template <
typename F>
405 std::weak_ptr<RJittedDefine> *wkJittedDefine,
408 if (wkJittedDefine->expired()) {
411 delete wkJittedDefine;
415 delete prevNodeOnHeap;
419 auto jittedDefine = wkJittedDefine->lock();
423 using ColTypes_t =
typename TTraits::CallableTraits<Callable_t>::arg_types;
424 constexpr
auto nColumns = ColTypes_t::list_size;
428 RDFInternal::AddDSColumns(cols, *lm, *
ds, ColTypes_t());
432 const auto dummyType =
"jittedCol_t";
434 jittedDefine->SetDefine(std::unique_ptr<RDefineBase>(
442 delete prevNodeOnHeap;
443 delete wkJittedDefine;
447 template <
typename ActionTag,
typename... ColTypes,
typename PrevNodeType,
typename HelperArgType>
448 void CallBuildAction(std::shared_ptr<PrevNodeType> *prevNodeOnHeap,
const ColumnNames_t &cols,
449 const unsigned int nSlots, std::weak_ptr<HelperArgType> *wkHelperArgOnHeap,
450 std::weak_ptr<RJittedAction> *wkJittedActionOnHeap,
453 if (wkHelperArgOnHeap->expired()) {
454 delete wkHelperArgOnHeap;
455 delete wkJittedActionOnHeap;
459 delete prevNodeOnHeap;
463 const auto helperArgOnHeap = wkHelperArgOnHeap->lock();
464 auto jittedActionOnHeap = wkJittedActionOnHeap->lock();
467 auto &prevNodePtr = *prevNodeOnHeap;
468 auto &loopManager = *prevNodePtr->GetLoopManagerUnchecked();
469 using ColTypes_t =
TypeList<ColTypes...>;
470 constexpr
auto nColumns = ColTypes_t::list_size;
471 auto ds = loopManager.GetDataSource();
473 RDFInternal::AddDSColumns(cols, loopManager, *
ds, ColTypes_t());
476 BuildAction<ColTypes...>(cols, std::move(helperArgOnHeap), nSlots, std::move(prevNodePtr), ActionTag{}, *defines);
477 jittedActionOnHeap->SetAction(std::move(actionPtr));
483 delete wkHelperArgOnHeap;
484 delete prevNodeOnHeap;
485 delete wkJittedActionOnHeap;
489 template <typename T, bool Container = RDFInternal::IsDataContainer<T>::value && !std::is_same<T, std::string>::value>
490 struct RMinReturnType {
495 struct RMinReturnType<RInferredType, false> {
499 template <
typename T>
500 struct RMinReturnType<
T, true> {
501 using type = TTraits::TakeFirstParameter_t<T>;
505 template <
typename R,
typename F,
typename... Args>
508 return [
f](
unsigned int, Args...
a) ->
R {
return f(
a...); };
511 template <
typename ColType,
typename... Rest>
512 struct RNeedJittingHelper {
513 static constexpr
bool value = RNeedJittingHelper<Rest...>::value;
516 template <
typename... Rest>
517 struct RNeedJittingHelper<RInferredType, Rest...> {
518 static constexpr
bool value =
true;
521 template <
typename T>
522 struct RNeedJittingHelper<
T> {
523 static constexpr
bool value =
false;
527 struct RNeedJittingHelper<RInferredType> {
528 static constexpr
bool value =
true;
531 template <
typename ...ColTypes>
532 struct RNeedJitting {
533 static constexpr
bool value = RNeedJittingHelper<ColTypes...>::value;
537 struct RNeedJitting<> {
538 static constexpr
bool value =
false;
546 typename mergeArgsNoDecay_t =
typename CallableTraits<Merge>::arg_types_nodecay,
547 typename mergeArgs_t =
typename CallableTraits<Merge>::arg_types,
548 typename mergeRet_t =
typename CallableTraits<Merge>::ret_type>
551 constexpr
bool isAggregatorOk =
552 (std::is_same<R, decayedU>::value) || (std::is_same<R, void>::value && std::is_lvalue_reference<U>::value);
553 static_assert(isAggregatorOk,
"aggregator function must have signature `U(U,T)` or `void(U&,T)`");
554 constexpr
bool isMergeOk =
555 (std::is_same<TypeList<decayedU, decayedU>, mergeArgs_t>::value && std::is_same<decayedU, mergeRet_t>::value) ||
556 (std::is_same<
TypeList<std::vector<decayedU> &>, mergeArgsNoDecay_t>::value &&
557 std::is_same<void, mergeRet_t>::value);
558 static_assert(isMergeOk,
"merge function must have signature `U(U,U)` or `void(std::vector<U>&)`");
563 template <
typename R,
typename T>
564 void CheckAggregate(
T)
566 static_assert(
sizeof(
T) == 0,
"aggregator function must take exactly two arguments");
581 std::vector<std::string>
GetFilterNames(
const std::shared_ptr<RLoopManager> &loopManager);
584 template <
typename NodeType>
585 std::vector<std::string>
GetFilterNames(
const std::shared_ptr<NodeType> &node)
587 std::vector<std::string> filterNames;
588 node->AddFilterName(filterNames);
592 struct ParsedTreePath {
593 std::string fTreeName;
594 std::string fDirName;
603 template <
bool... bs>
604 using IsTrueForAllImpl_t =
typename std::is_same<TBoolPack<bs...,
true>, TBoolPack<
true, bs...>>;
606 template <
bool... Conditions>
608 static constexpr
bool value = IsTrueForAllImpl_t<Conditions...>::value;
615 struct IsList_t : std::false_type {};
617 template <
typename T>
618 struct IsList_t<std::list<T>> : std::true_type {};
621 struct IsDeque_t : std::false_type {};
623 template <
typename T>
624 struct IsDeque_t<std::deque<T>> : std::true_type {};
634 template <
typename T>
637 template <
typename T>
638 using MaxReturnType_t = MinReturnType_t<T>;
640 template <
typename T>
641 using SumReturnType_t = MinReturnType_t<T>;