CMS 3D CMS Logo

FastTimerServiceClient.cc
Go to the documentation of this file.
1 // C++ headers
2 #include <string>
3 #include <cstring>
4 
5 // boost headers
6 #include <boost/regex.hpp>
7 
8 // Root headers
9 #include <TH1F.h>
10 
11 // CMSSW headers
24 
25 struct MEPSet {
28  int nbins;
29  double xmin;
30  double xmax;
31 };
32 
34 public:
36  ~FastTimerServiceClient() override;
37 
38  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
41 
42 private:
44 
46  DQMStore::IGetter& getter,
47  edm::LuminosityBlock const&,
48  edm::EventSetup const&) override;
49  void dqmEndJob(DQMStore::IBooker& booker, DQMStore::IGetter& getter) override;
50 
54  DQMStore::IGetter& getter,
55  double events,
56  std::string const& path);
58  DQMStore::IGetter& getter,
59  std::string const& current_path,
60  std::string const& suffix,
61  MEPSet pset);
62 
64 
68 
72 
74 };
75 
77  : m_dqm_path(config.getUntrackedParameter<std::string>("dqmPath")),
78  doPlotsVsScalLumi_(config.getParameter<bool>("doPlotsVsScalLumi")),
79  doPlotsVsPixelLumi_(config.getParameter<bool>("doPlotsVsPixelLumi")),
80  doPlotsVsPU_(config.getParameter<bool>("doPlotsVsPU")),
81  scalLumiMEPSet_(doPlotsVsScalLumi_ ? getHistoPSet(config.getParameter<edm::ParameterSet>("scalLumiME"))
82  : MEPSet{}),
83  pixelLumiMEPSet_(doPlotsVsPixelLumi_ ? getHistoPSet(config.getParameter<edm::ParameterSet>("pixelLumiME"))
84  : MEPSet{}),
85  puMEPSet_(doPlotsVsPU_ ? getHistoPSet(config.getParameter<edm::ParameterSet>("puME")) : MEPSet{}),
86  fillEveryLumiSection_(config.getParameter<bool>("fillEveryLumiSection")) {}
87 
89 
91  fillSummaryPlots(booker, getter);
92 }
93 
95  DQMStore::IGetter& getter,
97  edm::EventSetup const& setup) {
99  fillSummaryPlots(booker, getter);
100 }
101 
103  if (getter.get(m_dqm_path + "/event time_real")) {
104  // the plots are directly in the configured folder
105  fillProcessSummaryPlots(booker, getter, m_dqm_path);
106  } else {
107  static const boost::regex running_n_processes(".*/Running .*");
108 
110  std::vector<std::string> subdirs = getter.getSubdirs();
111  for (auto const& subdir : subdirs) {
112  // the plots are in a per-number-of-processes folder
113  if (boost::regex_match(subdir, running_n_processes)) {
114  booker.setCurrentFolder(subdir);
115  if (getter.get(subdir + "/event time_real"))
116  fillProcessSummaryPlots(booker, getter, subdir);
117 
118  std::vector<std::string> subsubdirs = getter.getSubdirs();
119  for (auto const& subsubdir : subsubdirs) {
120  if (getter.get(subsubdir + "/event time_real"))
121  fillProcessSummaryPlots(booker, getter, subsubdir);
122  }
123  }
124  } // loop on subdirs
125  }
126 }
127 
129  DQMStore::IGetter& getter,
130  std::string const& current_path) {
131  MonitorElement* me = getter.get(current_path + "/event time_real");
132  if (me == nullptr)
133  // no FastTimerService DQM information
134  return;
135 
136  if (doPlotsVsScalLumi_)
137  fillPlotsVsLumi(booker, getter, current_path, "VsScalLumi", scalLumiMEPSet_);
139  fillPlotsVsLumi(booker, getter, current_path, "VsPixelLumi", pixelLumiMEPSet_);
140  if (doPlotsVsPU_)
141  fillPlotsVsLumi(booker, getter, current_path, "VsPU", puMEPSet_);
142 
143  // getter.setCurrentFolder(current_path);
144 
145  double events = me->getTH1F()->GetEntries();
146 
147  // look for per-process directories
148  static const boost::regex process_name(".*/process .*");
149 
150  booker.setCurrentFolder(current_path); // ?!?!?
151  std::vector<std::string> subdirs = getter.getSubdirs();
152  for (auto const& subdir : subdirs) {
153  if (boost::regex_match(subdir, process_name)) {
154  getter.setCurrentFolder(subdir);
155  // look for per-path plots inside each per-process directory
156  std::vector<std::string> subsubdirs = getter.getSubdirs();
157  for (auto const& subsubdir : subsubdirs) {
158  if (getter.get(subsubdir + "/path time_real")) {
159  fillPathSummaryPlots(booker, getter, events, subdir);
160  break;
161  }
162  }
163  }
164  } // loop on subdir
165 }
166 
168  DQMStore::IGetter& getter,
169  double events,
170  std::string const& current_path) {
171  // note: the following checks need to be kept separate, as any of these histograms might be missing
172 
173  booker.setCurrentFolder(current_path);
174  std::vector<std::string> subsubdirs = getter.getSubdirs();
175  size_t npaths = subsubdirs.size();
176 
177  MonitorElement* paths_time =
178  booker.book1D("paths_time_real", "Total (real) time spent in each path", npaths, -0.5, double(npaths) - 0.5);
179  MonitorElement* paths_thread =
180  booker.book1D("paths_time_thread", "Total (thread) time spent in each path", npaths, -0.5, double(npaths) - 0.5);
181  MonitorElement* paths_allocated =
182  booker.book1D("paths_allocated", "Total allocated memory in each path", npaths, -0.5, double(npaths) - 0.5);
183  MonitorElement* paths_deallocated =
184  booker.book1D("paths_deallocated", "Total deallocated in each path", npaths, -0.5, double(npaths) - 0.5);
185 
187  double mean = -1.;
188 
189  // extract the list of Paths and EndPaths from the summary plots
190  int ibin = 1;
191  for (auto const& subsubdir : subsubdirs) {
192  std::string test = "/path ";
193  if (subsubdir.find(test) == std::string::npos)
194  continue;
195 
196  static const boost::regex prefix(current_path + "/path ");
197  std::string path = boost::regex_replace(subsubdir, prefix, "");
198 
199  paths_time->setBinLabel(ibin, path);
200  paths_thread->setBinLabel(ibin, path);
201  paths_allocated->setBinLabel(ibin, path);
202  paths_deallocated->setBinLabel(ibin, path);
203 
204  if ((me = getter.get(subsubdir + "/path time_real"))) {
205  mean = me->getMean();
206  paths_time->setBinContent(ibin, mean);
207  }
208  if ((me = getter.get(subsubdir + "/path time_thread"))) {
209  mean = me->getMean();
210  paths_thread->setBinContent(ibin, mean);
211  }
212  if ((me = getter.get(subsubdir + "/path allocated"))) {
213  mean = me->getMean();
214  paths_allocated->setBinContent(ibin, mean);
215  }
216 
217  if ((me = getter.get(subsubdir + "/path deallocated"))) {
218  mean = me->getMean();
219  paths_deallocated->setBinContent(ibin, mean);
220  }
221 
222  ibin++;
223  }
224 
225  for (auto const& subsubdir : subsubdirs) {
226  // for each path, fill histograms with
227  // - the average time spent in each module (total time spent in that module, averaged over all events)
228  // - the running time spent in each module (total time spent in that module, averaged over the events where that module actually ran)
229  // - the "efficiency" of each module (number of time a module succeded divided by the number of times the has run)
230 
231  getter.setCurrentFolder(subsubdir);
232  std::vector<std::string> allmenames = getter.getMEs();
233  if (allmenames.empty())
234  continue;
235 
236  MonitorElement* me_counter = getter.get(subsubdir + "/module_counter");
237  MonitorElement* me_real_total = getter.get(subsubdir + "/module_time_real_total");
238  MonitorElement* me_thread_total = getter.get(subsubdir + "/module_time_thread_total");
239 
240  if (me_counter == nullptr or me_real_total == nullptr)
241  continue;
242 
243  TH1D* counter = me_counter->getTH1D();
244  TH1D* real_total = me_real_total->getTH1D();
245  TH1D* thread_total = me_thread_total->getTH1D();
246  uint32_t bins = counter->GetXaxis()->GetNbins() - 1;
247  double min = counter->GetXaxis()->GetXmin();
248  double max = counter->GetXaxis()->GetXmax() - 1;
249 
250  TH1F* real_average;
251  TH1F* real_running;
252  TH1F* thread_average;
253  TH1F* thread_running;
254  TH1F* efficiency;
256 
257  booker.setCurrentFolder(subsubdir);
258  me = getter.get(subsubdir + "/module_time_real_average");
259  if (me) {
260  real_average = me->getTH1F();
261  assert(me->getTH1F()->GetXaxis()->GetXmin() == min);
262  assert(me->getTH1F()->GetXaxis()->GetXmax() == max);
263  real_average->Reset();
264  } else {
265  real_average = booker.book1D("module_time_real_average", "module real average timing", bins, min, max)->getTH1F();
266  real_average->SetYTitle("average processing (real) time [ms]");
267  for (uint32_t i = 1; i <= bins; ++i) {
268  const char* module = counter->GetXaxis()->GetBinLabel(i);
269  real_average->GetXaxis()->SetBinLabel(i, module);
270  }
271  }
272 
273  me = getter.get(subsubdir + "/module_time_thread_average");
274  if (me) {
275  thread_average = me->getTH1F();
276  assert(me->getTH1F()->GetXaxis()->GetXmin() == min);
277  assert(me->getTH1F()->GetXaxis()->GetXmax() == max);
278  thread_average->Reset();
279  } else {
280  thread_average =
281  booker.book1D("module_time_thread_average", "module thread average timing", bins, min, max)->getTH1F();
282  thread_average->SetYTitle("average processing (thread) time [ms]");
283  for (uint32_t i = 1; i <= bins; ++i) {
284  const char* module = counter->GetXaxis()->GetBinLabel(i);
285  thread_average->GetXaxis()->SetBinLabel(i, module);
286  }
287  }
288 
289  me = getter.get(subsubdir + "/module_time_real_running");
290  if (me) {
291  real_running = me->getTH1F();
292  assert(me->getTH1F()->GetXaxis()->GetXmin() == min);
293  assert(me->getTH1F()->GetXaxis()->GetXmax() == max);
294  real_running->Reset();
295  } else {
296  real_running = booker.book1D("module_time_real_running", "module real running timing", bins, min, max)->getTH1F();
297  real_running->SetYTitle("running processing (real) time [ms]");
298  for (uint32_t i = 1; i <= bins; ++i) {
299  const char* module = counter->GetXaxis()->GetBinLabel(i);
300  real_running->GetXaxis()->SetBinLabel(i, module);
301  }
302  }
303 
304  me = getter.get(subsubdir + "/module_time_thread_running");
305  if (me) {
306  thread_running = me->getTH1F();
307  assert(me->getTH1F()->GetXaxis()->GetXmin() == min);
308  assert(me->getTH1F()->GetXaxis()->GetXmax() == max);
309  thread_running->Reset();
310  } else {
311  thread_running =
312  booker.book1D("module_time_thread_running", "module thread running timing", bins, min, max)->getTH1F();
313  thread_running->SetYTitle("running processing (thread) time [ms]");
314  for (uint32_t i = 1; i <= bins; ++i) {
315  const char* module = counter->GetXaxis()->GetBinLabel(i);
316  thread_running->GetXaxis()->SetBinLabel(i, module);
317  }
318  }
319 
320  me = getter.get(subsubdir + "/module_efficiency");
321  if (me) {
322  efficiency = me->getTH1F();
323  assert(me->getTH1F()->GetXaxis()->GetXmin() == min);
324  assert(me->getTH1F()->GetXaxis()->GetXmax() == max);
325  efficiency->Reset();
326  } else {
327  efficiency = booker.book1D("module_efficiency", "module efficiency", bins, min, max)->getTH1F();
328  efficiency->SetYTitle("filter efficiency");
329  efficiency->SetMaximum(1.05);
330  for (uint32_t i = 1; i <= bins; ++i) {
331  const char* module = counter->GetXaxis()->GetBinLabel(i);
332  efficiency->GetXaxis()->SetBinLabel(i, module);
333  }
334  }
335 
336  for (uint32_t i = 1; i <= bins; ++i) {
337  double n = counter->GetBinContent(i);
338  double p = counter->GetBinContent(i + 1);
339  if (n)
340  efficiency->SetBinContent(i, p / n);
341 
342  // real timing
343  double t = real_total->GetBinContent(i);
344  real_average->SetBinContent(i, t / events);
345  if (n)
346  real_running->SetBinContent(i, t / n);
347 
348  // thread timing
349  t = thread_total->GetBinContent(i);
350  thread_average->SetBinContent(i, t / events);
351  if (n)
352  thread_running->SetBinContent(i, t / n);
353  }
354 
355  // vs lumi
356  if (doPlotsVsScalLumi_)
357  fillPlotsVsLumi(booker, getter, subsubdir, "VsScalLumi", scalLumiMEPSet_);
359  fillPlotsVsLumi(booker, getter, subsubdir, "VsPixelLumi", pixelLumiMEPSet_);
360  if (doPlotsVsPU_)
361  fillPlotsVsLumi(booker, getter, subsubdir, "VsPU", puMEPSet_);
362  }
363 }
364 
367  DQMStore::IGetter& getter,
368  std::string const& current_path,
369  std::string const& suffix,
370  MEPSet pset) {
371  std::vector<std::string> menames;
372 
373  static const boost::regex byls(".*byls");
374  static const boost::regex test(suffix);
375  // get all MEs in the current_path
376  getter.setCurrentFolder(current_path);
377  std::vector<std::string> allmenames = getter.getMEs();
378  for (auto const& m : allmenames) {
379  // get only MEs vs LS
380  if (boost::regex_match(m, byls))
381  menames.push_back(m);
382  }
383  // if no MEs available, return
384  if (menames.empty())
385  return;
386 
387  // get info for getting the lumi VS LS histogram
388  std::string folder = pset.folder;
389  std::string name = pset.name;
390  int nbins = pset.nbins;
391  double xmin = pset.xmin;
392  double xmax = pset.xmax;
393 
394  // get lumi/PU VS LS ME
395  getter.setCurrentFolder(folder);
396  MonitorElement* lumiVsLS = getter.get(folder + "/" + name);
397  // if no ME available, return
398  if (!lumiVsLS) {
399  edm::LogWarning("FastTimerServiceClient") << "no " << name << " ME is available in " << folder << std::endl;
400  return;
401  }
402 
403  // get range and binning for new MEs x-axis
404  size_t size = lumiVsLS->getTProfile()->GetXaxis()->GetNbins();
405  std::string xtitle = lumiVsLS->getTProfile()->GetYaxis()->GetTitle();
406 
407  std::vector<double> lumi;
408  std::vector<int> LS;
409  for (size_t ibin = 1; ibin <= size; ++ibin) {
410  // avoid to store points w/ no info
411  if (lumiVsLS->getTProfile()->GetBinContent(ibin) == 0.)
412  continue;
413 
414  lumi.push_back(lumiVsLS->getTProfile()->GetBinContent(ibin));
415  LS.push_back(lumiVsLS->getTProfile()->GetXaxis()->GetBinCenter(ibin));
416  }
417 
418  booker.setCurrentFolder(current_path);
419  getter.setCurrentFolder(current_path);
420  for (auto const& m : menames) {
421  std::string label = m;
422  label.erase(label.find("_byls"));
423 
424  MonitorElement* me = getter.get(current_path + "/" + m);
425  float ymin = 0.;
427  std::string ytitle = me->getTProfile()->GetYaxis()->GetTitle();
428 
429  MonitorElement* meVsLumi = getter.get(current_path + "/" + label + "_" + suffix);
430  if (meVsLumi) {
431  assert(meVsLumi->getTProfile()->GetXaxis()->GetXmin() == xmin);
432  assert(meVsLumi->getTProfile()->GetXaxis()->GetXmax() == xmax);
433  meVsLumi->Reset(); // do I have to do it ?!?!?
434  } else {
435  meVsLumi = booker.bookProfile(label + "_" + suffix, label + "_" + suffix, nbins, xmin, xmax, ymin, ymax);
436  // TProfile* meVsLumi_p = meVsLumi->getTProfile();
437  meVsLumi->getTProfile()->GetXaxis()->SetTitle(xtitle.c_str());
438  meVsLumi->getTProfile()->GetYaxis()->SetTitle(ytitle.c_str());
439  }
440  for (size_t ils = 0; ils < LS.size(); ++ils) {
441  int ibin = me->getTProfile()->GetXaxis()->FindBin(LS[ils]);
442  double y = me->getTProfile()->GetBinContent(ibin);
443 
444  meVsLumi->Fill(lumi[ils], y);
445  }
446  }
447 }
448 
450  pset.add<std::string>("folder", "HLT/LumiMonitoring");
451  pset.add<std::string>("name", "lumiVsLS");
452  pset.add<int>("nbins", 440);
453  pset.add<double>("xmin", 0.);
454  pset.add<double>("xmax", 22000.);
455 }
456 
458  pset.add<std::string>("folder", "HLT/LumiMonitoring");
459  pset.add<std::string>("name", "puVsLS");
460  pset.add<int>("nbins", 260);
461  pset.add<double>("xmin", 0.);
462  pset.add<double>("xmax", 130.);
463 }
464 
466  return MEPSet{
467  pset.getParameter<std::string>("folder"),
468  pset.getParameter<std::string>("name"),
469  pset.getParameter<int>("nbins"),
470  pset.getParameter<double>("xmin"),
471  pset.getParameter<double>("xmax"),
472  };
473 }
474 
476  // The following says we do not know what parameters are allowed so do no validation
477  // Please change this to state exactly what you do use, even if it is no parameters
479  desc.addUntracked<std::string>("dqmPath", "HLT/TimerService");
480  desc.add<bool>("doPlotsVsScalLumi", true);
481  desc.add<bool>("doPlotsVsPixelLumi", false);
482  desc.add<bool>("doPlotsVsPU", true);
483 
484  edm::ParameterSetDescription scalLumiMEPSet;
485  fillLumiMePSetDescription(scalLumiMEPSet);
486  desc.add<edm::ParameterSetDescription>("scalLumiME", scalLumiMEPSet);
487 
488  edm::ParameterSetDescription pixelLumiMEPSet;
489  fillLumiMePSetDescription(pixelLumiMEPSet);
490  desc.add<edm::ParameterSetDescription>("pixelLumiME", pixelLumiMEPSet);
491 
493  fillPUMePSetDescription(puMEPSet);
494  desc.add<edm::ParameterSetDescription>("puME", puMEPSet);
495  desc.add<bool>("fillEveryLumiSection", true);
496  descriptions.add("fastTimerServiceClient", desc);
497 }
498 
499 // declare this class as a framework plugin
size
Write out results.
static void fillPUMePSetDescription(edm::ParameterSetDescription &pset)
void dqmEndLuminosityBlock(DQMStore::IBooker &booker, DQMStore::IGetter &getter, edm::LuminosityBlock const &, edm::EventSetup const &) override
virtual TProfile * getTProfile() const
virtual void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:32
void fillPlotsVsLumi(DQMStore::IBooker &booker, DQMStore::IGetter &getter, std::string const &current_path, std::string const &suffix, MEPSet pset)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
virtual std::vector< std::string > getMEs() const
Definition: DQMStore.cc:720
std::string folder
void fillProcessSummaryPlots(DQMStore::IBooker &booker, DQMStore::IGetter &getter, std::string const &path)
Definition: config.py:1
assert(be >=bs)
~FastTimerServiceClient() override
void Fill(long long x)
virtual void Reset()
Remove all data from the ME, keept the empty histogram with all its settings.
void dqmEndJob(DQMStore::IBooker &booker, DQMStore::IGetter &getter) override
char const * label
static MEPSet getHistoPSet(const edm::ParameterSet &pset)
void fillPathSummaryPlots(DQMStore::IBooker &booker, DQMStore::IGetter &getter, double events, std::string const &path)
MonitorElement * bookProfile(TString const &name, TString const &title, int nchX, double lowX, double highX, int, double lowY, double highY, char const *option="s", FUNC onbooking=NOOP())
Definition: DQMStore.h:399
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
static void fillLumiMePSetDescription(edm::ParameterSetDescription &pset)
virtual TH1D * getTH1D() const
virtual void setBinLabel(int bin, const std::string &label, int axis=1)
set bin label for x, y or z axis (axis=1, 2, 3 respectively)
FastTimerServiceClient(edm::ParameterSet const &)
std::string name
void fillSummaryPlots(DQMStore::IBooker &booker, DQMStore::IGetter &getter)
virtual void setBinContent(int binx, double content)
set content of bin (1-D)
virtual TH1F * getTH1F() const
void add(std::string const &label, ParameterSetDescription const &psetDescription)
virtual MonitorElement * get(std::string const &fullpath) const
Definition: DQMStore.cc:673
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
HLT enums.
Log< level::Warning, false > LogWarning
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
Definition: DQMStore.h:98
int events
virtual DQM_DEPRECATED std::vector< std::string > getSubdirs() const
Definition: DQMStore.cc:700