CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FastTimerService.cc
Go to the documentation of this file.
1 // FIXME
2 // we are by-passing the ME's when filling the plots, so we might need to call the ME's update() by hand
3 
4 
5 // C++ headers
6 #include <cmath>
7 #include <limits>
8 #include <iostream>
9 #include <iomanip>
10 #include <string>
11 #include <sstream>
12 #include <unordered_set>
13 #include <unordered_map>
14 
15 // boost headers
16 #include <boost/format.hpp>
17 
18 // CMSSW headers
35 
36 
37 // file-static methods to fill a vector of strings with "(dup.) (...)" entries
38 static
39 void fill_dups(std::vector<std::string> & dups, unsigned int size) {
40  dups.reserve(size);
41  for (unsigned int i = dups.size(); i < size; ++i)
42  dups.push_back( (boost::format("(dup.) (%d)") % i).str() );
43 }
44 
45 
47  // configuration
48  // FIXME - reimplement support for cpu time vs. real time
49  m_use_realtime( config.getUntrackedParameter<bool>( "useRealTimeClock" ) ),
50  m_enable_timing_paths( config.getUntrackedParameter<bool>( "enableTimingPaths" ) ),
51  m_enable_timing_modules( config.getUntrackedParameter<bool>( "enableTimingModules" ) ),
52  m_enable_timing_exclusive( config.getUntrackedParameter<bool>( "enableTimingExclusive" ) ),
53  m_enable_timing_summary( config.getUntrackedParameter<bool>( "enableTimingSummary" ) ),
54  m_skip_first_path( config.getUntrackedParameter<bool>( "skipFirstPath" ) ),
55  // dqm configuration
56  m_enable_dqm( config.getUntrackedParameter<bool>( "enableDQM" ) ),
57  m_enable_dqm_bypath_active( config.getUntrackedParameter<bool>( "enableDQMbyPathActive" ) ),
58  m_enable_dqm_bypath_total( config.getUntrackedParameter<bool>( "enableDQMbyPathTotal" ) ),
59  m_enable_dqm_bypath_overhead( config.getUntrackedParameter<bool>( "enableDQMbyPathOverhead" ) ),
60  m_enable_dqm_bypath_details( config.getUntrackedParameter<bool>( "enableDQMbyPathDetails" ) ),
61  m_enable_dqm_bypath_counters( config.getUntrackedParameter<bool>( "enableDQMbyPathCounters" ) ),
62  m_enable_dqm_bypath_exclusive( config.getUntrackedParameter<bool>( "enableDQMbyPathExclusive" ) ),
63  m_enable_dqm_bymodule( config.getUntrackedParameter<bool>( "enableDQMbyModule" ) ),
64  m_enable_dqm_bymoduletype( config.getUntrackedParameter<bool>( "enableDQMbyModuleType" ) ),
65  m_enable_dqm_summary( config.getUntrackedParameter<bool>( "enableDQMSummary" ) ),
66  m_enable_dqm_byls( config.getUntrackedParameter<bool>( "enableDQMbyLumiSection" ) ),
67  m_enable_dqm_bynproc( config.getUntrackedParameter<bool>( "enableDQMbyProcesses" ) ),
68  // job configuration
69  m_concurrent_runs( 0 ),
70  m_concurrent_streams( 0 ),
71  m_concurrent_threads( 0 ),
72  m_module_id( edm::ModuleDescription::invalidID() ),
73  m_dqm_eventtime_range( config.getUntrackedParameter<double>( "dqmTimeRange" ) ), // ms
74  m_dqm_eventtime_resolution( config.getUntrackedParameter<double>( "dqmTimeResolution" ) ), // ms
75  m_dqm_pathtime_range( config.getUntrackedParameter<double>( "dqmPathTimeRange" ) ), // ms
76  m_dqm_pathtime_resolution( config.getUntrackedParameter<double>( "dqmPathTimeResolution" ) ), // ms
77  m_dqm_moduletime_range( config.getUntrackedParameter<double>( "dqmModuleTimeRange" ) ), // ms
78  m_dqm_moduletime_resolution( config.getUntrackedParameter<double>( "dqmModuleTimeResolution" ) ), // ms
79  m_dqm_path( config.getUntrackedParameter<std::string>("dqmPath" ) ),
80  // description of the process(es)
81  m_process(),
82  // description of the luminosity axes
83  m_dqm_luminosity(),
84  // DQM - these are initialized at preStreamBeginRun(), to make sure the DQM service has been loaded
85  m_stream(),
86  // summary data
87  m_run_summary(),
88  m_job_summary(),
89  m_run_summary_perprocess(),
90  m_job_summary_perprocess()
91 {
92  // enable timers if required by DQM plots
100 
109 
112 
113 
122  registry.watchPostEndJob( this, & FastTimerService::postEndJob );
126  registry.watchPreEvent( this, & FastTimerService::preEvent );
127  registry.watchPostEvent( this, & FastTimerService::postEvent );
128  // watch per-path events
131  // watch per-module events if enabled
137  }
138 
139  // if requested, reserve plots for timing vs. lumisection
140  // there is no need to store the id, as it wil always be 0
141  if (m_enable_dqm_byls)
142  reserveLuminosityPlots("ls", "lumisection", "lumisection", config.getUntrackedParameter<uint32_t>("dqmLumiSectionsRange"), 1.);
143 
144 }
145 
147 {
148 }
149 
150 // reserve plots for timing vs. luminosity
151 unsigned int FastTimerService::reserveLuminosityPlots(std::string const & name, std::string const & title, std::string const & label, double range, double resolution)
152 {
153  // FIXME check that this is only called before any preStreamBeginRun
154  // FIXME check that this is not called with the same "name" twice
155  m_dqm_luminosity.push_back(LuminosityDescription(name, title, label, range, resolution));
156 
157  // resize the luminosity per event buffer
158  for (auto & stream: m_stream)
159  stream.luminosity.resize(m_dqm_luminosity.size(), 0);
160 
161  return m_dqm_luminosity.size() - 1;
162 }
163 
165 {
166  // FIXME check that this is only called before any preStreamBeginRun
167  // FIXME check that this is not called with the same "name" twice
168  m_dqm_luminosity.push_back(LuminosityDescription(name, title, label, range, resolution));
169 
170  // resize the luminosity per event buffer
171  for (auto & stream: m_stream)
172  stream.luminosity.resize(m_dqm_luminosity.size(), 0);
173 
174  return m_dqm_luminosity.size() - 1;
175 }
176 
177 // set the event luminosity
178 void FastTimerService::setLuminosity(unsigned int stream_id, unsigned int luminosity_id, double value)
179 {
180  // FIXME check that the luminosity id is valid ?
181  m_stream[stream_id].luminosity[luminosity_id] = value;
182 }
183 
185 {
186  unsigned int pid = processID(gc.processContext());
187  unsigned int rid = gc.runIndex();
188 
190 
191  // cache the names of the first and last path and endpath
192  if (m_process.size() <= pid)
193  m_process.resize(pid+1);
194  m_process[pid].name = gc.processContext()->processName();
195  if (m_skip_first_path and pid == 0) {
196  // skip the first path
197  if (tns.getTrigPaths().size() > 1) {
198  m_process[pid].first_path = tns.getTrigPaths().at(1);
199  m_process[pid].last_path = tns.getTrigPaths().back();
200  }
201  } else {
202  if (not tns.getTrigPaths().empty()) {
203  m_process[pid].first_path = tns.getTrigPaths().front();
204  m_process[pid].last_path = tns.getTrigPaths().back();
205  }
206  }
207  if (not tns.getEndPaths().empty()) {
208  m_process[pid].first_endpath = tns.getEndPaths().front();
209  m_process[pid].last_endpath = tns.getEndPaths().back();
210  }
211 
212  uint32_t size_p = tns.getTrigPaths().size();
213  uint32_t size_e = tns.getEndPaths().size();
214  uint32_t size = size_p + size_e;
215  // resize the path maps
216  for (auto & stream: m_stream)
217  if (stream.paths.size() <= pid)
218  stream.paths.resize(pid+1);
219  for (uint32_t i = 0; i < size_p; ++i) {
220  std::string const & label = tns.getTrigPath(i);
221  for (auto & stream: m_stream)
222  stream.paths[pid][label].index = i;
223  }
224  for (uint32_t i = 0; i < size_e; ++i) {
225  std::string const & label = tns.getEndPath(i);
226  for (auto & stream: m_stream)
227  stream.paths[pid][label].index = size_p + i;
228  }
229  for (auto & stream: m_stream) {
230  // resize the stream buffers to account the number of subprocesses
231  if (stream.timing_perprocess.size() <= pid)
232  stream.timing_perprocess.resize(pid+1);
233  stream.timing_perprocess[pid].paths_interpaths.assign(size + 1, 0.);
234  // resize the stream plots to account the number of subprocesses
235  if (stream.dqm_perprocess.size() <= pid)
236  stream.dqm_perprocess.resize(pid+1);
237  if (stream.dqm_perprocess_byluminosity.size() <= pid)
238  stream.dqm_perprocess_byluminosity.resize(pid+1);
239  if (stream.dqm_paths.size() <= pid)
240  stream.dqm_paths.resize(pid+1);
241  }
242  for (auto & summary: m_run_summary_perprocess) {
243  if (summary.size() <= pid)
244  summary.resize(pid+1);
245  summary[pid].paths_interpaths.assign(size + 1, 0);
246  }
247  if (m_job_summary_perprocess.size() <= pid)
248  m_job_summary_perprocess.resize(pid+1);
249  m_job_summary_perprocess[pid].paths_interpaths.assign(size + 1, 0.);
250 
251  // reset the run summaries
252  if (pid == 0)
253  m_run_summary[rid].reset();
254  m_run_summary_perprocess[rid][pid].reset();
255 
256  // associate to each path all the modules it contains
257  for (uint32_t i = 0; i < tns.getTrigPaths().size(); ++i)
258  fillPathMap( pid, tns.getTrigPath(i), tns.getTrigPathModules(i) );
259  for (uint32_t i = 0; i < tns.getEndPaths().size(); ++i)
260  fillPathMap( pid, tns.getEndPath(i), tns.getEndPathModules(i) );
261 }
262 
264 {
266  unsigned int pid = processID(sc.processContext());
267  unsigned int sid = sc.streamID().value();
268  auto & stream = m_stream[sid];
269 
270  if (not m_enable_dqm)
271  return;
272 
273  if (not edm::Service<DQMStore>().isAvailable()) {
274  // the DQMStore is not available, disable all DQM plots
275  m_enable_dqm = false;
276  return;
277  }
278 
280  uint32_t size_p = tns.getTrigPaths().size();
281  uint32_t size_e = tns.getEndPaths().size();
282  uint32_t size = size_p + size_e;
283 
284  int eventbins = (int) std::ceil(m_dqm_eventtime_range / m_dqm_eventtime_resolution);
285  int pathbins = (int) std::ceil(m_dqm_pathtime_range / m_dqm_pathtime_resolution);
286  int modulebins = (int) std::ceil(m_dqm_moduletime_range / m_dqm_moduletime_resolution);
287 
288  // define a callback that can book the histograms
289  auto bookTransactionCallback = [&, this] (DQMStore::IBooker & booker) {
290 
291  // event summary plots
292  if (m_enable_dqm_summary) {
293  // whole event
294  if (pid == 0) {
295  booker.setCurrentFolder(m_dqm_path);
296  stream.dqm.presource = booker.book1D("presource", "Pre-Source processing time", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
297  stream.dqm.presource ->StatOverflows(true);
298  stream.dqm.presource ->SetXTitle("processing time [ms]");
299  stream.dqm.source = booker.book1D("source", "Source processing time", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
300  stream.dqm.source ->StatOverflows(true);
301  stream.dqm.source ->SetXTitle("processing time [ms]");
302  stream.dqm.preevent = booker.book1D("preevent", "Pre-Event processing time", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
303  stream.dqm.preevent ->StatOverflows(true);
304  stream.dqm.preevent ->SetXTitle("processing time [ms]");
305  stream.dqm.event = booker.book1D("event", "Event processing time", eventbins, 0., m_dqm_eventtime_range)->getTH1F();
306  stream.dqm.event ->StatOverflows(true);
307  stream.dqm.event ->SetXTitle("processing time [ms]");
308  }
309 
310  // per subprocess
311  booker.setCurrentFolder(m_dqm_path + "/process " + process_name);
312  stream.dqm_perprocess[pid].preevent = booker.book1D("preevent", "Pre-Event processing time", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
313  stream.dqm_perprocess[pid].preevent ->StatOverflows(true);
314  stream.dqm_perprocess[pid].preevent ->SetXTitle("processing time [ms]");
315  stream.dqm_perprocess[pid].event = booker.book1D("event", "Event processing time", eventbins, 0., m_dqm_eventtime_range)->getTH1F();
316  stream.dqm_perprocess[pid].event ->StatOverflows(true);
317  stream.dqm_perprocess[pid].event ->SetXTitle("processing time [ms]");
318  stream.dqm_perprocess[pid].all_paths = booker.book1D("all_paths", "Paths processing time", eventbins, 0., m_dqm_eventtime_range)->getTH1F();
319  stream.dqm_perprocess[pid].all_paths ->StatOverflows(true);
320  stream.dqm_perprocess[pid].all_paths ->SetXTitle("processing time [ms]");
321  stream.dqm_perprocess[pid].all_endpaths = booker.book1D("all_endpaths", "EndPaths processing time", pathbins, 0., m_dqm_pathtime_range)->getTH1F();
322  stream.dqm_perprocess[pid].all_endpaths ->StatOverflows(true);
323  stream.dqm_perprocess[pid].all_endpaths ->SetXTitle("processing time [ms]");
324  stream.dqm_perprocess[pid].interpaths = booker.book1D("interpaths", "Time spent between paths", pathbins, 0., m_dqm_eventtime_range)->getTH1F();
325  stream.dqm_perprocess[pid].interpaths ->StatOverflows(true);
326  stream.dqm_perprocess[pid].interpaths ->SetXTitle("processing time [ms]");
327  }
328 
329  // plots by path
330  if (m_enable_timing_paths) {
331  booker.setCurrentFolder(m_dqm_path + "/process " + process_name);
332  stream.dqm_paths[pid].active_time = booker.bookProfile("paths_active_time", "Additional time spent in each path", size, -0.5, size-0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
333  stream.dqm_paths[pid].active_time ->StatOverflows(true);
334  stream.dqm_paths[pid].active_time ->SetYTitle("processing time [ms]");
335  stream.dqm_paths[pid].total_time = booker.bookProfile("paths_total_time", "Total time spent in each path", size, -0.5, size-0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
336  stream.dqm_paths[pid].total_time ->StatOverflows(true);
337  stream.dqm_paths[pid].total_time ->SetYTitle("processing time [ms]");
338  stream.dqm_paths[pid].exclusive_time = booker.bookProfile("paths_exclusive_time", "Exclusive time spent in each path", size, -0.5, size-0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
339  stream.dqm_paths[pid].exclusive_time ->StatOverflows(true);
340  stream.dqm_paths[pid].exclusive_time ->SetYTitle("processing time [ms]");
341  stream.dqm_paths[pid].interpaths = booker.bookProfile("paths_interpaths", "Time spent between each path", size+1, -0.5, size+0.5, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
342  stream.dqm_paths[pid].interpaths ->StatOverflows(true);
343  stream.dqm_paths[pid].interpaths ->SetYTitle("processing time [ms]");
344 
345  for (uint32_t i = 0; i < size_p; ++i) {
346  std::string const & label = tns.getTrigPath(i);
347  stream.dqm_paths[pid].active_time ->GetXaxis()->SetBinLabel(i + 1, label.c_str());
348  stream.dqm_paths[pid].total_time ->GetXaxis()->SetBinLabel(i + 1, label.c_str());
349  stream.dqm_paths[pid].exclusive_time ->GetXaxis()->SetBinLabel(i + 1, label.c_str());
350  stream.dqm_paths[pid].interpaths ->GetXaxis()->SetBinLabel(i + 1, label.c_str());
351  }
352  for (uint32_t i = 0; i < size_e; ++i) {
353  std::string const & label = tns.getEndPath(i);
354  stream.dqm_paths[pid].active_time ->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
355  stream.dqm_paths[pid].total_time ->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
356  stream.dqm_paths[pid].exclusive_time ->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
357  stream.dqm_paths[pid].interpaths ->GetXaxis()->SetBinLabel(i + size_p + 1, label.c_str());
358  }
359  }
360 
361  // plots vs. instantaneous luminosity
362  if (not m_dqm_luminosity.empty()) {
363  if (pid == 0) {
364  // resize the plots vs. luminosity
365  stream.dqm_byluminosity.resize(m_dqm_luminosity.size());
366 
367  // whole event
368  booker.setCurrentFolder(m_dqm_path);
369  for (unsigned int i = 0; i < m_dqm_luminosity.size(); ++i) {
370  auto & plots = stream.dqm_byluminosity[i];
371  int lumibins = (int) std::ceil(m_dqm_luminosity[i].range / m_dqm_luminosity[i].resolution);
372  plots.presource = booker.bookProfile("presource_by" + m_dqm_luminosity[i].name, "Pre-Source processing time vs. " + m_dqm_luminosity[i].title, lumibins, 0., m_dqm_luminosity[i].range, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
373  plots.presource ->StatOverflows(true);
374  plots.presource ->SetXTitle(m_dqm_luminosity[i].label.c_str());
375  plots.presource ->SetYTitle("processing time [ms]");
376  plots.source = booker.bookProfile("source_by" + m_dqm_luminosity[i].name, "Source processing time vs. " + m_dqm_luminosity[i].title, lumibins, 0., m_dqm_luminosity[i].range, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
377  plots.source ->StatOverflows(true);
378  plots.source ->SetXTitle(m_dqm_luminosity[i].label.c_str());
379  plots.source ->SetYTitle("processing time [ms]");
380  plots.preevent = booker.bookProfile("preevent_by" + m_dqm_luminosity[i].name, "Pre-Event processing time vs. " + m_dqm_luminosity[i].title, lumibins, 0., m_dqm_luminosity[i].range, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
381  plots.preevent ->StatOverflows(true);
382  plots.preevent ->SetXTitle(m_dqm_luminosity[i].label.c_str());
383  plots.preevent ->SetYTitle("processing time [ms]");
384  plots.event = booker.bookProfile("event_by" + m_dqm_luminosity[i].name, "Event processing time vs. " + m_dqm_luminosity[i].title, lumibins, 0., m_dqm_luminosity[i].range, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
385  plots.event ->StatOverflows(true);
386  plots.event ->SetXTitle(m_dqm_luminosity[i].label.c_str());
387  plots.event ->SetYTitle("processing time [ms]");
388  }
389  }
390 
391  // resize the plots vs. luminosity
392  stream.dqm_perprocess_byluminosity[pid].resize(m_dqm_luminosity.size());
393 
394  // per subprocess
395  booker.setCurrentFolder(m_dqm_path + "/process " + process_name);
396  for (unsigned int i = 0; i < m_dqm_luminosity.size(); ++i) {
397  auto & plots = stream.dqm_perprocess_byluminosity[pid][i];
398  int lumibins = (int) std::ceil(m_dqm_luminosity[i].range / m_dqm_luminosity[i].resolution);
399  plots.preevent = booker.bookProfile("preevent_by" + m_dqm_luminosity[i].name, "Pre-Event processing time vs. " + m_dqm_luminosity[i].title, lumibins, 0., m_dqm_luminosity[i].range, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
400  plots.preevent ->StatOverflows(true);
401  plots.preevent ->SetXTitle(m_dqm_luminosity[i].label.c_str());
402  plots.preevent ->SetYTitle("processing time [ms]");
403  plots.event = booker.bookProfile("event_by" + m_dqm_luminosity[i].name, "Event processing time vs. " + m_dqm_luminosity[i].title, lumibins, 0., m_dqm_luminosity[i].range, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
404  plots.event ->StatOverflows(true);
405  plots.event ->SetXTitle(m_dqm_luminosity[i].label.c_str());
406  plots.event ->SetYTitle("processing time [ms]");
407  plots.all_paths = booker.bookProfile("all_paths_by" + m_dqm_luminosity[i].name, "Paths processing time vs. " + m_dqm_luminosity[i].title, lumibins, 0., m_dqm_luminosity[i].range, eventbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
408  plots.all_paths ->StatOverflows(true);
409  plots.all_paths ->SetXTitle(m_dqm_luminosity[i].label.c_str());
410  plots.all_paths ->SetYTitle("processing time [ms]");
411  plots.all_endpaths = booker.bookProfile("all_endpaths_by" + m_dqm_luminosity[i].name, "EndPaths processing time vs. " + m_dqm_luminosity[i].title, lumibins, 0., m_dqm_luminosity[i].range, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
412  plots.all_endpaths ->StatOverflows(true);
413  plots.all_endpaths ->SetXTitle(m_dqm_luminosity[i].label.c_str());
414  plots.all_endpaths ->SetYTitle("processing time [ms]");
415  plots.interpaths = booker.bookProfile("interpaths_by" + m_dqm_luminosity[i].name, "Time spent between paths vs. " + m_dqm_luminosity[i].title, lumibins, 0., m_dqm_luminosity[i].range, pathbins, 0., std::numeric_limits<double>::infinity(), " ")->getTProfile();
416  plots.interpaths ->StatOverflows(true);
417  plots.interpaths ->SetXTitle(m_dqm_luminosity[i].label.c_str());
418  plots.interpaths ->SetYTitle("processing time [ms]");
419  }
420  }
421 
422  // per-path and per-module accounting
423  if (m_enable_timing_paths) {
424  booker.setCurrentFolder(m_dqm_path + "/process " + process_name + "/Paths");
425  for (auto & keyval: stream.paths[pid]) {
426  std::string const & pathname = keyval.first;
427  PathInfo & pathinfo = keyval.second;
428 
430  pathinfo.dqm_active = booker.book1D(pathname + "_active", pathname + " active time", pathbins, 0., m_dqm_pathtime_range)->getTH1F();
431  pathinfo.dqm_active ->StatOverflows(true);
432  pathinfo.dqm_active ->SetXTitle("processing time [ms]");
433  }
434 
436  pathinfo.dqm_total = booker.book1D(pathname + "_total", pathname + " total time", pathbins, 0., m_dqm_pathtime_range)->getTH1F();
437  pathinfo.dqm_total ->StatOverflows(true);
438  pathinfo.dqm_total ->SetXTitle("processing time [ms]");
439  }
440 
442  pathinfo.dqm_premodules = booker.book1D(pathname + "_premodules", pathname + " pre-modules overhead", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
443  pathinfo.dqm_premodules ->StatOverflows(true);
444  pathinfo.dqm_premodules ->SetXTitle("processing time [ms]");
445  pathinfo.dqm_intermodules = booker.book1D(pathname + "_intermodules", pathname + " inter-modules overhead", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
446  pathinfo.dqm_intermodules ->StatOverflows(true);
447  pathinfo.dqm_intermodules ->SetXTitle("processing time [ms]");
448  pathinfo.dqm_postmodules = booker.book1D(pathname + "_postmodules", pathname + " post-modules overhead", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
449  pathinfo.dqm_postmodules ->StatOverflows(true);
450  pathinfo.dqm_postmodules ->SetXTitle("processing time [ms]");
451  pathinfo.dqm_overhead = booker.book1D(pathname + "_overhead", pathname + " overhead time", modulebins, 0., m_dqm_moduletime_range)->getTH1F();
452  pathinfo.dqm_overhead ->StatOverflows(true);
453  pathinfo.dqm_overhead ->SetXTitle("processing time [ms]");
454  }
455 
457  // book histograms for modules-in-paths statistics
458 
459  // find histograms X-axis labels
460  uint32_t id;
461  std::vector<std::string> const & modules = ((id = tns.findTrigPath(pathname)) != tns.getTrigPaths().size()) ? tns.getTrigPathModules(id) :
462  ((id = tns.findEndPath(pathname)) != tns.getEndPaths().size()) ? tns.getEndPathModules(id) :
463  std::vector<std::string>();
464 
465  static std::vector<std::string> dup;
466  if (modules.size() > dup.size())
467  fill_dups(dup, modules.size());
468 
469  std::vector<const char *> labels(modules.size(), nullptr);
470  for (uint32_t i = 0; i < modules.size(); ++i)
471  labels[i] = (pathinfo.modules[i]) ? modules[i].c_str() : dup[i].c_str();
472 
473  // book counter histograms
474  if (m_enable_dqm_bypath_counters) {
475  pathinfo.dqm_module_counter = booker.book1D(pathname + "_module_counter", pathname + " module counter", modules.size(), -0.5, modules.size() - 0.5)->getTH1F();
476  // find module labels
477  for (uint32_t i = 0; i < modules.size(); ++i) {
478  pathinfo.dqm_module_counter->GetXaxis()->SetBinLabel( i+1, labels[i] );
479  }
480  }
481  // book detailed timing histograms
483  pathinfo.dqm_module_active = booker.book1D(pathname + "_module_active", pathname + " module active", modules.size(), -0.5, modules.size() - 0.5)->getTH1F();
484  pathinfo.dqm_module_active ->SetYTitle("cumulative processing time [ms]");
485  pathinfo.dqm_module_total = booker.book1D(pathname + "_module_total", pathname + " module total", modules.size(), -0.5, modules.size() - 0.5)->getTH1F();
486  pathinfo.dqm_module_total ->SetYTitle("cumulative processing time [ms]");
487  // find module labels
488  for (uint32_t i = 0; i < modules.size(); ++i) {
489  pathinfo.dqm_module_active ->GetXaxis()->SetBinLabel( i+1, labels[i] );
490  pathinfo.dqm_module_total ->GetXaxis()->SetBinLabel( i+1, labels[i] );
491  }
492  }
493  }
494 
495  // book exclusive path time histograms
497  pathinfo.dqm_exclusive = booker.book1D(pathname + "_exclusive", pathname + " exclusive time", pathbins, 0., m_dqm_pathtime_range)->getTH1F();
498  pathinfo.dqm_exclusive ->StatOverflows(true);
499  pathinfo.dqm_exclusive ->SetXTitle("processing time [ms]");
500  }
501 
502  }
503  }
504 
505  if (m_enable_dqm_bymodule) {
506  booker.setCurrentFolder(m_dqm_path + "/Modules");
507  for (auto & keyval: stream.modules) {
508  std::string const & label = keyval.first;
509  ModuleInfo & module = keyval.second;
510  module.dqm_active = booker.book1D(label, label, modulebins, 0., m_dqm_moduletime_range)->getTH1F();
511  module.dqm_active->StatOverflows(true);
512  module.dqm_active->SetXTitle("processing time [ms]");
513  }
514  }
515 
517  booker.setCurrentFolder(m_dqm_path + "/ModuleTypes");
518  for (auto & keyval: stream.moduletypes) {
519  std::string const & label = keyval.first;
520  ModuleInfo & module = keyval.second;
521  module.dqm_active = booker.book1D(label, label, modulebins, 0., m_dqm_moduletime_range)->getTH1F();
522  module.dqm_active->StatOverflows(true);
523  module.dqm_active->SetXTitle("processing time [ms]");
524  }
525  }
526 
527  };
528 
529  // book MonitorElement's for this stream
530  edm::Service<DQMStore>()->bookTransaction(bookTransactionCallback, sc.eventID().run(), sid, m_module_id);
531 }
532 
533 
534 void
536 {
540 
542  m_dqm_path += (boost::format("/Running %d processes") % m_concurrent_threads).str();
543 
547 
548  // assign a pseudo module id to the FastTimerService
550  for (auto & stream: m_stream) {
551  stream.fast_modules.resize( m_module_id, nullptr);
552  stream.fast_moduletypes.resize(m_module_id, nullptr);
553  }
554 
555  // resize the luminosity per event buffer
556  for (auto & stream: m_stream)
557  stream.luminosity.resize(m_dqm_luminosity.size(), 0);
558 }
559 
560 
561 void
563  unsigned int sid = sc.streamID().value();
564  auto & stream = m_stream[sid];
565  stream.timer_last_transition = FastTimer::Clock::now();
566 }
567 
568 void
570 {
571  unsigned int sid = sc.streamID().value();
572  auto & stream = m_stream[sid];
573 
574  if (m_enable_dqm) {
575  DQMStore * store = edm::Service<DQMStore>().operator->();
576  assert(store);
578  }
579 
580  stream.reset();
581  stream.timer_last_transition = FastTimer::Clock::now();
582 }
583 
584 void
586  unsigned int sid = sc.streamID().value();
587  auto & stream = m_stream[sid];
588  stream.timer_last_transition = FastTimer::Clock::now();
589 }
590 
591 void
593  unsigned int sid = sc.streamID().value();
594  auto & stream = m_stream[sid];
595 
596  if (m_enable_dqm) {
597  DQMStore * store = edm::Service<DQMStore>().operator->();
598  assert(store);
600  }
601 
602  stream.timer_last_transition = FastTimer::Clock::now();
603 }
604 
605 void
607 {
609  unsigned int pid = processID(gc.processContext());
610  unsigned int rid = gc.runIndex();
611  unsigned int run = gc.luminosityBlockID().run();
612  const std::string label = (boost::format("run %d") % run).str();
613 
615 
616  if (pid+1 == m_process.size())
617  printSummary(m_run_summary[rid], label);
618  }
619 }
620 
621 void
623 {
625  const std::string label = "the whole job";
626  for (unsigned int pid = 0; pid < m_process.size(); ++pid)
628 
629  printSummary(m_job_summary, label);
630  }
631 }
632 
633 void
635 {
636  // print a timing summary for the run or job, for each subprocess
637  std::ostringstream out;
638  out << std::fixed << std::setprecision(6);
639  out << "FastReport for " << label << ", process " << process << '\n';
640  //out << "FastReport " << (m_use_realtime ? "(real time) " : "(CPU time) ") << '\n';
641  out << "FastReport " << std::right << std::setw(10) << summary.preevent / (double) total.count << " Pre-Event" << '\n';
642  out << "FastReport " << std::right << std::setw(10) << summary.event / (double) total.count << " Event" << '\n';
643  out << "FastReport " << std::right << std::setw(10) << summary.all_paths / (double) total.count << " all Paths" << '\n';
644  out << "FastReport " << std::right << std::setw(10) << summary.all_endpaths / (double) total.count << " all EndPaths" << '\n';
645  out << "FastReport " << std::right << std::setw(10) << summary.interpaths / (double) total.count << " between paths" << '\n';
646  edm::LogVerbatim("FastReport") << out.str();
647 }
648 
649 void
651 {
652  // print a timing summary for the run or job
653  //edm::service::TriggerNamesService & tns = * edm::Service<edm::service::TriggerNamesService>();
654 
655  std::ostringstream out;
656  out << std::fixed << std::setprecision(6);
657  out << "FastReport for " << label << ", over all subprocesses" << '\n';
658  //out << "FastReport " << (m_use_realtime ? "(real time) " : "(CPU time) ") << '\n';
659  out << "FastReport " << std::right << std::setw(10) << summary.presource / (double) summary.count << " Pre-Source" << '\n';
660  out << "FastReport " << std::right << std::setw(10) << summary.source / (double) summary.count << " Source" << '\n';
661  out << "FastReport " << std::right << std::setw(10) << summary.preevent / (double) summary.count << " Pre-Event" << '\n';
662  out << "FastReport " << std::right << std::setw(10) << summary.event / (double) summary.count << " Event" << '\n';
663  edm::LogVerbatim("FastReport") << out.str();
664 }
665 
666 /*
667  if (m_enable_timing_modules) {
668  double modules_total = 0.;
669  for (auto & keyval: m_stream.modules)
670  modules_total += keyval.second.summary_active;
671  out << "FastReport " << std::right << std::setw(10) << modules_total / (double) summary.count << " all Modules" << '\n';
672  }
673  out << '\n';
674  if (m_enable_timing_paths and not m_enable_timing_modules) {
675  //out << "FastReport " << (m_use_realtime ? "(real time) " : "(CPU time) ") << " Active Path" << '\n';
676  for (auto const & name: tns.getTrigPaths())
677  out << "FastReport "
678  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_active / (double) summary.count << " "
679  << name << '\n';
680  out << '\n';
681  //out << "FastReport " << (m_use_realtime ? "(real time) " : "(CPU time) ") << " Active EndPath" << '\n';
682  for (auto const & name: tns.getEndPaths())
683  out << "FastReport "
684  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_active / (double) summary.count << " "
685  << name << '\n';
686  } else if (m_enable_timing_paths and m_enable_timing_modules) {
687  //out << "FastReport " << (m_use_realtime ? "(real time) " : "(CPU time) ") << " Active Pre- Inter- Post-mods Overhead Total Path" << '\n';
688  for (auto const & name: tns.getTrigPaths()) {
689  out << "FastReport "
690  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_active / (double) summary.count << " "
691  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_premodules / (double) summary.count << " "
692  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_intermodules / (double) summary.count << " "
693  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_postmodules / (double) summary.count << " "
694  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_overhead / (double) summary.count << " "
695  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_total / (double) summary.count << " "
696  << name << '\n';
697  }
698  out << '\n';
699  //out << "FastReport " << (m_use_realtime ? "(real time) " : "(CPU time) ") << " Active Pre- Inter- Post-mods Overhead Total EndPath" << '\n';
700  for (auto const & name: tns.getEndPaths()) {
701  out << "FastReport "
702  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_active / (double) summary.count << " "
703  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_premodules / (double) summary.count << " "
704  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_intermodules / (double) summary.count << " "
705  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_postmodules / (double) summary.count << " "
706  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_overhead / (double) summary.count << " "
707  << std::right << std::setw(10) << m_stream.paths[pid][name].summary_total / (double) summary.count << " "
708  << name << '\n';
709  }
710  }
711  out << '\n';
712  if (m_enable_timing_modules) {
713  //out << "FastReport " << (m_use_realtime ? "(real time) " : "(CPU time) ") << " Active Module" << '\n';
714  for (auto & keyval: m_stream.modules) {
715  std::string const & label = keyval.first;
716  ModuleInfo const & module = keyval.second;
717  out << "FastReport " << std::right << std::setw(10) << module.summary_active / (double) summary.count << " " << label << '\n';
718  }
719  //out << "FastReport " << (m_use_realtime ? "(real time) " : "(CPU time) ") << " Active Module" << '\n';
720  out << '\n';
721  //out << "FastReport " << (m_use_realtime ? "(real time) " : "(CPU time) ") << " Active Module" << '\n';
722  for (auto & keyval: m_stream.moduletypes) {
723  std::string const & label = keyval.first;
724  ModuleInfo const & module = keyval.second;
725  out << "FastReport " << std::right << std::setw(10) << module.summary_active / (double) summary.count << " " << label << '\n';
726  }
727  //out << "FastReport " << (m_use_realtime ? "(real time) " : "(CPU time) ") << " Active Module" << '\n';
728  }
729 */
730 
732  // allocate a counter for each module and module type
733  for (auto & stream: m_stream) {
734  if (module.id() >= stream.fast_modules.size())
735  stream.fast_modules.resize(module.id() + 1, nullptr);
736  if (module.id() >= stream.fast_moduletypes.size())
737  stream.fast_moduletypes.resize(module.id() + 1, nullptr);
738 
739  stream.fast_modules[module.id()] = & stream.modules[module.moduleLabel()];;
740  stream.fast_moduletypes[module.id()] = & stream.moduletypes[module.moduleName()];
741  }
742 }
743 
745  unsigned int pid = processID(sc.processContext());
746  unsigned int sid = sc.streamID().value();
747  auto & stream = m_stream[sid];
748 
749  // new event, reset the per-event counter
750  stream.timer_event.start();
751 
752  // account the time spent between the last transition and the beginning of the event
753  stream.timing_perprocess[pid].preevent = delta(stream.timer_last_transition, stream.timer_event.getStartTime());
754 
755  // clear the event counters
756  stream.timing_perprocess[pid].event = 0;
757  stream.timing_perprocess[pid].all_paths = 0;
758  stream.timing_perprocess[pid].all_endpaths = 0;
759  stream.timing_perprocess[pid].interpaths = 0;
760  stream.timing_perprocess[pid].paths_interpaths.assign(stream.paths[pid].size() + 1, 0);
761  for (auto & keyval : stream.paths[pid]) {
762  keyval.second.timer.reset();
763  keyval.second.time_active = 0.;
764  keyval.second.time_exclusive = 0.;
765  keyval.second.time_premodules = 0.;
766  keyval.second.time_intermodules = 0.;
767  keyval.second.time_postmodules = 0.;
768  keyval.second.time_total = 0.;
769  }
770 
771  // copy the start event timestamp as the end of the previous path
772  // used by the inter-path overhead measurement
773  stream.timer_last_path = stream.timer_event.getStartTime();
774 
775  // if requested, set the lumisection for timing vs. lumisection plots
776  if (m_enable_dqm_byls and pid == 0)
777  setLuminosity(sid, 0, sc.eventID().luminosityBlock());
778 }
779 
781  unsigned int pid = processID(sc.processContext());
782  unsigned int sid = sc.streamID();
783  unsigned int rid = sc.runIndex();
784  auto & stream = m_stream[sid];
785 
786  // stop the per-event timer, and account event time
787  stream.timer_event.stop();
788  stream.timer_last_transition = stream.timer_event.getStopTime();
789  stream.timing_perprocess[pid].event = stream.timer_event.seconds();
790 
791  // the last part of inter-path overhead is the time between the end of the last (end)path and the end of the event processing
792  double interpaths = delta(stream.timer_last_path, stream.timer_event.getStopTime());
793  stream.timing_perprocess[pid].interpaths += interpaths;
794  stream.timing_perprocess[pid].paths_interpaths.back() = interpaths;
795 
796  {
797  // prevent different threads from updating the summary information at the same time
798  std::lock_guard<std::mutex> lock_summary(m_summary_mutex);
799 
800  // keep track of the total number of events and add this event's time to the per-run and per-job summary
801  m_run_summary_perprocess[rid][pid] += stream.timing_perprocess[pid];
802  m_job_summary_perprocess[pid] += stream.timing_perprocess[pid];
803 
804  // account the whole event timing details
805  if (pid+1 == m_process.size()) {
806  stream.timing.count = 1;
807  stream.timing.preevent = stream.timing_perprocess[0].preevent;
808  stream.timing.event = stream.timing_perprocess[0].event;
809  for (unsigned int i = 1; i < m_process.size(); ++i) {
810  stream.timing.event += stream.timing_perprocess[i].preevent;
811  stream.timing.event += stream.timing_perprocess[i].event;
812  }
813  m_run_summary[rid] += stream.timing;
814  m_job_summary += stream.timing;
815  }
816  }
817 
818  // elaborate "exclusive" modules
820  for (auto & keyval: stream.paths[pid]) {
821  PathInfo & pathinfo = keyval.second;
822  pathinfo.time_exclusive = pathinfo.time_overhead;
823 
824  for (uint32_t i = 0; i < pathinfo.last_run; ++i) {
825  ModuleInfo * module = pathinfo.modules[i];
826  if (module == 0)
827  // this is a module occurring more than once in the same path, skip it after the first occurrence
828  continue;
829  if ((module->run_in_path == & pathinfo) and (module->counter == 1))
830  pathinfo.time_exclusive += module->time_active;
831  }
832  }
833  }
834 
835  // fill the information per module type
836  // note: this is done here because during event processing two theads could try to update the same module type at the same time
837  // note: this is done only for the last subprocess, to avoid double conuting the modules' contributions
838  if ((m_enable_timing_modules) and (pid+1 == m_process.size())) {
839  for (unsigned int i = 0; i < stream.fast_modules.size(); ++i)
840  // check for null pointers - there is no guarantee that all module ids are valid and used
841  if (stream.fast_modules[i]) {
842  double active = stream.fast_modules[i]->time_active;
843  ModuleInfo & moduletype = * stream.fast_moduletypes[i];
844  moduletype.time_active += active;
845  moduletype.summary_active += active;
846  }
847  }
848 
849  // fill the DQM plots from the internal buffers
850  if (not m_enable_dqm)
851  return;
852 
853  // fill plots for per-event time by path
854  if (m_enable_timing_paths) {
855 
856  for (auto & keyval: stream.paths[pid]) {
857  PathInfo & pathinfo = keyval.second;
858 
859  stream.dqm_paths[pid].active_time->Fill(pathinfo.index, pathinfo.time_active * 1000.);
861  pathinfo.dqm_active->Fill(pathinfo.time_active * 1000.);
862 
863  stream.dqm_paths[pid].exclusive_time->Fill(pathinfo.index, pathinfo.time_exclusive * 1000.);
865  pathinfo.dqm_exclusive->Fill(pathinfo.time_exclusive * 1000.);
866 
867  stream.dqm_paths[pid].total_time->Fill(pathinfo.index, pathinfo.time_total * 1000.);
869  pathinfo.dqm_total->Fill(pathinfo.time_total * 1000.);
870 
871  // fill path overhead histograms
873  pathinfo.dqm_premodules ->Fill(pathinfo.time_premodules * 1000.);
874  pathinfo.dqm_intermodules->Fill(pathinfo.time_intermodules * 1000.);
875  pathinfo.dqm_postmodules ->Fill(pathinfo.time_postmodules * 1000.);
876  pathinfo.dqm_overhead ->Fill(pathinfo.time_overhead * 1000.);
877  }
878 
879  // fill detailed timing histograms
881  for (uint32_t i = 0; i < pathinfo.last_run; ++i) {
882  ModuleInfo * module = pathinfo.modules[i];
883  // skip duplicate modules
884  if (module == nullptr)
885  continue;
886  // fill the total time for all non-duplicate modules
887  pathinfo.dqm_module_total->Fill(i, module->time_active * 1000.);
888  // fill the active time only for module that have actually run in this path
889  if (module->run_in_path == & pathinfo)
890  pathinfo.dqm_module_active->Fill(i, module->time_active * 1000.);
891  }
892  }
893 
894  // fill path counter histograms
895  // - also for duplicate modules, to properly extract rejection information
896  // - fill the N+1th bin for paths accepting the event, so the FastTimerServiceClient can properly measure the last filter efficiency
898  for (uint32_t i = 0; i < pathinfo.last_run; ++i)
899  pathinfo.dqm_module_counter->Fill(i);
900  if (pathinfo.accept)
901  pathinfo.dqm_module_counter->Fill(pathinfo.modules.size());
902  }
903 
904  }
905  }
906 
907  // fill plots for per-event time by module
908  // note: this is done only for the last subprocess, to avoid filling the same plots multiple times
909  if ((m_enable_dqm_bymodule) and (pid+1 == m_process.size())) {
910  for (auto & keyval : stream.modules) {
911  ModuleInfo & module = keyval.second;
912  module.dqm_active->Fill(module.time_active * 1000.);
913  }
914  }
915 
916  // fill plots for per-event time by module type
917  // note: this is done only for the last subprocess, to avoid filling the same plots multiple times
918  if ((m_enable_dqm_bymoduletype) and (pid+1 == m_process.size())) {
919  for (auto & keyval : stream.moduletypes) {
920  ModuleInfo & module = keyval.second;
921  module.dqm_active->Fill(module.time_active * 1000.);
922  }
923  }
924 
925  // fill the interpath overhead plot
927  for (unsigned int i = 0; i <= stream.paths[pid].size(); ++i)
928  stream.dqm_paths[pid].interpaths->Fill(i, stream.timing_perprocess[pid].paths_interpaths[i] * 1000.);
929 
930  if (m_enable_dqm_summary) {
931  if (pid+1 == m_process.size())
932  stream.dqm.fill(stream.timing);
933  stream.dqm_perprocess[pid].fill(stream.timing_perprocess[pid]);
934  }
935 
936  if (not m_dqm_luminosity.empty()) {
937  if (pid+1 == m_process.size())
938  for (unsigned int i = 0; i < m_dqm_luminosity.size(); ++i)
939  stream.dqm_byluminosity[i].fill(stream.luminosity[i], stream.timing);
940  for (unsigned int i = 0; i < m_dqm_luminosity.size(); ++i)
941  stream.dqm_perprocess_byluminosity[pid][i].fill(stream.luminosity[i], stream.timing_perprocess[pid]);
942  }
943 
944 }
945 
947  auto & stream = m_stream[sid];
948 
949  // clear the event counters
950  stream.timing.reset();
951  stream.timer_source.start();
952 
953  // clear the event counters
954  // note: this is done here and not in preEvent to avoid clearing the counter before each subprocess
955  for (auto & keyval : stream.modules) {
956  keyval.second.timer.reset();
957  keyval.second.time_active = 0.;
958  keyval.second.run_in_path = nullptr;
959  keyval.second.counter = 0;
960  }
961  for (auto & keyval : stream.moduletypes) {
962  keyval.second.timer.reset();
963  keyval.second.time_active = 0.;
964  keyval.second.run_in_path = nullptr;
965  keyval.second.counter = 0;
966  }
967 
968  // account the time spent before the source
969  stream.timing.presource = delta(stream.timer_last_transition, stream.timer_source.getStartTime());
970 }
971 
973  auto & stream = m_stream[sid];
974  stream.timer_source.stop();
975  stream.timer_last_transition = stream.timer_source.getStopTime();
976 
977  // account the time spent in the source
978  stream.timing.source = stream.timer_source.seconds();
979 }
980 
981 
983  std::string const & path = pc.pathName();
984  unsigned int pid = processID(sc.processContext());
985  unsigned int sid = sc.streamID();
986  auto & stream = m_stream[sid];
987 
988  auto keyval = stream.paths[pid].find(path);
989  if (keyval != stream.paths[pid].end()) {
990  stream.current_path = & keyval->second;
991  } else {
992  // should never get here
993  stream.current_path = nullptr;
994  edm::LogError("FastTimerService") << "FastTimerService::prePathEvent: unexpected path " << path;
995  return;
996  }
997 
998  // prepare to measure the time spent between the beginning of the path and the execution of the first module
999  stream.current_path->first_module = nullptr;
1000 
1001  // time each (end)path
1002  stream.current_path->timer.start();
1003 
1004  if (path == m_process[pid].first_path) {
1005  // this is the first path, start the "all paths" counter
1006  stream.timer_paths.setStartTime(stream.current_path->timer.getStartTime());
1007  } else if (path == m_process[pid].first_endpath) {
1008  // this is the first endpath, start the "all paths" counter
1009  stream.timer_endpaths.setStartTime(stream.current_path->timer.getStartTime());
1010  }
1011 
1012  // measure the inter-path overhead as the time elapsed since the end of preiovus path
1013  // (or the beginning of the event, if this is the first path - see preEvent)
1014  double interpaths = delta(stream.timer_last_path, stream.current_path->timer.getStartTime());
1015  stream.timing_perprocess[pid].interpaths += interpaths;
1016  stream.timing_perprocess[pid].paths_interpaths[stream.current_path->index] = interpaths;
1017 }
1018 
1019 
1021  std::string const & path = pc.pathName();
1022  unsigned int pid = processID(sc.processContext());
1023  unsigned int sid = sc.streamID().value();
1024  auto & stream = m_stream[sid];
1025 
1026  if (stream.current_path == nullptr) {
1027  edm::LogError("FastTimerService") << "FastTimerService::postPathEvent: unexpected path " << path;
1028  return;
1029  }
1030 
1031  // time each (end)path
1032  stream.current_path->timer.stop();
1033  stream.current_path->time_active = stream.current_path->timer.seconds();
1034  stream.timer_last_path = stream.current_path->timer.getStopTime();
1035 
1036  double active = stream.current_path->time_active;
1037 
1038  // if enabled, account each (end)path
1039  if (m_enable_timing_paths) {
1040 
1041  PathInfo & pathinfo = * stream.current_path;
1042  pathinfo.summary_active += active;
1043 
1044  // measure the time spent between the execution of the last module and the end of the path
1046  double pre = 0.; // time spent before the first active module
1047  double inter = 0.; // time spent between active modules
1048  double post = 0.; // time spent after the last active module
1049  double overhead = 0.; // time spent before, between, or after modules
1050  double current = 0.; // time spent in modules active in the current path
1051  double total = active; // total per-path time, including modules already run as part of other paths
1052 
1053  // implementation note:
1054  // "active" has already measured all the time spent in this path
1055  // "current" will be the sum of the time spent inside each module while running this path, so that
1056  // "overhead" will be active - current
1057  // "total" will be active + the sum of the time spent in non-active modules
1058 
1059  uint32_t last_run = 0; // index of the last module run in this path, plus one
1060  if (status.wasrun() and not pathinfo.modules.empty())
1061  last_run = status.index() + 1; // index of the last module run in this path, plus one
1062  for (uint32_t i = 0; i < last_run; ++i) {
1063  ModuleInfo * module = pathinfo.modules[i];
1064 
1065  if (module == 0)
1066  // this is a module occurring more than once in the same path, skip it after the first occurrence
1067  continue;
1068 
1069  ++module->counter;
1070  if (module->run_in_path == & pathinfo) {
1071  current += module->time_active;
1072  } else {
1073  total += module->time_active;
1074  }
1075 
1076  }
1077 
1078  if (stream.current_path->first_module == nullptr) {
1079  // no modules were active during this path, account all the time as overhead
1080  pre = 0.;
1081  inter = 0.;
1082  post = active;
1083  overhead = active;
1084  } else {
1085  // extract overhead information
1086  pre = delta(stream.current_path->timer.getStartTime(), stream.current_path->first_module->timer.getStartTime());
1087  post = delta(stream.current_module->timer.getStopTime(), stream.current_path->timer.getStopTime());
1088  inter = active - pre - current - post;
1089  // take care of numeric precision and rounding errors - the timer is less precise than nanosecond resolution
1090  if (std::abs(inter) < 1e-9)
1091  inter = 0.;
1092  overhead = active - current;
1093  // take care of numeric precision and rounding errors - the timer is less precise than nanosecond resolution
1094  if (std::abs(overhead) < 1e-9)
1095  overhead = 0.;
1096  }
1097 
1098  pathinfo.time_premodules = pre;
1099  pathinfo.time_intermodules = inter;
1100  pathinfo.time_postmodules = post;
1101  pathinfo.time_overhead = overhead;
1102  pathinfo.time_total = total;
1103  pathinfo.summary_premodules += pre;
1104  pathinfo.summary_intermodules += inter;
1105  pathinfo.summary_postmodules += post;
1106  pathinfo.summary_overhead += overhead;
1107  pathinfo.summary_total += total;
1108  pathinfo.last_run = last_run;
1109  pathinfo.accept = status.accept();
1110  }
1111  }
1112 
1113  if (path == m_process[pid].last_path) {
1114  // this is the last path, stop and account the "all paths" counter
1115  stream.timer_paths.setStopTime(stream.current_path->timer.getStopTime());
1116  stream.timing_perprocess[pid].all_paths = stream.timer_paths.seconds();
1117  } else if (path == m_process[pid].last_endpath) {
1118  // this is the last endpath, stop and account the "all endpaths" counter
1119  stream.timer_endpaths.setStopTime(stream.current_path->timer.getStopTime());
1120  stream.timing_perprocess[pid].all_endpaths = stream.timer_endpaths.seconds();
1121  }
1122 
1123 }
1124 
1126  // this is ever called only if m_enable_timing_modules = true
1127  assert(m_enable_timing_modules);
1128 
1129  if (mcc.moduleDescription() == nullptr) {
1130  edm::LogError("FastTimerService") << "FastTimerService::postModuleEventDelayedGet: invalid module";
1131  return;
1132  }
1133 
1134  edm::ModuleDescription const & md = * mcc.moduleDescription();
1135  unsigned int sid = sc.streamID().value();
1136  auto & stream = m_stream[sid];
1137 
1138  // time each module
1139  if (md.id() < stream.fast_modules.size()) {
1140  ModuleInfo & module = * stream.fast_modules[md.id()];
1141  module.run_in_path = stream.current_path;
1142  module.timer.start();
1143  stream.current_module = & module;
1144  // used to measure the time spent between the beginning of the path and the execution of the first module
1145  if (stream.current_path->first_module == nullptr)
1146  stream.current_path->first_module = & module;
1147  } else {
1148  // should never get here
1149  edm::LogError("FastTimerService") << "FastTimerService::preModuleEvent: unexpected module " << md.moduleLabel();
1150  }
1151 }
1152 
1154  // this is ever called only if m_enable_timing_modules = true
1155  assert(m_enable_timing_modules);
1156 
1157  if (mcc.moduleDescription() == nullptr) {
1158  edm::LogError("FastTimerService") << "FastTimerService::postModuleEventDelayedGet: invalid module";
1159  return;
1160  }
1161 
1162  edm::ModuleDescription const & md = * mcc.moduleDescription();
1163  unsigned int sid = sc.streamID().value();
1164  auto & stream = m_stream[sid];
1165 
1166  double active = 0.;
1167 
1168  // time and account each module
1169  if (md.id() < stream.fast_modules.size()) {
1170  ModuleInfo & module = * stream.fast_modules[md.id()];
1171  module.timer.stop();
1172  active = module.timer.seconds();
1173  module.time_active = active;
1174  module.summary_active += active;
1175  // plots are filled post event processing
1176  } else {
1177  // should never get here
1178  edm::LogError("FastTimerService") << "FastTimerService::postModuleEvent: unexpected module " << md.moduleLabel();
1179  }
1180 }
1181 
1183  // this is ever called only if m_enable_timing_modules = true
1184  assert(m_enable_timing_modules);
1185 
1186  if (mcc.moduleDescription() == nullptr) {
1187  edm::LogError("FastTimerService") << "FastTimerService::postModuleEventDelayedGet: invalid module";
1188  return;
1189  }
1190 
1191  edm::ModuleDescription const & md = * mcc.moduleDescription();
1192  unsigned int sid = sc.streamID().value();
1193  auto & stream = m_stream[sid];
1194 
1195  // if the ModuleCallingContext state is "Pefetching", the module is not running,
1196  // and is asking for its dependencies due to a "consumes" declaration.
1197  // we can ignore this signal.
1198 
1199  // if the ModuleCallingContext state is "Running", the module was running:
1200  // it declared its dependencies as "mayConsume", and is now calling getByToken/getByLabel.
1201  // we pause the timer for this module, and resume it later in the postModuleEventDelayedGet signal.
1202 
1203  // if the ModuleCallingContext state is "Invalid", we ignore the signal.
1204 
1206  if (md.id() < stream.fast_modules.size()) {
1207  ModuleInfo & module = * stream.fast_modules[md.id()];
1208  module.timer.pause();
1209  } else {
1210  // should never get here
1211  edm::LogError("FastTimerService") << "FastTimerService::preModuleEventDelayedGet: unexpected module " << md.moduleLabel();
1212  }
1213  }
1214 
1215 }
1216 
1218  // this is ever called only if m_enable_timing_modules = true
1219  assert(m_enable_timing_modules);
1220 
1221  if (mcc.moduleDescription() == nullptr) {
1222  edm::LogError("FastTimerService") << "FastTimerService::postModuleEventDelayedGet: invalid module";
1223  return;
1224  }
1225 
1226  edm::ModuleDescription const & md = * mcc.moduleDescription();
1227  unsigned int sid = sc.streamID().value();
1228  auto & stream = m_stream[sid];
1229 
1230  // see the description of the possible ModuleCallingContext states in preModuleEventDelayedGet, above.
1232  if (md.id() < stream.fast_modules.size()) {
1233  ModuleInfo & module = * stream.fast_modules[md.id()];
1234  module.timer.resume();
1235  } else {
1236  // should never get here
1237  edm::LogError("FastTimerService") << "FastTimerService::postModuleEventDelayedGet: unexpected module " << md.moduleLabel();
1238  }
1239  }
1240 
1241 }
1242 
1243 // associate to a path all the modules it contains
1244 void FastTimerService::fillPathMap(unsigned int pid, std::string const & name, std::vector<std::string> const & modules) {
1245  for (auto & stream: m_stream) {
1246 
1247  std::vector<ModuleInfo *> & pathmap = stream.paths[pid][name].modules;
1248  pathmap.clear();
1249  pathmap.reserve( modules.size() );
1250  std::unordered_set<ModuleInfo const *> pool; // keep track of inserted modules
1251  for (auto const & module: modules) {
1252  // fix the name of negated or ignored modules
1253  std::string const & label = (module[0] == '!' or module[0] == '-') ? module.substr(1) : module;
1254 
1255  auto const & it = stream.modules.find(label);
1256  if (it == stream.modules.end()) {
1257  // no matching module was found
1258  pathmap.push_back( 0 );
1259  } else if (pool.insert(& it->second).second) {
1260  // new module
1261  pathmap.push_back(& it->second);
1262  } else {
1263  // duplicate module
1264  pathmap.push_back( 0 );
1265  }
1266  }
1267 
1268  }
1269 }
1270 
1271 
1272 // query the current module/path/event
1273 // Note: these functions incur in a "per-call timer overhead" (see above), currently of the order of 340ns
1274 
1275 // return the time spent since the last preModuleEvent() event
1277  return m_stream[sid].current_module->timer.secondsUntilNow();
1278 }
1279 
1280 // return the time spent since the last prePathEvent() event
1282  return m_stream[sid].current_path->timer.secondsUntilNow();
1283 }
1284 
1285 // return the time spent since the last preEvent() event
1287  return m_stream[sid].timer_event.secondsUntilNow();
1288 }
1289 
1290 // query the time spent in a module (available after the module has run)
1292  if (module.id() < m_stream[sid].fast_modules.size()) {
1293  return m_stream[sid].fast_modules[module.id()]->time_active;
1294  } else {
1295  edm::LogError("FastTimerService") << "FastTimerService::queryModuleTime: unexpected module " << module.moduleLabel();
1296  return 0.;
1297  }
1298 }
1299 
1300 // query the time spent in a module (available after the module has run)
1301 double FastTimerService::queryModuleTime(edm::StreamID sid, unsigned int id) const {
1302  if (id < m_stream[sid].fast_modules.size()) {
1303  return m_stream[sid].fast_modules[id]->time_active;
1304  } else {
1305  edm::LogError("FastTimerService") << "FastTimerService::queryModuleTime: unexpected module id " << id;
1306  return 0.;
1307  }
1308 }
1309 
1310 // query the time spent in a module (available after the module has run)
1312  auto const & keyval = m_stream[sid].modules.find(label);
1313  if (keyval != m_stream[sid].modules.end()) {
1314  return keyval->second.time_active;
1315  } else {
1316  // module not found
1317  edm::LogError("FastTimerService") << "FastTimerService::queryModuleTimeByLabel: unexpected module " << label;
1318  return 0.;
1319  }
1320 }
1321 
1322 // query the time spent in a type of module (available after the module has run)
1324  auto const & keyval = m_stream[sid].moduletypes.find(type);
1325  if (keyval != m_stream[sid].moduletypes.end()) {
1326  return keyval->second.time_active;
1327  } else {
1328  // module not found
1329  edm::LogError("FastTimerService") << "FastTimerService::queryModuleTimeByType: unexpected module type " << type;
1330  return 0.;
1331  }
1332 }
1333 
1334 /* FIXME re-implement taking into account subprocesses
1335 // query the time spent in a path (available after the path has run)
1336 double FastTimerService::queryPathActiveTime(edm::StreamID sid, const std::string & path) const {
1337  PathMap<PathInfo>::const_iterator keyval = m_stream[sid].paths.find(path);
1338  if (keyval != m_stream[sid].paths.end()) {
1339  return keyval->second.time_active;
1340  } else {
1341  edm::LogError("FastTimerService") << "FastTimerService::queryPathActiveTime: unexpected path " << path;
1342  return 0.;
1343  }
1344 }
1345 
1346 // query the time spent in a path (available after the path has run)
1347 double FastTimerService::queryPathExclusiveTime(edm::StreamID sid, const std::string & path) const {
1348  PathMap<PathInfo>::const_iterator keyval = m_stream[sid].paths.find(path);
1349  if (keyval != m_stream[sid].paths.end()) {
1350  return keyval->second.time_exclusive;
1351  } else {
1352  edm::LogError("FastTimerService") << "FastTimerService::queryPathExclusiveTime: unexpected path " << path;
1353  return 0.;
1354  }
1355 }
1356 
1357 // query the total time spent in a path (available after the path has run)
1358 double FastTimerService::queryPathTotalTime(edm::StreamID sid, const std::string & path) const {
1359  PathMap<PathInfo>::const_iterator keyval = m_stream[sid].paths.find(path);
1360  if (keyval != m_stream[sid].paths.end()) {
1361  return keyval->second.time_total;
1362  } else {
1363  edm::LogError("FastTimerService") << "FastTimerService::queryPathTotalTime: unexpected path " << path;
1364  return 0.;
1365  }
1366 }
1367 */
1368 
1369 // query the time spent in the current event's source (available during event processing)
1371  return m_stream[sid].timing.source;
1372 }
1373 
1374 // query the time spent processing the current event (available after the event has been processed)
1376  return m_stream[sid].timing.event;
1377 }
1378 
1379 /* FIXME re-implement taking into account subprocesses
1380 // query the time spent in the current event's paths (available during endpaths)
1381 double FastTimerService::queryPathsTime(edm::StreamID sid) const {
1382  return m_stream[sid].timing.all_paths;
1383 }
1384 
1385 // query the time spent in the current event's endpaths (available after all endpaths have run)
1386 double FastTimerService::queryEndPathsTime(edm::StreamID sid) const {
1387  return m_stream[sid].timing.all_endpaths;
1388 }
1389 */
1390 
1391 // describe the module's configuration
1394  desc.addUntracked<bool>( "useRealTimeClock", true);
1395  desc.addUntracked<bool>( "enableTimingPaths", true);
1396  desc.addUntracked<bool>( "enableTimingModules", true);
1397  desc.addUntracked<bool>( "enableTimingExclusive", false);
1398  desc.addUntracked<bool>( "enableTimingSummary", false);
1399  desc.addUntracked<bool>( "skipFirstPath", false),
1400  desc.addUntracked<bool>( "enableDQM", true);
1401  desc.addUntracked<bool>( "enableDQMbyPathActive", false);
1402  desc.addUntracked<bool>( "enableDQMbyPathTotal", true);
1403  desc.addUntracked<bool>( "enableDQMbyPathOverhead", false);
1404  desc.addUntracked<bool>( "enableDQMbyPathDetails", false);
1405  desc.addUntracked<bool>( "enableDQMbyPathCounters", true);
1406  desc.addUntracked<bool>( "enableDQMbyPathExclusive", false);
1407  desc.addUntracked<bool>( "enableDQMbyModule", false);
1408  desc.addUntracked<bool>( "enableDQMbyModuleType", false);
1409  desc.addUntracked<bool>( "enableDQMSummary", false);
1410  desc.addUntracked<bool>( "enableDQMbyLumiSection", false);
1411  desc.addUntracked<bool>( "enableDQMbyProcesses", false);
1412  desc.addUntracked<double>( "dqmTimeRange", 1000. ); // ms
1413  desc.addUntracked<double>( "dqmTimeResolution", 5. ); // ms
1414  desc.addUntracked<double>( "dqmPathTimeRange", 100. ); // ms
1415  desc.addUntracked<double>( "dqmPathTimeResolution", 0.5); // ms
1416  desc.addUntracked<double>( "dqmModuleTimeRange", 40. ); // ms
1417  desc.addUntracked<double>( "dqmModuleTimeResolution", 0.2); // ms
1418  desc.addUntracked<uint32_t>( "dqmLumiSectionsRange", 2500 ); // ~ 16 hours
1419  desc.addUntracked<std::string>( "dqmPath", "HLT/TimerService");
1420  descriptions.add("FastTimerService", desc);
1421 }
1422 
1423 // assign a "process id" to a process, given its ProcessContext
1425 {
1426  unsigned int pid = 0;
1427 
1428  // iterate through the chain of ProcessContext until we reach the topmost process
1429  while (context->isSubProcess()) {
1430  context = & context->parentProcessContext();
1431  ++pid;
1432  }
1433  return pid;
1434 }
RunNumber_t run() const
Definition: EventID.h:39
void preGlobalBeginRun(edm::GlobalContext const &)
void preModuleEventDelayedGet(edm::StreamContext const &, edm::ModuleCallingContext const &)
std::string const & pathName() const
Definition: PathContext.h:37
type
Definition: HCALResponse.h:21
unsigned int maxNumberOfThreads() const
Definition: SystemBounds.h:46
T getUntrackedParameter(std::string const &, T const &) const
void postStreamBeginRun(edm::StreamContext const &)
void watchPreEvent(PreEvent::slot_type const &iSlot)
double queryEventTime(edm::StreamID) const
int i
Definition: DBlmapReader.cc:9
const double m_dqm_eventtime_resolution
Strings const & getTrigPathModules(std::string const &name) const
void postStreamEndLumi(edm::StreamContext const &)
std::string const & processName() const
std::string const & getTrigPath(size_type const i) const
void watchPrePathEvent(PrePathEvent::slot_type const &iSlot)
void watchPreallocate(Preallocate::slot_type const &iSlot)
static double delta(FastTimer::Clock::time_point const &first, FastTimer::Clock::time_point const &second)
static void fill_dups(std::vector< std::string > &dups, unsigned int size)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
void watchPostEndJob(PostEndJob::slot_type const &iSlot)
Strings const & getEndPaths() const
void resume()
Definition: FastTimer.cc:51
unsigned int m_concurrent_streams
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::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void postModuleEvent(edm::StreamContext const &, edm::ModuleCallingContext const &)
bool wasrun() const
was this path run?
Definition: HLTPathStatus.h:60
void watchPreModuleEvent(PreModuleEvent::slot_type const &iSlot)
const bool m_enable_dqm_bypath_counters
const bool m_skip_first_path
void watchPostEvent(PostEvent::slot_type const &iSlot)
const bool m_enable_dqm_bypath_exclusive
LuminosityBlockID const & luminosityBlockID() const
Definition: GlobalContext.h:52
void printSummary(Timing const &summary, std::string const &label) const
std::vector< ProcessDescription > m_process
void watchPostStreamEndLumi(PostStreamEndLumi::slot_type const &iSlot)
const double m_dqm_pathtime_range
std::string const & moduleName() const
void watchPostPathEvent(PostPathEvent::slot_type const &iSlot)
void watchPostModuleEvent(PostModuleEvent::slot_type const &iSlot)
double currentPathTime(edm::StreamID) const
void watchPostSourceEvent(PostSourceEvent::slot_type const &iSlot)
std::vector< TimingPerProcess > m_job_summary_perprocess
RunIndex const & runIndex() const
Definition: StreamContext.h:60
string format
Some error handling for the usage.
void postPathEvent(edm::StreamContext const &, edm::PathContext const &, edm::HLTPathStatus const &)
unsigned int m_concurrent_threads
LuminosityBlockNumber_t luminosityBlock() const
Definition: EventID.h:40
std::string const & moduleLabel() const
static unsigned int getUniqueID()
Returns a unique id each time called. Intended to be passed to ModuleDescription&#39;s constructor&#39;s modI...
std::string m_dqm_path
ProcessContext const & parentProcessContext() const
unsigned int m_concurrent_runs
void postStreamBeginLumi(edm::StreamContext const &)
RunIndex const & runIndex() const
Definition: GlobalContext.h:53
unsigned int maxNumberOfStreams() const
Definition: SystemBounds.h:43
void preModuleBeginJob(edm::ModuleDescription const &)
const bool m_enable_dqm_bynproc
Strings const & getEndPathModules(std::string const &name) const
size_type findTrigPath(std::string const &name) const
std::vector< LuminosityDescription > m_dqm_luminosity
unsigned int m_module_id
tuple path
else: Piece not in the list, fine.
void prePathEvent(edm::StreamContext const &, edm::PathContext const &)
void stop()
Definition: FastTimer.cc:29
const bool m_enable_dqm_byls
void watchPostStreamBeginLumi(PostStreamBeginLumi::slot_type const &iSlot)
const double m_dqm_moduletime_resolution
std::mutex m_summary_mutex
void pause()
Definition: FastTimer.cc:40
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
FastTimerService(const edm::ParameterSet &, edm::ActivityRegistry &)
double queryModuleTimeByLabel(edm::StreamID, const std::string &) const
double currentEventTime(edm::StreamID) const
void watchPreModuleEventDelayedGet(PreModuleEventDelayedGet::slot_type const &iSlot)
void postEvent(edm::StreamContext const &)
void postGlobalEndRun(edm::GlobalContext const &)
void setLuminosity(unsigned int stream_id, unsigned int luminosity_id, double value)
ModuleDescription const * moduleDescription() const
std::vector< std::vector< TimingPerProcess > > m_run_summary_perprocess
const double infinity
void postStreamEndRun(edm::StreamContext const &)
void preModuleEvent(edm::StreamContext const &, edm::ModuleCallingContext const &)
RunNumber_t run() const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double seconds() const
Definition: FastTimer.cc:75
const bool m_enable_dqm_bypath_details
std::vector< Timing > m_run_summary
void fillPathMap(unsigned int pid, std::string const &name, std::vector< std::string > const &modules)
ProcessContext const * processContext() const
Definition: StreamContext.h:63
const bool m_enable_dqm_bypath_overhead
size_type findEndPath(std::string const &name) const
void watchPreModuleBeginJob(PreModuleBeginJob::slot_type const &iSlot)
void watchPostStreamEndRun(PostStreamEndRun::slot_type const &iSlot)
void mergeAndResetMEsRunSummaryCache(uint32_t run, uint32_t streamId, uint32_t moduleId)
Definition: DQMStore.cc:339
StreamID const & streamID() const
Definition: StreamContext.h:57
tuple out
Definition: dbtoconf.py:99
void watchPreGlobalBeginRun(PreGlobalBeginRun::slot_type const &iSlot)
const bool m_enable_dqm_bymodule
void postModuleEventDelayedGet(edm::StreamContext const &, edm::ModuleCallingContext const &)
const double m_dqm_moduletime_range
unsigned int value() const
Definition: StreamID.h:46
void watchPostModuleEventDelayedGet(PostModuleEventDelayedGet::slot_type const &iSlot)
double querySourceTime(edm::StreamID) const
int inter
tuple pid
Definition: sysUtil.py:22
void watchPostGlobalEndRun(PostGlobalEndRun::slot_type const &iSlot)
void preSourceEvent(edm::StreamID)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void preEvent(edm::StreamContext const &)
const bool m_enable_timing_summary
bool accept() const
has this path accepted the event?
Definition: HLTPathStatus.h:62
ProcessContext const * processContext() const
Definition: GlobalContext.h:56
void postSourceEvent(edm::StreamID)
const bool m_enable_dqm_bymoduletype
const bool m_enable_dqm_summary
void watchPostStreamBeginRun(PostStreamBeginRun::slot_type const &iSlot)
double queryModuleTimeByType(edm::StreamID, const std::string &) const
std::string const & getEndPath(size_type const i) const
const bool m_enable_dqm_bypath_total
void watchPreStreamBeginRun(PreStreamBeginRun::slot_type const &iSlot)
Strings const & getTrigPaths() const
double queryModuleTime(edm::StreamID, const edm::ModuleDescription &) const
const bool m_enable_dqm_bypath_active
unsigned int maxNumberOfConcurrentRuns() const
Definition: SystemBounds.h:44
std::vector< ModuleInfo * > modules
EventID const & eventID() const
Definition: StreamContext.h:59
void watchPreSourceEvent(PreSourceEvent::slot_type const &iSlot)
static Interceptor::Registry registry("Interceptor")
tuple status
Definition: ntuplemaker.py:245
tuple process
Definition: LaserDQM_cfg.py:3
static unsigned int processID(edm::ProcessContext const *)
double currentModuleTime(edm::StreamID) const
void mergeAndResetMEsLuminositySummaryCache(uint32_t run, uint32_t lumi, uint32_t streamId, uint32_t moduleId)
Definition: DQMStore.cc:394
void preStreamBeginRun(edm::StreamContext const &)
std::vector< StreamData > m_stream
bool isSubProcess() const
Definition: vlib.h:208
tuple size
Write out results.
unsigned int reserveLuminosityPlots(std::string const &name, std::string const &title, std::string const &label, double range, double resolution)
void printProcessSummary(Timing const &total, TimingPerProcess const &summary, std::string const &label, std::string const &process) const
void preallocate(edm::service::SystemBounds const &)
unsigned int id() const
const double m_dqm_eventtime_range
const double m_dqm_pathtime_resolution
unsigned int index() const
Definition: HLTPathStatus.h:55
void start()
Definition: FastTimer.cc:17