File indexing completed on 2024-11-15 09:55:42
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef ROOT_RDF_TINTERFACE_UTILS
0012 #define ROOT_RDF_TINTERFACE_UTILS
0013
0014 #include "RColumnRegister.hxx"
0015 #include <ROOT/RDF/RAction.hxx>
0016 #include <ROOT/RDF/ActionHelpers.hxx> // for BuildAction
0017 #include <ROOT/RDF/RColumnRegister.hxx>
0018 #include <ROOT/RDF/RDefine.hxx>
0019 #include <ROOT/RDF/RDefinePerSample.hxx>
0020 #include <ROOT/RDF/RFilter.hxx>
0021 #include <ROOT/RDF/Utils.hxx>
0022 #include <ROOT/RDF/RJittedAction.hxx>
0023 #include <ROOT/RDF/RJittedDefine.hxx>
0024 #include <ROOT/RDF/RJittedFilter.hxx>
0025 #include <ROOT/RDF/RJittedVariation.hxx>
0026 #include <ROOT/RDF/RLoopManager.hxx>
0027 #include <ROOT/RStringView.hxx>
0028 #include <ROOT/RDF/RVariation.hxx>
0029 #include <ROOT/TypeTraits.hxx>
0030 #include <TError.h> // gErrorIgnoreLevel
0031 #include <TH1.h>
0032 #include <TROOT.h> // IsImplicitMTEnabled
0033
0034 #include <deque>
0035 #include <functional>
0036 #include <map>
0037 #include <memory>
0038 #include <string>
0039 #include <type_traits>
0040 #include <typeinfo>
0041 #include <vector>
0042 #include <unordered_map>
0043
0044 class TObjArray;
0045 class TTree;
0046 namespace ROOT {
0047 namespace Detail {
0048 namespace RDF {
0049 class RNodeBase;
0050 }
0051 }
0052 namespace RDF {
0053 template <typename T>
0054 class RResultPtr;
0055 template<typename T, typename V>
0056 class RInterface;
0057 using RNode = RInterface<::ROOT::Detail::RDF::RNodeBase, void>;
0058 class RDataSource;
0059 }
0060
0061 }
0062
0063
0064
0065 namespace ROOT {
0066 namespace Internal {
0067 namespace RDF {
0068 using namespace ROOT::Detail::RDF;
0069 using namespace ROOT::RDF;
0070 namespace TTraits = ROOT::TypeTraits;
0071
0072 std::string DemangleTypeIdName(const std::type_info &typeInfo);
0073
0074 ColumnNames_t
0075 ConvertRegexToColumns(const ColumnNames_t &colNames, std::string_view columnNameRegexp, std::string_view callerName);
0076
0077
0078 class RIgnoreErrorLevelRAII {
0079 private:
0080 int fCurIgnoreErrorLevel = gErrorIgnoreLevel;
0081
0082 public:
0083 RIgnoreErrorLevelRAII(int errorIgnoreLevel) { gErrorIgnoreLevel = errorIgnoreLevel; }
0084 ~RIgnoreErrorLevelRAII() { gErrorIgnoreLevel = fCurIgnoreErrorLevel; }
0085 };
0086
0087
0088
0089
0090
0091 namespace ActionTags {
0092 struct Histo1D{};
0093 struct Histo2D{};
0094 struct Histo3D{};
0095 struct HistoND{};
0096 struct Graph{};
0097 struct GraphAsymmErrors{};
0098 struct Profile1D{};
0099 struct Profile2D{};
0100 struct Min{};
0101 struct Max{};
0102 struct Sum{};
0103 struct Mean{};
0104 struct Fill{};
0105 struct StdDev{};
0106 struct Display{};
0107 struct Snapshot{};
0108 struct Book{};
0109 }
0110
0111
0112 template <typename T, bool ISV6HISTO = std::is_base_of<TH1, std::decay_t<T>>::value>
0113 struct HistoUtils {
0114 static void SetCanExtendAllAxes(T &h) { h.SetCanExtend(::TH1::kAllAxes); }
0115 static bool HasAxisLimits(T &h)
0116 {
0117 auto xaxis = h.GetXaxis();
0118 return !(xaxis->GetXmin() == 0. && xaxis->GetXmax() == 0.);
0119 }
0120 };
0121
0122 template <typename T>
0123 struct HistoUtils<T, false> {
0124 static void SetCanExtendAllAxes(T &) {}
0125 static bool HasAxisLimits(T &) { return true; }
0126 };
0127
0128
0129 template <typename... ColTypes, typename ActionTag, typename ActionResultType, typename PrevNodeType>
0130 std::unique_ptr<RActionBase>
0131 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<ActionResultType> &h, const unsigned int nSlots,
0132 std::shared_ptr<PrevNodeType> prevNode, ActionTag, const RColumnRegister &colRegister)
0133 {
0134 using Helper_t = FillHelper<ActionResultType>;
0135 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0136 return std::make_unique<Action_t>(Helper_t(h, nSlots), bl, std::move(prevNode), colRegister);
0137 }
0138
0139
0140 template <typename... ColTypes, typename PrevNodeType>
0141 std::unique_ptr<RActionBase>
0142 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<::TH1D> &h, const unsigned int nSlots,
0143 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Histo1D, const RColumnRegister &colRegister)
0144 {
0145 auto hasAxisLimits = HistoUtils<::TH1D>::HasAxisLimits(*h);
0146
0147 if (hasAxisLimits || !IsImplicitMTEnabled()) {
0148 using Helper_t = FillHelper<::TH1D>;
0149 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0150 return std::make_unique<Action_t>(Helper_t(h, nSlots), bl, std::move(prevNode), colRegister);
0151 } else {
0152 using Helper_t = BufferedFillHelper;
0153 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0154 return std::make_unique<Action_t>(Helper_t(h, nSlots), bl, std::move(prevNode), colRegister);
0155 }
0156 }
0157
0158 template <typename... ColTypes, typename PrevNodeType>
0159 std::unique_ptr<RActionBase>
0160 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<TGraph> &g, const unsigned int nSlots,
0161 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Graph, const RColumnRegister &colRegister)
0162 {
0163 using Helper_t = FillTGraphHelper;
0164 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0165 return std::make_unique<Action_t>(Helper_t(g, nSlots), bl, std::move(prevNode), colRegister);
0166 }
0167
0168 template <typename... ColTypes, typename PrevNodeType>
0169 std::unique_ptr<RActionBase>
0170 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<TGraphAsymmErrors> &g, const unsigned int nSlots,
0171 std::shared_ptr<PrevNodeType> prevNode, ActionTags::GraphAsymmErrors, const RColumnRegister &colRegister)
0172 {
0173 using Helper_t = FillTGraphAsymmErrorsHelper;
0174 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0175 return std::make_unique<Action_t>(Helper_t(g, nSlots), bl, std::move(prevNode), colRegister);
0176 }
0177
0178
0179 template <typename ColType, typename PrevNodeType, typename ActionResultType>
0180 std::unique_ptr<RActionBase>
0181 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<ActionResultType> &minV, const unsigned int nSlots,
0182 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Min, const RColumnRegister &colRegister)
0183 {
0184 using Helper_t = MinHelper<ActionResultType>;
0185 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
0186 return std::make_unique<Action_t>(Helper_t(minV, nSlots), bl, std::move(prevNode), colRegister);
0187 }
0188
0189
0190 template <typename ColType, typename PrevNodeType, typename ActionResultType>
0191 std::unique_ptr<RActionBase>
0192 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<ActionResultType> &maxV, const unsigned int nSlots,
0193 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Max, const RColumnRegister &colRegister)
0194 {
0195 using Helper_t = MaxHelper<ActionResultType>;
0196 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
0197 return std::make_unique<Action_t>(Helper_t(maxV, nSlots), bl, std::move(prevNode), colRegister);
0198 }
0199
0200
0201 template <typename ColType, typename PrevNodeType, typename ActionResultType>
0202 std::unique_ptr<RActionBase>
0203 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<ActionResultType> &sumV, const unsigned int nSlots,
0204 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Sum, const RColumnRegister &colRegister)
0205 {
0206 using Helper_t = SumHelper<ActionResultType>;
0207 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
0208 return std::make_unique<Action_t>(Helper_t(sumV, nSlots), bl, std::move(prevNode), colRegister);
0209 }
0210
0211
0212 template <typename ColType, typename PrevNodeType>
0213 std::unique_ptr<RActionBase>
0214 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<double> &meanV, const unsigned int nSlots,
0215 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Mean, const RColumnRegister &colRegister)
0216 {
0217 using Helper_t = MeanHelper;
0218 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
0219 return std::make_unique<Action_t>(Helper_t(meanV, nSlots), bl, std::move(prevNode), colRegister);
0220 }
0221
0222
0223 template <typename ColType, typename PrevNodeType>
0224 std::unique_ptr<RActionBase>
0225 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<double> &stdDeviationV, const unsigned int nSlots,
0226 std::shared_ptr<PrevNodeType> prevNode, ActionTags::StdDev, const RColumnRegister &colRegister)
0227 {
0228 using Helper_t = StdDevHelper;
0229 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColType>>;
0230 return std::make_unique<Action_t>(Helper_t(stdDeviationV, nSlots), bl, prevNode, colRegister);
0231 }
0232
0233 using displayHelperArgs_t = std::pair<size_t, std::shared_ptr<ROOT::RDF::RDisplay>>;
0234
0235
0236 template <typename... ColTypes, typename PrevNodeType>
0237 std::unique_ptr<RActionBase>
0238 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<displayHelperArgs_t> &helperArgs, const unsigned int,
0239 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Display, const RColumnRegister &colRegister)
0240 {
0241 using Helper_t = DisplayHelper<PrevNodeType>;
0242 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0243 return std::make_unique<Action_t>(Helper_t(helperArgs->first, helperArgs->second, prevNode), bl, prevNode,
0244 colRegister);
0245 }
0246
0247 struct SnapshotHelperArgs {
0248 std::string fFileName;
0249 std::string fDirName;
0250 std::string fTreeName;
0251 std::vector<std::string> fOutputColNames;
0252 ROOT::RDF::RSnapshotOptions fOptions;
0253 };
0254
0255
0256 template <typename... ColTypes, typename PrevNodeType>
0257 std::unique_ptr<RActionBase>
0258 BuildAction(const ColumnNames_t &colNames, const std::shared_ptr<SnapshotHelperArgs> &snapHelperArgs,
0259 const unsigned int nSlots, std::shared_ptr<PrevNodeType> prevNode, ActionTags::Snapshot,
0260 const RColumnRegister &colRegister)
0261 {
0262 const auto &filename = snapHelperArgs->fFileName;
0263 const auto &dirname = snapHelperArgs->fDirName;
0264 const auto &treename = snapHelperArgs->fTreeName;
0265 const auto &outputColNames = snapHelperArgs->fOutputColNames;
0266 const auto &options = snapHelperArgs->fOptions;
0267
0268 auto makeIsDefine = [&] {
0269 std::vector<bool> isDef;
0270 isDef.reserve(sizeof...(ColTypes));
0271 for (auto i = 0u; i < sizeof...(ColTypes); ++i)
0272 isDef.push_back(colRegister.IsDefineOrAlias(colNames[i]));
0273 return isDef;
0274 };
0275 std::vector<bool> isDefine = makeIsDefine();
0276
0277 std::unique_ptr<RActionBase> actionPtr;
0278 if (!ROOT::IsImplicitMTEnabled()) {
0279
0280 using Helper_t = SnapshotHelper<ColTypes...>;
0281 using Action_t = RAction<Helper_t, PrevNodeType>;
0282 actionPtr.reset(
0283 new Action_t(Helper_t(filename, dirname, treename, colNames, outputColNames, options, std::move(isDefine)),
0284 colNames, prevNode, colRegister));
0285 } else {
0286
0287 using Helper_t = SnapshotHelperMT<ColTypes...>;
0288 using Action_t = RAction<Helper_t, PrevNodeType>;
0289 actionPtr.reset(new Action_t(
0290 Helper_t(nSlots, filename, dirname, treename, colNames, outputColNames, options, std::move(isDefine)),
0291 colNames, prevNode, colRegister));
0292 }
0293 return actionPtr;
0294 }
0295
0296
0297 template <typename... ColTypes, typename PrevNodeType, typename Helper_t>
0298 std::unique_ptr<RActionBase>
0299 BuildAction(const ColumnNames_t &bl, const std::shared_ptr<Helper_t> &h, const unsigned int ,
0300 std::shared_ptr<PrevNodeType> prevNode, ActionTags::Book, const RColumnRegister &colRegister)
0301 {
0302 using Action_t = RAction<Helper_t, PrevNodeType, TTraits::TypeList<ColTypes...>>;
0303 return std::make_unique<Action_t>(Helper_t(std::move(*h)), bl, std::move(prevNode), colRegister);
0304 }
0305
0306
0307
0308 template <typename Filter>
0309 void CheckFilter(Filter &)
0310 {
0311 using FilterRet_t = typename RDF::CallableTraits<Filter>::ret_type;
0312 static_assert(std::is_convertible<FilterRet_t, bool>::value,
0313 "filter expression returns a type that is not convertible to bool");
0314 }
0315
0316 ColumnNames_t FilterArraySizeColNames(const ColumnNames_t &columnNames, const std::string &action);
0317
0318 void CheckValidCppVarName(std::string_view var, const std::string &where);
0319
0320 void CheckForRedefinition(const std::string &where, std::string_view definedCol, const RColumnRegister &colRegister,
0321 const ColumnNames_t &treeColumns, const ColumnNames_t &dataSourceColumns);
0322
0323 void CheckForDefinition(const std::string &where, std::string_view definedColView, const RColumnRegister &colRegister,
0324 const ColumnNames_t &treeColumns, const ColumnNames_t &dataSourceColumns);
0325
0326 void CheckForNoVariations(const std::string &where, std::string_view definedColView,
0327 const RColumnRegister &colRegister);
0328
0329 std::string PrettyPrintAddr(const void *const addr);
0330
0331 std::shared_ptr<RJittedFilter> BookFilterJit(std::shared_ptr<RNodeBase> *prevNodeOnHeap, std::string_view name,
0332 std::string_view expression, const ColumnNames_t &branches,
0333 const RColumnRegister &colRegister, TTree *tree, RDataSource *ds);
0334
0335 std::shared_ptr<RJittedDefine> BookDefineJit(std::string_view name, std::string_view expression, RLoopManager &lm,
0336 RDataSource *ds, const RColumnRegister &colRegister,
0337 const ColumnNames_t &branches, std::shared_ptr<RNodeBase> *prevNodeOnHeap);
0338
0339 std::shared_ptr<RJittedDefine> BookDefinePerSampleJit(std::string_view name, std::string_view expression,
0340 RLoopManager &lm, const RColumnRegister &colRegister,
0341 std::shared_ptr<RNodeBase> *upcastNodeOnHeap);
0342
0343 std::shared_ptr<RJittedVariation>
0344 BookVariationJit(const std::vector<std::string> &colNames, std::string_view variationName,
0345 const std::vector<std::string> &variationTags, std::string_view expression, RLoopManager &lm,
0346 RDataSource *ds, const RColumnRegister &colRegister, const ColumnNames_t &branches,
0347 std::shared_ptr<RNodeBase> *upcastNodeOnHeap, bool isSingleColumn);
0348
0349 std::string JitBuildAction(const ColumnNames_t &bl, std::shared_ptr<RDFDetail::RNodeBase> *prevNode,
0350 const std::type_info &art, const std::type_info &at, void *rOnHeap, TTree *tree,
0351 const unsigned int nSlots, const RColumnRegister &colRegister, RDataSource *ds,
0352 std::weak_ptr<RJittedAction> *jittedActionOnHeap);
0353
0354
0355
0356
0357
0358
0359
0360 template <typename T>
0361 std::weak_ptr<T> *MakeWeakOnHeap(const std::shared_ptr<T> &shPtr)
0362 {
0363 return new std::weak_ptr<T>(shPtr);
0364 }
0365
0366
0367 template <typename T>
0368 std::shared_ptr<T> *MakeSharedOnHeap(const std::shared_ptr<T> &shPtr)
0369 {
0370 return new std::shared_ptr<T>(shPtr);
0371 }
0372
0373 bool AtLeastOneEmptyString(const std::vector<std::string_view> strings);
0374
0375
0376
0377 std::shared_ptr<RNodeBase> UpcastNode(std::shared_ptr<RNodeBase> ptr);
0378
0379 ColumnNames_t GetValidatedColumnNames(RLoopManager &lm, const unsigned int nColumns, const ColumnNames_t &columns,
0380 const RColumnRegister &validDefines, RDataSource *ds);
0381
0382 std::vector<std::string> GetValidatedArgTypes(const ColumnNames_t &colNames, const RColumnRegister &colRegister,
0383 TTree *tree, RDataSource *ds, const std::string &context,
0384 bool vector2rvec);
0385
0386 std::vector<bool> FindUndefinedDSColumns(const ColumnNames_t &requestedCols, const ColumnNames_t &definedDSCols);
0387
0388 template <typename T>
0389 void AddDSColumnsHelper(const std::string &colName, RLoopManager &lm, RDataSource &ds, RColumnRegister &colRegister)
0390 {
0391 if (colRegister.IsDefineOrAlias(colName) || !ds.HasColumn(colName) ||
0392 lm.HasDataSourceColumnReaders(colName, typeid(T)))
0393 return;
0394
0395 const auto nSlots = lm.GetNSlots();
0396 std::vector<std::unique_ptr<RColumnReaderBase>> colReaders;
0397 colReaders.reserve(nSlots);
0398
0399 const auto valuePtrs = ds.GetColumnReaders<T>(colName);
0400 if (!valuePtrs.empty()) {
0401 for (auto *ptr : valuePtrs)
0402 colReaders.emplace_back(new RDSColumnReader<T>(ptr));
0403
0404 } else {
0405
0406 for (auto slot = 0u; slot < lm.GetNSlots(); ++slot)
0407 colReaders.emplace_back(ds.GetColumnReaders(slot, colName, typeid(T)));
0408 }
0409
0410 lm.AddDataSourceColumnReaders(colName, std::move(colReaders), typeid(T));
0411 }
0412
0413
0414
0415 template <typename... ColumnTypes>
0416 void AddDSColumns(const std::vector<std::string> &requiredCols, RLoopManager &lm, RDataSource &ds,
0417 TTraits::TypeList<ColumnTypes...>, RColumnRegister &colRegister)
0418 {
0419
0420 using expander = int[];
0421 int i = 0;
0422 (void)expander{(AddDSColumnsHelper<ColumnTypes>(requiredCols[i], lm, ds, colRegister), ++i)..., 0};
0423 }
0424
0425
0426 template <typename F, typename PrevNode>
0427 void JitFilterHelper(F &&f, const char **colsPtr, std::size_t colsSize, std::string_view name,
0428 std::weak_ptr<RJittedFilter> *wkJittedFilter, std::shared_ptr<PrevNode> *prevNodeOnHeap,
0429 RColumnRegister *colRegister) noexcept
0430 {
0431 if (wkJittedFilter->expired()) {
0432
0433
0434 delete wkJittedFilter;
0435 delete colRegister;
0436 delete prevNodeOnHeap;
0437 return;
0438 }
0439
0440 const ColumnNames_t cols(colsPtr, colsPtr + colsSize);
0441 delete[] colsPtr;
0442
0443 const auto jittedFilter = wkJittedFilter->lock();
0444
0445
0446 using Callable_t = std::decay_t<F>;
0447 using F_t = RFilter<Callable_t, PrevNode>;
0448 using ColTypes_t = typename TTraits::CallableTraits<Callable_t>::arg_types;
0449 constexpr auto nColumns = ColTypes_t::list_size;
0450 CheckFilter(f);
0451
0452 auto &lm = *jittedFilter->GetLoopManagerUnchecked();
0453 auto ds = lm.GetDataSource();
0454
0455 if (ds != nullptr)
0456 AddDSColumns(cols, lm, *ds, ColTypes_t(), *colRegister);
0457
0458 jittedFilter->SetFilter(
0459 std::unique_ptr<RFilterBase>(new F_t(std::forward<F>(f), cols, *prevNodeOnHeap, *colRegister, name)));
0460
0461
0462 delete colRegister;
0463 delete prevNodeOnHeap;
0464 delete wkJittedFilter;
0465 }
0466
0467 namespace DefineTypes {
0468 struct RDefineTag {};
0469 struct RDefinePerSampleTag {};
0470 }
0471
0472 template <typename F>
0473 auto MakeDefineNode(DefineTypes::RDefineTag, std::string_view name, std::string_view dummyType, F &&f,
0474 const ColumnNames_t &cols, RColumnRegister &colRegister, RLoopManager &lm)
0475 {
0476 return std::unique_ptr<RDefineBase>(new RDefine<std::decay_t<F>, ExtraArgsForDefine::None>(
0477 name, dummyType, std::forward<F>(f), cols, colRegister, lm));
0478 }
0479
0480 template <typename F>
0481 auto MakeDefineNode(DefineTypes::RDefinePerSampleTag, std::string_view name, std::string_view dummyType, F &&f,
0482 const ColumnNames_t &, RColumnRegister &, RLoopManager &lm)
0483 {
0484 return std::unique_ptr<RDefineBase>(
0485 new RDefinePerSample<std::decay_t<F>>(name, dummyType, std::forward<F>(f), lm));
0486 }
0487
0488
0489
0490
0491 template <typename RDefineTypeTag, typename F>
0492 void JitDefineHelper(F &&f, const char **colsPtr, std::size_t colsSize, std::string_view name, RLoopManager *lm,
0493 std::weak_ptr<RJittedDefine> *wkJittedDefine, RColumnRegister *colRegister,
0494 std::shared_ptr<RNodeBase> *prevNodeOnHeap) noexcept
0495 {
0496
0497 auto doDeletes = [&] {
0498 delete wkJittedDefine;
0499 delete colRegister;
0500 delete prevNodeOnHeap;
0501 delete[] colsPtr;
0502 };
0503
0504 if (wkJittedDefine->expired()) {
0505
0506
0507 doDeletes();
0508 return;
0509 }
0510
0511 const ColumnNames_t cols(colsPtr, colsPtr + colsSize);
0512
0513 auto jittedDefine = wkJittedDefine->lock();
0514
0515 using Callable_t = std::decay_t<F>;
0516 using ColTypes_t = typename TTraits::CallableTraits<Callable_t>::arg_types;
0517
0518 auto ds = lm->GetDataSource();
0519 if (ds != nullptr)
0520 AddDSColumns(cols, *lm, *ds, ColTypes_t(), *colRegister);
0521
0522
0523
0524 const auto dummyType = "jittedCol_t";
0525
0526 std::unique_ptr<RDefineBase> newCol{
0527 MakeDefineNode(RDefineTypeTag{}, name, dummyType, std::forward<F>(f), cols, *colRegister, *lm)};
0528 jittedDefine->SetDefine(std::move(newCol));
0529
0530 doDeletes();
0531 }
0532
0533 template <bool IsSingleColumn, typename F>
0534 void JitVariationHelper(F &&f, const char **colsPtr, std::size_t colsSize, const char **variedCols,
0535 std::size_t variedColsSize, const char **variationTags, std::size_t variationTagsSize,
0536 std::string_view variationName, RLoopManager *lm,
0537 std::weak_ptr<RJittedVariation> *wkJittedVariation, RColumnRegister *colRegister,
0538 std::shared_ptr<RNodeBase> *prevNodeOnHeap) noexcept
0539 {
0540
0541 auto doDeletes = [&] {
0542 delete[] colsPtr;
0543 delete[] variedCols;
0544 delete[] variationTags;
0545
0546 delete wkJittedVariation;
0547 delete colRegister;
0548 delete prevNodeOnHeap;
0549 };
0550
0551 if (wkJittedVariation->expired()) {
0552
0553
0554 doDeletes();
0555 return;
0556 }
0557
0558 const ColumnNames_t inputColNames(colsPtr, colsPtr + colsSize);
0559 std::vector<std::string> variedColNames(variedCols, variedCols + variedColsSize);
0560 std::vector<std::string> tags(variationTags, variationTags + variationTagsSize);
0561
0562 auto jittedVariation = wkJittedVariation->lock();
0563
0564 using Callable_t = std::decay_t<F>;
0565 using ColTypes_t = typename TTraits::CallableTraits<Callable_t>::arg_types;
0566
0567 auto ds = lm->GetDataSource();
0568 if (ds != nullptr)
0569 AddDSColumns(inputColNames, *lm, *ds, ColTypes_t(), *colRegister);
0570
0571
0572 std::unique_ptr<RVariationBase> newVariation{new RVariation<std::decay_t<F>, IsSingleColumn>(
0573 std::move(variedColNames), variationName, std::forward<F>(f), std::move(tags), jittedVariation->GetTypeName(),
0574 *colRegister, *lm, std::move(inputColNames))};
0575 jittedVariation->SetVariation(std::move(newVariation));
0576
0577 doDeletes();
0578 }
0579
0580
0581 template <typename ActionTag, typename... ColTypes, typename PrevNodeType, typename HelperArgType>
0582 void CallBuildAction(std::shared_ptr<PrevNodeType> *prevNodeOnHeap, const char **colsPtr, std::size_t colsSize,
0583 const unsigned int nSlots, std::shared_ptr<HelperArgType> *helperArgOnHeap,
0584 std::weak_ptr<RJittedAction> *wkJittedActionOnHeap, RColumnRegister *colRegister) noexcept
0585 {
0586
0587 auto doDeletes = [&] {
0588 delete[] colsPtr;
0589 delete helperArgOnHeap;
0590 delete wkJittedActionOnHeap;
0591
0592
0593 delete colRegister;
0594 delete prevNodeOnHeap;
0595 };
0596
0597 if (wkJittedActionOnHeap->expired()) {
0598
0599
0600 doDeletes();
0601 return;
0602 }
0603
0604 const ColumnNames_t cols(colsPtr, colsPtr + colsSize);
0605
0606 auto jittedActionOnHeap = wkJittedActionOnHeap->lock();
0607
0608
0609 auto &prevNodePtr = *prevNodeOnHeap;
0610 auto &loopManager = *prevNodePtr->GetLoopManagerUnchecked();
0611 using ColTypes_t = TypeList<ColTypes...>;
0612 constexpr auto nColumns = ColTypes_t::list_size;
0613 auto ds = loopManager.GetDataSource();
0614 if (ds != nullptr)
0615 AddDSColumns(cols, loopManager, *ds, ColTypes_t(), *colRegister);
0616
0617 auto actionPtr = BuildAction<ColTypes...>(cols, std::move(*helperArgOnHeap), nSlots, std::move(prevNodePtr),
0618 ActionTag{}, *colRegister);
0619 jittedActionOnHeap->SetAction(std::move(actionPtr));
0620
0621 doDeletes();
0622 }
0623
0624
0625 template <typename T, bool Container = IsDataContainer<T>::value && !std::is_same<T, std::string>::value>
0626 struct RMinReturnType {
0627 using type = T;
0628 };
0629
0630 template <>
0631 struct RMinReturnType<RInferredType, false> {
0632 using type = double;
0633 };
0634
0635 template <typename T>
0636 struct RMinReturnType<T, true> {
0637 using type = TTraits::TakeFirstParameter_t<T>;
0638 };
0639
0640
0641 template <typename R, typename F, typename... Args>
0642 std::function<R(unsigned int, Args...)> AddSlotParameter(F &f, TypeList<Args...>)
0643 {
0644 return [f](unsigned int, Args... a) mutable -> R { return f(a...); };
0645 }
0646
0647 template <typename ColType, typename... Rest>
0648 struct RNeedJittingHelper {
0649 static constexpr bool value = RNeedJittingHelper<Rest...>::value;
0650 };
0651
0652 template <typename... Rest>
0653 struct RNeedJittingHelper<RInferredType, Rest...> {
0654 static constexpr bool value = true;
0655 };
0656
0657 template <typename T>
0658 struct RNeedJittingHelper<T> {
0659 static constexpr bool value = false;
0660 };
0661
0662 template <>
0663 struct RNeedJittingHelper<RInferredType> {
0664 static constexpr bool value = true;
0665 };
0666
0667 template <typename ...ColTypes>
0668 struct RNeedJitting {
0669 static constexpr bool value = RNeedJittingHelper<ColTypes...>::value;
0670 };
0671
0672 template <>
0673 struct RNeedJitting<> {
0674 static constexpr bool value = false;
0675 };
0676
0677
0678
0679
0680
0681 template <typename R, typename Merge, typename U, typename T, typename decayedU = std::decay_t<U>,
0682 typename mergeArgsNoDecay_t = typename CallableTraits<Merge>::arg_types_nodecay,
0683 typename mergeArgs_t = typename CallableTraits<Merge>::arg_types,
0684 typename mergeRet_t = typename CallableTraits<Merge>::ret_type>
0685 void CheckAggregate(TypeList<U, T>)
0686 {
0687 constexpr bool isAggregatorOk =
0688 (std::is_same<R, decayedU>::value) || (std::is_same<R, void>::value && std::is_lvalue_reference<U>::value);
0689 static_assert(isAggregatorOk, "aggregator function must have signature `U(U,T)` or `void(U&,T)`");
0690 constexpr bool isMergeOk =
0691 (std::is_same<TypeList<decayedU, decayedU>, mergeArgs_t>::value && std::is_same<decayedU, mergeRet_t>::value) ||
0692 (std::is_same<TypeList<std::vector<decayedU> &>, mergeArgsNoDecay_t>::value &&
0693 std::is_same<void, mergeRet_t>::value);
0694 static_assert(isMergeOk, "merge function must have signature `U(U,U)` or `void(std::vector<U>&)`");
0695 }
0696
0697
0698
0699 template <typename R, typename T>
0700 void CheckAggregate(T)
0701 {
0702 static_assert(sizeof(T) == 0, "aggregator function must take exactly two arguments");
0703 }
0704
0705
0706
0707 void CheckTypesAndPars(unsigned int nTemplateParams, unsigned int nColumnNames);
0708
0709
0710 const ColumnNames_t SelectColumns(unsigned int nArgs, const ColumnNames_t &bl, const ColumnNames_t &defBl);
0711
0712
0713 ColumnNames_t FindUnknownColumns(const ColumnNames_t &requiredCols, const ColumnNames_t &datasetColumns,
0714 const RColumnRegister &definedCols, const ColumnNames_t &dataSourceColumns);
0715
0716
0717 std::vector<std::string> GetFilterNames(const std::shared_ptr<RLoopManager> &loopManager);
0718
0719
0720 template <typename NodeType>
0721 std::vector<std::string> GetFilterNames(const std::shared_ptr<NodeType> &node)
0722 {
0723 std::vector<std::string> filterNames;
0724 node->AddFilterName(filterNames);
0725 return filterNames;
0726 }
0727
0728 struct ParsedTreePath {
0729 std::string fTreeName;
0730 std::string fDirName;
0731 };
0732
0733 ParsedTreePath ParseTreePath(std::string_view fullTreeName);
0734
0735
0736 template <bool...>
0737 struct TBoolPack;
0738
0739 template <bool... bs>
0740 using IsTrueForAllImpl_t = typename std::is_same<TBoolPack<bs..., true>, TBoolPack<true, bs...>>;
0741
0742 template <bool... Conditions>
0743 struct TEvalAnd {
0744 static constexpr bool value = IsTrueForAllImpl_t<Conditions...>::value;
0745 };
0746
0747
0748
0749
0750 template <typename>
0751 struct IsList_t : std::false_type {};
0752
0753 template <typename T>
0754 struct IsList_t<std::list<T>> : std::true_type {};
0755
0756 template <typename>
0757 struct IsDeque_t : std::false_type {};
0758
0759 template <typename T>
0760 struct IsDeque_t<std::deque<T>> : std::true_type {};
0761
0762
0763 void CheckForDuplicateSnapshotColumns(const ColumnNames_t &cols);
0764
0765 template <typename T>
0766 struct InnerValueType {
0767 using type = T;
0768 };
0769
0770 template <typename Elem>
0771 struct InnerValueType<ROOT::VecOps::RVec<ROOT::VecOps::RVec<Elem>>> {
0772 using type = Elem;
0773 };
0774
0775 template <typename T>
0776 using InnerValueType_t = typename InnerValueType<T>::type;
0777
0778 std::pair<std::vector<std::string>, std::vector<std::string>>
0779 AddSizeBranches(const std::vector<std::string> &branches, TTree *tree, std::vector<std::string> &&colsWithoutAliases,
0780 std::vector<std::string> &&colsWithAliases);
0781
0782 void RemoveDuplicates(ColumnNames_t &columnNames);
0783
0784 }
0785 }
0786
0787 namespace Detail {
0788 namespace RDF {
0789
0790
0791 template <typename T>
0792 using MinReturnType_t = typename RDFInternal::RMinReturnType<T>::type;
0793
0794 template <typename T>
0795 using MaxReturnType_t = MinReturnType_t<T>;
0796
0797 template <typename T>
0798 using SumReturnType_t = MinReturnType_t<T>;
0799
0800 }
0801 }
0802 }
0803
0804
0805
0806 #endif