Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RRange.hxx
Go to the documentation of this file.
1// Author: Enrico Guiraud, Danilo Piparo CERN 09/2018
2
3/*************************************************************************
4 * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11#ifndef ROOT_RDFRANGE
12#define ROOT_RDFRANGE
13
16#include "ROOT/RDF/Utils.hxx"
17#include "RtypesCore.h"
18
19#include <cassert>
20#include <memory>
21#include <string>
22#include <string_view>
23#include <vector>
24
25namespace ROOT {
26
27// fwd decl
28namespace Internal {
29namespace RDF {
30namespace GraphDrawing {
31std::shared_ptr<GraphNode> CreateRangeNode(const ROOT::Detail::RDF::RRangeBase *rangePtr,
32 std::unordered_map<void *, std::shared_ptr<GraphNode>> &visitedMap);
33} // ns GraphDrawing
34} // ns RDF
35} // ns Internal
36
37namespace Detail {
38namespace RDF {
40class RJittedFilter;
41
42template <typename PrevNodeRaw>
43class RRange final : public RRangeBase {
44 // If the PrevNode is a RJittedFilter, treat it as a more generic RFilterBase: when dealing with systematic
45 // variations we'll have a RJittedFilter node for the nominal case but other "universes" will use concrete filters,
46 // so we normalize the "previous node type" to the base type RFilterBase.
47 using PrevNode_t = std::conditional_t<std::is_same<PrevNodeRaw, RJittedFilter>::value, RFilterBase, PrevNodeRaw>;
48 const std::shared_ptr<PrevNode_t> fPrevNodePtr;
50
51public:
52 RRange(unsigned int start, unsigned int stop, unsigned int stride, std::shared_ptr<PrevNode_t> pd)
53 : RRangeBase(pd->GetLoopManagerUnchecked(), start, stop, stride, pd->GetLoopManagerUnchecked()->GetNSlots(),
54 pd->GetVariations()),
55 fPrevNodePtr(std::move(pd)), fPrevNode(*fPrevNodePtr)
56 {
58 }
59
60 RRange(const RRange &) = delete;
61 RRange &operator=(const RRange &) = delete;
62 // must call Deregister here, before fPrevNode is destroyed,
63 // otherwise if fPrevNode is fLoopManager we get a use after delete
65
66 /// Ranges act as filters when it comes to selecting entries that downstream nodes should process
67 bool CheckFilters(unsigned int slot, Long64_t entry) final
68 {
69 if (entry != fLastCheckedEntry) {
70 if (fHasStopped)
71 return false;
72 if (!fPrevNode.CheckFilters(slot, entry)) {
73 // a filter upstream returned false, cache the result
74 fLastResult = false;
75 } else {
76 // apply range filter logic, cache the result
78 (fStride != 1 && (fNProcessedEntries - fStart) % fStride != 0))
79 fLastResult = false;
80 else
81 fLastResult = true;
84 fHasStopped = true;
85 fPrevNode.StopProcessing();
86 }
87 }
88 fLastCheckedEntry = entry;
89 }
90 return fLastResult;
91 }
92
93 // recursive chain of `Report`s
94 // RRange simply forwards these calls to the previous node
95 void Report(ROOT::RDF::RCutFlowReport &rep) const final { fPrevNode.PartialReport(rep); }
96
97 void PartialReport(ROOT::RDF::RCutFlowReport &rep) const final { fPrevNode.PartialReport(rep); }
98
99 void StopProcessing() final
100 {
103 fPrevNode.StopProcessing();
104 }
105
106 void IncrChildrenCount() final
107 {
108 ++fNChildren;
109 // propagate "children activation" upstream
110 if (fNChildren == 1)
111 fPrevNode.IncrChildrenCount();
112 }
113
114 /// This function must be defined by all nodes, but only the filters will add their name
115 void AddFilterName(std::vector<std::string> &filters) final { fPrevNode.AddFilterName(filters); }
116 std::shared_ptr<RDFGraphDrawing::GraphNode>
117 GetGraph(std::unordered_map<void *, std::shared_ptr<RDFGraphDrawing::GraphNode>> &visitedMap) final
118 {
119 // TODO: Ranges node have no information about custom columns, hence it is not possible now
120 // if defines have been used before.
121 auto prevNode = fPrevNode.GetGraph(visitedMap);
122 const auto &prevColumns = prevNode->GetDefinedColumns();
123
124 auto thisNode = RDFGraphDrawing::CreateRangeNode(this, visitedMap);
125
126 /* If the returned node is not new, there is no need to perform any other operation.
127 * This is a likely scenario when building the entire graph in which branches share
128 * some nodes. */
129 if (!thisNode->IsNew()) {
130 return thisNode;
131 }
132 thisNode->SetPrevNode(prevNode);
133
134 // If there have been some defines between the last Filter and this Range node we won't detect them:
135 // Ranges don't keep track of Defines (they have no RColumnRegister data member).
136 // Let's pretend that the Defines of this node are the same as the node above, so that in the graph
137 // the Defines will just appear below the Range instead (no functional change).
138 // TODO: Converting the string_views for backward compatibility.
139 // Since they are names of defined columns, they were added to the
140 // register of column names of the RLoopManager object by the
141 // RColumnRegister, so we could also change GetDefinedColumns to return string_views directly
142 std::vector<std::string_view> colsViews;
143 colsViews.reserve(prevColumns.size());
144 for (const auto &col : prevColumns)
145 colsViews.push_back(col);
146 thisNode->AddDefinedColumns(colsViews);
147
148 return thisNode;
149 }
150
151 std::shared_ptr<RNodeBase> GetVariedFilter(const std::string &variationName) final
152 {
153 // nobody should ask for a varied filter for the nominal variation: they can just
154 // use the nominal filter!
155 assert(variationName != "nominal");
156 // nobody should ask for a varied filter for a variation on which this filter does not depend:
157 // they can just use the nominal filter.
158 assert(RDFInternal::IsStrInVec(variationName, fVariations));
159
160 auto it = fVariedRanges.find(variationName);
161 if (it != fVariedRanges.end())
162 return it->second;
163
164 auto prevNode = fPrevNodePtr;
165 if (static_cast<RNodeBase *>(fPrevNodePtr.get()) != static_cast<RNodeBase *>(fLoopManager) &&
166 RDFInternal::IsStrInVec(variationName, prevNode->GetVariations()))
167 prevNode = std::static_pointer_cast<PrevNode_t>(prevNode->GetVariedFilter(variationName));
168
169 auto variedRange = std::unique_ptr<RRangeBase>(new RRange(fStart, fStop, fStride, std::move(prevNode)));
170 auto e = fVariedRanges.insert({variationName, std::move(variedRange)});
171 return e.first->second;
172 }
173};
174
175} // namespace RDF
176} // namespace Detail
177} // namespace ROOT
178
179#endif // ROOT_RDFRANGE
#define e(i)
Definition RSha256.hxx:103
long long Long64_t
Definition RtypesCore.h:80
const char * filters[]
void Register(RDFInternal::RActionBase *actionPtr)
void Deregister(RDFInternal::RActionBase *actionPtr)
Base class for non-leaf nodes of the computational graph.
Definition RNodeBase.hxx:43
const std::vector< std::string > & GetVariations() const
Definition RNodeBase.hxx:74
virtual RLoopManager * GetLoopManagerUnchecked()
Definition RNodeBase.hxx:72
unsigned int fNStopsReceived
Number of times that a children node signaled to stop processing entries.
Definition RNodeBase.hxx:47
unsigned int fNChildren
Number of nodes of the functional graph hanging from this object.
Definition RNodeBase.hxx:46
std::vector< std::string > fVariations
List of systematic variations that affect this node.
Definition RNodeBase.hxx:48
std::unordered_map< std::string, std::shared_ptr< RRangeBase > > fVariedRanges
bool fHasStopped
True if the end of the range has been reached.
bool CheckFilters(unsigned int slot, Long64_t entry) final
Ranges act as filters when it comes to selecting entries that downstream nodes should process.
Definition RRange.hxx:67
const std::shared_ptr< PrevNode_t > fPrevNodePtr
Definition RRange.hxx:48
PrevNode_t & fPrevNode
Definition RRange.hxx:49
RRange & operator=(const RRange &)=delete
std::conditional_t< std::is_same< PrevNodeRaw, RJittedFilter >::value, RFilterBase, PrevNodeRaw > PrevNode_t
Definition RRange.hxx:47
void StopProcessing() final
Definition RRange.hxx:99
void IncrChildrenCount() final
Definition RRange.hxx:106
void AddFilterName(std::vector< std::string > &filters) final
This function must be defined by all nodes, but only the filters will add their name.
Definition RRange.hxx:115
void Report(ROOT::RDF::RCutFlowReport &rep) const final
Definition RRange.hxx:95
RRange(const RRange &)=delete
RRange(unsigned int start, unsigned int stop, unsigned int stride, std::shared_ptr< PrevNode_t > pd)
Definition RRange.hxx:52
std::shared_ptr< RNodeBase > GetVariedFilter(const std::string &variationName) final
Return a clone of this node that acts as a Filter working with values in the variationName "universe"...
Definition RRange.hxx:151
std::shared_ptr< RDFGraphDrawing::GraphNode > GetGraph(std::unordered_map< void *, std::shared_ptr< RDFGraphDrawing::GraphNode > > &visitedMap) final
Definition RRange.hxx:117
void PartialReport(ROOT::RDF::RCutFlowReport &rep) const final
Definition RRange.hxx:97
std::shared_ptr< GraphNode > CreateRangeNode(const ROOT::Detail::RDF::RRangeBase *rangePtr, std::unordered_map< void *, std::shared_ptr< GraphNode > > &visitedMap)
bool IsStrInVec(const std::string &str, const std::vector< std::string > &vec)
Definition RDFUtils.cxx:439
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...