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
22namespace ROOT {
23
24// fwd decl
25namespace Internal {
26namespace RDF {
27namespace GraphDrawing {
28std::shared_ptr<GraphNode> CreateRangeNode(const ROOT::Detail::RDF::RRangeBase *rangePtr,
29 std::unordered_map<void *, std::shared_ptr<GraphNode>> &visitedMap);
30} // ns GraphDrawing
31} // ns RDF
32} // ns Internal
33
34namespace Detail {
35namespace RDF {
37class RJittedFilter;
38
39template <typename PrevNodeRaw>
40class RRange final : public RRangeBase {
41 // If the PrevNode is a RJittedFilter, treat it as a more generic RFilterBase: when dealing with systematic
42 // variations we'll have a RJittedFilter node for the nominal case but other "universes" will use concrete filters,
43 // so we normalize the "previous node type" to the base type RFilterBase.
44 using PrevNode_t = std::conditional_t<std::is_same<PrevNodeRaw, RJittedFilter>::value, RFilterBase, PrevNodeRaw>;
45 const std::shared_ptr<PrevNode_t> fPrevNodePtr;
47
48public:
49 RRange(unsigned int start, unsigned int stop, unsigned int stride, std::shared_ptr<PrevNode_t> pd)
50 : RRangeBase(pd->GetLoopManagerUnchecked(), start, stop, stride, pd->GetLoopManagerUnchecked()->GetNSlots(),
51 pd->GetVariations()),
52 fPrevNodePtr(std::move(pd)), fPrevNode(*fPrevNodePtr)
53 {
55 }
56
57 RRange(const RRange &) = delete;
58 RRange &operator=(const RRange &) = delete;
59 // must call Deregister here, before fPrevNode is destroyed,
60 // otherwise if fPrevNode is fLoopManager we get a use after delete
62
63 /// Ranges act as filters when it comes to selecting entries that downstream nodes should process
64 bool CheckFilters(unsigned int slot, Long64_t entry) final
65 {
66 if (entry != fLastCheckedEntry) {
67 if (fHasStopped)
68 return false;
69 if (!fPrevNode.CheckFilters(slot, entry)) {
70 // a filter upstream returned false, cache the result
71 fLastResult = false;
72 } else {
73 // apply range filter logic, cache the result
75 (fStride != 1 && (fNProcessedEntries - fStart) % fStride != 0))
76 fLastResult = false;
77 else
78 fLastResult = true;
81 fHasStopped = true;
82 fPrevNode.StopProcessing();
83 }
84 }
85 fLastCheckedEntry = entry;
86 }
87 return fLastResult;
88 }
89
90 // recursive chain of `Report`s
91 // RRange simply forwards these calls to the previous node
92 void Report(ROOT::RDF::RCutFlowReport &rep) const final { fPrevNode.PartialReport(rep); }
93
94 void PartialReport(ROOT::RDF::RCutFlowReport &rep) const final { fPrevNode.PartialReport(rep); }
95
96 void StopProcessing() final
97 {
100 fPrevNode.StopProcessing();
101 }
102
103 void IncrChildrenCount() final
104 {
105 ++fNChildren;
106 // propagate "children activation" upstream
107 if (fNChildren == 1)
108 fPrevNode.IncrChildrenCount();
109 }
110
111 /// This function must be defined by all nodes, but only the filters will add their name
112 void AddFilterName(std::vector<std::string> &filters) final { fPrevNode.AddFilterName(filters); }
113 std::shared_ptr<RDFGraphDrawing::GraphNode>
114 GetGraph(std::unordered_map<void *, std::shared_ptr<RDFGraphDrawing::GraphNode>> &visitedMap) final
115 {
116 // TODO: Ranges node have no information about custom columns, hence it is not possible now
117 // if defines have been used before.
118 auto prevNode = fPrevNode.GetGraph(visitedMap);
119 const auto &prevColumns = prevNode->GetDefinedColumns();
120
121 auto thisNode = RDFGraphDrawing::CreateRangeNode(this, visitedMap);
122
123 /* If the returned node is not new, there is no need to perform any other operation.
124 * This is a likely scenario when building the entire graph in which branches share
125 * some nodes. */
126 if (!thisNode->IsNew()) {
127 return thisNode;
128 }
129 thisNode->SetPrevNode(prevNode);
130
131 // If there have been some defines between the last Filter and this Range node we won't detect them:
132 // Ranges don't keep track of Defines (they have no RColumnRegister data member).
133 // Let's pretend that the Defines of this node are the same as the node above, so that in the graph
134 // the Defines will just appear below the Range instead (no functional change).
135 thisNode->AddDefinedColumns(prevColumns);
136
137 return thisNode;
138 }
139
140 std::shared_ptr<RNodeBase> GetVariedFilter(const std::string &variationName) final
141 {
142 // nobody should ask for a varied filter for the nominal variation: they can just
143 // use the nominal filter!
144 assert(variationName != "nominal");
145 // nobody should ask for a varied filter for a variation on which this filter does not depend:
146 // they can just use the nominal filter.
147 assert(RDFInternal::IsStrInVec(variationName, fVariations));
148
149 auto it = fVariedRanges.find(variationName);
150 if (it != fVariedRanges.end())
151 return it->second;
152
153 auto prevNode = fPrevNodePtr;
154 if (static_cast<RNodeBase *>(fPrevNodePtr.get()) != static_cast<RNodeBase *>(fLoopManager) &&
155 RDFInternal::IsStrInVec(variationName, prevNode->GetVariations()))
156 prevNode = std::static_pointer_cast<PrevNode_t>(prevNode->GetVariedFilter(variationName));
157
158 auto variedRange = std::unique_ptr<RRangeBase>(new RRange(fStart, fStop, fStride, std::move(prevNode)));
159 auto e = fVariedRanges.insert({variationName, std::move(variedRange)});
160 return e.first->second;
161 }
162};
163
164} // namespace RDF
165} // namespace Detail
166} // namespace ROOT
167
168#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:64
const std::shared_ptr< PrevNode_t > fPrevNodePtr
Definition RRange.hxx:45
PrevNode_t & fPrevNode
Definition RRange.hxx:46
RRange & operator=(const RRange &)=delete
std::conditional_t< std::is_same< PrevNodeRaw, RJittedFilter >::value, RFilterBase, PrevNodeRaw > PrevNode_t
Definition RRange.hxx:44
void StopProcessing() final
Definition RRange.hxx:96
void IncrChildrenCount() final
Definition RRange.hxx:103
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:112
void Report(ROOT::RDF::RCutFlowReport &rep) const final
Definition RRange.hxx:92
RRange(const RRange &)=delete
RRange(unsigned int start, unsigned int stop, unsigned int stride, std::shared_ptr< PrevNode_t > pd)
Definition RRange.hxx:49
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:140
std::shared_ptr< RDFGraphDrawing::GraphNode > GetGraph(std::unordered_map< void *, std::shared_ptr< RDFGraphDrawing::GraphNode > > &visitedMap) final
Definition RRange.hxx:114
void PartialReport(ROOT::RDF::RCutFlowReport &rep) const final
Definition RRange.hxx:94
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:417
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.