Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
Utils.hxx
Go to the documentation of this file.
1// Author: Enrico Guiraud, Danilo Piparo CERN 12/2016
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_RDFUTILS
12#define ROOT_RDFUTILS
13
14#include "ROOT/RSpan.hxx"
15#include <string_view>
16#include "ROOT/RVec.hxx"
17#include "ROOT/TypeTraits.hxx"
18#include "Rtypes.h"
19
20#include <array>
21#include <deque>
22#include <functional>
23#include <memory>
24#include <new> // std::hardware_destructive_interference_size
25#include <unordered_set>
26#include <shared_mutex>
27#include <string>
28#include <type_traits> // std::decay, std::false_type
29#include <vector>
30
31class TTree;
32class TTreeReader;
33
35class RDatasetSpec;
36}
37namespace ROOT {
38namespace RDF {
39using ColumnNames_t = std::vector<std::string>;
40}
41
42class RLogChannel;
43
44namespace RDF {
45class RDataSource;
46}
47
48namespace Detail {
49namespace RDF {
50
52
54
55// fwd decl for ColumnName2ColumnTypeName
56class RDefineBase;
57
58// type used for tag dispatching
60};
61
62} // end ns Detail
63} // end ns RDF
64
65namespace Internal {
66namespace RDF {
67
68/// Warn once about experimental filling of RHist.
69void WarnHist();
70/// Warn once about experimental filling of RProfile.
71void WarnProfile();
72
73using namespace ROOT::TypeTraits;
74using namespace ROOT::Detail::RDF;
75using namespace ROOT::RDF;
76
77/// Obtain or set the number of threads that will share a clone of a thread-safe 3D histogram.
78/// Setting it to N will make N threads share a clone, setting it to 0 or 1 will use one clone
79/// per thread.
80/// Setting it to higher numbers reduces the RDF memory consumption, but might create contention
81/// on TH3Ds. When the RDF computation graph consists mostly of filling TH3Ds, lower values are better.
82/// \return A reference to the current divider.
83unsigned int &NThreadPerTH3();
84
85/// Check for container traits.
86///
87/// Note that for all uses in RDF we don't want to classify std::string as a container.
88/// Template specializations of IsDataContainer make it return `true` for std::span<T>, std::vector<bool> and
89/// RVec<bool>, which we do want to count as containers even though they do not satisfy all the traits tested by the
90/// generic IsDataContainer<T>.
91template <typename T>
93 using Test_t = std::decay_t<T>;
94
95 template <typename A>
96 static constexpr bool Test(A *pt, A const *cpt = nullptr, decltype(pt->begin()) * = nullptr,
97 decltype(pt->end()) * = nullptr, decltype(cpt->begin()) * = nullptr,
98 decltype(cpt->end()) * = nullptr, typename A::iterator *pi = nullptr,
99 typename A::const_iterator *pci = nullptr)
100 {
101 using It_t = typename A::iterator;
102 using CIt_t = typename A::const_iterator;
103 using V_t = typename A::value_type;
104 return std::is_same<decltype(pt->begin()), It_t>::value && std::is_same<decltype(pt->end()), It_t>::value &&
105 std::is_same<decltype(cpt->begin()), CIt_t>::value && std::is_same<decltype(cpt->end()), CIt_t>::value &&
106 std::is_same<decltype(**pi), V_t &>::value && std::is_same<decltype(**pci), V_t const &>::value &&
107 !std::is_same<T, std::string>::value;
108 }
109
110 template <typename A>
111 static constexpr bool Test(...)
112 {
113 return false;
114 }
115
116 static constexpr bool value = Test<Test_t>(nullptr);
117};
118
119template<>
120struct IsDataContainer<std::vector<bool>> {
121 static constexpr bool value = true;
122};
123
124template<>
126 static constexpr bool value = true;
127};
128
129template<typename T>
130struct IsDataContainer<std::span<T>> {
131 static constexpr bool value = true;
132};
133
134/// Detect whether a type is an instantiation of vector<T,A>
135template <typename>
136struct IsVector_t : public std::false_type {};
137
138template <typename T, typename A>
139struct IsVector_t<std::vector<T, A>> : public std::true_type {};
140
141std::string GetBranchOrLeafTypeName(TTree &t, const std::string &colName);
142
143const std::type_info &TypeName2TypeID(const std::string &name);
144
145std::string TypeID2TypeName(const std::type_info &id);
146
147std::string GetTypeNameWithOpts(const ROOT::RDF::RDataSource &df, std::string_view colName, bool vector2RVec);
148std::string
149ColumnName2ColumnTypeName(const std::string &colName, TTree *, RDataSource *, RDefineBase *, bool vector2RVec = true);
150
151char TypeName2ROOTTypeName(const std::string &b);
152char TypeID2ROOTTypeName(const std::type_info &tid);
153
154unsigned int GetNSlots();
155
156/// `type` is TypeList if MustRemove is false, otherwise it is a TypeList with the first type removed
157template <bool MustRemove, typename TypeList>
161
162template <typename TypeList>
166
167template <bool MustRemove, typename TypeList>
169
170template <bool MustRemove, typename TypeList>
174
175template <typename TypeList>
180
181template <bool MustRemove, typename TypeList>
183
184// Check the value_type type of a type with a SFINAE to allow compilation in presence
185// fundamental types
186template <typename T,
187 bool IsDataContainer = IsDataContainer<std::decay_t<T>>::value || std::is_same<std::string, T>::value>
188struct ValueType {
189 using value_type = typename T::value_type;
190};
191
192template <typename T>
193struct ValueType<T, false> {
194 using value_type = T;
195};
196
197template <typename T>
198struct ValueType<ROOT::VecOps::RVec<T>, false> {
199 using value_type = T;
200};
201
202std::vector<std::string> ReplaceDotWithUnderscore(const std::vector<std::string> &columnNames);
203
204/// Erase `that` element from vector `v`
205template <typename T>
206void Erase(const T &that, std::vector<T> &v)
207{
208 v.erase(std::remove(v.begin(), v.end(), that), v.end());
209}
210
211/// Declare code in the interpreter via the TInterpreter::Declare method, throw in case of errors
212void InterpreterDeclare(const std::string &code);
213
214/// Jit code in the interpreter with TInterpreter::Calc, throw in case of errors.
215/// The optional `context` parameter, if present, is mentioned in the error message.
216void InterpreterCalc(const std::string &code, const std::string &context = "");
217
218/// Whether custom column with name colName is an "internal" column such as rdfentry_ or rdfslot_
219bool IsInternalColumn(std::string_view colName);
220
221/// Get optimal column width for printing a table given the names and the desired minimal space between columns
222unsigned int GetColumnWidth(const std::vector<std::string>& names, const unsigned int minColumnSpace = 8u);
223
224/// Stepping through CacheLineStep<T> values in a vector<T> brings you to a new cache line.
225/// Useful to avoid false sharing.
226template <typename T>
227constexpr std::size_t CacheLineStep() {
228 constexpr std::size_t cacheLineSize = R__HARDWARE_INTERFERENCE_SIZE;
229 return (cacheLineSize + sizeof(T) - 1) / sizeof(T);
230}
231
232void CheckReaderTypeMatches(const std::type_info &colType, const std::type_info &requestedType,
233 const std::string &colName);
234
235// TODO in C++17 this could be a lambda within FillHelper::Exec
236template <typename T>
237constexpr std::size_t FindIdxTrue(const T &arr)
238{
239 for (size_t i = 0; i < arr.size(); ++i) {
240 if (arr[i])
241 return i;
242 }
243 return arr.size();
244}
245
246// return type has to be decltype(auto) to preserve perfect forwarding
247template <std::size_t N, typename... Ts>
248decltype(auto) GetNthElement(Ts &&...args)
249{
250 auto tuple = std::forward_as_tuple(args...);
251 return std::get<N>(tuple);
252}
253
254bool IsStrInVec(const std::string &str, const std::vector<std::string> &vec);
255
256/// Return a vector with all elements of v1 and v2 and duplicates removed.
257/// Precondition: each of v1 and v2 must not have duplicate elements.
258template <typename T>
259std::vector<T> Union(const std::vector<T> &v1, const std::vector<T> &v2)
260{
261 std::vector<T> res = v1;
262
263 // Add the variations coming from the input columns
264 for (const auto &e : v2)
265 if (std::find(v1.begin(), v1.end(), e) == v1.end())
266 res.emplace_back(e);
267
268 return res;
269}
270
271/**
272 * \brief A Thread-safe cache for strings.
273 *
274 * This is used to generically store strings that are created in the computation
275 * graph machinery, for example when adding a new node.
276 */
278 std::unordered_set<std::string> fStrings{};
279 std::shared_mutex fMutex{};
280
281public:
282 /**
283 * \brief Inserts the input string in the cache and returns an iterator to the cached string.
284 *
285 * The function implements the following strategy for thread-safety:
286 * 1. Take a shared lock and early return if the string is already in the cache.
287 * 2. Release the shared lock and take an exclusive lock.
288 * 3. Check again if another thread filled the cache meanwhile. If so, return the cached value.
289 * 4. Insert the new value in the cache and return.
290 */
291 auto Insert(const std::string &string) -> decltype(fStrings)::const_iterator;
292};
293
294/**
295 * \brief Struct to wrap the call to a function with a guaranteed order of
296 * execution of its arguments.
297 * \tparam F Type of the callable.
298 * \tparam Args Variadic types of the arguments to the callable.
299 *
300 * The execution order is guaranteed by calling the function in the constructor
301 * thus enabling the exploitation of the list-initialization sequenced-before
302 * feature (See rule 9 at https://en.cppreference.com/w/cpp/language/eval_order).
303 */
305 template <typename F, typename... Args>
306 CallGuaranteedOrder(F &&f, Args &&...args)
307 {
308 f(std::forward<Args>(args)...);
309 }
310};
311
312template <typename T>
313auto MakeAliasedSharedPtr(T *rawPtr)
314{
315 const static std::shared_ptr<T> fgRawPtrCtrlBlock;
316 return std::shared_ptr<T>(fgRawPtrCtrlBlock, rawPtr);
317}
318
319
320/**
321 * \brief Function to retrieve RDatasetSpec from JSON file provided
322 * \param[in] jsonFile Path to the dataset specification JSON file.
323 *
324 * This function allows us to have access to an RDatasetSpec which needs to
325 * be created when we use the FromSpec factory function.
326 */
328
329/**
330 * Tag to let data sources use the native data type when creating a column reader.
331 *
332 * See usage of this in RNTupleDS
333 */
335
336} // end NS RDF
337} // end NS Internal
338} // end NS ROOT
339
340#endif // RDFUTILS
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define e(i)
Definition RSha256.hxx:103
#define N
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
char name[80]
Definition TGX11.cxx:142
A Thread-safe cache for strings.
Definition Utils.hxx:277
auto Insert(const std::string &string) -> decltype(fStrings)::const_iterator
Inserts the input string in the cache and returns an iterator to the cached string.
Definition RDFUtils.cxx:577
std::unordered_set< std::string > fStrings
Definition Utils.hxx:278
The dataset specification for RDataFrame.
RDataSource defines an API that RDataFrame can use to read arbitrary data formats.
A log configuration for a channel, e.g.
Definition RLogger.hxx:97
typename RemoveFirstParameter< T >::type RemoveFirstParameter_t
A "std::vector"-like collection of values implementing handy operation to analyse them.
Definition RVec.hxx:1509
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition TTreeReader.h:46
A TTree represents a columnar dataset.
Definition TTree.h:95
TPaveText * pt
ROOT::RLogChannel & RDFLogChannel()
Definition RDFUtils.cxx:43
auto MakeAliasedSharedPtr(T *rawPtr)
Definition Utils.hxx:313
std::vector< std::string > ReplaceDotWithUnderscore(const std::vector< std::string > &columnNames)
Replace occurrences of '.
Definition RDFUtils.cxx:436
const std::type_info & TypeName2TypeID(const std::string &name)
Return the type_info associated to a name.
Definition RDFUtils.cxx:98
typename RemoveFirstTwoParametersIf< MustRemove, TypeList >::type RemoveFirstTwoParametersIf_t
Definition Utils.hxx:182
ROOT::RDF::Experimental::RDatasetSpec RetrieveSpecFromJson(const std::string &jsonFile)
Function to retrieve RDatasetSpec from JSON file provided.
Definition RDFUtils.cxx:594
unsigned int GetNSlots()
Definition RDFUtils.cxx:423
decltype(auto) GetNthElement(Ts &&...args)
Definition Utils.hxx:248
char TypeName2ROOTTypeName(const std::string &b)
Convert type name (e.g.
Definition RDFUtils.cxx:381
std::string TypeID2TypeName(const std::type_info &id)
Returns the name of a type starting from its type_info An empty string is returned in case of failure...
Definition RDFUtils.cxx:212
bool IsStrInVec(const std::string &str, const std::vector< std::string > &vec)
Definition RDFUtils.cxx:572
void Erase(const T &that, std::vector< T > &v)
Erase that element from vector v
Definition Utils.hxx:206
unsigned int GetColumnWidth(const std::vector< std::string > &names, const unsigned int minColumnSpace=8u)
Get optimal column width for printing a table given the names and the desired minimal space between c...
Definition RDFUtils.cxx:513
std::string GetBranchOrLeafTypeName(TTree &t, const std::string &colName)
Return the typename of object colName stored in t, if any.
Definition RDFUtils.cxx:294
constexpr std::size_t CacheLineStep()
Stepping through CacheLineStep<T> values in a vector<T> brings you to a new cache line.
Definition Utils.hxx:227
std::string ColumnName2ColumnTypeName(const std::string &colName, TTree *, RDataSource *, RDefineBase *, bool vector2RVec=true)
Return a string containing the type of the given branch.
Definition RDFUtils.cxx:351
void InterpreterCalc(const std::string &code, const std::string &context="")
Jit code in the interpreter with TInterpreter::Calc, throw in case of errors.
Definition RDFUtils.cxx:467
void CheckReaderTypeMatches(const std::type_info &colType, const std::type_info &requestedType, const std::string &colName)
Definition RDFUtils.cxx:525
void WarnProfile()
Warn once about experimental filling of RProfile.
Definition RDFUtils.cxx:67
constexpr std::size_t FindIdxTrue(const T &arr)
Definition Utils.hxx:237
std::vector< T > Union(const std::vector< T > &v1, const std::vector< T > &v2)
Return a vector with all elements of v1 and v2 and duplicates removed.
Definition Utils.hxx:259
bool IsInternalColumn(std::string_view colName)
Whether custom column with name colName is an "internal" column such as rdfentry_ or rdfslot_.
Definition RDFUtils.cxx:504
void WarnHist()
Warn once about experimental filling of RHist.
Definition RDFUtils.cxx:55
std::string GetTypeNameWithOpts(const ROOT::RDF::RDataSource &ds, std::string_view colName, bool vector2RVec)
Definition RDFUtils.cxx:676
void InterpreterDeclare(const std::string &code)
Declare code in the interpreter via the TInterpreter::Declare method, throw in case of errors.
Definition RDFUtils.cxx:455
unsigned int & NThreadPerTH3()
Obtain or set the number of threads that will share a clone of a thread-safe 3D histogram.
Definition RDFUtils.cxx:88
typename RemoveFirstParameterIf< MustRemove, TypeList >::type RemoveFirstParameterIf_t
Definition Utils.hxx:168
char TypeID2ROOTTypeName(const std::type_info &tid)
Definition RDFUtils.cxx:240
std::vector< std::string > ColumnNames_t
ROOT type_traits extensions.
Struct to wrap the call to a function with a guaranteed order of execution of its arguments.
Definition Utils.hxx:304
CallGuaranteedOrder(F &&f, Args &&...args)
Definition Utils.hxx:306
Check for container traits.
Definition Utils.hxx:92
static constexpr bool Test(A *pt, A const *cpt=nullptr, decltype(pt->begin()) *=nullptr, decltype(pt->end()) *=nullptr, decltype(cpt->begin()) *=nullptr, decltype(cpt->end()) *=nullptr, typename A::iterator *pi=nullptr, typename A::const_iterator *pci=nullptr)
Definition Utils.hxx:96
static constexpr bool Test(...)
Definition Utils.hxx:111
static constexpr bool value
Definition Utils.hxx:116
Detect whether a type is an instantiation of vector<T,A>
Definition Utils.hxx:136
type is TypeList if MustRemove is false, otherwise it is a TypeList with the first type removed
Definition Utils.hxx:158
typename RemoveFirstParameterIf< true, typeTmp >::type type
Definition Utils.hxx:178
typename RemoveFirstParameterIf< true, TypeList >::type typeTmp
Definition Utils.hxx:177
Tag to let data sources use the native data type when creating a column reader.
Definition Utils.hxx:334
typename T::value_type value_type
Definition Utils.hxx:189
Lightweight storage for a collection of types.