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
25 
26 struct MEPSet {
29  int nbins;
30  double xmin;
31  double xmax;
32 };
33 
35 public:
36  explicit FastTimerServiceClient(edm::ParameterSet const &);
38 
39  static void fillDescriptions(edm::ConfigurationDescriptions & descriptions);
40  static void fillLumiMePSetDescription(edm::ParameterSetDescription & pset);
41 
42 private:
44 
45  void dqmEndLuminosityBlock(DQMStore::IBooker & booker, DQMStore::IGetter & getter, edm::LuminosityBlock const &, edm::EventSetup const&) override;
46  void dqmEndJob(DQMStore::IBooker & booker, DQMStore::IGetter & getter) override;
47 
48  void fillSummaryPlots( DQMStore::IBooker & booker, DQMStore::IGetter & getter);
49  void fillProcessSummaryPlots( DQMStore::IBooker & booker, DQMStore::IGetter & getter, std::string const & path);
50  void fillPathSummaryPlots( DQMStore::IBooker & booker, DQMStore::IGetter & getter, double events, std::string const & path);
51  void fillPlotsVsLumi(DQMStore::IBooker & booker, DQMStore::IGetter & getter, std::string const & current_path, std::string const & suffix, MEPSet pset);
52 
53  static MEPSet getHistoPSet (edm::ParameterSet pset);
54 
57 
60 
61 };
62 
63 
65  m_dqm_path( config.getUntrackedParameter<std::string>( "dqmPath" ) )
66  , doPlotsVsScalLumi_ ( config.getParameter<bool>( "doPlotsVsScalLumi" ) )
67  , doPlotsVsPixelLumi_( config.getParameter<bool>( "doPlotsVsPixelLumi" ) )
68  , scalLumiMEPSet_ ( doPlotsVsScalLumi_ ? getHistoPSet(config.getParameter<edm::ParameterSet>("scalLumiME")) : MEPSet{} )
69  , pixelLumiMEPSet_( doPlotsVsPixelLumi_ ? getHistoPSet(config.getParameter<edm::ParameterSet>("pixelLumiME")) : MEPSet{} )
70 {
71 }
72 
74 {
75 }
76 
77 void
79 {
80  fillSummaryPlots(booker, getter);
81 }
82 
83 void
85 {
86  fillSummaryPlots(booker, getter);
87 }
88 
89 void
91 {
92  if (getter.get(m_dqm_path + "/event time_real")) {
93  // the plots are directly in the configured folder
94  fillProcessSummaryPlots(booker, getter, m_dqm_path);
95  } else {
96  static const boost::regex running_n_processes(".*/Running [0-9]+ processes");
97 
99  std::vector<std::string> subdirs = getter.getSubdirs();
100  for (auto const & subdir: subdirs) {
101 
102  // the plots are in a per-number-of-processes folder
103  if (boost::regex_match(subdir, running_n_processes)) {
104 
105  booker.setCurrentFolder(subdir);
106  if ( getter.get(subdir + "/event time_real") )
107  fillProcessSummaryPlots(booker, getter, subdir);
108 
109  std::vector<std::string> subsubdirs = getter.getSubdirs();
110  for (auto const & subsubdir: subsubdirs) {
111  if ( getter.get(subsubdir + "/event time_real") )
112  fillProcessSummaryPlots(booker, getter, subsubdir);
113  }
114 
115  }
116  } // loop on subdirs
117  }
118 }
119 
120 
121 
122 void
124 
125  MonitorElement * me = getter.get(current_path + "/event time_real");
126  if (me == 0)
127  // no FastTimerService DQM information
128  return;
129 
130  if ( doPlotsVsScalLumi_ )
131  fillPlotsVsLumi( booker,getter, current_path, "VsScalLumi", scalLumiMEPSet_ );
132  if ( doPlotsVsPixelLumi_ )
133  fillPlotsVsLumi( booker,getter, current_path, "VsPixelLumi", pixelLumiMEPSet_ );
134 
135  // getter.setCurrentFolder(current_path);
136 
137  double events = me->getTH1F()->GetEntries();
138 
139  // look for per-process directories
140  static const boost::regex process_name(".*/process .*");
141 
142  booker.setCurrentFolder(current_path); // ?!?!?
143  std::vector<std::string> subdirs = getter.getSubdirs();
144  for (auto const & subdir: subdirs) {
145 
146  if (boost::regex_match(subdir, process_name)) {
147 
148  getter.setCurrentFolder(subdir);
149  // look for per-path plots inside each per-process directory
150  std::vector<std::string> subsubdirs = getter.getSubdirs();
151  for (auto const & subsubdir: subsubdirs) {
152  if ( getter.get(subsubdir + "/path time_real") ) {
153  fillPathSummaryPlots(booker, getter, events, subdir);
154  break;
155  }
156  }
157 
158  }
159  } // loop on subdir
160 
161 }
162 
163 void
165  // note: the following checks need to be kept separate, as any of these histograms might be missing
166 
167  booker.setCurrentFolder(current_path);
168  std::vector<std::string> subsubdirs = getter.getSubdirs();
169  size_t npaths = subsubdirs.size();
170 
171  MonitorElement* paths_time = booker.book1D("paths_time_real", "Total (real) time spent in each path", npaths, -0.5, double(npaths)-0.5);
172  MonitorElement* paths_thread = booker.book1D("paths_time_thread","Total (thread) time spent in each path", npaths, -0.5, double(npaths)-0.5);
173  MonitorElement* paths_allocated = booker.book1D("paths_allocated", "Total allocated memory in each path", npaths, -0.5, double(npaths)-0.5);
174  MonitorElement* paths_deallocated = booker.book1D("paths_deallocated","Total deallocated in each path", npaths, -0.5, double(npaths)-0.5);
175 
176  MonitorElement * me;
177  double mean = -1.;
178 
179  // extract the list of Paths and EndPaths from the summary plots
180  int ibin = 1;
181  for (auto const & subsubdir: subsubdirs) {
182 
183  std::string test = "/path ";
184  if ( subsubdir.find(test)==std::string::npos ) continue;
185 
186  static const boost::regex prefix(current_path + "/path ");
187  std::string path = boost::regex_replace(subsubdir,prefix,"");
188 
189  paths_time ->getTH1F()->GetXaxis()->SetBinLabel(ibin,path.c_str());
190  paths_thread ->getTH1F()->GetXaxis()->SetBinLabel(ibin,path.c_str());
191  paths_allocated ->getTH1F()->GetXaxis()->SetBinLabel(ibin,path.c_str());
192  paths_deallocated->getTH1F()->GetXaxis()->SetBinLabel(ibin,path.c_str());
193 
194 
195  if ( (me = getter.get(subsubdir + "/path time_real")) ) {
196  mean = me->getMean();
197  paths_time->getTH1F()->SetBinContent(ibin,mean);
198  }
199  if ( (me = getter.get(subsubdir + "/path time_thread")) ) {
200  mean = me->getMean();
201  paths_thread->getTH1F()->SetBinContent(ibin,mean);
202  }
203  if ( (me = getter.get(subsubdir + "/path allocated")) ) {
204  mean = me->getMean();
205  paths_allocated->getTH1F()->SetBinContent(ibin,mean);
206  }
207 
208  if ( (me = getter.get(subsubdir + "/path deallocated")) ) {
209  mean = me->getMean();
210  paths_deallocated->getTH1F()->SetBinContent(ibin,mean);
211  }
212 
213  ibin++;
214  }
215 
216 
217  for (auto const & subsubdir: subsubdirs) {
218  // for each path, fill histograms with
219  // - the average time spent in each module (total time spent in that module, averaged over all events)
220  // - the running time spent in each module (total time spent in that module, averaged over the events where that module actually ran)
221  // - the "efficiency" of each module (number of time a module succeded divided by the number of times the has run)
222 
223  getter.setCurrentFolder(subsubdir);
224  std::vector<std::string> allmenames = getter.getMEs();
225  if ( allmenames.size() == 0 ) continue;
226 
227  MonitorElement * me_counter = getter.get( subsubdir + "/module_counter" );
228  MonitorElement * me_real_total = getter.get( subsubdir + "/module_time_real_total" );
229  MonitorElement * me_thread_total = getter.get( subsubdir + "/module_time_thread_total" );
230 
231  if (me_counter == 0 or me_real_total == 0)
232  continue;
233 
234  TH1D * counter = me_counter ->getTH1D();
235  TH1D * real_total = me_real_total->getTH1D();
236  TH1D * thread_total = me_thread_total->getTH1D();
237  uint32_t bins = counter->GetXaxis()->GetNbins() - 1;
238  double min = counter->GetXaxis()->GetXmin();
239  double max = counter->GetXaxis()->GetXmax() - 1;
240 
241  TH1F * real_average;
242  TH1F * real_running;
243  TH1F * thread_average;
244  TH1F * thread_running;
245  TH1F * efficiency;
246  MonitorElement * me;
247 
248  booker.setCurrentFolder(subsubdir);
249  me = getter.get( "module_time_real_average" );
250  if (me) {
251  real_average = me->getTH1F();
252  assert( me->getTH1F()->GetXaxis()->GetXmin() == min );
253  assert( me->getTH1F()->GetXaxis()->GetXmax() == max );
254  real_average->Reset();
255  } else {
256  real_average = booker.book1D("module_time_real_average", "module real average timing", bins, min, max)->getTH1F();
257  real_average->SetYTitle("average processing (real) time [ms]");
258  for (uint32_t i = 1; i <= bins; ++i) {
259  const char * module = counter->GetXaxis()->GetBinLabel(i);
260  real_average->GetXaxis()->SetBinLabel(i, module);
261  }
262  }
263 
264  me = getter.get( "module_time_thread_average" );
265  if (me) {
266  thread_average = me->getTH1F();
267  assert( me->getTH1F()->GetXaxis()->GetXmin() == min );
268  assert( me->getTH1F()->GetXaxis()->GetXmax() == max );
269  thread_average->Reset();
270  } else {
271  thread_average = booker.book1D("module_time_thread_average", "module thread average timing", bins, min, max)->getTH1F();
272  thread_average->SetYTitle("average processing (thread) time [ms]");
273  for (uint32_t i = 1; i <= bins; ++i) {
274  const char * module = counter->GetXaxis()->GetBinLabel(i);
275  thread_average->GetXaxis()->SetBinLabel(i, module);
276  }
277  }
278 
279  me = getter.get( "module_time_real_running" );
280  if (me) {
281  real_running = me->getTH1F();
282  assert( me->getTH1F()->GetXaxis()->GetXmin() == min );
283  assert( me->getTH1F()->GetXaxis()->GetXmax() == max );
284  real_running->Reset();
285  } else {
286  real_running = booker.book1D("module_time_real_running", "module real running timing", bins, min, max)->getTH1F();
287  real_running->SetYTitle("running processing (real) time [ms]");
288  for (uint32_t i = 1; i <= bins; ++i) {
289  const char * module = counter->GetXaxis()->GetBinLabel(i);
290  real_running->GetXaxis()->SetBinLabel(i, module);
291  }
292  }
293 
294  me = getter.get( "module_time_thread_running" );
295  if (me) {
296  thread_running = me->getTH1F();
297  assert( me->getTH1F()->GetXaxis()->GetXmin() == min );
298  assert( me->getTH1F()->GetXaxis()->GetXmax() == max );
299  thread_running->Reset();
300  } else {
301  thread_running = booker.book1D("module_time_thread_running", "module thread running timing", bins, min, max)->getTH1F();
302  thread_running->SetYTitle("running processing (thread) time [ms]");
303  for (uint32_t i = 1; i <= bins; ++i) {
304  const char * module = counter->GetXaxis()->GetBinLabel(i);
305  thread_running->GetXaxis()->SetBinLabel(i, module);
306  }
307  }
308 
309  me = getter.get( "module_efficiency" );
310  if (me) {
311  efficiency = me->getTH1F();
312  assert( me->getTH1F()->GetXaxis()->GetXmin() == min );
313  assert( me->getTH1F()->GetXaxis()->GetXmax() == max );
314  efficiency->Reset();
315  } else {
316  efficiency = booker.book1D("module_efficiency", "module efficiency", bins, min, max)->getTH1F();
317  efficiency->SetYTitle("filter efficiency");
318  efficiency->SetMaximum(1.05);
319  for (uint32_t i = 1; i <= bins; ++i) {
320  const char * module = counter->GetXaxis()->GetBinLabel(i);
321  efficiency->GetXaxis()->SetBinLabel(i, module);
322  }
323  }
324 
325 
326  for (uint32_t i = 1; i <= bins; ++i) {
327  double n = counter ->GetBinContent(i);
328  double p = counter ->GetBinContent(i+1);
329  if (n)
330  efficiency->SetBinContent(i, p / n);
331 
332  // real timing
333  double t = real_total->GetBinContent(i);
334  real_average->SetBinContent(i, t / events);
335  if (n)
336  real_running->SetBinContent(i, t / n);
337 
338  // thread timing
339  t = thread_total->GetBinContent(i);
340  thread_average->SetBinContent(i, t / events);
341  if (n)
342  thread_running->SetBinContent(i, t / n);
343  }
344 
345  // vs lumi
346  if ( doPlotsVsScalLumi_ )
347  fillPlotsVsLumi( booker,getter, subsubdir, "VsScalLumi", scalLumiMEPSet_ );
348  if ( doPlotsVsPixelLumi_ )
349  fillPlotsVsLumi( booker,getter, subsubdir, "VsPixelLumi", pixelLumiMEPSet_ );
350 
351  }
352 
353 }
354 
356 void
358 
359  std::vector<std::string> menames;
360 
361  static const boost::regex byls(".*byls");
362  static const boost::regex test(suffix);
363  // get all MEs in the current_path
364  getter.setCurrentFolder(current_path);
365  std::vector<std::string> allmenames = getter.getMEs();
366  for ( const auto & m : allmenames ) {
367  // get only MEs vs LS
368  if (boost::regex_match(m, byls))
369  menames.push_back(m);
370  }
371  // if no MEs available, return
372  if ( menames.size() == 0 )
373  return;
374 
375  // get info for getting the lumi VS LS histogram
376  std::string folder = pset.folder;
377  std::string name = pset.name;
378  int nbins = pset.nbins;
379  double xmin = pset.xmin;
380  double xmax = pset.xmax;
381 
382  // get lumi VS LS ME
383  getter.setCurrentFolder(folder);
384  MonitorElement* lumiVsLS = getter.get(folder+"/"+name);
385  // if no ME available, return
386  if ( !lumiVsLS ) {
387  edm::LogWarning("FastTimerServiceClient") << "no " << name << " ME is available in " << folder << std::endl;
388  return;
389  }
390 
391  // get range and binning for new MEs x-axis
392  size_t size = lumiVsLS->getTProfile()->GetXaxis()->GetNbins();
393  std::string xtitle = lumiVsLS->getTProfile()->GetYaxis()->GetTitle();
394 
395  std::vector<double> lumi;
396  std::vector<int> LS;
397  for ( size_t ibin=1; ibin <= size; ++ibin ) {
398  // avoid to store points w/ no info
399  if ( lumiVsLS->getTProfile()->GetBinContent(ibin) == 0. ) continue;
400 
401  lumi.push_back( lumiVsLS->getTProfile()->GetBinContent(ibin) );
402  LS.push_back ( lumiVsLS->getTProfile()->GetXaxis()->GetBinCenter(ibin) );
403  }
404 
405  booker.setCurrentFolder(current_path);
406  getter.setCurrentFolder(current_path);
407  for ( auto m : menames ) {
408  std::string label = m;
409  label.erase(label.find("_byls"));
410 
411  MonitorElement* me = getter.get(current_path + "/" + m);
412  double ymin = me->getTProfile()->GetMinimum();
413  double ymax = me->getTProfile()->GetMaximum();
414  std::string ytitle = me->getTProfile()->GetYaxis()->GetTitle();
415 
416  MonitorElement* meVsLumi = getter.get( current_path + "/" + label + "_" + suffix );
417  if (meVsLumi) {
418  assert( meVsLumi->getTProfile()->GetXaxis()->GetXmin() == xmin );
419  assert( meVsLumi->getTProfile()->GetXaxis()->GetXmax() == xmax );
420  meVsLumi->Reset(); // do I have to do it ?!?!?
421  } else {
422  meVsLumi = booker.bookProfile(label + "_" + suffix, label + "_" + suffix, nbins, xmin, xmax, ymin, ymax);
423  // TProfile* meVsLumi_p = meVsLumi->getTProfile();
424  meVsLumi->getTProfile()->GetXaxis()->SetTitle(xtitle.c_str());
425  meVsLumi->getTProfile()->GetYaxis()->SetTitle(ytitle.c_str());
426  }
427  for ( size_t ils=0; ils < LS.size(); ++ils ) {
428  int ibin = me->getTProfile()->GetXaxis()->FindBin(LS[ils]);
429  double y = me->getTProfile()->GetBinContent(ibin);
430 
431  meVsLumi->Fill(lumi[ils],y);
432  }
433  }
434 
435 
436 }
437 
438 void
440  pset.add<std::string>("folder", "HLT/LumiMonitoring");
441  pset.add<std::string>("name" , "lumiVsLS");
442  pset.add<int> ("nbins", 6500 );
443  pset.add<double>("xmin", 0.);
444  pset.add<double>("xmax", 13000.);
445 }
446 
447 
449 {
450  return MEPSet{
451  pset.getParameter<std::string>("folder"),
452  pset.getParameter<std::string>("name"),
453  pset.getParameter<int>("nbins"),
454  pset.getParameter<double>("xmin"),
455  pset.getParameter<double>("xmax"),
456  };
457 }
458 
459 void
461  // The following says we do not know what parameters are allowed so do no validation
462  // Please change this to state exactly what you do use, even if it is no parameters
464  desc.addUntracked<std::string>( "dqmPath", "HLT/TimerService");
465  desc.add<bool>( "doPlotsVsScalLumi", true );
466  desc.add<bool>( "doPlotsVsPixelLumi", false );
467 
468  edm::ParameterSetDescription scalLumiMEPSet;
469  fillLumiMePSetDescription(scalLumiMEPSet);
470  desc.add<edm::ParameterSetDescription>("scalLumiME", scalLumiMEPSet);
471 
472  edm::ParameterSetDescription pixelLumiMEPSet;
473  fillLumiMePSetDescription(pixelLumiMEPSet);
474  desc.add<edm::ParameterSetDescription>("pixelLumiME", pixelLumiMEPSet);
475 
476  descriptions.add("fastTimerServiceClient", desc);
477 }
478 
479 //define this as a plug-in
size
Write out results.
T getParameter(std::string const &) const
static MEPSet getHistoPSet(edm::ParameterSet pset)
void dqmEndLuminosityBlock(DQMStore::IBooker &booker, DQMStore::IGetter &getter, edm::LuminosityBlock const &, edm::EventSetup const &) override
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
MonitorElement * bookProfile(Args &&...args)
Definition: DQMStore.h:157
void fillPlotsVsLumi(DQMStore::IBooker &booker, DQMStore::IGetter &getter, std::string const &current_path, std::string const &suffix, MEPSet pset)
MonitorElement * get(const std::string &path)
Definition: DQMStore.cc:305
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
std::string folder
void fillProcessSummaryPlots(DQMStore::IBooker &booker, DQMStore::IGetter &getter, std::string const &path)
TH1D * getTH1D(void) const
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:1
Definition: config.py:1
double getMean(int axis=1) const
get mean value of histogram along x, y or z axis (axis=1, 2, 3 respectively)
void Fill(long long x)
void dqmEndJob(DQMStore::IBooker &booker, DQMStore::IGetter &getter) override
void fillPathSummaryPlots(DQMStore::IBooker &booker, DQMStore::IGetter &getter, double events, std::string const &path)
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
MonitorElement * book1D(Args &&...args)
Definition: DQMStore.h:115
static void fillLumiMePSetDescription(edm::ParameterSetDescription &pset)
T min(T a, T b)
Definition: MathUtil.h:58
ParameterDescriptionBase * add(U const &iLabel, T const &value)
std::vector< std::string > getMEs(void)
Definition: DQMStore.cc:327
FastTimerServiceClient(edm::ParameterSet const &)
std::string name
void fillSummaryPlots(DQMStore::IBooker &booker, DQMStore::IGetter &getter)
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:277
TH1F * getTH1F(void) const
void add(std::string const &label, ParameterSetDescription const &psetDescription)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::vector< std::string > getSubdirs(void)
Definition: DQMStore.cc:323
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:347
HLT enums.
TProfile * getTProfile(void) const
void Reset(void)
reset ME (ie. contents, errors, etc)
Definition: vlib.h:208