CMS 3D CMS Logo

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 <mutex>
11 #include <string>
12 #include <sstream>
13 #include <unordered_set>
14 #include <unordered_map>
15 
16 // boost headers
17 #include <boost/format.hpp>
18 #include <boost/range/irange.hpp>
19 
20 // CMSSW headers
37 
38 
40 
41 namespace {
42 
43  // convert any std::chrono::duration to milliseconds
44  template <class Rep, class Period>
45  double ms(std::chrono::duration<Rep, Period> duration)
46  {
47  return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(duration).count();;
48  }
49 
50  // convert any boost::chrono::duration to milliseconds
51  template <class Rep, class Period>
52  double ms(boost::chrono::duration<Rep, Period> duration)
53  {
54  return boost::chrono::duration_cast<boost::chrono::duration<double, boost::milli>>(duration).count();;
55  }
56 
57 } // namespace
58 
60 
61 // resources being monitored by the service
62 
63 // Resources
64 
66  time_thread(boost::chrono::nanoseconds::zero()),
67  time_real(boost::chrono::nanoseconds::zero())
68 { }
69 
70 void
72  time_thread = boost::chrono::nanoseconds::zero();
73  time_real = boost::chrono::nanoseconds::zero();
74 }
75 
78  time_thread += other.time_thread;
79  time_real += other.time_real;
80  return *this;
81 }
82 
85  Resources result(*this);
86  result += other;
87  return result;
88 }
89 
90 // ResourcesPerModule
91 
93  = default;
94 
95 void
97  total.reset();
98  events = 0;
99 }
100 
103  total += other.total;
104  events += other.events;
105  return *this;
106 }
107 
110  ResourcesPerModule result(*this);
111  result += other;
112  return result;
113 }
114 
115 
116 // ResourcesPerPath
117 
119  = default;
120 
121 void
123  active.reset();
124  total.reset();
125  last = 0;
126  status = false;
127 }
128 
131  active += other.active;
132  total += other.total;
133  last = 0; // summing these makes no sense, reset them instead
134  status = false;
135  return *this;
136 }
137 
140  ResourcesPerPath result(*this);
141  result += other;
142  return result;
143 }
144 
145 
146 // ResourcesPerProcess
147 
149  total(),
150  paths(process.paths_.size()),
151  endpaths(process.endPaths_.size())
152 {
153 }
154 
155 void
157  total.reset();
158  for (auto & path: paths)
159  path.reset();
160  for (auto & path: endpaths)
161  path.reset();
162 }
163 
166  total += other.total;
167  assert(paths.size() == other.paths.size());
168  for (unsigned int i: boost::irange(0ul, paths.size()))
169  paths[i] += other.paths[i];
170  assert(endpaths.size() == other.endpaths.size());
171  for (unsigned int i: boost::irange(0ul, endpaths.size()))
172  endpaths[i] += other.endpaths[i];
173  return *this;
174 }
175 
179  result += other;
180  return result;
181 }
182 
183 
184 // ResourcesPerJob
185 
187  = default;
188 
189 FastTimerService::ResourcesPerJob::ResourcesPerJob(ProcessCallGraph const& job, std::vector<GroupOfModules> const& groups) :
190  total(),
191  highlight( groups.size() ),
192  modules( job.size() ),
193  processes(),
194  events(0)
195 {
196  processes.reserve(job.processes().size());
197  for (auto const& process: job.processes())
198  processes.emplace_back(process);
199 }
200 
201 void
203  total.reset();
204  for (auto & module: highlight)
205  module.reset();
206  for (auto & module: modules)
207  module.reset();
208  for (auto & process: processes)
209  process.reset();
210  events = 0;
211 }
212 
215  total += other.total;
216  assert(highlight.size() == other.highlight.size());
217  for (unsigned int i: boost::irange(0ul, highlight.size()))
218  highlight[i] += other.highlight[i];
219  assert(modules.size() == other.modules.size());
220  for (unsigned int i: boost::irange(0ul, modules.size()))
221  modules[i] += other.modules[i];
222  assert(processes.size() == other.processes.size());
223  for (unsigned int i: boost::irange(0ul, processes.size()))
224  processes[i] += other.processes[i];
225  events += other.events;
226  return *this;
227 }
228 
231  ResourcesPerJob result(*this);
232  result += other;
233  return result;
234 }
235 
236 
237 // per-thread measurements
238 
239 // Measurement
240 
242  = default;
243 
244 void
246  #ifdef DEBUG_THREAD_CONCURRENCY
247  id = std::this_thread::get_id();
248  #endif // DEBUG_THREAD_CONCURRENCY
249  time_thread = boost::chrono::thread_clock::now();
251 }
252 
253 void
255  #ifdef DEBUG_THREAD_CONCURRENCY
256  assert(std::this_thread::get_id() == id);
257  #endif // DEBUG_THREAD_CONCURRENCY
258  auto new_time_thread = boost::chrono::thread_clock::now();
259  auto new_time_real = boost::chrono::high_resolution_clock::now();
260  store.time_thread = new_time_thread - time_thread;
261  store.time_real = new_time_real - time_real;
262  time_thread = new_time_thread;
263  time_real = new_time_real;
264 }
265 
267 
269  time_thread_(nullptr),
270  time_thread_byls_(nullptr),
271  time_real_(nullptr),
272  time_real_byls_(nullptr)
273 {
274 }
275 
276 void
278 {
279  // the plots are owned by the DQMStore
280  time_thread_ = nullptr;
281  time_thread_byls_ = nullptr;
282  time_real_ = nullptr;
283  time_real_byls_ = nullptr;
284 }
285 
286 void
288  DQMStore::IBooker & booker,
289  std::string const& name,
290  std::string const& title,
291  double range,
292  double resolution,
293  unsigned int lumisections,
294  bool byls)
295 {
296  int bins = (int) std::ceil(range / resolution);
297  std::string y_title = (boost::format("events / %.1f ms") % resolution).str();
298 
299  time_thread_ = booker.book1D(
300  name + " time_thread",
301  title + " processing time (cpu)",
302  bins, 0., range
303  )->getTH1F();
304  time_thread_->StatOverflows(true);
305  time_thread_->SetXTitle("processing time [ms]");
306  time_thread_->SetYTitle(y_title.c_str());
307 
308  time_real_ = booker.book1D(
309  name + " time_real",
310  title + " processing time (real)",
311  bins, 0., range
312  )->getTH1F();
313  time_real_->StatOverflows(true);
314  time_real_->SetXTitle("processing time [ms]");
315  time_real_->SetYTitle(y_title.c_str());
316 
317  if (not byls)
318  return;
319 
321  name + " time_thread_byls",
322  title + " processing time (cpu) vs. lumisection",
323  lumisections, 0.5, lumisections + 0.5,
325  " ")->getTProfile();
326  time_thread_byls_->StatOverflows(true);
327  time_thread_byls_->SetXTitle("lumisection");
328  time_thread_byls_->SetYTitle("processing time [ms]");
329 
330  time_real_byls_ = booker.bookProfile(
331  name + " time_real_byls",
332  title + " processing time (real) vs. lumisection",
333  lumisections, 0.5, lumisections + 0.5,
335  " ")->getTProfile();
336  time_real_byls_->StatOverflows(true);
337  time_real_byls_->SetXTitle("lumisection");
338  time_real_byls_->SetYTitle("processing time [ms]");
339 }
340 
341 void
342 FastTimerService::PlotsPerElement::fill(Resources const& data, unsigned int lumisection)
343 {
344  if (time_thread_)
345  time_thread_->Fill(ms(data.time_thread));
346 
347  if (time_thread_byls_)
348  time_thread_byls_->Fill(lumisection, ms(data.time_thread));
349 
350  if (time_real_)
351  time_real_->Fill(ms(data.time_real));
352 
353  if (time_real_byls_)
354  time_real_byls_->Fill(lumisection, ms(data.time_real));
355 }
356 
357 void
359 {
360  float total;
361  float fraction;
362 
363  total = ms(data.time_thread);
364  fraction = (total > 0.) ? (ms(part.time_thread) / total) : 0.;
365  if (time_thread_)
366  time_thread_->Fill(total, fraction);
367 
368  if (time_thread_byls_)
369  time_thread_byls_->Fill(lumisection, total, fraction);
370 
371  total = ms(data.time_real);
372  fraction = (total > 0.) ? (ms(part.time_real) / total) : 0.;
373  if (time_real_)
374  time_real_->Fill(total, fraction);
375 
376  if (time_real_byls_)
377  time_real_byls_->Fill(lumisection, total, fraction);
378 }
379 
380 
382  total_(),
383  module_counter_(nullptr),
384  module_time_thread_total_(nullptr),
385  module_time_real_total_(nullptr)
386 {
387 }
388 
389 void
391 {
392  // the plots are owned by the DQMStore
393  total_.reset();
394  module_counter_ = nullptr;
395  module_time_thread_total_ = nullptr;
396  module_time_real_total_ = nullptr;
397 }
398 
399 void
401  DQMStore::IBooker & booker,
402  ProcessCallGraph const& job,
404  double range,
405  double resolution,
406  unsigned int lumisections,
407  bool byls)
408 {
409  const std::string basedir = booker.pwd();
410  booker.setCurrentFolder(basedir + "/path " + path.name_);
411 
412  total_.book(booker, "path", path.name_, range, resolution, lumisections, byls);
413 
414  unsigned int bins = path.modules_and_dependencies_.size();
415  module_counter_ = booker.book1DD(
416  "module_counter",
417  "module counter",
418  bins + 1, -0.5, bins + 0.5
419  )->getTH1D();
420  module_counter_->SetYTitle("processing time [ms]");
422  "module_time_thread_total",
423  "total module time (cpu)",
424  bins, -0.5, bins - 0.5
425  )->getTH1D();
426  module_time_thread_total_->SetYTitle("processing time [ms]");
428  "module_time_real_total",
429  "total module time (real)",
430  bins, -0.5, bins - 0.5
431  )->getTH1D();
432  module_time_real_total_->SetYTitle("processing time [ms]");
433  for (unsigned int bin: boost::irange(0u, bins)) {
434  auto const& module = job[path.modules_and_dependencies_[bin]];
435  std::string const& label = module.scheduled_ ? module.module_.moduleLabel() : module.module_.moduleLabel() + " (unscheduled)";
436  module_counter_ ->GetXaxis()->SetBinLabel(bin + 1, label.c_str());
437  module_time_thread_total_->GetXaxis()->SetBinLabel(bin + 1, label.c_str());
438  module_time_real_total_ ->GetXaxis()->SetBinLabel(bin + 1, label.c_str());
439  }
440  module_counter_->GetXaxis()->SetBinLabel(bins + 1, "");
441 
442  booker.setCurrentFolder(basedir);
443 }
444 
445 void
447 {
448  // fill the total path time
449  total_.fill(path.total, ls);
450 
451  // fill the modules that actually ran and the total time spent in each od them
452  for (unsigned int i = 0; i < path.last; ++i) {
453  auto const& module = data.modules[description.modules_and_dependencies_[i]];
454  module_counter_->Fill(i);
455  module_time_thread_total_->Fill(i, ms(module.total.time_thread));
456  module_time_real_total_->Fill(i, ms(module.total.time_real));
457  }
458  if (path.status)
459  module_counter_->Fill(path.last);
460 }
461 
462 
464  event_(),
465  paths_(process.paths_.size()),
466  endpaths_(process.endPaths_.size())
467 {
468 }
469 
470 void
472 {
473  event_.reset();
474  for (auto & path: paths_)
475  path.reset();
476  for (auto & path: endpaths_)
477  path.reset();
478 }
479 
480 void
482  DQMStore::IBooker & booker,
483  ProcessCallGraph const& job,
485  double event_range,
486  double event_resolution,
487  double path_range,
488  double path_resolution,
489  unsigned int lumisections,
490  bool byls)
491 {
492  const std::string basedir = booker.pwd();
493  event_.book(booker,
494  "process " + process.name_, "process " + process.name_,
495  event_range,
496  event_resolution,
497  lumisections,
498  byls);
499  booker.setCurrentFolder(basedir + "/process " + process.name_ + " paths");
500  for (unsigned int id: boost::irange(0ul, paths_.size()))
501  {
502  paths_[id].book(booker,
503  job, process.paths_[id],
504  path_range,
505  path_resolution,
506  lumisections,
507  byls);
508  }
509  for (unsigned int id: boost::irange(0ul, endpaths_.size()))
510  {
511  endpaths_[id].book(booker,
512  job, process.endPaths_[id],
513  path_range,
514  path_resolution,
515  lumisections,
516  byls);
517  }
518  booker.setCurrentFolder(basedir);
519 }
520 
521 void
523 {
524  // fill process event plots
525  event_.fill(process.total, ls);
526 
527  // fill all paths plots
528  for (unsigned int id: boost::irange(0ul, paths_.size()))
529  paths_[id].fill(description.paths_[id], data, process.paths[id], ls);
530 
531  // fill all endpaths plots
532  for (unsigned int id: boost::irange(0ul, endpaths_.size()))
533  endpaths_[id].fill(description.endPaths_[id], data, process.endpaths[id], ls);
534 }
535 
536 FastTimerService::PlotsPerJob::PlotsPerJob(ProcessCallGraph const& job, std::vector<GroupOfModules> const& groups) :
537  event_(),
538  highlight_(groups.size()),
539  modules_(job.size()),
540  processes_()
541 {
542  processes_.reserve(job.processes().size());
543  for (auto const& process: job.processes())
544  processes_.emplace_back(process);
545 }
546 
547 void
549 {
550  event_.reset();
551  for (auto & module: highlight_)
552  module.reset();
553  for (auto & module: modules_)
554  module.reset();
555  for (auto & process: processes_)
556  process.reset();
557 }
558 
559 void
561  DQMStore::IBooker & booker,
562  ProcessCallGraph const& job,
563  std::vector<GroupOfModules> const& groups,
564  double event_range,
565  double event_resolution,
566  double path_range,
567  double path_resolution,
568  double module_range,
569  double module_resolution,
570  unsigned int lumisections,
571  bool bymodule,
572  bool byls)
573 {
574  const std::string basedir = booker.pwd();
575 
576  // event summary plots
577  event_.book(booker,
578  "event", "Event",
579  event_range,
580  event_resolution,
581  lumisections,
582  byls);
583 
584  modules_[job.source().id()].book(booker,
585  "source", "Source",
586  module_range,
587  module_resolution,
588  lumisections,
589  byls);
590 
591  // plot the time spent in few given groups of modules
592  for (unsigned int group: boost::irange(0ul, groups.size())) {
593  auto const & label = groups[group].label;
594  highlight_[group].book(booker,
595  "highlight " + label, "Highlight " + label,
596  event_range,
597  event_resolution,
598  lumisections,
599  byls);
600  }
601 
602  // plots per subprocess (event, modules, paths and endpaths)
603  for (unsigned int pid: boost::irange(0ul, job.processes().size())) {
604  auto const& process = job.processDescription(pid);
605  processes_[pid].book(booker,
606  job, process,
607  event_range,
608  event_resolution,
609  path_range,
610  path_resolution,
611  lumisections,
612  byls);
613 
614  if (bymodule) {
615  booker.setCurrentFolder(basedir + "/process " + process.name_ + " modules");
616  for (unsigned int id: process.modules_)
617  {
618  auto const& module_name = job.module(id).moduleLabel();
619  modules_[id].book(booker,
621  module_range,
622  module_resolution,
623  lumisections,
624  byls);
625  }
626  booker.setCurrentFolder(basedir);
627  }
628  }
629 }
630 
631 void
633 {
634  // fill total event plots
635  event_.fill(data.total, ls);
636 
637  // fill highltight plots
638  for (unsigned int group: boost::irange(0ul, highlight_.size()))
639  highlight_[group].fill_fraction(data.total, data.highlight[group], ls);
640 
641  // fill modules plots
642  for (unsigned int id: boost::irange(0ul, modules_.size()))
643  modules_[id].fill(data.modules[id].total, ls);
644 
645  for (unsigned int pid: boost::irange(0ul, processes_.size()))
646  processes_[pid].fill(job.processDescription(pid), data, data.processes[pid], ls);
647 }
648 
649 
651 
653  // configuration
654  callgraph_(),
655  // job configuration
656  concurrent_runs_( 0 ),
657  concurrent_streams_( 0 ),
658  concurrent_threads_( 0 ),
659  print_event_summary_( config.getUntrackedParameter<bool>( "printEventSummary" ) ),
660  print_run_summary_( config.getUntrackedParameter<bool>( "printRunSummary" ) ),
661  print_job_summary_( config.getUntrackedParameter<bool>( "printJobSummary" ) ),
662  // dqm configuration
663  module_id_( edm::ModuleDescription::invalidID() ),
664  enable_dqm_( config.getUntrackedParameter<bool>( "enableDQM" ) ),
665  enable_dqm_bymodule_( config.getUntrackedParameter<bool>( "enableDQMbyModule" ) ),
666  enable_dqm_byls_( config.getUntrackedParameter<bool>( "enableDQMbyLumiSection" ) ),
667  enable_dqm_bynproc_( config.getUntrackedParameter<bool>( "enableDQMbyProcesses" ) ),
668  dqm_eventtime_range_( config.getUntrackedParameter<double>( "dqmTimeRange" ) ), // ms
669  dqm_eventtime_resolution_( config.getUntrackedParameter<double>( "dqmTimeResolution" ) ), // ms
670  dqm_pathtime_range_( config.getUntrackedParameter<double>( "dqmPathTimeRange" ) ), // ms
671  dqm_pathtime_resolution_( config.getUntrackedParameter<double>( "dqmPathTimeResolution" ) ), // ms
672  dqm_moduletime_range_( config.getUntrackedParameter<double>( "dqmModuleTimeRange" ) ), // ms
673  dqm_moduletime_resolution_( config.getUntrackedParameter<double>( "dqmModuleTimeResolution" ) ), // ms
674  dqm_lumisections_range_( config.getUntrackedParameter<unsigned int>( "dqmLumiSectionsRange" ) ),
675  dqm_path_( config.getUntrackedParameter<std::string>("dqmPath" ) ),
676  // highlight configuration
677  highlight_module_psets_( config.getUntrackedParameter<std::vector<edm::ParameterSet>>("highlightModules") ),
678  highlight_modules_( highlight_module_psets_.size()) // filled in postBeginJob()
679 {
683  registry.watchPostEndJob( this, & FastTimerService::postEndJob );
685 //registry.watchPostGlobalBeginRun( this, & FastTimerService::postGlobalBeginRun );
686 //registry.watchPreGlobalEndRun( this, & FastTimerService::preGlobalEndRun );
689 //registry.watchPostStreamBeginRun( this, & FastTimerService::postStreamBeginRun );
690 //registry.watchPreStreamEndRun( this, & FastTimerService::preStreamEndRun );
692 //registry.watchPreGlobalBeginLumi( this, & FastTimerService::preGlobalBeginLumi );
693 //registry.watchPostGlobalBeginLumi( this, & FastTimerService::postGlobalBeginLumi );
694 //registry.watchPreGlobalEndLumi( this, & FastTimerService::preGlobalEndLumi );
695 //registry.watchPostGlobalEndLumi( this, & FastTimerService::postGlobalEndLumi );
697 //registry.watchPostStreamBeginLumi( this, & FastTimerService::postStreamBeginLumi );
698 //registry.watchPreStreamEndLumi( this, & FastTimerService::preStreamEndLumi );
700 //registry.watchPreEvent( this, & FastTimerService::preEvent );
701  registry.watchPostEvent( this, & FastTimerService::postEvent );
705 //registry.watchPostSourceConstruction( this, & FastTimerService::postSourceConstruction);
706 //registry.watchPreSourceRun( this, & FastTimerService::preSourceRun );
707 //registry.watchPostSourceRun( this, & FastTimerService::postSourceRun );
708 //registry.watchPreSourceLumi( this, & FastTimerService::preSourceLumi );
709 //registry.watchPostSourceLumi( this, & FastTimerService::postSourceLumi );
712 //registry.watchPreModuleBeginJob( this, & FastTimerService::preModuleBeginJob );
713 //registry.watchPostModuleBeginJob( this, & FastTimerService::postModuleBeginJob );
714 //registry.watchPreModuleEndJob( this, & FastTimerService::preModuleEndJob );
715 //registry.watchPostModuleEndJob( this, & FastTimerService::postModuleEndJob );
716 //registry.watchPreModuleBeginStream( this, & FastTimerService::preModuleBeginStream );
717 //registry.watchPostModuleBeginStream( this, & FastTimerService::postModuleBeginStream );
718 //registry.watchPreModuleEndStream( this, & FastTimerService::preModuleEndStream );
719 //registry.watchPostModuleEndStream( this, & FastTimerService::postModuleEndStream );
720 //registry.watchPreModuleGlobalBeginRun( this, & FastTimerService::preModuleGlobalBeginRun );
721 //registry.watchPostModuleGlobalBeginRun( this, & FastTimerService::postModuleGlobalBeginRun );
722 //registry.watchPreModuleGlobalEndRun( this, & FastTimerService::preModuleGlobalEndRun );
723 //registry.watchPostModuleGlobalEndRun( this, & FastTimerService::postModuleGlobalEndRun );
724 //registry.watchPreModuleGlobalBeginLumi( this, & FastTimerService::preModuleGlobalBeginLumi );
725 //registry.watchPostModuleGlobalBeginLumi( this, & FastTimerService::postModuleGlobalBeginLumi );
726 //registry.watchPreModuleGlobalEndLumi( this, & FastTimerService::preModuleGlobalEndLumi );
727 //registry.watchPostModuleGlobalEndLumi( this, & FastTimerService::postModuleGlobalEndLumi );
728 //registry.watchPreModuleStreamBeginRun( this, & FastTimerService::preModuleStreamBeginRun );
729 //registry.watchPostModuleStreamBeginRun( this, & FastTimerService::postModuleStreamBeginRun );
730 //registry.watchPreModuleStreamEndRun( this, & FastTimerService::preModuleStreamEndRun );
731 //registry.watchPostModuleStreamEndRun( this, & FastTimerService::postModuleStreamEndRun );
732 //registry.watchPreModuleStreamBeginLumi( this, & FastTimerService::preModuleStreamBeginLumi );
733 //registry.watchPostModuleStreamBeginLumi( this, & FastTimerService::postModuleStreamBeginLumi );
734 //registry.watchPreModuleStreamEndLumi( this, & FastTimerService::preModuleStreamEndLumi );
735 //registry.watchPostModuleStreamEndLumi( this, & FastTimerService::postModuleStreamEndLumi );
736 //registry.watchPreModuleEventPrefetching( this, & FastTimerService::preModuleEventPrefetching );
737 //registry.watchPostModuleEventPrefetching( this, & FastTimerService::postModuleEventPrefetching );
742 //registry.watchPreEventReadFromSource( this, & FastTimerService::preEventReadFromSource );
743 //registry.watchPostEventReadFromSource( this, & FastTimerService::postEventReadFromSource );
744 }
745 
747 
748 double
750 {
751  // private version, assume "id" is valid
752  auto const& stream = streams_[sid];
753  auto const& module = stream.modules[id];
754  return ms(module.total.time_real);
755 }
756 
757 double
759 {
760  return queryModuleTime_(sid, callgraph_.source().id());
761 }
762 
763 double
765 {
766  auto const& stream = streams_[sid];
767  return ms(stream.total.time_real);
768 }
769 
770 double
772 {
773  unsigned int pid = callgraph_.processId(process);
774  auto const& stream = streams_[sid];
775  return ms(stream.processes[pid].total.time_real);
776 }
777 
778 double
780 {
781  return queryModuleTime_(sid, md.id());
782 }
783 
784 double
786 {
787  if (id < callgraph_.size())
788  return queryModuleTime_(sid, id);
789 
790  // FIXME issue a LogWarning, raise an exception, or return NaN
791  return 0.;
792 }
793 
794 double
796 {
797  for (unsigned int id: boost::irange(0u, callgraph_.size()))
798  if (callgraph_.module(id).moduleLabel() == label)
799  return queryModuleTime_(sid, id);
800 
801  // FIXME issue a LogWarning, raise an exception, or return NaN
802  return 0.;
803 }
804 
805 double
807 {
808  for (unsigned int id: callgraph_.processDescription(process).modules_)
809  if (callgraph_.module(id).moduleLabel() == label)
810  return queryModuleTime_(sid, id);
811 
812  // FIXME issue a LogWarning, raise an exception, or return NaN
813  return 0.;
814 }
815 
816 double
818 {
819  auto const& stream = streams_[sid];
820  for (unsigned int pid: boost::irange(0ul, callgraph_.processes().size()))
821  {
822  auto const& desc = callgraph_.processDescription(pid);
823  for (unsigned int id: boost::irange(0ul, desc.paths_.size()))
824  if (desc.paths_[id].name_ == path)
825  return ms(stream.processes[pid].paths[id].total.time_real);
826  for (unsigned int id: boost::irange(0ul, desc.endPaths_.size()))
827  if (desc.paths_[id].name_ == path)
828  return ms(stream.processes[pid].endpaths[id].total.time_real);
829  }
830 
831  // FIXME issue a LogWarning, raise an exception, or return NaN
832  return 0.;
833 }
834 
835 double
837 {
838  auto const& stream = streams_[sid];
839  unsigned int pid = callgraph_.processId(process);
840  auto const& desc = callgraph_.processDescription(pid);
841  for (unsigned int id: boost::irange(0ul, desc.paths_.size()))
842  if (desc.paths_[id].name_ == path)
843  return ms(stream.processes[pid].paths[id].total.time_real);
844  for (unsigned int id: boost::irange(0ul, desc.endPaths_.size()))
845  if (desc.paths_[id].name_ == path)
846  return ms(stream.processes[pid].endpaths[id].total.time_real);
847 
848  // FIXME issue a LogWarning, raise an exception, or return NaN
849  return 0.;
850 }
851 
852 double
854 {
855  auto const& stream = streams_[sid];
856  for (unsigned int group: boost::irange(0ul, highlight_modules_.size()))
857  if (highlight_modules_[group].label == label)
858  return ms(stream.highlight[group].time_real);
859 
860  // FIXME issue a LogWarning, raise an exception, or return NaN
861  return 0.;
862 }
863 
864 
865 void
867 {
868  LogDebug("FastTimerService") << "The FastTimerService received is currently not monitoring the signal \"" << signal << "\".\n";
869 }
870 
871 void
873 {
874  // warn about each signal only once per job
875  if (unsupported_signals_.insert(signal).second)
876  edm::LogWarning("FastTimerService") << "The FastTimerService received the unsupported signal \"" << signal << "\".\n"
877  << "Please report how to reproduce the issue to cms-hlt@cern.ch .";
878 }
879 
880 void
882 {
883  ignoredSignal(__func__);
884 
885  // reset the run counters only during the main process being run
886  if (isFirstSubprocess(gc)) {
888  run_summary_[gc.runIndex()].reset();
889  }
890 }
891 
892 void
894 {
895  ignoredSignal(__func__);
896 }
897 
898 void
900 {
901  ignoredSignal(__func__);
902 
903  unsigned int sid = sc.streamID().value();
904 
905  // reset counters and book the DQM plots during the main process being run
906  if (isFirstSubprocess(sc)) {
907  subprocess_run_check_[sid] = 0;
908 
909  // book the DQM plots
910  if (enable_dqm_) {
911  // define a callback to book the MonitorElements
912  auto bookTransactionCallback = [&, this] (DQMStore::IBooker & booker)
913  {
914  booker.setCurrentFolder(dqm_path_);
915  stream_plots_[sid].book(booker, callgraph_,
926  };
927 
928  // book MonitorElements for this stream
929  edm::Service<DQMStore>()->bookTransaction(bookTransactionCallback, sc.eventID().run(), sid, module_id_);
930  }
931  }
932 }
933 
934 
935 void
937 {
941 
943  dqm_path_ += (boost::format("/Running %d processes") % concurrent_threads_).str();
944 
945  // allocate atomic variables to keep track of the completion of each step, process by process
946  subprocess_event_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_streams_);
947  for (unsigned int i = 0; i < concurrent_streams_; ++i)
949  subprocess_lumisection_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_streams_);
950  for (unsigned int i = 0; i < concurrent_streams_; ++i)
952  subprocess_run_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_streams_);
953  for (unsigned int i = 0; i < concurrent_streams_; ++i)
955  subprocess_global_run_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_streams_);
956  for (unsigned int i = 0; i < concurrent_runs_; ++i)
958 
959  // assign a pseudo module id to the FastTimerService
961 }
962 
963 void
966 }
967 
968 void
970  callgraph_.preBeginJob(pathsAndConsumes, context);
971 }
972 
973 void
975  unsigned int modules = callgraph_.size();
976 
977  // module highlights
978  for (unsigned int group: boost::irange(0ul, highlight_module_psets_.size())) {
979  // copy and sort for faster search via std::binary_search
980  auto labels = highlight_module_psets_[group].getUntrackedParameter<std::vector<std::string>>("modules");
981  std::sort(labels.begin(), labels.end());
982 
983  highlight_modules_[group].label = highlight_module_psets_[group].getUntrackedParameter<std::string>("label");
984  highlight_modules_[group].modules.reserve(labels.size());
985  // convert the module labels in module ids
986  for (unsigned int i = 0; i < modules; ++i) {
987  auto const & label = callgraph_.module(i).moduleLabel();
988  if (std::binary_search(labels.begin(), labels.end(), label))
989  highlight_modules_[group].modules.push_back(i);
990  }
991  }
992  highlight_module_psets_.clear();
993 
994  // allocate the resource counters for each stream, process, path and module
996  streams_.resize(concurrent_streams_, temp);
997  run_summary_.resize(concurrent_runs_, temp);
998  job_summary_ = temp;
999 
1000  // check that the DQMStore service is available
1001  if (enable_dqm_ and not edm::Service<DQMStore>().isAvailable()) {
1002  // the DQMStore is not available, disable all DQM plots
1003  enable_dqm_ = false;
1004  // FIXME issue a LogWarning ?
1005  }
1006 
1007  // allocate the structures to hold pointers to the DQM plots
1008  if (enable_dqm_)
1010 
1011 }
1012 
1013 void
1015 {
1016  ignoredSignal(__func__);
1017 }
1018 
1019 void
1021 {
1022  ignoredSignal(__func__);
1023 }
1024 
1025 void
1027 {
1028  ignoredSignal(__func__);
1029 
1030  unsigned int sid = sc.streamID().value();
1031 
1032  // merge plots only after the last subprocess has run
1034  if (enable_dqm_ and last) {
1035  DQMStore & store = * edm::Service<DQMStore>();
1037  }
1038 }
1039 
1040 void
1042 {
1043  ignoredSignal(__func__);
1044 }
1045 
1046 void
1048 {
1049  ignoredSignal(__func__);
1050 }
1051 
1052 void
1054 {
1055  ignoredSignal(__func__);
1056 }
1057 
1058 void
1060 {
1061  ignoredSignal(__func__);
1062 }
1063 
1064 void
1066 {
1067  ignoredSignal(__func__);
1068 
1069  // reset counters only during the main process transition
1070  if (isFirstSubprocess(sc)) {
1071  unsigned int sid = sc.streamID().value();
1073  }
1074 }
1075 
1076 void
1078 {
1079  ignoredSignal(__func__);
1080 }
1081 
1082 void
1084 {
1085  ignoredSignal(__func__);
1086 }
1087 
1088 void
1090  ignoredSignal(__func__);
1091 
1092  unsigned int sid = sc.streamID().value();
1093 
1094  // merge plots only after the last subprocess has run
1096  if (enable_dqm_ and last) {
1097  DQMStore & store = * edm::Service<DQMStore>();
1099  }
1100 }
1101 
1102 void
1104 {
1105  ignoredSignal(__func__);
1106 }
1107 
1108 void
1110 {
1111  ignoredSignal(__func__);
1112 
1113  // handle the summaries only after the last subprocess has run
1115  if (print_run_summary_ and last) {
1116  edm::LogVerbatim out("FastReport");
1117  printSummary(out, run_summary_[gc.runIndex()], "Run");
1118  }
1119 }
1120 
1121 void
1123 {
1124  ignoredSignal(__func__);
1125 }
1126 
1127 void
1129 {
1130  ignoredSignal(__func__);
1131 }
1132 
1133 void
1135 {
1136  ignoredSignal(__func__);
1137 }
1138 
1139 void
1141 {
1142  ignoredSignal(__func__);
1143 }
1144 
1145 void
1147 {
1148  if (print_job_summary_) {
1149  edm::LogVerbatim out("FastReport");
1150  printSummary(out, job_summary_, "Job");
1151  }
1152 }
1153 
1154 
1155 
1156 template <typename T>
1158 {
1159  out << "FastReport --------------------------- Event Summary ---------------------------\n";
1160  out << "FastReport CPU time Real time Modules\n";
1161  auto const& source_d = callgraph_.source();
1162  auto const& source = data.modules[source_d.id()];
1163  out << boost::format("FastReport %10.3f ms %10.3f ms %s\n") % ms(source.total.time_thread) % ms(source.total.time_real) % source_d.moduleLabel();
1164  for (unsigned int i = 0; i < callgraph_.processes().size(); ++i) {
1165  auto const& proc_d = callgraph_.processDescription(i);
1166  auto const& proc = data.processes[i];
1167  out << boost::format("FastReport %10.3f ms %10.3f ms process %s\n") % ms(proc.total.time_thread) % ms(proc.total.time_real) % proc_d.name_;
1168  for (unsigned int m: proc_d.modules_) {
1169  auto const& module_d = callgraph_.module(m);
1170  auto const& module = data.modules[m];
1171  out << boost::format("FastReport %10.3f ms %10.3f ms %s\n") % ms(module.total.time_thread) % ms(module.total.time_real) % module_d.moduleLabel();
1172  }
1173  }
1174  out << boost::format("FastReport %10.3f ms %10.3f ms total\n") % ms(data.total.time_thread) % ms(data.total.time_real);
1175  out << '\n';
1176  out << "FastReport CPU time Real time Processes and Paths\n";
1177  out << boost::format("FastReport %10.3f ms %10.3f ms %s\n") % ms(source.total.time_thread) % ms(source.total.time_real) % source_d.moduleLabel();
1178  for (unsigned int i = 0; i < callgraph_.processes().size(); ++i) {
1179  auto const& proc_d = callgraph_.processDescription(i);
1180  auto const& proc = data.processes[i];
1181  out << boost::format("FastReport %10.3f ms %10.3f ms process %s\n") % ms(proc.total.time_thread) % ms(proc.total.time_real) % proc_d.name_;
1182  for (unsigned int p = 0; p < proc.paths.size(); ++p) {
1183  auto const& name = proc_d.paths_[p].name_;
1184  auto const& path = proc.paths[p];
1185  out << boost::format("FastReport %10.3f ms %10.3f ms %s (only scheduled modules)\n") % ms(path.active.time_thread) % ms(path.active.time_real) % name;
1186  out << boost::format("FastReport %10.3f ms %10.3f ms %s (including dependencies)\n") % ms(path.total.time_thread) % ms(path.total.time_real) % name;
1187  }
1188  for (unsigned int p = 0; p < proc.endpaths.size(); ++p) {
1189  auto const& name = proc_d.endPaths_[p].name_;
1190  auto const& path = proc.endpaths[p];
1191  out << boost::format("FastReport %10.3f ms %10.3f ms %s (only scheduled modules)\n") % ms(path.active.time_thread) % ms(path.active.time_real) % name;
1192  out << boost::format("FastReport %10.3f ms %10.3f ms %s (including dependencies)\n") % ms(path.total.time_thread) % ms(path.total.time_real) % name;
1193  }
1194  }
1195  out << boost::format("FastReport %10.3f ms %10.3f ms total\n") % ms(data.total.time_thread) % ms(data.total.time_real);
1196  out << '\n';
1197  for (unsigned int group: boost::irange(0ul, highlight_modules_.size())) {
1198  out << "FastReport CPU time Real time Highlighted modules\n";
1199  for (unsigned int m: highlight_modules_[group].modules) {
1200  auto const& module_d = callgraph_.module(m);
1201  auto const& module = data.modules[m];
1202  out << boost::format("FastReport %10.3f ms %10.3f ms %s\n") % ms(module.total.time_thread) % ms(module.total.time_real) % module_d.moduleLabel();
1203  }
1204  out << boost::format("FastReport %10.3f ms %10.3f ms %s\n") % ms(data.highlight[group].time_thread) % ms(data.highlight[group].time_real) % highlight_modules_[group].label;
1205  out << '\n';
1206  }
1207 }
1208 
1209 template <typename T>
1211 {
1212  out << "FastReport ";
1213  if (label.size() < 60)
1214  for (unsigned int i = (60-label.size()) / 2; i > 0; --i)
1215  out << '-';
1216  out << ' ' << label << " Summary ";
1217  if (label.size() < 60)
1218  for (unsigned int i = (59-label.size()) / 2; i > 0; --i)
1219  out << '-';
1220  out << '\n';
1221  out << "FastReport CPU time avg. when run Real time avg. when run Modules\n";
1222  auto const& source_d = callgraph_.source();
1223  auto const& source = data.modules[source_d.id()];
1224  out << boost::format("FastReport %10.3f ms %10.3f ms %10.3f ms %10.3f ms %s\n")
1225  % (ms(source.total.time_thread) / data.events) % (ms(source.total.time_thread) / source.events)
1226  % (ms(source.total.time_real) / data.events) % (ms(source.total.time_real) / source.events)
1227  % source_d.moduleLabel();
1228  for (unsigned int i = 0; i < callgraph_.processes().size(); ++i) {
1229  auto const& proc_d = callgraph_.processDescription(i);
1230  auto const& proc = data.processes[i];
1231  out << boost::format("FastReport %10.3f ms %10.3f ms process %s\n")
1232  % (ms(proc.total.time_thread) / data.events)
1233  % (ms(proc.total.time_real) / data.events)
1234  % proc_d.name_;
1235  for (unsigned int m: proc_d.modules_) {
1236  auto const& module_d = callgraph_.module(m);
1237  auto const& module = data.modules[m];
1238  out << boost::format("FastReport %10.3f ms %10.3f ms %10.3f ms %10.3f ms %s\n")
1239  % (ms(module.total.time_thread) / data.events) % (ms(module.total.time_thread) / module.events)
1240  % (ms(module.total.time_real) / data.events) % (ms(module.total.time_real) / module.events)
1241  % module_d.moduleLabel();
1242  }
1243  }
1244  out << boost::format("FastReport %10.3f ms %10.3f ms total\n")
1245  % (ms(data.total.time_thread) / data.events)
1246  % (ms(data.total.time_real) / data.events);
1247  out << '\n';
1248  out << "FastReport CPU time Real time Processes and Paths\n";
1249  out << boost::format("FastReport %10.3f ms %10.3f ms %s\n")
1250  % (ms(source.total.time_thread) / data.events)
1251  % (ms(source.total.time_real) / data.events)
1252  % source_d.moduleLabel();
1253  for (unsigned int i = 0; i < callgraph_.processes().size(); ++i) {
1254  auto const& proc_d = callgraph_.processDescription(i);
1255  auto const& proc = data.processes[i];
1256  out << boost::format("FastReport %10.3f ms %10.3f ms process %s\n")
1257  % (ms(proc.total.time_thread) / data.events)
1258  % (ms(proc.total.time_real) / data.events)
1259  % proc_d.name_;
1260  for (unsigned int p = 0; p < proc.paths.size(); ++p) {
1261  auto const& name = proc_d.paths_[p].name_;
1262  auto const& path = proc.paths[p];
1263  out << boost::format("FastReport %10.3f ms %10.3f ms %s (only scheduled modules)\n")
1264  % (ms(path.active.time_thread) / data.events)
1265  % (ms(path.active.time_real) / data.events)
1266  % name;
1267  out << boost::format("FastReport %10.3f ms %10.3f ms %s (including dependencies)\n")
1268  % (ms(path.total.time_thread) / data.events)
1269  % (ms(path.total.time_real) / data.events)
1270  % name;
1271  }
1272  for (unsigned int p = 0; p < proc.endpaths.size(); ++p) {
1273  auto const& name = proc_d.endPaths_[p].name_;
1274  auto const& path = proc.endpaths[p];
1275  out << boost::format("FastReport %10.3f ms %10.3f ms %s (only scheduled modules)\n")
1276  % (ms(path.active.time_thread) / data.events)
1277  % (ms(path.active.time_real) / data.events)
1278  % name;
1279  out << boost::format("FastReport %10.3f ms %10.3f ms %s (including dependencies)\n")
1280  % (ms(path.total.time_thread) / data.events)
1281  % (ms(path.total.time_real) / data.events)
1282  % name;
1283  }
1284  }
1285  out << boost::format("FastReport %10.3f ms %10.3f ms total\n")
1286  % (ms(data.total.time_thread) / data.events)
1287  % (ms(data.total.time_real) / data.events);
1288  out << '\n';
1289  for (unsigned int group: boost::irange(0ul, highlight_modules_.size())) {
1290  out << "FastReport CPU time avg. when run Real time avg. when run Highlighted modules\n";
1291  for (unsigned int m: highlight_modules_[group].modules) {
1292  auto const& module_d = callgraph_.module(m);
1293  auto const& module = data.modules[m];
1294  out << boost::format("FastReport %10.3f ms %10.3f ms %10.3f ms %10.3f ms %s\n")
1295  % (ms(module.total.time_thread) / data.events) % (ms(module.total.time_thread) / module.events)
1296  % (ms(module.total.time_real) / data.events) % (ms(module.total.time_real) / module.events)
1297  % module_d.moduleLabel();
1298  }
1299  out << boost::format("FastReport %10.3f ms %10.3f ms %s\n")
1300  % (ms(data.highlight[group].time_thread) / data.events)
1301  % (ms(data.highlight[group].time_real) / data.events)
1302  % highlight_modules_[group].label;
1303  out << '\n';
1304  }
1305 }
1306 
1307 // check if this is the first process being signalled
1308 bool
1310 {
1311  return (not sc.processContext()->isSubProcess());
1312 }
1313 
1314 bool
1316 {
1317  return (not gc.processContext()->isSubProcess());
1318 }
1319 
1320 // check if this is the last process being signalled
1321 bool
1322 FastTimerService::isLastSubprocess(std::atomic<unsigned int>& check)
1323 {
1324  // release-acquire semantic guarantees that all writes in this and other threads are visible
1325  // after this operation; full sequentially-consistent ordering is (probably) not needed.
1326  unsigned int old_value = check.fetch_add(1, std::memory_order_acq_rel);
1327  return (old_value == callgraph_.processes().size() - 1);
1328 }
1329 
1330 void
1332 {
1333  ignoredSignal(__func__);
1334 }
1335 
1336 void
1338 {
1339  ignoredSignal(__func__);
1340 
1341  unsigned int pid = callgraph_.processId(* sc.processContext());
1342  unsigned int sid = sc.streamID();
1343  auto & stream = streams_[sid];
1344  auto & process = callgraph_.processDescription(pid);
1345 
1346  // compute the event timing as the sum of all modules' timing
1347  auto & data = stream.processes[pid].total;
1348  for (unsigned int i: process.modules_)
1349  data += stream.modules[i].total;
1350  stream.total += data;
1351 
1352  // handle the summaries and fill the plots only after the last subprocess has run
1354  if (not last)
1355  return;
1356 
1357  // highlighted modules
1358  for (unsigned int group: boost::irange(0ul, highlight_modules_.size()))
1359  for (unsigned int i: highlight_modules_[group].modules)
1360  stream.highlight[group] += stream.modules[i].total;
1361 
1362  // avoid concurrent access to the summary objects
1363  {
1364  std::lock_guard<std::mutex> guard(summary_mutex_);
1365  job_summary_ += stream;
1366  run_summary_[sc.runIndex()] += stream;
1367  }
1368 
1369  if (print_event_summary_) {
1370  edm::LogVerbatim out("FastReport");
1371  printEvent(out, stream);
1372  }
1373 
1374  if (enable_dqm_)
1375  stream_plots_[sid].fill(callgraph_, stream, sc.eventID().luminosityBlock());
1376 }
1377 
1378 void
1380 {
1381  // clear the event counters
1382  auto & stream = streams_[sid];
1383  stream.reset();
1384  ++stream.events;
1385 
1386  subprocess_event_check_[sid] = 0;
1387 
1388  thread().measure();
1389 }
1390 
1391 
1392 void
1394 {
1396  unsigned int id = md.id();
1397  auto & stream = streams_[sid];
1398 
1399  thread().measure_and_store(stream.modules[id].total);
1400  ++stream.modules[id].events;
1401 }
1402 
1403 
1404 void
1406 {
1407  unsigned int sid = sc.streamID().value();
1408  unsigned int pid = callgraph_.processId(* sc.processContext());
1409  unsigned int id = pc.pathID();
1410  auto & stream = streams_[sid];
1411  auto & data = pc.isEndPath() ? stream.processes[pid].endpaths[id] : stream.processes[pid].paths[id];
1412  data.status = false;
1413  data.last = 0;
1414 }
1415 
1416 
1417 void
1419 {
1420  unsigned int sid = sc.streamID().value();
1421  unsigned int pid = callgraph_.processId(* sc.processContext());
1422  unsigned int id = pc.pathID();
1423  auto & stream = streams_[sid];
1424  auto & data = pc.isEndPath() ? stream.processes[pid].endpaths[id] : stream.processes[pid].paths[id];
1425 
1427  unsigned int index = path.modules_on_path_.empty() ? 0 : status.index() + 1;
1428  data.last = path.modules_on_path_.empty() ? 0 : path.last_dependency_of_module_[status.index()];
1429 
1430  for (unsigned int i = 0; i < index; ++i) {
1431  auto const& module = stream.modules[path.modules_on_path_[i]];
1432  data.active += module.total;
1433  }
1434  for (unsigned int i = 0; i < data.last; ++i) {
1435  auto const& module = stream.modules[path.modules_and_dependencies_[i]];
1436  data.total += module.total;
1437  }
1438 }
1439 
1440 void
1442 {
1443  thread().measure();
1444 }
1445 
1446 void
1448 {
1449  edm::ModuleDescription const& md = * mcc.moduleDescription();
1450  unsigned int id = md.id();
1451  unsigned int sid = sc.streamID().value();
1452  auto & stream = streams_[sid];
1453 
1454  thread().measure_and_store(stream.modules[id].total);
1455  ++stream.modules[id].events;
1456 }
1457 
1458 void
1460 {
1461  unsupportedSignal(__func__);
1462 }
1463 
1464 void
1466 {
1467  unsupportedSignal(__func__);
1468 }
1469 
1470 void
1472 {
1473  ignoredSignal(__func__);
1474 }
1475 
1476 void
1478 {
1479  ignoredSignal(__func__);
1480 }
1481 
1482 void
1484 {
1485  ignoredSignal(__func__);
1486 }
1487 
1488 void
1490 {
1491  ignoredSignal(__func__);
1492 }
1493 
1494 void
1496 {
1497  ignoredSignal(__func__);
1498 }
1499 
1500 void
1502 {
1503  ignoredSignal(__func__);
1504 }
1505 
1506 void
1508 {
1509  ignoredSignal(__func__);
1510 }
1511 
1512 void
1514 {
1515  ignoredSignal(__func__);
1516 }
1517 
1518 void
1520 {
1521  ignoredSignal(__func__);
1522 }
1523 
1524 void
1526 {
1527  ignoredSignal(__func__);
1528 }
1529 
1530 void
1532 {
1533  ignoredSignal(__func__);
1534 }
1535 
1536 void
1538 {
1539  ignoredSignal(__func__);
1540 }
1541 
1542 void
1544 {
1545  ignoredSignal(__func__);
1546 }
1547 
1548 void
1550 {
1551  ignoredSignal(__func__);
1552 }
1553 
1554 void
1556 {
1557  ignoredSignal(__func__);
1558 }
1559 
1560 void
1562 {
1563  ignoredSignal(__func__);
1564 }
1565 
1566 void
1568 {
1569  ignoredSignal(__func__);
1570 }
1571 
1572 void
1574 {
1575  ignoredSignal(__func__);
1576 }
1577 
1578 void
1580 {
1581  ignoredSignal(__func__);
1582 }
1583 
1584 void
1586 {
1587  ignoredSignal(__func__);
1588 }
1589 
1590 
1593 {
1594  return threads_.local();
1595 }
1596 
1597 
1598 // describe the module's configuration
1599 void
1601 {
1603  desc.addUntracked<bool>( "printEventSummary", false);
1604  desc.addUntracked<bool>( "printRunSummary", true);
1605  desc.addUntracked<bool>( "printJobSummary", true);
1606  desc.addUntracked<bool>( "enableDQM", true);
1607  desc.addUntracked<bool>( "enableDQMbyModule", false);
1608  desc.addUntracked<bool>( "enableDQMbyLumiSection", false);
1609  desc.addUntracked<bool>( "enableDQMbyProcesses", false);
1610  desc.addUntracked<double>( "dqmTimeRange", 1000. ); // ms
1611  desc.addUntracked<double>( "dqmTimeResolution", 5. ); // ms
1612  desc.addUntracked<double>( "dqmPathTimeRange", 100. ); // ms
1613  desc.addUntracked<double>( "dqmPathTimeResolution", 0.5); // ms
1614  desc.addUntracked<double>( "dqmModuleTimeRange", 40. ); // ms
1615  desc.addUntracked<double>( "dqmModuleTimeResolution", 0.2); // ms
1616  desc.addUntracked<unsigned>( "dqmLumiSectionsRange", 2500 ); // ~ 16 hours
1617  desc.addUntracked<std::string>( "dqmPath", "HLT/TimerService");
1618 
1619  edm::ParameterSetDescription highlightModulesDescription;
1620  highlightModulesDescription.addUntracked<std::vector<std::string>>("modules", {});
1621  highlightModulesDescription.addUntracked<std::string>("label", "producers");
1622  desc.addVPSetUntracked("highlightModules", highlightModulesDescription, {});
1623 
1624  // # OBSOLETE - these parameters are ignored, they are left only not to break old configurations
1625  // they will not be printed in the generated cfi.py file
1626  desc.addOptionalNode(edm::ParameterDescription<bool>("useRealTimeClock", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1627  desc.addOptionalNode(edm::ParameterDescription<bool>("enableTimingPaths", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1628  desc.addOptionalNode(edm::ParameterDescription<bool>("enableTimingModules", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1629  desc.addOptionalNode(edm::ParameterDescription<bool>("enableTimingExclusive", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1630  desc.addOptionalNode(edm::ParameterDescription<bool>("enableTimingSummary", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1631  desc.addOptionalNode(edm::ParameterDescription<bool>("skipFirstPath", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1632  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathActive", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1633  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathTotal", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1634  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathOverhead", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1635  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathDetails", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1636  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathCounters", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1637  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathExclusive", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1638  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyModuleType", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1639  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMSummary", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1640 
1641  descriptions.add("FastTimerService", desc);
1642 }
#define LogDebug(id)
RunNumber_t run() const
Definition: EventID.h:39
size
Write out results.
void preGlobalBeginRun(edm::GlobalContext const &)
void preModuleEventDelayedGet(edm::StreamContext const &, edm::ModuleCallingContext const &)
const bool print_run_summary_
unsigned int maxNumberOfThreads() const
Definition: SystemBounds.h:46
void fill(Resources const &, unsigned int lumisection)
void setComment(std::string const &value)
void postStreamBeginRun(edm::StreamContext const &)
double queryEventTime(edm::StreamID) const
void postGlobalEndLumi(edm::GlobalContext const &)
void postGlobalBeginLumi(edm::GlobalContext const &)
void postStreamEndLumi(edm::StreamContext const &)
std::vector< edm::ParameterSet > highlight_module_psets_
const double dqm_pathtime_resolution_
void postModuleGlobalEndLumi(edm::GlobalContext const &, edm::ModuleCallingContext const &)
void preEventReadFromSource(edm::StreamContext const &, edm::ModuleCallingContext const &)
void preGlobalEndRun(edm::GlobalContext const &)
void book(DQMStore::IBooker &, std::string const &name, std::string const &title, double range, double resolution, unsigned int lumisections, bool byls)
void preBeginJob(edm::PathsAndConsumesOfModulesBase const &, edm::ProcessContext const &)
const double dqm_moduletime_range_
void watchPrePathEvent(PrePathEvent::slot_type const &iSlot)
void watchPreallocate(Preallocate::slot_type const &iSlot)
const double dqm_moduletime_resolution_
unsigned int concurrent_threads_
std::vector< unsigned int > modules_and_dependencies_
void postEventReadFromSource(edm::StreamContext const &, edm::ModuleCallingContext const &)
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
Definition: CLHEP.h:16
double queryHighlightTime(edm::StreamID sid, std::string const &label) const
void watchPostEndJob(PostEndJob::slot_type const &iSlot)
void postModuleGlobalEndRun(edm::GlobalContext const &, edm::ModuleCallingContext const &)
void postModuleEvent(edm::StreamContext const &, edm::ModuleCallingContext const &)
std::vector< GroupOfModules > highlight_modules_
ResourcesPerJob job_summary_
MonitorElement * bookProfile(Args &&...args)
Definition: DQMStore.h:157
PlotsPerJob(ProcessCallGraph const &job, std::vector< GroupOfModules > const &groups)
void watchPreModuleEvent(PreModuleEvent::slot_type const &iSlot)
unsigned int processId(edm::ProcessContext const &) const
TrainProcessor *const proc
Definition: MVATrainer.cc:101
PlotsPerProcess(ProcessCallGraph::ProcessType const &)
const double dqm_eventtime_range_
void preGlobalEndLumi(edm::GlobalContext const &)
std::vector< ResourcesPerPath > endpaths
void watchPostEvent(PostEvent::slot_type const &iSlot)
const std::string & pwd(void)
Definition: DQMStore.cc:285
double queryModuleTime_(edm::StreamID, unsigned int id) const
bool isFirstSubprocess(edm::StreamContext const &)
void watchPreSourceConstruction(PreSourceConstruction::slot_type const &iSlot)
const bool enable_dqm_bynproc_
unsigned int concurrent_runs_
void watchPostStreamEndLumi(PostStreamEndLumi::slot_type const &iSlot)
boost::chrono::nanoseconds time_real
void watchPostPathEvent(PostPathEvent::slot_type const &iSlot)
void watchPostModuleEvent(PostModuleEvent::slot_type const &iSlot)
TH1D * getTH1D(void) const
std::unique_ptr< std::atomic< unsigned int >[]> subprocess_global_run_check_
void watchPostSourceEvent(PostSourceEvent::slot_type const &iSlot)
std::vector< ResourcesPerJob > streams_
RunIndex const & runIndex() const
Definition: StreamContext.h:60
Definition: config.py:1
void postPathEvent(edm::StreamContext const &, edm::PathContext const &, edm::HLTPathStatus const &)
std::vector< PlotsPerElement > highlight_
void preModuleGlobalBeginLumi(edm::GlobalContext const &, edm::ModuleCallingContext const &)
#define nullptr
ResourcesPerProcess & operator+=(ResourcesPerProcess const &other)
LuminosityBlockNumber_t luminosityBlock() const
Definition: EventID.h:40
const bool print_job_summary_
std::string const & moduleLabel() const
edm::ModuleDescription const & source() const
static unsigned int getUniqueID()
Returns a unique id each time called. Intended to be passed to ModuleDescription&#39;s constructor&#39;s modI...
Measurement & thread()
tbb::enumerable_thread_specific< Measurement, tbb::cache_aligned_allocator< Measurement >, tbb::ets_key_per_instance > threads_
void postStreamBeginLumi(edm::StreamContext const &)
void printSummary(T &out, ResourcesPerJob const &, std::string const &label) const
RunIndex const & runIndex() const
Definition: GlobalContext.h:53
unsigned int maxNumberOfStreams() const
Definition: SystemBounds.h:43
ResourcesPerProcess operator+(ResourcesPerProcess const &other) const
ResourcesPerJob operator+(ResourcesPerJob const &other) const
std::vector< ResourcesPerModule > modules
bool isEndPath() const
Definition: PathContext.h:42
void printEvent(T &out, ResourcesPerJob const &) const
void postModuleStreamEndLumi(edm::StreamContext const &, edm::ModuleCallingContext const &)
std::mutex summary_mutex_
ResourcesPerJob & operator+=(ResourcesPerJob const &other)
std::vector< PlotsPerJob > stream_plots_
void fill(ProcessCallGraph::ProcessType const &, ResourcesPerJob const &, ResourcesPerProcess const &, unsigned int ls)
double queryModuleTime(edm::StreamID, const edm::ModuleDescription &module) const
void prePathEvent(edm::StreamContext const &, edm::PathContext const &)
void book(DQMStore::IBooker &, ProcessCallGraph const &, ProcessCallGraph::PathType const &, double range, double resolution, unsigned int lumisections, bool byls)
unsigned int module_id_
std::vector< ResourcesPerJob > run_summary_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
FastTimerService(const edm::ParameterSet &, edm::ActivityRegistry &)
void preModuleStreamEndLumi(edm::StreamContext const &, edm::ModuleCallingContext const &)
void watchPreModuleEventDelayedGet(PreModuleEventDelayedGet::slot_type const &iSlot)
void postEvent(edm::StreamContext const &)
std::unique_ptr< std::atomic< unsigned int >[]> subprocess_lumisection_check_
void preBeginJob(edm::PathsAndConsumesOfModulesBase const &, edm::ProcessContext const &)
void postGlobalEndRun(edm::GlobalContext const &)
ModuleDescription const * moduleDescription() const
std::unique_ptr< std::atomic< unsigned int >[]> subprocess_event_check_
void fill_fraction(Resources const &, Resources const &, unsigned int lumisection)
std::vector< ProcessType > const & processes() const
MonitorElement * book1D(Args &&...args)
Definition: DQMStore.h:115
ResourcesPerModule operator+(ResourcesPerModule const &other) const
const double infinity
const unsigned int dqm_lumisections_range_
void postStreamEndRun(edm::StreamContext const &)
std::vector< PathType > paths_
void preModuleEvent(edm::StreamContext const &, edm::ModuleCallingContext const &)
ResourcesPerPath & operator+=(ResourcesPerPath const &other)
std::vector< PlotsPerElement > modules_
ProcessType const & processDescription(unsigned int) const
ParameterDescriptionNode * addOptionalNode(ParameterDescriptionNode const &node, bool writeToCfi)
void book(DQMStore::IBooker &, ProcessCallGraph const &, std::vector< GroupOfModules > const &, double event_range, double event_resolution, double path_range, double path_resolution, double module_range, double module_resolution, unsigned int lumisections, bool bymodule, bool byls)
std::string dqm_path_
void preSourceConstruction(edm::ModuleDescription const &)
unsigned int pathID() const
Definition: PathContext.h:39
format
Some error handling for the usage.
ProcessContext const * processContext() const
Definition: StreamContext.h:63
void watchPostStreamEndRun(PostStreamEndRun::slot_type const &iSlot)
void mergeAndResetMEsRunSummaryCache(uint32_t run, uint32_t streamId, uint32_t moduleId)
Definition: DQMStore.cc:360
Resources operator+(Resources const &other) const
std::vector< Resources > highlight
const bool enable_dqm_bymodule_
void book(DQMStore::IBooker &, ProcessCallGraph const &, ProcessCallGraph::ProcessType const &, double event_range, double event_resolution, double path_range, double path_resolution, unsigned int lumisections, bool byls)
bin
set the eta bin as selection string.
StreamID const & streamID() const
Definition: StreamContext.h:57
void watchPreGlobalBeginRun(PreGlobalBeginRun::slot_type const &iSlot)
const double dqm_eventtime_resolution_
std::vector< PlotsPerPath > endpaths_
const bool enable_dqm_byls_
def ls(path, rec=False)
Definition: eostools.py:348
std::vector< PlotsPerProcess > processes_
void postModuleEventDelayedGet(edm::StreamContext const &, edm::ModuleCallingContext const &)
const bool print_event_summary_
unsigned int value() const
Definition: StreamID.h:46
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:277
void watchPostModuleEventDelayedGet(PostModuleEventDelayedGet::slot_type const &iSlot)
void postModuleStreamBeginLumi(edm::StreamContext const &, edm::ModuleCallingContext const &)
double querySourceTime(edm::StreamID) const
void preModuleStreamEndRun(edm::StreamContext const &, edm::ModuleCallingContext const &)
void postModuleStreamEndRun(edm::StreamContext const &, edm::ModuleCallingContext const &)
part
Definition: HCALResponse.h:20
void postModuleStreamBeginRun(edm::StreamContext const &, edm::ModuleCallingContext const &)
TH1F * getTH1F(void) const
void watchPostGlobalEndRun(PostGlobalEndRun::slot_type const &iSlot)
void preSourceEvent(edm::StreamID)
boost::chrono::nanoseconds time_thread
void watchPreStreamBeginLumi(PreStreamBeginLumi::slot_type const &iSlot)
void add(std::string const &label, ParameterSetDescription const &psetDescription)
susybsm::MuonSegment ms
Definition: classes.h:31
void preEvent(edm::StreamContext const &)
void watchPreBeginJob(PreBeginJob::slot_type const &iSlot)
convenience function for attaching to signal
void postGlobalBeginRun(edm::GlobalContext const &)
ProcessContext const * processContext() const
Definition: GlobalContext.h:56
void preStreamBeginLumi(edm::StreamContext const &)
ResourcesPerProcess(ProcessCallGraph::ProcessType const &process)
void postSourceEvent(edm::StreamID)
void preModuleStreamBeginLumi(edm::StreamContext const &, edm::ModuleCallingContext const &)
void preStreamEndRun(edm::StreamContext const &)
HLT enums.
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
void preModuleStreamBeginRun(edm::StreamContext const &, edm::ModuleCallingContext const &)
void preStreamEndLumi(edm::StreamContext const &)
void watchPreStreamBeginRun(PreStreamBeginRun::slot_type const &iSlot)
void measure_and_store(Resources &store)
ResourcesPerModule & operator+=(ResourcesPerModule const &other)
std::vector< PathType > endPaths_
TProfile * getTProfile(void) const
void event_()
void unsupportedSignal(std::string signal) const
void postModuleEventPrefetching(edm::StreamContext const &, edm::ModuleCallingContext const &)
void preModuleGlobalEndLumi(edm::GlobalContext const &, edm::ModuleCallingContext const &)
unsigned int size() const
edm::ModuleDescription const & module(unsigned int module) const
void ignoredSignal(std::string signal) const
double queryPathTime(edm::StreamID, std::string const &path) const
void preGlobalBeginLumi(edm::GlobalContext const &)
unsigned int maxNumberOfConcurrentRuns() const
Definition: SystemBounds.h:44
Resources & operator+=(Resources const &other)
void preModuleEventPrefetching(edm::StreamContext const &, edm::ModuleCallingContext const &)
void preSourceConstruction(edm::ModuleDescription const &)
void preModuleGlobalEndRun(edm::GlobalContext const &, edm::ModuleCallingContext const &)
tbb::concurrent_unordered_set< std::string > unsupported_signals_
std::vector< PlotsPerPath > paths_
EventID const & eventID() const
Definition: StreamContext.h:59
void postModuleGlobalBeginRun(edm::GlobalContext const &, edm::ModuleCallingContext const &)
void watchPreSourceEvent(PreSourceEvent::slot_type const &iSlot)
std::vector< ResourcesPerProcess > processes
static Interceptor::Registry registry("Interceptor")
double queryModuleTimeByLabel(edm::StreamID, std::string const &module) const
boost::date_time::subsecond_duration< boost::posix_time::time_duration, 1000000000 > nanoseconds
def check(config)
Definition: trackerTree.py:14
ProcessCallGraph callgraph_
long double T
void mergeAndResetMEsLuminositySummaryCache(uint32_t run, uint32_t lumi, uint32_t streamId, uint32_t moduleId)
Definition: DQMStore.cc:434
void postModuleGlobalBeginLumi(edm::GlobalContext const &, edm::ModuleCallingContext const &)
void preStreamBeginRun(edm::StreamContext const &)
std::vector< ResourcesPerPath > paths
MonitorElement * book1DD(Args &&...args)
Definition: DQMStore.h:127
bool isSubProcess() const
ResourcesPerPath operator+(ResourcesPerPath const &other) const
Definition: vlib.h:208
void preModuleGlobalBeginRun(edm::GlobalContext const &, edm::ModuleCallingContext const &)
ParameterDescriptionBase * addVPSetUntracked(U const &iLabel, ParameterSetDescription const &validator, std::vector< ParameterSet > const &defaults)
static std::string const source
Definition: EdmProvDump.cc:43
std::unique_ptr< std::atomic< unsigned int >[]> subprocess_run_check_
std::vector< unsigned int > modules_
unsigned int concurrent_streams_
bool isLastSubprocess(std::atomic< unsigned int > &check)
void preallocate(edm::service::SystemBounds const &)
void fill(ProcessCallGraph const &, ResourcesPerJob const &, unsigned int ls)
const double dqm_pathtime_range_
unsigned int id() const
void watchPostBeginJob(PostBeginJob::slot_type const &iSlot)
convenience function for attaching to signal
void fill(ProcessCallGraph::PathType const &, ResourcesPerJob const &, ResourcesPerPath const &, unsigned int lumisection)
unsigned int index() const
Definition: HLTPathStatus.h:55