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