CMS 3D CMS Logo

FastTimerService.cc
Go to the documentation of this file.
1 // C++ headers
2 #include <cmath>
3 #include <limits>
4 #include <iostream>
5 #include <iomanip>
6 #include <mutex>
7 #include <string>
8 #include <sstream>
9 #include <unordered_set>
10 #include <unordered_map>
11 
12 // boost headers
13 #include <boost/format.hpp>
14 #include <boost/range/irange.hpp>
15 
16 // CMSSW headers
33 
34 // local headers
35 #include "memory_usage.h"
36 #include "processor_model.h"
37 
38 using namespace std::literals;
39 
41 
42 namespace {
43 
44  // convert any std::chrono::duration to milliseconds
45  template <class Rep, class Period>
46  double ms(std::chrono::duration<Rep, Period> duration)
47  {
48  return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(duration).count();;
49  }
50 
51  // convert any boost::chrono::duration to milliseconds
52  template <class Rep, class Period>
53  double ms(boost::chrono::duration<Rep, Period> duration)
54  {
55  return boost::chrono::duration_cast<boost::chrono::duration<double, boost::milli>>(duration).count();;
56  }
57 
58  // convert from bytes to kilobytes, rounding down
59  uint64_t kB(uint64_t bytes)
60  {
61  return bytes / 1024;
62  }
63 } // namespace
64 
66 
67 // resources being monitored by the service
68 
69 // Resources
70 
72  time_thread(boost::chrono::nanoseconds::zero()),
73  time_real(boost::chrono::nanoseconds::zero()),
74  allocated(0ul),
75  deallocated(0ul)
76 { }
77 
78 void
80  time_thread = boost::chrono::nanoseconds::zero();
81  time_real = boost::chrono::nanoseconds::zero();
82  allocated = 0ul;
83  deallocated = 0ul;
84 }
85 
88  time_thread += other.time_thread;
89  time_real += other.time_real;
90  allocated += other.allocated;
91  deallocated += other.deallocated;
92  return *this;
93 }
94 
97  Resources result(*this);
98  result += other;
99  return result;
100 }
101 
102 // AtomicResources
103 // operation on the whole object are not atomic, as the operations
104 // on the individual fields could be interleaved; however, accumulation
105 // of results should yield the correct result.
106 
108  time_thread(0ul),
109  time_real(0ul),
110  allocated(0ul),
111  deallocated(0ul)
112 { }
113 
115  time_thread(other.time_thread.load()),
116  time_real(other.time_real.load()),
117  allocated(other.allocated.load()),
118  deallocated(other.deallocated.load())
119 { }
120 
121 void
123  time_thread = 0ul;
124  time_real = 0ul;
125  allocated = 0ul;
126  deallocated = 0ul;
127 }
128 
131  time_thread = other.time_thread.load();
132  time_real = other.time_real.load();
133  allocated = other.allocated.load();
134  deallocated = other.deallocated.load();
135  return *this;
136 }
137 
140  time_thread += other.time_thread.load();
141  time_real += other.time_real.load();
142  allocated += other.allocated.load();
143  deallocated += other.deallocated.load();
144  return *this;
145 }
146 
149  AtomicResources result(*this);
150  result += other;
151  return result;
152 }
153 
154 // ResourcesPerModule
155 
156 void
158  total.reset();
159  events = 0;
160 }
161 
164  total += other.total;
165  events += other.events;
166  return *this;
167 }
168 
171  ResourcesPerModule result(*this);
172  result += other;
173  return result;
174 }
175 
176 
177 // ResourcesPerPath
178 
179 void
181  active.reset();
182  total.reset();
183  last = 0;
184  status = false;
185 }
186 
189  active += other.active;
190  total += other.total;
191  last = 0; // summing these makes no sense, reset them instead
192  status = false;
193  return *this;
194 }
195 
198  ResourcesPerPath result(*this);
199  result += other;
200  return result;
201 }
202 
203 
204 // ResourcesPerProcess
205 
207  total(),
208  paths(process.paths_.size()),
209  endpaths(process.endPaths_.size())
210 {
211 }
212 
213 void
215  total.reset();
216  for (auto & path: paths)
217  path.reset();
218  for (auto & path: endpaths)
219  path.reset();
220 }
221 
224  total += other.total;
225  assert(paths.size() == other.paths.size());
226  for (unsigned int i: boost::irange(0ul, paths.size()))
227  paths[i] += other.paths[i];
228  assert(endpaths.size() == other.endpaths.size());
229  for (unsigned int i: boost::irange(0ul, endpaths.size()))
230  endpaths[i] += other.endpaths[i];
231  return *this;
232 }
233 
237  result += other;
238  return result;
239 }
240 
241 
242 // ResourcesPerJob
243 
244 FastTimerService::ResourcesPerJob::ResourcesPerJob(ProcessCallGraph const& job, std::vector<GroupOfModules> const& groups) :
245  total(),
246  overhead(),
247  event(),
248  highlight(groups.size()),
249  modules(job.size()),
250  processes(),
251  events(0)
252 {
253  processes.reserve(job.processes().size());
254  for (auto const& process: job.processes())
255  processes.emplace_back(process);
256 }
257 
258 void
260  total.reset();
261  overhead.reset();
262  event.reset();
263  for (auto & module: highlight)
264  module.reset();
265  for (auto & module: modules)
266  module.reset();
267  for (auto & process: processes)
268  process.reset();
269  events = 0;
270 }
271 
274  total += other.total;
275  overhead += other.overhead;
276  event += other.event;
277  assert(highlight.size() == other.highlight.size());
278  for (unsigned int i: boost::irange(0ul, highlight.size()))
279  highlight[i] += other.highlight[i];
280  assert(modules.size() == other.modules.size());
281  for (unsigned int i: boost::irange(0ul, modules.size()))
282  modules[i] += other.modules[i];
283  assert(processes.size() == other.processes.size());
284  for (unsigned int i: boost::irange(0ul, processes.size()))
285  processes[i] += other.processes[i];
286  events += other.events;
287  return *this;
288 }
289 
292  ResourcesPerJob result(*this);
293  result += other;
294  return result;
295 }
296 
297 
298 // per-thread measurements
299 
300 // Measurement
301 
303  measure();
304 }
305 
306 void
308  #ifdef DEBUG_THREAD_CONCURRENCY
309  id = std::this_thread::get_id();
310  #endif // DEBUG_THREAD_CONCURRENCY
311  time_thread = boost::chrono::thread_clock::now();
313  allocated = memory_usage::allocated();
314  deallocated = memory_usage::deallocated();
315 }
316 
317 void
319  #ifdef DEBUG_THREAD_CONCURRENCY
320  assert(std::this_thread::get_id() == id);
321  #endif // DEBUG_THREAD_CONCURRENCY
322  auto new_time_thread = boost::chrono::thread_clock::now();
323  auto new_time_real = boost::chrono::high_resolution_clock::now();
324  auto new_allocated = memory_usage::allocated();
325  auto new_deallocated = memory_usage::deallocated();
326  store.time_thread = new_time_thread - time_thread;
327  store.time_real = new_time_real - time_real;
328  store.allocated = new_allocated - allocated;
329  store.deallocated = new_deallocated - deallocated;
330  time_thread = new_time_thread;
331  time_real = new_time_real;
332  allocated = new_allocated;
333  deallocated = new_deallocated;
334 }
335 
336 void
338  #ifdef DEBUG_THREAD_CONCURRENCY
339  assert(std::this_thread::get_id() == id);
340  #endif // DEBUG_THREAD_CONCURRENCY
341  auto new_time_thread = boost::chrono::thread_clock::now();
342  auto new_time_real = boost::chrono::high_resolution_clock::now();
343  auto new_allocated = memory_usage::allocated();
344  auto new_deallocated = memory_usage::deallocated();
345  store.time_thread += boost::chrono::duration_cast<boost::chrono::nanoseconds>(new_time_thread - time_thread).count();
346  store.time_real += boost::chrono::duration_cast<boost::chrono::nanoseconds>(new_time_real - time_real).count();
347  store.allocated += new_allocated - allocated;
348  store.deallocated += new_deallocated - deallocated;
349  time_thread = new_time_thread;
350  time_real = new_time_real;
351  allocated = new_allocated;
352  deallocated = new_deallocated;
353 }
354 
356 
358  = default;
359 
360 void
363  std::string const& name,
364  std::string const& title,
365  PlotRanges const& ranges,
366  unsigned int lumisections,
367  bool byls)
368 {
369  int time_bins = (int) std::ceil(ranges.time_range / ranges.time_resolution);
370  int mem_bins = (int) std::ceil(ranges.memory_range / ranges.memory_resolution);
371  std::string y_title_ms = (boost::format("events / %.1f ms") % ranges.time_resolution).str();
372  std::string y_title_kB = (boost::format("events / %.1f kB") % ranges.memory_resolution).str();
373 
374  time_thread_ = booker.book1D(
375  name + " time_thread",
376  title + " processing time (cpu)",
377  time_bins, 0., ranges.time_range);
378  time_thread_.setXTitle("processing time [ms]");
379  time_thread_.setYTitle(y_title_ms.c_str());
380 
381  time_real_ = booker.book1D(
382  name + " time_real",
383  title + " processing time (real)",
384  time_bins, 0., ranges.time_range);
385  time_real_.setXTitle("processing time [ms]");
386  time_real_.setYTitle(y_title_ms.c_str());
387 
389  {
390  allocated_ = booker.book1D(
391  name + " allocated",
392  title + " allocated memory",
393  mem_bins, 0., ranges.memory_range);
394  allocated_.setXTitle("memory [kB]");
395  allocated_.setYTitle(y_title_kB.c_str());
396 
397  deallocated_ = booker.book1D(
398  name + " deallocated",
399  title + " deallocated memory",
400  mem_bins, 0., ranges.memory_range);
401  deallocated_.setXTitle("memory [kB]");
402  deallocated_.setYTitle(y_title_kB.c_str());
403  }
404 
405  if (not byls)
406  return;
407 
408  time_thread_byls_ = booker.bookProfile(
409  name + " time_thread_byls",
410  title + " processing time (cpu) vs. lumisection",
411  lumisections, 0.5, lumisections + 0.5,
412  time_bins, 0., std::numeric_limits<double>::infinity(),
413  " ");
414  time_thread_byls_.setXTitle("lumisection");
415  time_thread_byls_.setYTitle("processing time [ms]");
416 
417  time_real_byls_ = booker.bookProfile(
418  name + " time_real_byls",
419  title + " processing time (real) vs. lumisection",
420  lumisections, 0.5, lumisections + 0.5,
421  time_bins, 0., std::numeric_limits<double>::infinity(),
422  " ");
423  time_real_byls_.setXTitle("lumisection");
424  time_real_byls_.setYTitle("processing time [ms]");
425 
427  {
428  allocated_byls_ = booker.bookProfile(
429  name + " allocated_byls",
430  title + " allocated memory vs. lumisection",
431  lumisections, 0.5, lumisections + 0.5,
433  " ");
434  allocated_byls_.setXTitle("lumisection");
435  allocated_byls_.setYTitle("memory [kB]");
436 
437  deallocated_byls_ = booker.bookProfile(
438  name + " deallocated_byls",
439  title + " deallocated memory vs. lumisection",
440  lumisections, 0.5, lumisections + 0.5,
442  " ");
443  deallocated_byls_.setXTitle("lumisection");
444  deallocated_byls_.setYTitle("memory [kB]");
445  }
446 }
447 
448 void
449 FastTimerService::PlotsPerElement::fill(Resources const& data, unsigned int lumisection)
450 {
451  // enable underflows and overflows in the computation of mean and rms
452  TH1::StatOverflows(true);
453 
454  if (time_thread_)
455  time_thread_.fill(ms(data.time_thread));
456 
457  if (time_thread_byls_)
458  time_thread_byls_.fill(lumisection, ms(data.time_thread));
459 
460  if (time_real_)
461  time_real_.fill(ms(data.time_real));
462 
463  if (time_real_byls_)
464  time_real_byls_.fill(lumisection, ms(data.time_real));
465 
466  if (allocated_)
467  allocated_.fill(kB(data.allocated));
468 
469  if (allocated_byls_)
470  allocated_byls_.fill(lumisection, kB(data.allocated));
471 
472  if (deallocated_)
473  deallocated_.fill(kB(data.deallocated));
474 
475  if (deallocated_byls_)
476  deallocated_byls_.fill(lumisection, kB(data.deallocated));
477 }
478 
479 void
481 {
482  // enable underflows and overflows in the computation of mean and rms
483  TH1::StatOverflows(true);
484 
485  if (time_thread_)
486  time_thread_.fill(ms(boost::chrono::nanoseconds(data.time_thread.load())));
487 
488  if (time_thread_byls_)
489  time_thread_byls_.fill(lumisection, ms(boost::chrono::nanoseconds(data.time_thread.load())));
490 
491  if (time_real_)
492  time_real_.fill(ms(boost::chrono::nanoseconds(data.time_real.load())));
493 
494  if (time_real_byls_)
495  time_real_byls_.fill(lumisection, ms(boost::chrono::nanoseconds(data.time_real.load())));
496 
497  if (allocated_)
498  allocated_.fill(kB(data.allocated));
499 
500  if (allocated_byls_)
501  allocated_byls_.fill(lumisection, kB(data.allocated));
502 
503  if (deallocated_)
504  deallocated_.fill(kB(data.deallocated));
505 
506  if (deallocated_byls_)
507  deallocated_byls_.fill(lumisection, kB(data.deallocated));
508 }
509 
510 void
512 {
513  // enable underflows and overflows in the computation of mean and rms
514  TH1::StatOverflows(true);
515 
516  float total;
517  float fraction;
518 
519  total = ms(data.time_thread);
520  fraction = (total > 0.) ? (ms(part.time_thread) / total) : 0.;
521  if (time_thread_)
522  time_thread_.fill(total, fraction);
523 
524  if (time_thread_byls_)
525  time_thread_byls_.fill(lumisection, total, fraction);
526 
527  total = ms(data.time_real);
528  fraction = (total > 0.) ? (ms(part.time_real) / total) : 0.;
529  if (time_real_)
530  time_real_.fill(total, fraction);
531 
532  if (time_real_byls_)
533  time_real_byls_.fill(lumisection, total, fraction);
534 
535  total = kB(data.allocated);
536  fraction = (total > 0.) ? (kB(part.allocated) / total) : 0.;
537  if (allocated_)
538  allocated_.fill(total, fraction);
539 
540  if (allocated_byls_)
541  allocated_byls_.fill(lumisection, total, fraction);
542 
543  total = kB(data.deallocated);
544  fraction = (total > 0.) ? (kB(part.deallocated) / total) : 0.;
545  if (deallocated_)
546  deallocated_.fill(total, fraction);
547 
548  if (deallocated_byls_)
549  deallocated_byls_.fill(lumisection, total, fraction);
550 }
551 
552 
554  = default;
555 
556 void
559  std::string const & prefixDir,
560  ProcessCallGraph const& job,
562  PlotRanges const& ranges,
563  unsigned int lumisections,
564  bool byls)
565 {
566  const std::string basedir = booker.pwd();
567  // booker.setCurrentFolder(basedir + "/path " + path.name_);
568  booker.setCurrentFolder(basedir + "/" + prefixDir + path.name_);
569 
570  total_.book(booker, "path", path.name_, ranges, lumisections, byls);
571 
572  unsigned int bins = path.modules_and_dependencies_.size();
573  module_counter_ = booker.book1DD(
574  "module_counter",
575  "module counter",
576  bins + 1, -0.5, bins + 0.5);
577  module_counter_.setYTitle("events");
578  module_time_thread_total_ = booker.book1DD(
579  "module_time_thread_total",
580  "total module time (cpu)",
581  bins, -0.5, bins - 0.5);
582  module_time_thread_total_.setYTitle("processing time [ms]");
583  module_time_real_total_ = booker.book1DD(
584  "module_time_real_total",
585  "total module time (real)",
586  bins, -0.5, bins - 0.5);
587  module_time_real_total_.setYTitle("processing time [ms]");
589  {
590  module_allocated_total_ = booker.book1DD(
591  "module_allocated_total",
592  "total allocated memory",
593  bins, -0.5, bins - 0.5);
594  module_allocated_total_.setYTitle("memory [kB]");
595  module_deallocated_total_ = booker.book1DD(
596  "module_deallocated_total",
597  "total deallocated memory",
598  bins, -0.5, bins - 0.5);
599  module_deallocated_total_.setYTitle("memory [kB]");
600  }
601  for (unsigned int bin: boost::irange(0u, bins)) {
602  auto const& module = job[path.modules_and_dependencies_[bin]];
603  std::string const& label = module.scheduled_ ? module.module_.moduleLabel() : module.module_.moduleLabel() + " (unscheduled)";
604  module_counter_ .setBinLabel(bin + 1, label.c_str());
605  module_time_thread_total_.setBinLabel(bin + 1, label.c_str());
606  module_time_real_total_ .setBinLabel(bin + 1, label.c_str());
608  {
609  module_allocated_total_ .setBinLabel(bin + 1, label.c_str());
610  module_deallocated_total_.setBinLabel(bin + 1, label.c_str());
611  }
612  }
613  module_counter_.setBinLabel(bins + 1, "");
614 
615  booker.setCurrentFolder(basedir);
616 }
617 
618 void
620 {
621  // fill the total path time
622  total_.fill(path.total, ls);
623 
624  // fill the modules that actually ran and the total time spent in each od them
625  for (unsigned int i = 0; i < path.last; ++i) {
626  auto const& module = data.modules[description.modules_and_dependencies_[i]];
627  if (module_counter_)
628  module_counter_.fill(i);
629 
630  if (module_time_thread_total_)
631  module_time_thread_total_.fill(i, ms(module.total.time_thread));
632 
633  if (module_time_real_total_)
634  module_time_real_total_.fill(i, ms(module.total.time_real));
635 
636  if (module_allocated_total_)
637  module_allocated_total_.fill(i, kB(module.total.allocated));
638 
639  if (module_deallocated_total_)
640  module_deallocated_total_.fill(i, kB(module.total.deallocated));
641  }
642  if (module_counter_ and path.status)
643  module_counter_.fill(path.last);
644 }
645 
646 
648  event_(),
649  paths_(process.paths_.size()),
650  endpaths_(process.endPaths_.size())
651 {
652 }
653 
654 void
657  ProcessCallGraph const& job,
659  PlotRanges const& event_ranges,
660  PlotRanges const& path_ranges,
661  unsigned int lumisections,
662  bool bypath,
663  bool byls)
664 {
665  const std::string basedir = booker.pwd();
666  event_.book(booker,
667  "process " + process.name_, "process " + process.name_,
668  event_ranges,
669  lumisections,
670  byls);
671  if (bypath) {
672  booker.setCurrentFolder(basedir + "/process " + process.name_ + " paths");
673  for (unsigned int id: boost::irange(0ul, paths_.size()))
674  {
675  paths_[id].book(booker,"path ",
676  job, process.paths_[id],
677  path_ranges,
678  lumisections,
679  byls);
680  }
681  for (unsigned int id: boost::irange(0ul, endpaths_.size()))
682  {
683  endpaths_[id].book(booker,"endpath ",
684  job, process.endPaths_[id],
685  path_ranges,
686  lumisections,
687  byls);
688  }
689  booker.setCurrentFolder(basedir);
690  }
691 }
692 
693 void
695 {
696  // fill process event plots
697  event_.fill(process.total, ls);
698 
699  // fill all paths plots
700  for (unsigned int id: boost::irange(0ul, paths_.size()))
701  paths_[id].fill(description.paths_[id], data, process.paths[id], ls);
702 
703  // fill all endpaths plots
704  for (unsigned int id: boost::irange(0ul, endpaths_.size()))
705  endpaths_[id].fill(description.endPaths_[id], data, process.endpaths[id], ls);
706 }
707 
708 FastTimerService::PlotsPerJob::PlotsPerJob(ProcessCallGraph const& job, std::vector<GroupOfModules> const& groups) :
709  event_(),
710  event_ex_(),
711  overhead_(),
712  highlight_(groups.size()),
713  modules_(job.size()),
714  processes_()
715 {
716  processes_.reserve(job.processes().size());
717  for (auto const& process: job.processes())
718  processes_.emplace_back(process);
719 }
720 
721 void
724  ProcessCallGraph const& job,
725  std::vector<GroupOfModules> const& groups,
726  PlotRanges const& event_ranges,
727  PlotRanges const& path_ranges,
728  PlotRanges const& module_ranges,
729  unsigned int lumisections,
730  bool bymodule,
731  bool bypath,
732  bool byls,
733  bool transitions)
734 {
735  const std::string basedir = booker.pwd();
736 
737  // event summary plots
738  event_.book(booker,
739  "event", "Event",
740  event_ranges,
741  lumisections,
742  byls);
743 
744  event_ex_.book(booker,
745  "explicit", "Event (explicit)",
746  event_ranges,
747  lumisections,
748  byls);
749 
750  overhead_.book(booker,
751  "overhead", "Overhead",
752  event_ranges,
753  lumisections,
754  byls);
755 
756  modules_[job.source().id()].book(booker,
757  "source", "Source",
758  module_ranges,
759  lumisections,
760  byls);
761 
762  if (transitions) {
763  lumi_.book(booker,
764  "lumi", "LumiSection transitions",
765  event_ranges,
766  lumisections,
767  byls);
768 
769  run_.book(booker,
770  "run", "Run transtions",
771  event_ranges,
772  lumisections,
773  false);
774  }
775 
776  // plot the time spent in few given groups of modules
777  for (unsigned int group: boost::irange(0ul, groups.size())) {
778  auto const & label = groups[group].label;
779  highlight_[group].book(booker,
780  "highlight " + label, "Highlight " + label,
781  event_ranges,
782  lumisections,
783  byls);
784  }
785 
786  // plots per subprocess (event, modules, paths and endpaths)
787  for (unsigned int pid: boost::irange(0ul, job.processes().size())) {
788  auto const& process = job.processDescription(pid);
789  processes_[pid].book(booker,
790  job, process,
791  event_ranges,
792  path_ranges,
793  lumisections,
794  bypath,
795  byls);
796 
797  if (bymodule) {
798  booker.setCurrentFolder(basedir + "/process " + process.name_ + " modules");
799  for (unsigned int id: process.modules_)
800  {
801  auto const& module_name = job.module(id).moduleLabel();
802  modules_[id].book(booker,
804  module_ranges,
805  lumisections,
806  byls);
807  }
808  booker.setCurrentFolder(basedir);
809  }
810  }
811 }
812 
813 void
815 {
816  // fill total event plots
817  event_.fill(data.total, ls);
818  event_ex_.fill(data.event, ls);
819  overhead_.fill(data.overhead, ls);
820 
821  // fill highltight plots
822  for (unsigned int group: boost::irange(0ul, highlight_.size()))
823  highlight_[group].fill_fraction(data.total, data.highlight[group], ls);
824 
825  // fill modules plots
826  for (unsigned int id: boost::irange(0ul, modules_.size()))
827  modules_[id].fill(data.modules[id].total, ls);
828 
829  for (unsigned int pid: boost::irange(0ul, processes_.size()))
830  processes_[pid].fill(job.processDescription(pid), data, data.processes[pid], ls);
831 }
832 
833 void
835 {
836  // fill run transition plots
837  run_.fill(data, 0);
838 }
839 
840 void
842 {
843  // fill lumisection transition plots
844  lumi_.fill(data, ls);
845 }
846 
848 
850  // configuration
851  callgraph_(),
852  // job configuration
853  concurrent_lumis_( 0 ),
854  concurrent_runs_( 0 ),
855  concurrent_streams_( 0 ),
856  concurrent_threads_( 0 ),
857  print_event_summary_( config.getUntrackedParameter<bool>( "printEventSummary" ) ),
858  print_run_summary_( config.getUntrackedParameter<bool>( "printRunSummary" ) ),
859  print_job_summary_( config.getUntrackedParameter<bool>( "printJobSummary" ) ),
860  // dqm configuration
861  enable_dqm_( config.getUntrackedParameter<bool>( "enableDQM" ) ),
862  enable_dqm_bymodule_( config.getUntrackedParameter<bool>( "enableDQMbyModule" ) ),
863  enable_dqm_bypath_( config.getUntrackedParameter<bool>( "enableDQMbyPath" ) ),
864  enable_dqm_byls_( config.getUntrackedParameter<bool>( "enableDQMbyLumiSection" ) ),
865  enable_dqm_bynproc_( config.getUntrackedParameter<bool>( "enableDQMbyProcesses" ) ),
866  enable_dqm_transitions_( config.getUntrackedParameter<bool>( "enableDQMTransitions" ) ),
867  dqm_event_ranges_( { config.getUntrackedParameter<double>( "dqmTimeRange" ), // ms
868  config.getUntrackedParameter<double>( "dqmTimeResolution" ), // ms
869  config.getUntrackedParameter<double>( "dqmMemoryRange" ), // kB
870  config.getUntrackedParameter<double>( "dqmMemoryResolution" ) } ), // kB
871  dqm_path_ranges_( { config.getUntrackedParameter<double>( "dqmPathTimeRange" ), // ms
872  config.getUntrackedParameter<double>( "dqmPathTimeResolution" ), // ms
873  config.getUntrackedParameter<double>( "dqmPathMemoryRange" ), // kB
874  config.getUntrackedParameter<double>( "dqmPathMemoryResolution" ) } ), // kB
875  dqm_module_ranges_( { config.getUntrackedParameter<double>( "dqmModuleTimeRange" ), // ms
876  config.getUntrackedParameter<double>( "dqmModuleTimeResolution" ), // ms
877  config.getUntrackedParameter<double>( "dqmModuleMemoryRange" ), // kB
878  config.getUntrackedParameter<double>( "dqmModuleMemoryResolution") } ), // kB
879  dqm_lumisections_range_( config.getUntrackedParameter<unsigned int>( "dqmLumiSectionsRange" ) ),
880  dqm_path_( config.getUntrackedParameter<std::string>("dqmPath" ) ),
881  // highlight configuration
882  highlight_module_psets_( config.getUntrackedParameter<std::vector<edm::ParameterSet>>("highlightModules") ),
883  highlight_modules_( highlight_module_psets_.size()) // filled in postBeginJob()
884 {
885  // start observing when a thread enters or leaves the TBB global thread arena
886  tbb::task_scheduler_observer::observe();
887 
888  // register EDM call backs
889  registry.watchPreallocate( this, & FastTimerService::preallocate );
890  registry.watchPreBeginJob( this, & FastTimerService::preBeginJob );
891  registry.watchPostBeginJob( this, & FastTimerService::postBeginJob );
892  registry.watchPostEndJob( this, & FastTimerService::postEndJob );
893  registry.watchPreGlobalBeginRun( this, & FastTimerService::preGlobalBeginRun );
894 //registry.watchPostGlobalBeginRun( this, & FastTimerService::postGlobalBeginRun );
895 //registry.watchPreGlobalEndRun( this, & FastTimerService::preGlobalEndRun );
896  registry.watchPostGlobalEndRun( this, & FastTimerService::postGlobalEndRun );
897  registry.watchPreStreamBeginRun( this, & FastTimerService::preStreamBeginRun );
898 //registry.watchPostStreamBeginRun( this, & FastTimerService::postStreamBeginRun );
899 //registry.watchPreStreamEndRun( this, & FastTimerService::preStreamEndRun );
900  registry.watchPostStreamEndRun( this, & FastTimerService::postStreamEndRun );
901  registry.watchPreGlobalBeginLumi( this, & FastTimerService::preGlobalBeginLumi );
902 //registry.watchPostGlobalBeginLumi( this, & FastTimerService::postGlobalBeginLumi );
903 //registry.watchPreGlobalEndLumi( this, & FastTimerService::preGlobalEndLumi );
904  registry.watchPostGlobalEndLumi( this, & FastTimerService::postGlobalEndLumi );
905  registry.watchPreStreamBeginLumi( this, & FastTimerService::preStreamBeginLumi );
906 //registry.watchPostStreamBeginLumi( this, & FastTimerService::postStreamBeginLumi );
907 //registry.watchPreStreamEndLumi( this, & FastTimerService::preStreamEndLumi );
908  registry.watchPostStreamEndLumi( this, & FastTimerService::postStreamEndLumi );
909  registry.watchPreEvent( this, & FastTimerService::preEvent );
910  registry.watchPostEvent( this, & FastTimerService::postEvent );
911  registry.watchPrePathEvent( this, & FastTimerService::prePathEvent );
912  registry.watchPostPathEvent( this, & FastTimerService::postPathEvent );
913  registry.watchPreSourceConstruction( this, & FastTimerService::preSourceConstruction);
914 //registry.watchPostSourceConstruction( this, & FastTimerService::postSourceConstruction);
915  registry.watchPreSourceRun( this, & FastTimerService::preSourceRun );
916  registry.watchPostSourceRun( this, & FastTimerService::postSourceRun );
917  registry.watchPreSourceLumi( this, & FastTimerService::preSourceLumi );
918  registry.watchPostSourceLumi( this, & FastTimerService::postSourceLumi );
919  registry.watchPreSourceEvent( this, & FastTimerService::preSourceEvent );
920  registry.watchPostSourceEvent( this, & FastTimerService::postSourceEvent );
921 //registry.watchPreModuleConstruction( this, & FastTimerService::preModuleConstruction);
922 //registry.watchPostModuleConstruction( this, & FastTimerService::postModuleConstruction);
923 //registry.watchPreModuleBeginJob( this, & FastTimerService::preModuleBeginJob );
924 //registry.watchPostModuleBeginJob( this, & FastTimerService::postModuleBeginJob );
925 //registry.watchPreModuleEndJob( this, & FastTimerService::preModuleEndJob );
926 //registry.watchPostModuleEndJob( this, & FastTimerService::postModuleEndJob );
927 //registry.watchPreModuleBeginStream( this, & FastTimerService::preModuleBeginStream );
928 //registry.watchPostModuleBeginStream( this, & FastTimerService::postModuleBeginStream );
929 //registry.watchPreModuleEndStream( this, & FastTimerService::preModuleEndStream );
930 //registry.watchPostModuleEndStream( this, & FastTimerService::postModuleEndStream );
931  registry.watchPreModuleGlobalBeginRun( this, & FastTimerService::preModuleGlobalBeginRun );
932  registry.watchPostModuleGlobalBeginRun( this, & FastTimerService::postModuleGlobalBeginRun );
933  registry.watchPreModuleGlobalEndRun( this, & FastTimerService::preModuleGlobalEndRun );
934  registry.watchPostModuleGlobalEndRun( this, & FastTimerService::postModuleGlobalEndRun );
935  registry.watchPreModuleGlobalBeginLumi( this, & FastTimerService::preModuleGlobalBeginLumi );
936  registry.watchPostModuleGlobalBeginLumi( this, & FastTimerService::postModuleGlobalBeginLumi );
937  registry.watchPreModuleGlobalEndLumi( this, & FastTimerService::preModuleGlobalEndLumi );
938  registry.watchPostModuleGlobalEndLumi( this, & FastTimerService::postModuleGlobalEndLumi );
939  registry.watchPreModuleStreamBeginRun( this, & FastTimerService::preModuleStreamBeginRun );
940  registry.watchPostModuleStreamBeginRun( this, & FastTimerService::postModuleStreamBeginRun );
941  registry.watchPreModuleStreamEndRun( this, & FastTimerService::preModuleStreamEndRun );
942  registry.watchPostModuleStreamEndRun( this, & FastTimerService::postModuleStreamEndRun );
943  registry.watchPreModuleStreamBeginLumi( this, & FastTimerService::preModuleStreamBeginLumi );
944  registry.watchPostModuleStreamBeginLumi( this, & FastTimerService::postModuleStreamBeginLumi );
945  registry.watchPreModuleStreamEndLumi( this, & FastTimerService::preModuleStreamEndLumi );
946  registry.watchPostModuleStreamEndLumi( this, & FastTimerService::postModuleStreamEndLumi );
947 //registry.watchPreModuleEventPrefetching( this, & FastTimerService::preModuleEventPrefetching );
948 //registry.watchPostModuleEventPrefetching( this, & FastTimerService::postModuleEventPrefetching );
949  registry.watchPreModuleEvent( this, & FastTimerService::preModuleEvent );
950  registry.watchPostModuleEvent( this, & FastTimerService::postModuleEvent );
951  registry.watchPreModuleEventDelayedGet( this, & FastTimerService::preModuleEventDelayedGet );
952  registry.watchPostModuleEventDelayedGet( this, & FastTimerService::postModuleEventDelayedGet );
953 //registry.watchPreEventReadFromSource( this, & FastTimerService::preEventReadFromSource );
954 //registry.watchPostEventReadFromSource( this, & FastTimerService::postEventReadFromSource );
955 }
956 
958 
959 double
961 {
962  // private version, assume "id" is valid
963  auto const& stream = streams_[sid];
964  auto const& module = stream.modules[id];
965  return ms(module.total.time_real);
966 }
967 
968 double
970 {
971  return queryModuleTime_(sid, callgraph_.source().id());
972 }
973 
974 double
976 {
977  auto const& stream = streams_[sid];
978  return ms(stream.total.time_real);
979 }
980 
981 double
983 {
984  unsigned int pid = callgraph_.processId(process);
985  auto const& stream = streams_[sid];
986  return ms(stream.processes[pid].total.time_real);
987 }
988 
989 double
991 {
992  return queryModuleTime_(sid, md.id());
993 }
994 
995 double
996 FastTimerService::queryModuleTime(edm::StreamID sid, unsigned int id) const
997 {
998  if (id < callgraph_.size())
999  return queryModuleTime_(sid, id);
1000 
1001  // FIXME issue a LogWarning, raise an exception, or return NaN
1002  return 0.;
1003 }
1004 
1005 double
1007 {
1008  for (unsigned int id: boost::irange(0u, callgraph_.size()))
1009  if (callgraph_.module(id).moduleLabel() == label)
1010  return queryModuleTime_(sid, id);
1011 
1012  // FIXME issue a LogWarning, raise an exception, or return NaN
1013  return 0.;
1014 }
1015 
1016 double
1018 {
1019  for (unsigned int id: callgraph_.processDescription(process).modules_)
1020  if (callgraph_.module(id).moduleLabel() == label)
1021  return queryModuleTime_(sid, id);
1022 
1023  // FIXME issue a LogWarning, raise an exception, or return NaN
1024  return 0.;
1025 }
1026 
1027 double
1029 {
1030  auto const& stream = streams_[sid];
1031  for (unsigned int pid: boost::irange(0ul, callgraph_.processes().size()))
1032  {
1033  auto const& desc = callgraph_.processDescription(pid);
1034  for (unsigned int id: boost::irange(0ul, desc.paths_.size()))
1035  if (desc.paths_[id].name_ == path)
1036  return ms(stream.processes[pid].paths[id].total.time_real);
1037  for (unsigned int id: boost::irange(0ul, desc.endPaths_.size()))
1038  if (desc.paths_[id].name_ == path)
1039  return ms(stream.processes[pid].endpaths[id].total.time_real);
1040  }
1041 
1042  // FIXME issue a LogWarning, raise an exception, or return NaN
1043  return 0.;
1044 }
1045 
1046 double
1048 {
1049  auto const& stream = streams_[sid];
1050  unsigned int pid = callgraph_.processId(process);
1051  auto const& desc = callgraph_.processDescription(pid);
1052  for (unsigned int id: boost::irange(0ul, desc.paths_.size()))
1053  if (desc.paths_[id].name_ == path)
1054  return ms(stream.processes[pid].paths[id].total.time_real);
1055  for (unsigned int id: boost::irange(0ul, desc.endPaths_.size()))
1056  if (desc.paths_[id].name_ == path)
1057  return ms(stream.processes[pid].endpaths[id].total.time_real);
1058 
1059  // FIXME issue a LogWarning, raise an exception, or return NaN
1060  return 0.;
1061 }
1062 
1063 double
1065 {
1066  auto const& stream = streams_[sid];
1067  for (unsigned int group: boost::irange(0ul, highlight_modules_.size()))
1068  if (highlight_modules_[group].label == label)
1069  return ms(stream.highlight[group].time_real);
1070 
1071  // FIXME issue a LogWarning, raise an exception, or return NaN
1072  return 0.;
1073 }
1074 
1075 
1076 void
1078 {
1079  LogDebug("FastTimerService") << "The FastTimerService received is currently not monitoring the signal \"" << signal << "\".\n";
1080 }
1081 
1082 void
1084 {
1085  // warn about each signal only once per job
1086  if (unsupported_signals_.insert(signal).second)
1087  edm::LogWarning("FastTimerService") << "The FastTimerService received the unsupported signal \"" << signal << "\".\n"
1088  << "Please report how to reproduce the issue to cms-hlt@cern.ch .";
1089 }
1090 
1091 void
1093 {
1094  ignoredSignal(__func__);
1095 
1096  // reset the run counters only during the main process being run
1097  if (isFirstSubprocess(gc)) {
1098  auto index = gc.runIndex();
1100  run_transition_[index].reset();
1101  run_summary_[index].reset();
1102 
1103  // book the DQM plots
1104  if (enable_dqm_) {
1105  // define a callback to book the MonitorElements
1106  auto bookTransactionCallback = [&, this] (DQMStore::ConcurrentBooker & booker)
1107  {
1108  booker.setCurrentFolder(dqm_path_);
1109  plots_->book(booker, callgraph_,
1119  };
1120 
1121  // book MonitorElements for this stream
1122  edm::Service<DQMStore>()->bookConcurrentTransaction(bookTransactionCallback, gc.luminosityBlockID().run());
1123  }
1124  }
1125 }
1126 
1127 void
1129 {
1130  ignoredSignal(__func__);
1131 }
1132 
1133 void
1135 {
1136  ignoredSignal(__func__);
1137 }
1138 
1139 void
1141 {
1146 
1147  if (enable_dqm_bynproc_)
1148  dqm_path_ += (boost::format("/Running on %s with %d streams on %d threads") % processor_model % concurrent_streams_ % concurrent_threads_).str();
1149 
1150  // clean characters that are deemed unsafe for DQM
1151  // see the definition of `s_safe` in DQMServices/Core/src/DQMStore.cc
1152  auto safe_for_dqm = "/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+=_()# "s;
1153  for (auto & c: dqm_path_)
1154  if (safe_for_dqm.find(c) == std::string::npos)
1155  c = '_';
1156 
1157  // allocate atomic variables to keep track of the completion of each step, process by process
1158  subprocess_event_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_streams_);
1159  for (unsigned int i = 0; i < concurrent_streams_; ++i)
1161  subprocess_global_run_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_runs_);
1162  for (unsigned int i = 0; i < concurrent_runs_; ++i)
1164  subprocess_global_lumi_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_lumis_);
1165  for (unsigned int i = 0; i < concurrent_lumis_; ++i)
1167 
1168  // allocate buffers to keep track of the resources spent in the lumi and run transitions
1169  lumi_transition_.resize(concurrent_lumis_);
1170  run_transition_.resize(concurrent_runs_);
1171 }
1172 
1173 void
1176 }
1177 
1178 void
1180  callgraph_.preBeginJob(pathsAndConsumes, context);
1181 }
1182 
1183 void
1185  unsigned int modules = callgraph_.size();
1186 
1187  // module highlights
1188  for (unsigned int group: boost::irange(0ul, highlight_module_psets_.size())) {
1189  // copy and sort for faster search via std::binary_search
1190  auto labels = highlight_module_psets_[group].getUntrackedParameter<std::vector<std::string>>("modules");
1191  std::sort(labels.begin(), labels.end());
1192 
1193  highlight_modules_[group].label = highlight_module_psets_[group].getUntrackedParameter<std::string>("label");
1194  highlight_modules_[group].modules.reserve(labels.size());
1195  // convert the module labels in module ids
1196  for (unsigned int i = 0; i < modules; ++i) {
1197  auto const & label = callgraph_.module(i).moduleLabel();
1198  if (std::binary_search(labels.begin(), labels.end(), label))
1199  highlight_modules_[group].modules.push_back(i);
1200  }
1201  }
1202  highlight_module_psets_.clear();
1203 
1204  // allocate the resource counters for each stream, process, path and module
1206  streams_.resize(concurrent_streams_, temp);
1207  run_summary_.resize(concurrent_runs_, temp);
1208  job_summary_ = temp;
1209 
1210  // check that the DQMStore service is available
1211  if (enable_dqm_ and not edm::Service<DQMStore>().isAvailable()) {
1212  // the DQMStore is not available, disable all DQM plots
1213  enable_dqm_ = false;
1214  // FIXME issue a LogWarning ?
1215  }
1216 
1217  // allocate the structures to hold pointers to the DQM plots
1218  if (enable_dqm_) {
1219  plots_ = std::make_unique<PlotsPerJob>(callgraph_, highlight_modules_);
1220  }
1221 
1222 }
1223 
1224 void
1226 {
1227  ignoredSignal(__func__);
1228 }
1229 
1230 void
1232 {
1233  ignoredSignal(__func__);
1234 }
1235 
1236 void
1238 {
1239  ignoredSignal(__func__);
1240 }
1241 
1242 void
1244 {
1245  ignoredSignal(__func__);
1246 
1247  // reset the lumi counters only during the main process being run
1248  if (isFirstSubprocess(gc)) {
1249  auto index = gc.luminosityBlockIndex();
1251  lumi_transition_[index].reset();
1252  }
1253 }
1254 
1255 void
1257 {
1258  ignoredSignal(__func__);
1259 }
1260 
1261 void
1263 {
1264  ignoredSignal(__func__);
1265 }
1266 
1267 void
1269 {
1270  ignoredSignal(__func__);
1271 
1272  // handle the summaries only after the last subprocess has run
1273  auto index = gc.luminosityBlockIndex();
1275  if (not last)
1276  return;
1277 
1278  edm::LogVerbatim out("FastReport");
1279  auto const& label = (boost::format("run %d, lumisection %d") % gc.luminosityBlockID().run() % gc.luminosityBlockID().luminosityBlock()).str();
1280  printTransition(out, lumi_transition_[index], label);
1281 
1283  plots_->fill_lumi(lumi_transition_[index], gc.luminosityBlockID().luminosityBlock());
1284  }
1285 }
1286 
1287 void
1289 {
1290  ignoredSignal(__func__);
1291 }
1292 
1293 void
1295 {
1296  ignoredSignal(__func__);
1297 }
1298 
1299 void
1301 {
1302  ignoredSignal(__func__);
1303 }
1304 
1305 void
1307  ignoredSignal(__func__);
1308 }
1309 
1310 void
1312 {
1313  ignoredSignal(__func__);
1314 }
1315 
1316 void
1318 {
1319  ignoredSignal(__func__);
1320 
1321  // handle the summaries only after the last subprocess has run
1322  auto index = gc.runIndex();
1324  if (not last)
1325  return;
1326 
1327  edm::LogVerbatim out("FastReport");
1328  auto const& label = (boost::format("Run %d") % gc.luminosityBlockID().run()).str();
1329  if (print_run_summary_) {
1330  printSummary(out, run_summary_[index], label);
1331  }
1332  printTransition(out, run_transition_[index], label);
1333 
1335  plots_->fill_run(run_transition_[index]);
1336  }
1337 }
1338 
1339 void
1341 {
1343 }
1344 
1345 void
1347 {
1349 }
1350 
1351 void
1353 {
1355 }
1356 
1357 void
1359 {
1361 }
1362 
1363 void
1365 {
1366  if (print_job_summary_) {
1367  edm::LogVerbatim out("FastReport");
1368  printSummary(out, job_summary_, "Job");
1369  }
1370 }
1371 
1372 
1373 template <typename T>
1375 {
1376  out << "FastReport ";
1377  if (label.size() < 60)
1378  for (unsigned int i = (60-label.size()) / 2; i > 0; --i)
1379  out << '-';
1380  out << ' ' << label << " Summary ";
1381  if (label.size() < 60)
1382  for (unsigned int i = (59-label.size()) / 2; i > 0; --i)
1383  out << '-';
1384  out << '\n';
1385 }
1386 
1387 template <typename T>
1389 {
1390  out << "FastReport CPU time Real time Allocated Deallocated " << label << "\n";
1391  // FastReport ########.# ms ########.# ms +######### kB -######### kB ...
1392 }
1393 
1394 template <typename T>
1396 {
1397  out << boost::format("FastReport %10.1f ms %10.1f ms %+10d kB %+10d kB %s\n")
1398  % ms(data.time_thread)
1399  % ms(data.time_real)
1400  % +static_cast<int64_t>(kB(data.allocated))
1401  % -static_cast<int64_t>(kB(data.deallocated))
1402  % label;
1403 }
1404 
1405 template <typename T>
1407 {
1408  out << boost::format("FastReport %10.1f ms %10.1f ms %+10d kB %+10d kB %s\n")
1409  % ms(boost::chrono::nanoseconds(data.time_thread.load()))
1410  % ms(boost::chrono::nanoseconds(data.time_real.load()))
1411  % +static_cast<int64_t>(kB(data.allocated))
1412  % -static_cast<int64_t>(kB(data.deallocated))
1413  % label;
1414 }
1415 
1416 template <typename T>
1418 {
1419  printHeader(out, "Event");
1420  printEventHeader(out, "Modules");
1421  auto const& source_d = callgraph_.source();
1422  auto const& source = data.modules[source_d.id()];
1423  printEventLine(out, source.total, source_d.moduleLabel());
1424  for (unsigned int i = 0; i < callgraph_.processes().size(); ++i) {
1425  auto const& proc_d = callgraph_.processDescription(i);
1426  auto const& proc = data.processes[i];
1427  printEventLine(out, proc.total, "process " + proc_d.name_);
1428  for (unsigned int m: proc_d.modules_) {
1429  auto const& module_d = callgraph_.module(m);
1430  auto const& module = data.modules[m];
1431  printEventLine(out, module.total, " " + module_d.moduleLabel());
1432  }
1433  }
1434  printEventLine(out, data.total, "total");
1435  out << '\n';
1436  printEventHeader(out, "Processes and Paths");
1437  printEventLine(out, source.total, source_d.moduleLabel());
1438  for (unsigned int i = 0; i < callgraph_.processes().size(); ++i) {
1439  auto const& proc_d = callgraph_.processDescription(i);
1440  auto const& proc = data.processes[i];
1441  printEventLine(out, proc.total, "process " + proc_d.name_);
1442  for (unsigned int p = 0; p < proc.paths.size(); ++p) {
1443  auto const& name = proc_d.paths_[p].name_;
1444  auto const& path = proc.paths[p];
1445  printEventLine(out, path.active, name + " (only scheduled modules)");
1446  printEventLine(out, path.total, name + " (including dependencies)");
1447  }
1448  for (unsigned int p = 0; p < proc.endpaths.size(); ++p) {
1449  auto const& name = proc_d.endPaths_[p].name_;
1450  auto const& path = proc.endpaths[p];
1451  printEventLine(out, path.active, name + " (only scheduled modules)");
1452  printEventLine(out, path.total, name + " (including dependencies)");
1453  }
1454  }
1455  printEventLine(out, data.total, "total");
1456  out << '\n';
1457  for (unsigned int group: boost::irange(0ul, highlight_modules_.size())) {
1458  printEventHeader(out, "Highlighted modules");
1459  for (unsigned int m: highlight_modules_[group].modules) {
1460  auto const& module_d = callgraph_.module(m);
1461  auto const& module = data.modules[m];
1462  printEventLine(out, module.total, " " + module_d.moduleLabel());
1463  }
1465  out << '\n';
1466  }
1467 }
1468 
1469 template <typename T>
1470 void FastTimerService::printSummaryHeader(T& out, std::string const& label, bool detailed) const
1471 {
1472  if (detailed)
1473  out << "FastReport CPU time avg. when run Real time avg. when run Alloc. avg. when run Dealloc. avg. when run ";
1474  // FastReport ########.# ms ########.# ms ########.# ms ########.# ms +######### kB +######### kB -######### kB -######### kB ...
1475  else
1476  out << "FastReport CPU time avg. Real time avg. Alloc. avg. Dealloc. avg. ";
1477  // FastReport ########.# ms ########.# ms +######### kB -######### kB ...
1478  out << label << '\n';
1479 }
1480 
1481 template <typename T>
1483 {
1484  out << "FastReport CPU time sched. / depend. Real time sched. / depend. Alloc. sched. / depend. Dealloc. sched. / depend. ";
1485  // FastReport ########.# ms ########.# ms ########.# ms ########.# ms +######### kB +######### kB -######### kB -######### kB ...
1486  out << label << '\n';
1487 }
1488 
1489 template <typename T>
1491 {
1492  out << boost::format("FastReport %10.1f ms %10.1f ms %+10d kB %+10d kB %s\n")
1493  % (events ? ms(data.time_thread) / events : 0)
1494  % (events ? ms(data.time_real) / events : 0)
1495  % (events ? +static_cast<int64_t>(kB(data.allocated) / events) : 0)
1496  % (events ? -static_cast<int64_t>(kB(data.deallocated) / events) : 0)
1497  % label;
1498 }
1499 
1500 template <typename T>
1502 {
1503  out << boost::format("FastReport %10.1f ms %10.1f ms %10.1f ms %10.1f ms %+10d kB %+10d kB %+10d kB %+10d kB %s\n")
1504  % (events ? ms(data.time_thread) / events : 0) % (active ? ms(data.time_thread) / active : 0)
1505  % (events ? ms(data.time_real) / events : 0) % (active ? ms(data.time_real) / active : 0)
1506  % (events ? +static_cast<int64_t>(kB(data.allocated) / events) : 0) % (active ? +static_cast<int64_t>(kB(data.allocated) / active) : 0)
1507  % (events ? -static_cast<int64_t>(kB(data.deallocated) / events) : 0) % (active ? -static_cast<int64_t>(kB(data.deallocated) / active) : 0)
1508  % label;
1509 }
1510 
1511 template <typename T>
1513 {
1514  out << boost::format("FastReport %10.1f ms %10.1f ms %10.1f ms %10.1f ms %+10d kB %+10d kB %+10d kB %+10d kB %s\n")
1515  % (events ? ms(data.time_thread) / events : 0) % (events ? ms(total.time_thread) / events : 0)
1516  % (events ? ms(data.time_real) / events : 0) % (events ? ms(total.time_real) / events : 0)
1517  % (events ? +static_cast<int64_t>(kB(data.allocated) / events) : 0) % (events ? +static_cast<int64_t>(kB(total.allocated) / events) : 0)
1518  % (events ? -static_cast<int64_t>(kB(data.deallocated) / events) : 0) % (events ? -static_cast<int64_t>(kB(total.deallocated) / events) : 0)
1519  % label;
1520 }
1521 
1522 template <typename T>
1524 {
1525  printHeader(out, label);
1526  printSummaryHeader(out, "Modules", true);
1527  auto const& source_d = callgraph_.source();
1528  auto const& source = data.modules[source_d.id()];
1529  printSummaryLine(out, source.total, data.events, source.events, source_d.moduleLabel());
1530  for (unsigned int i = 0; i < callgraph_.processes().size(); ++i) {
1531  auto const& proc_d = callgraph_.processDescription(i);
1532  auto const& proc = data.processes[i];
1533  printSummaryLine(out, proc.total, data.events, "process " + proc_d.name_);
1534  for (unsigned int m: proc_d.modules_) {
1535  auto const& module_d = callgraph_.module(m);
1536  auto const& module = data.modules[m];
1537  printSummaryLine(out, module.total, data.events, module.events, " " + module_d.moduleLabel());
1538  }
1539  }
1540  printSummaryLine(out, data.total, data.events, "total");
1541  out << '\n';
1542  printPathSummaryHeader(out, "Processes and Paths");
1543  printSummaryLine(out, source.total, data.events, source_d.moduleLabel());
1544  for (unsigned int i = 0; i < callgraph_.processes().size(); ++i) {
1545  auto const& proc_d = callgraph_.processDescription(i);
1546  auto const& proc = data.processes[i];
1547  printSummaryLine(out, proc.total, data.events, "process " + proc_d.name_);
1548  for (unsigned int p = 0; p < proc.paths.size(); ++p) {
1549  auto const& name = proc_d.paths_[p].name_;
1550  auto const& path = proc.paths[p];
1551  printPathSummaryLine(out, path.active, path.total, data.events, " " + name);
1552  }
1553  for (unsigned int p = 0; p < proc.endpaths.size(); ++p) {
1554  auto const& name = proc_d.endPaths_[p].name_;
1555  auto const& path = proc.endpaths[p];
1556  printPathSummaryLine(out, path.active, path.total, data.events, " " + name);
1557  }
1558  }
1559  printSummaryLine(out, data.total, data.events, "total");
1560  out << '\n';
1561  for (unsigned int group: boost::irange(0ul, highlight_modules_.size())) {
1562  printSummaryHeader(out, "Highlighted modules", true);
1563  for (unsigned int m: highlight_modules_[group].modules) {
1564  auto const& module_d = callgraph_.module(m);
1565  auto const& module = data.modules[m];
1566  printSummaryLine(out, module.total, data.events, module.events, module_d.moduleLabel());
1567  }
1568  printSummaryLine(out, data.highlight[group], data.events, highlight_modules_[group].label);
1569  out << '\n';
1570  }
1571 }
1572 
1573 template <typename T>
1575 {
1576  printEventHeader(out, "Transition");
1577  printEventLine(out, data, label);
1578 }
1579 
1580 // check if this is the first process being signalled
1581 bool
1583 {
1584  return (not sc.processContext()->isSubProcess());
1585 }
1586 
1587 bool
1589 {
1590  return (not gc.processContext()->isSubProcess());
1591 }
1592 
1593 // check if this is the last process being signalled
1594 bool
1595 FastTimerService::isLastSubprocess(std::atomic<unsigned int>& check)
1596 {
1597  // release-acquire semantic guarantees that all writes in this and other threads are visible
1598  // after this operation; full sequentially-consistent ordering is (probably) not needed.
1599  unsigned int old_value = check.fetch_add(1, std::memory_order_acq_rel);
1600  return (old_value == callgraph_.processes().size() - 1);
1601 }
1602 
1603 void
1605 {
1606  ignoredSignal(__func__);
1607 }
1608 
1609 void
1611 {
1612  ignoredSignal(__func__);
1613 
1614  unsigned int pid = callgraph_.processId(* sc.processContext());
1615  unsigned int sid = sc.streamID();
1616  auto & stream = streams_[sid];
1617  auto & process = callgraph_.processDescription(pid);
1618 
1619  // measure the event resources as the sum of all modules' resources
1620  auto & data = stream.processes[pid].total;
1621  for (unsigned int i: process.modules_)
1622  data += stream.modules[i].total;
1623  stream.total += data;
1624 
1625  // handle the summaries and fill the plots only after the last subprocess has run
1627  if (not last)
1628  return;
1629 
1630  // measure the event resources explicitly
1631  stream.event_measurement.measure_and_store(stream.event);
1632 
1633  // highlighted modules
1634  for (unsigned int group: boost::irange(0ul, highlight_modules_.size()))
1635  for (unsigned int i: highlight_modules_[group].modules)
1636  stream.highlight[group] += stream.modules[i].total;
1637 
1638  // avoid concurrent access to the summary objects
1639  {
1640  std::lock_guard<std::mutex> guard(summary_mutex_);
1641  job_summary_ += stream;
1642  run_summary_[sc.runIndex()] += stream;
1643  }
1644 
1645  if (print_event_summary_) {
1646  edm::LogVerbatim out("FastReport");
1647  printEvent(out, stream);
1648  }
1649 
1650  if (enable_dqm_) {
1651  plots_->fill(callgraph_, stream, sc.eventID().luminosityBlock());
1652  }
1653 }
1654 
1655 void
1657 {
1658  // clear the event counters
1659  auto & stream = streams_[sid];
1660  stream.reset();
1661  ++stream.events;
1662 
1663  subprocess_event_check_[sid] = 0;
1664 
1665  // reuse the same measurement for the Source module and for the explicit begin of the Event
1666  auto & measurement = thread();
1667  measurement.measure_and_accumulate(stream.overhead);
1668  stream.event_measurement = measurement;
1669 }
1670 
1671 
1672 void
1674 {
1676  unsigned int id = md.id();
1677  auto & stream = streams_[sid];
1678 
1679  thread().measure_and_store(stream.modules[id].total);
1680  ++stream.modules[id].events;
1681 }
1682 
1683 
1684 void
1686 {
1687  unsigned int sid = sc.streamID().value();
1688  unsigned int pid = callgraph_.processId(* sc.processContext());
1689  unsigned int id = pc.pathID();
1690  auto & stream = streams_[sid];
1691  auto & data = pc.isEndPath() ? stream.processes[pid].endpaths[id] : stream.processes[pid].paths[id];
1692  data.status = false;
1693  data.last = 0;
1694 }
1695 
1696 
1697 void
1699 {
1700  unsigned int sid = sc.streamID().value();
1701  unsigned int pid = callgraph_.processId(* sc.processContext());
1702  unsigned int id = pc.pathID();
1703  auto & stream = streams_[sid];
1704  auto & data = pc.isEndPath() ? stream.processes[pid].endpaths[id] : stream.processes[pid].paths[id];
1705 
1707  unsigned int index = path.modules_on_path_.empty() ? 0 : status.index() + 1;
1708  data.last = path.modules_on_path_.empty() ? 0 : path.last_dependency_of_module_[status.index()];
1709 
1710  for (unsigned int i = 0; i < index; ++i) {
1711  auto const& module = stream.modules[path.modules_on_path_[i]];
1712  data.active += module.total;
1713  }
1714  for (unsigned int i = 0; i < data.last; ++i) {
1715  auto const& module = stream.modules[path.modules_and_dependencies_[i]];
1716  data.total += module.total;
1717  }
1718 }
1719 
1720 void
1722 {
1723  unsigned int sid = sc.streamID().value();
1724  auto & stream = streams_[sid];
1725  thread().measure_and_accumulate(stream.overhead);
1726 }
1727 
1728 void
1730 {
1731  edm::ModuleDescription const& md = * mcc.moduleDescription();
1732  unsigned int id = md.id();
1733  unsigned int sid = sc.streamID().value();
1734  auto & stream = streams_[sid];
1735 
1736  thread().measure_and_store(stream.modules[id].total);
1737  ++stream.modules[id].events;
1738 }
1739 
1740 void
1742 {
1743  unsupportedSignal(__func__);
1744 }
1745 
1746 void
1748 {
1749  unsupportedSignal(__func__);
1750 }
1751 
1752 void
1754 {
1755  ignoredSignal(__func__);
1756 }
1757 
1758 void
1760 {
1761  ignoredSignal(__func__);
1762 }
1763 
1764 void
1766 {
1767  ignoredSignal(__func__);
1768 }
1769 
1770 void
1772 {
1773  ignoredSignal(__func__);
1774 }
1775 
1776 void
1778 {
1780 }
1781 
1782 void
1784 {
1785  auto index = gc.runIndex();
1787 }
1788 
1789 void
1791 {
1793 }
1794 
1795 void
1797 {
1798  auto index = gc.runIndex();
1800 }
1801 
1802 void
1804 {
1806 }
1807 
1808 void
1810 {
1811  auto index = gc.luminosityBlockIndex();
1813 }
1814 
1815 void
1817 {
1819 }
1820 
1821 void
1823 {
1824  auto index = gc.luminosityBlockIndex();
1826 }
1827 
1828 void
1830 {
1832 }
1833 
1834 void
1836 {
1837  auto index = sc.runIndex();
1839 }
1840 
1841 void
1843 {
1845 }
1846 
1847 void
1849 {
1850  auto index = sc.runIndex();
1852 }
1853 
1854 void
1856 {
1858 }
1859 
1860 void
1862 {
1863  auto index = sc.luminosityBlockIndex();
1865 }
1866 
1867 void
1869 {
1871 }
1872 
1873 void
1875 {
1876  auto index = sc.luminosityBlockIndex();
1878 }
1879 
1880 void
1882 {
1883  // initialise the measurement point for a thread that has newly joining the TBB pool
1884  thread().measure();
1885 }
1886 
1887 void
1889 {
1890  // account any resources used or freed by the thread before leaving the TBB pool
1892 }
1893 
1896 {
1897  return threads_.local();
1898 }
1899 
1900 
1901 // describe the module's configuration
1902 void
1904 {
1906  desc.addUntracked<bool>( "printEventSummary", false);
1907  desc.addUntracked<bool>( "printRunSummary", true);
1908  desc.addUntracked<bool>( "printJobSummary", true);
1909  desc.addUntracked<bool>( "enableDQM", true);
1910  desc.addUntracked<bool>( "enableDQMbyModule", false);
1911  desc.addUntracked<bool>( "enableDQMbyPath", false);
1912  desc.addUntracked<bool>( "enableDQMbyLumiSection", false);
1913  desc.addUntracked<bool>( "enableDQMbyProcesses", false);
1914  desc.addUntracked<bool>( "enableDQMTransitions", false);
1915  desc.addUntracked<double>( "dqmTimeRange", 1000. ); // ms
1916  desc.addUntracked<double>( "dqmTimeResolution", 5. ); // ms
1917  desc.addUntracked<double>( "dqmMemoryRange", 1000000. ); // kB
1918  desc.addUntracked<double>( "dqmMemoryResolution", 5000. ); // kB
1919  desc.addUntracked<double>( "dqmPathTimeRange", 100. ); // ms
1920  desc.addUntracked<double>( "dqmPathTimeResolution", 0.5); // ms
1921  desc.addUntracked<double>( "dqmPathMemoryRange", 1000000. ); // kB
1922  desc.addUntracked<double>( "dqmPathMemoryResolution", 5000. ); // kB
1923  desc.addUntracked<double>( "dqmModuleTimeRange", 40. ); // ms
1924  desc.addUntracked<double>( "dqmModuleTimeResolution", 0.2); // ms
1925  desc.addUntracked<double>( "dqmModuleMemoryRange", 100000. ); // kB
1926  desc.addUntracked<double>( "dqmModuleMemoryResolution", 500. ); // kB
1927  desc.addUntracked<unsigned>( "dqmLumiSectionsRange", 2500 ); // ~ 16 hours
1928  desc.addUntracked<std::string>( "dqmPath", "HLT/TimerService");
1929 
1930  edm::ParameterSetDescription highlightModulesDescription;
1931  highlightModulesDescription.addUntracked<std::vector<std::string>>("modules", {});
1932  highlightModulesDescription.addUntracked<std::string>("label", "producers");
1933  desc.addVPSetUntracked("highlightModules", highlightModulesDescription, {});
1934 
1935  // # OBSOLETE - these parameters are ignored, they are left only not to break old configurations
1936  // they will not be printed in the generated cfi.py file
1937  desc.addOptionalNode(edm::ParameterDescription<bool>("useRealTimeClock", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1938  desc.addOptionalNode(edm::ParameterDescription<bool>("enableTimingPaths", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1939  desc.addOptionalNode(edm::ParameterDescription<bool>("enableTimingModules", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1940  desc.addOptionalNode(edm::ParameterDescription<bool>("enableTimingExclusive", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1941  desc.addOptionalNode(edm::ParameterDescription<bool>("enableTimingSummary", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1942  desc.addOptionalNode(edm::ParameterDescription<bool>("skipFirstPath", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1943  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathActive", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1944  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathTotal", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1945  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathOverhead", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1946  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathDetails", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1947  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathCounters", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1948  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathExclusive", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1949  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyModuleType", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1950  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMSummary", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1951 
1952  descriptions.add("FastTimerService", desc);
1953 }
#define LogDebug(id)
ConcurrentMonitorElement book1DD(Args &&...args)
Definition: DQMStore.h:237
void book(DQMStore::ConcurrentBooker &, std::string const &name, std::string const &title, PlotRanges const &ranges, unsigned int lumisections, bool byls)
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)
ConcurrentMonitorElement bookProfile(Args &&...args)
Definition: DQMStore.h:272
void setComment(std::string const &value)
T getUntrackedParameter(std::string const &, T const &) const
std::unique_ptr< std::atomic< unsigned int >[]> subprocess_global_lumi_check_
void postStreamBeginRun(edm::StreamContext const &)
double queryEventTime(edm::StreamID) const
LuminosityBlockIndex const & luminosityBlockIndex() const
Definition: StreamContext.h:61
void postGlobalEndLumi(edm::GlobalContext const &)
void postGlobalBeginLumi(edm::GlobalContext const &)
void on_scheduler_entry(bool worker) final
void postStreamEndLumi(edm::StreamContext const &)
void on_scheduler_exit(bool worker) final
std::vector< edm::ParameterSet > highlight_module_psets_
void postModuleGlobalEndLumi(edm::GlobalContext const &, edm::ModuleCallingContext const &)
void preEventReadFromSource(edm::StreamContext const &, edm::ModuleCallingContext const &)
void preGlobalEndRun(edm::GlobalContext const &)
void preBeginJob(edm::PathsAndConsumesOfModulesBase const &, edm::ProcessContext const &)
void fill_lumi(AtomicResources const &, unsigned int lumisection)
void printSummary(T &out, ResourcesPerJob const &data, std::string const &label) const
AtomicResources operator+(AtomicResources const &other) const
void setYTitle(std::string const &title)
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
const PlotRanges dqm_event_ranges_
void postModuleGlobalEndRun(edm::GlobalContext const &, edm::ModuleCallingContext const &)
void postModuleEvent(edm::StreamContext const &, edm::ModuleCallingContext const &)
void unsupportedSignal(const std::string &signal) const
std::vector< GroupOfModules > highlight_modules_
ResourcesPerJob job_summary_
PlotsPerJob(ProcessCallGraph const &job, std::vector< GroupOfModules > const &groups)
void book(DQMStore::ConcurrentBooker &, std::string const &, ProcessCallGraph const &, ProcessCallGraph::PathType const &, PlotRanges const &ranges, unsigned int lumisections, bool byls)
unsigned int processId(edm::ProcessContext const &) const
TrainProcessor *const proc
Definition: MVATrainer.cc:101
PlotsPerProcess(ProcessCallGraph::ProcessType const &)
void preGlobalEndLumi(edm::GlobalContext const &)
std::vector< ResourcesPerPath > endpaths
double queryModuleTime_(edm::StreamID, unsigned int id) const
LuminosityBlockID const & luminosityBlockID() const
Definition: GlobalContext.h:52
AtomicResources overhead_
bool isFirstSubprocess(edm::StreamContext const &)
const bool enable_dqm_bynproc_
unsigned int concurrent_runs_
boost::chrono::nanoseconds time_real
void measure_and_accumulate(AtomicResources &store)
std::atomic< uint64_t > deallocated
std::unique_ptr< std::atomic< unsigned int >[]> subprocess_global_run_check_
std::vector< ResourcesPerJob > streams_
std::atomic< uint64_t > allocated
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 &)
ResourcesPerProcess & operator+=(ResourcesPerProcess const &other)
LuminosityBlockNumber_t luminosityBlock() const
Definition: EventID.h:40
const bool print_job_summary_
std::string const & moduleLabel() const
const bool enable_dqm_bypath_
edm::ModuleDescription const & source() const
Measurement & thread()
tbb::enumerable_thread_specific< Measurement, tbb::cache_aligned_allocator< Measurement >, tbb::ets_key_per_instance > threads_
void postStreamBeginLumi(edm::StreamContext const &)
const PlotRanges dqm_path_ranges_
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 book(DQMStore::ConcurrentBooker &, ProcessCallGraph const &, std::vector< GroupOfModules > const &, PlotRanges const &event_ranges, PlotRanges const &path_ranges, PlotRanges const &module_ranges, unsigned int lumisections, bool bymodule, bool bypath, bool byls, bool transitions)
void printEvent(T &out, ResourcesPerJob const &) const
void printHeader(T &out, std::string const &label) const
void postModuleStreamEndLumi(edm::StreamContext const &, edm::ModuleCallingContext const &)
std::mutex summary_mutex_
void printPathSummaryHeader(T &out, std::string const &label) const
ResourcesPerJob & operator+=(ResourcesPerJob const &other)
void printSummaryHeader(T &out, std::string const &label, bool detailed) const
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 &)
LuminosityBlockIndex const & luminosityBlockIndex() const
Definition: GlobalContext.h:54
std::vector< ResourcesPerJob > run_summary_
void printEventHeader(T &out, std::string const &label) const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
FastTimerService(const edm::ParameterSet &, edm::ActivityRegistry &)
void preModuleStreamEndLumi(edm::StreamContext const &, edm::ModuleCallingContext const &)
void postEvent(edm::StreamContext const &)
void preBeginJob(edm::PathsAndConsumesOfModulesBase const &, edm::ProcessContext const &)
void postGlobalEndRun(edm::GlobalContext const &)
static uint64_t deallocated()
Definition: memory_usage.cc:75
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
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 &)
RunNumber_t run() const
ResourcesPerPath & operator+=(ResourcesPerPath const &other)
std::vector< PlotsPerElement > modules_
ConcurrentMonitorElement book1D(Args &&...args)
Definition: DQMStore.h:223
ProcessType const & processDescription(unsigned int) const
ParameterDescriptionNode * addOptionalNode(ParameterDescriptionNode const &node, bool writeToCfi)
unsigned int concurrent_lumis_
std::string dqm_path_
void preSourceConstruction(edm::ModuleDescription const &)
void printSummaryLine(T &out, Resources const &data, uint64_t events, std::string const &label) const
unsigned int pathID() const
Definition: PathContext.h:39
format
Some error handling for the usage.
const bool enable_dqm_transitions_
ProcessContext const * processContext() const
Definition: StreamContext.h:63
void printEventLine(T &out, Resources const &data, std::string const &label) const
std::atomic< boost::chrono::nanoseconds::rep > time_thread
Resources operator+(Resources const &other) const
std::vector< Resources > highlight
const bool enable_dqm_bymodule_
void printPathSummaryLine(T &out, Resources const &data, Resources const &total, uint64_t events, std::string const &label) const
bin
set the eta bin as selection string.
string ranges
Definition: diffTwoXMLs.py:78
StreamID const & streamID() const
Definition: StreamContext.h:57
void fill_run(AtomicResources const &)
const std::string processor_model
~FastTimerService() override
const PlotRanges dqm_module_ranges_
std::vector< PlotsPerPath > endpaths_
static bool is_available()
Definition: memory_usage.cc:65
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:279
unsigned int maxNumberOfConcurrentLuminosityBlocks() const
Definition: SystemBounds.h:45
unsigned long long uint64_t
Definition: Time.h:15
void postModuleStreamBeginLumi(edm::StreamContext const &, edm::ModuleCallingContext const &)
double querySourceTime(edm::StreamID) const
void printTransition(T &out, AtomicResources const &data, std::string const &label) const
std::vector< AtomicResources > run_transition_
void preModuleStreamEndRun(edm::StreamContext const &, edm::ModuleCallingContext const &)
void postModuleStreamEndRun(edm::StreamContext const &, edm::ModuleCallingContext const &)
part
Definition: HCALResponse.h:20
def load(fileName)
Definition: svgfig.py:546
static uint64_t allocated()
Definition: memory_usage.cc:70
const std::string & pwd()
Definition: DQMStore.cc:287
void postModuleStreamBeginRun(edm::StreamContext const &, edm::ModuleCallingContext const &)
void preSourceEvent(edm::StreamID)
boost::chrono::nanoseconds time_thread
LuminosityBlockNumber_t luminosityBlock() const
void add(std::string const &label, ParameterSetDescription const &psetDescription)
susybsm::MuonSegment ms
Definition: classes.h:31
void preEvent(edm::StreamContext const &)
void postGlobalBeginRun(edm::GlobalContext const &)
ProcessContext const * processContext() const
Definition: GlobalContext.h:56
void preStreamBeginLumi(edm::StreamContext const &)
ResourcesPerProcess(ProcessCallGraph::ProcessType const &process)
void ignoredSignal(const std::string &signal) const
void postSourceEvent(edm::StreamID)
void preModuleStreamBeginLumi(edm::StreamContext const &, edm::ModuleCallingContext const &)
void preStreamEndRun(edm::StreamContext const &)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
std::atomic< boost::chrono::nanoseconds::rep > time_real
void preModuleStreamBeginRun(edm::StreamContext const &, edm::ModuleCallingContext const &)
void preStreamEndLumi(edm::StreamContext const &)
void measure_and_store(Resources &store)
ResourcesPerModule & operator+=(ResourcesPerModule const &other)
std::vector< PathType > endPaths_
void event_()
void postModuleEventPrefetching(edm::StreamContext const &, edm::ModuleCallingContext const &)
void preModuleGlobalEndLumi(edm::GlobalContext const &, edm::ModuleCallingContext const &)
std::unique_ptr< PlotsPerJob > plots_
unsigned int size() const
edm::ModuleDescription const & module(unsigned int module) const
double queryPathTime(edm::StreamID, std::string const &path) const
void preGlobalBeginLumi(edm::GlobalContext const &)
unsigned int maxNumberOfConcurrentRuns() const
Definition: SystemBounds.h:44
AtomicResources & operator+=(AtomicResources const &other)
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 &)
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
AtomicResources & operator=(AtomicResources const &other)
def check(config)
Definition: trackerTree.py:14
ProcessCallGraph callgraph_
long double T
void postModuleGlobalBeginLumi(edm::GlobalContext const &, edm::ModuleCallingContext const &)
void preStreamBeginRun(edm::StreamContext const &)
std::vector< ResourcesPerPath > paths
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)
std::vector< AtomicResources > lumi_transition_
static std::string const source
Definition: EdmProvDump.cc:43
void book(DQMStore::ConcurrentBooker &, ProcessCallGraph const &, ProcessCallGraph::ProcessType const &, PlotRanges const &event_ranges, PlotRanges const &path_ranges, unsigned int lumisections, bool bypath, bool byls)
std::vector< unsigned int > modules_
unsigned int concurrent_streams_
bool isLastSubprocess(std::atomic< unsigned int > &check)
Definition: event.py:1
void preallocate(edm::service::SystemBounds const &)
void fill(ProcessCallGraph const &, ResourcesPerJob const &, unsigned int ls)
unsigned int id() const
void fill(ProcessCallGraph::PathType const &, ResourcesPerJob const &, ResourcesPerPath const &, unsigned int lumisection)
void setXTitle(std::string const &title)
unsigned int index() const
Definition: HLTPathStatus.h:55