Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RNTupleMetrics.cxx
Go to the documentation of this file.
1/// \file RNTupleMetrics.cxx
2/// \author Jakob Blomer <jblomer@cern.ch>
3/// \date 2019-08-27
4/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
5/// is welcome!
6
7/*************************************************************************
8 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
9 * All rights reserved. *
10 * *
11 * For the licensing terms see $ROOTSYS/LICENSE. *
12 * For the list of contributors see $ROOTSYS/README/CREDITS. *
13 *************************************************************************/
14
16
17#include <ROOT/RField.hxx>
18#include <ROOT/RLogger.hxx>
19#include <ROOT/RNTupleModel.hxx>
20#include <ROOT/RNTupleUtils.hxx>
22
23#include <TFile.h>
24#include <TFileMerger.h>
25#include <TMemFile.h>
26#include <TSystem.h>
27
28#include <cstdint>
29#include <mutex>
30#include <ostream>
31#include <vector>
32
33namespace {
34
35std::mutex &GetMetricsExportMutex()
36{
37 static std::mutex mutex;
38 return mutex;
39}
40
41thread_local bool gSuppressMetricsExport = false;
42
43struct RSuppressMetricsRaii {
44 RSuppressMetricsRaii() { gSuppressMetricsExport = true; }
45 RSuppressMetricsRaii(const RSuppressMetricsRaii &other) = delete;
46 RSuppressMetricsRaii &operator=(const RSuppressMetricsRaii &other) = delete;
48};
49
50} // anonymous namespace
51
55
57{
58 return fName + kFieldSeperator + fUnit + kFieldSeperator + fDescription + kFieldSeperator + GetValueAsString();
59}
60
62{
63 return GetLocalCounter(name) != nullptr;
64}
65
68{
69 for (const auto &c : fCounters) {
70 if (c->GetName() == name)
71 return c.get();
72 }
73 return nullptr;
74}
75
78{
79 std::string prefix = fName + ".";
80 if (name.compare(0, prefix.length(), std::string_view(prefix)) != 0)
81 return nullptr;
82
83 auto innerName = name.substr(prefix.length());
84 if (auto counter = GetLocalCounter(innerName))
85 return counter;
86
87 for (auto m : fObservedMetrics) {
88 auto counter = m->GetCounter(innerName);
89 if (counter != nullptr)
90 return counter;
91 }
92
93 return nullptr;
94}
95
96void ROOT::Experimental::Detail::RNTupleMetrics::Print(std::ostream &output, const std::string &prefix) const
97{
98 if (!fIsEnabled) {
99 output << fName << " metrics disabled!\n";
100 return;
101 }
102
103 for (const auto &c : fCounters) {
104 output << prefix << fName << kNamespaceSeperator << c->ToString() << '\n';
105 }
106 for (const auto c : fObservedMetrics) {
107 c->Print(output, prefix + fName + ".");
108 }
109}
110
112{
113 for (auto &c: fCounters)
114 c->Enable();
115 fIsEnabled = true;
116 for (auto m: fObservedMetrics)
117 m->Enable();
118}
119
124
126{
128 return {};
129
130 if (const char *env = gSystem->Getenv("ROOT_EXPERIMENTAL_EXPORT_RNTUPLE_METRICS"); env && *env)
131 return env;
132
133 return {};
134}
135
137{
138 if (!fIsEnabled || fExportPath.empty())
139 return;
140
141 ExportToRootFile();
142}
143
145 std::vector<std::pair<std::string, const RNTuplePerfCounter *>> &counters, const std::string &prefix) const
146{
147 constexpr char kSeparator = '_';
148
149 R__ASSERT(!fName.empty());
150
151 std::string qualifiedName = prefix;
152 if (!qualifiedName.empty())
153 qualifiedName += kSeparator;
154 qualifiedName += fName;
155
156 for (const auto &counter : fCounters)
157 counters.emplace_back(qualifiedName + kSeparator + counter->GetName(), counter.get());
158
159 for (const auto *observed : fObservedMetrics)
160 observed->CollectCounters(counters, qualifiedName);
161}
162
164{
165 R__ASSERT(!fExportPath.empty());
166 R__ASSERT(!fNTupleName.empty());
167
168 std::vector<std::pair<std::string, const RNTuplePerfCounter *>> counters;
169 CollectCounters(counters);
170 R__ASSERT(!counters.empty());
171
172 // Avoid inifinite recursion (an RNTupleWriter is created to print the metrics)
173 RSuppressMetricsRaii suppressGuard;
174
175 auto model = ROOT::RNTupleModel::Create();
176 for (const auto &[fullyQualifiedName, counter] : counters) {
177 if (const auto *calc = dynamic_cast<const RNTupleCalcPerf *>(counter))
178 *model->MakeField<double>(fullyQualifiedName) = calc->GetValue();
179 else
180 *model->MakeField<std::int64_t>(fullyQualifiedName) = counter->GetValueAsInt();
181 }
182
183 TMemFile memoryFile(fNTupleName.c_str(), "RECREATE");
184 {
185 auto writer = ROOT::RNTupleWriter::Append(std::move(model), fNTupleName, memoryFile);
186 writer->Fill();
187 writer->CommitDataset();
188 }
189
190 std::lock_guard<std::mutex> lock(GetMetricsExportMutex());
191
193 merger.SetMergeOptions(std::string_view("rntuple.MergingMode=Union"));
194
195 if (!merger.OutputFile(fExportPath.c_str(), "UPDATE")) {
196 R__LOG_ERROR(ROOT::Internal::NTupleLog()) << "cannot open metrics export file '" << fExportPath << "'";
197 return;
198 }
199
200 if (!merger.AddFile(&memoryFile) || !merger.PartialMerge(TFileMerger::kAll | TFileMerger::kIncremental)) {
202 << "cannot merge metrics for '" << fNTupleName << "' into '" << fExportPath << "'";
203 }
204}
#define R__LOG_ERROR(...)
Definition RLogger.hxx:356
#define c(i)
Definition RSha256.hxx:101
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
char name[80]
Definition TGX11.cxx:142
R__EXTERN TSystem * gSystem
Definition TSystem.h:582
A metric element that computes its floating point value from other counters.
A collection of Counter objects with a name, a unit, and a description.
const RNTuplePerfCounter * GetCounter(std::string_view name) const
Searches this object and all the observed sub metrics.
void ObserveMetrics(RNTupleMetrics &observee)
const RNTuplePerfCounter * GetLocalCounter(std::string_view name) const
Searches counters registered in this object only. Returns nullptr if name is not found.
void CollectCounters(std::vector< std::pair< std::string, const RNTuplePerfCounter * > > &counters, const std::string &prefix="") const
Retrieves each counter of the observed metrics down to the class instances which own the counters and...
bool Contains(const std::string &name) const
void Print(std::ostream &output, const std::string &prefix="") const
A performance counter with a name and a unit, which can be activated on demand.
static std::unique_ptr< RNTupleModel > Create()
static std::unique_ptr< RNTupleWriter > Append(std::unique_ptr< ROOT::RNTupleModel > model, std::string_view ntupleName, TDirectory &fileOrDirectory, const ROOT::RNTupleWriteOptions &options=ROOT::RNTupleWriteOptions())
Creates an RNTupleWriter that writes into an existing TFile or TDirectory, without overwriting its co...
This class provides file copy and merging services.
Definition TFileMerger.h:30
@ kAll
Merge all type of objects (default)
Definition TFileMerger.h:87
@ kIncremental
Merge the input file with the content of the output file (if already existing).
Definition TFileMerger.h:82
A TMemFile is like a normal TFile except that it reads and writes only from memory.
Definition TMemFile.h:27
virtual const char * Getenv(const char *env)
Get environment variable.
Definition TSystem.cxx:1680
ROOT::RLogChannel & NTupleLog()
Log channel for RNTuple diagnostics.
TMarker m
Definition textangle.C:8