CMS 3D CMS Logo

FastTimerService.cc
Go to the documentation of this file.
1 // C++ headers
2 #include <cmath>
3 #include <iomanip>
4 #include <iostream>
5 #include <limits>
6 #include <mutex>
7 #include <sstream>
8 #include <string>
9 #include <unordered_map>
10 #include <unordered_set>
11 
12 // boost headers
13 #include <boost/format.hpp>
14 #include <boost/range/irange.hpp>
15 
16 // CMSSW headers
32 #include "FastTimerService.h"
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 
157  total(),
158  events(0),
159  has_acquire(false)
160 { }
161 
162 void
164  total.reset();
165  events = 0;
166  has_acquire = false;
167 }
168 
171  total += other.total;
172  events += other.events;
173  has_acquire = has_acquire or other.has_acquire;
174  return *this;
175 }
176 
179  ResourcesPerModule result(*this);
180  result += other;
181  return result;
182 }
183 
184 
185 // ResourcesPerPath
186 
187 void
189  active.reset();
190  total.reset();
191  last = 0;
192  status = false;
193 }
194 
197  active += other.active;
198  total += other.total;
199  last = 0; // summing these makes no sense, reset them instead
200  status = false;
201  return *this;
202 }
203 
206  ResourcesPerPath result(*this);
207  result += other;
208  return result;
209 }
210 
211 
212 // ResourcesPerProcess
213 
215  total(),
216  paths(process.paths_.size()),
217  endpaths(process.endPaths_.size())
218 {
219 }
220 
221 void
223  total.reset();
224  for (auto & path: paths)
225  path.reset();
226  for (auto & path: endpaths)
227  path.reset();
228 }
229 
232  total += other.total;
233  assert(paths.size() == other.paths.size());
234  for (unsigned int i: boost::irange(0ul, paths.size()))
235  paths[i] += other.paths[i];
236  assert(endpaths.size() == other.endpaths.size());
237  for (unsigned int i: boost::irange(0ul, endpaths.size()))
238  endpaths[i] += other.endpaths[i];
239  return *this;
240 }
241 
245  result += other;
246  return result;
247 }
248 
249 
250 // ResourcesPerJob
251 
252 FastTimerService::ResourcesPerJob::ResourcesPerJob(ProcessCallGraph const& job, std::vector<GroupOfModules> const& groups) :
253  total(),
254  overhead(),
255  event(),
256  highlight(groups.size()),
257  modules(job.size()),
258  processes(),
259  events(0)
260 {
261  processes.reserve(job.processes().size());
262  for (auto const& process: job.processes())
263  processes.emplace_back(process);
264 }
265 
266 void
268  total.reset();
269  overhead.reset();
270  event.reset();
271  for (auto & module: highlight)
272  module.reset();
273  for (auto & module: modules)
274  module.reset();
275  for (auto & process: processes)
276  process.reset();
277  events = 0;
278 }
279 
282  total += other.total;
283  overhead += other.overhead;
284  event += other.event;
285  assert(highlight.size() == other.highlight.size());
286  for (unsigned int i: boost::irange(0ul, highlight.size()))
287  highlight[i] += other.highlight[i];
288  assert(modules.size() == other.modules.size());
289  for (unsigned int i: boost::irange(0ul, modules.size()))
290  modules[i] += other.modules[i];
291  assert(processes.size() == other.processes.size());
292  for (unsigned int i: boost::irange(0ul, processes.size()))
293  processes[i] += other.processes[i];
294  events += other.events;
295  return *this;
296 }
297 
300  ResourcesPerJob result(*this);
301  result += other;
302  return result;
303 }
304 
305 
306 // per-thread measurements
307 
308 // Measurement
309 
311  measure();
312 }
313 
314 void
316  #ifdef DEBUG_THREAD_CONCURRENCY
317  id = std::this_thread::get_id();
318  #endif // DEBUG_THREAD_CONCURRENCY
319  time_thread = boost::chrono::thread_clock::now();
321  allocated = memory_usage::allocated();
322  deallocated = memory_usage::deallocated();
323 }
324 
325 void
327  #ifdef DEBUG_THREAD_CONCURRENCY
328  assert(std::this_thread::get_id() == id);
329  #endif // DEBUG_THREAD_CONCURRENCY
330  auto new_time_thread = boost::chrono::thread_clock::now();
331  auto new_time_real = boost::chrono::high_resolution_clock::now();
332  auto new_allocated = memory_usage::allocated();
333  auto new_deallocated = memory_usage::deallocated();
334  store.time_thread = new_time_thread - time_thread;
335  store.time_real = new_time_real - time_real;
336  store.allocated = new_allocated - allocated;
337  store.deallocated = new_deallocated - deallocated;
338  time_thread = new_time_thread;
339  time_real = new_time_real;
340  allocated = new_allocated;
341  deallocated = new_deallocated;
342 }
343 
344 void
346  #ifdef DEBUG_THREAD_CONCURRENCY
347  assert(std::this_thread::get_id() == id);
348  #endif // DEBUG_THREAD_CONCURRENCY
349  auto new_time_thread = boost::chrono::thread_clock::now();
350  auto new_time_real = boost::chrono::high_resolution_clock::now();
351  auto new_allocated = memory_usage::allocated();
352  auto new_deallocated = memory_usage::deallocated();
353  store.time_thread += new_time_thread - time_thread;
354  store.time_real += new_time_real - time_real;
355  store.allocated += new_allocated - allocated;
356  store.deallocated += new_deallocated - deallocated;
357  time_thread = new_time_thread;
358  time_real = new_time_real;
359  allocated = new_allocated;
360  deallocated = new_deallocated;
361 }
362 
363 void
365  #ifdef DEBUG_THREAD_CONCURRENCY
366  assert(std::this_thread::get_id() == id);
367  #endif // DEBUG_THREAD_CONCURRENCY
368  auto new_time_thread = boost::chrono::thread_clock::now();
369  auto new_time_real = boost::chrono::high_resolution_clock::now();
370  auto new_allocated = memory_usage::allocated();
371  auto new_deallocated = memory_usage::deallocated();
372  store.time_thread += boost::chrono::duration_cast<boost::chrono::nanoseconds>(new_time_thread - time_thread).count();
373  store.time_real += boost::chrono::duration_cast<boost::chrono::nanoseconds>(new_time_real - time_real).count();
374  store.allocated += new_allocated - allocated;
375  store.deallocated += new_deallocated - deallocated;
376  time_thread = new_time_thread;
377  time_real = new_time_real;
378  allocated = new_allocated;
379  deallocated = new_deallocated;
380 }
381 
383 
384 void
387  std::string const& name,
388  std::string const& title,
389  PlotRanges const& ranges,
390  unsigned int lumisections,
391  bool byls)
392 {
393  int time_bins = (int) std::ceil(ranges.time_range / ranges.time_resolution);
394  int mem_bins = (int) std::ceil(ranges.memory_range / ranges.memory_resolution);
395  std::string y_title_ms = (boost::format("events / %.1f ms") % ranges.time_resolution).str();
396  std::string y_title_kB = (boost::format("events / %.1f kB") % ranges.memory_resolution).str();
397 
398  time_thread_ = booker.book1D(
399  name + " time_thread",
400  title + " processing time (cpu)",
401  time_bins, 0., ranges.time_range);
402  time_thread_.setXTitle("processing time [ms]");
403  time_thread_.setYTitle(y_title_ms.c_str());
404 
405  time_real_ = booker.book1D(
406  name + " time_real",
407  title + " processing time (real)",
408  time_bins, 0., ranges.time_range);
409  time_real_.setXTitle("processing time [ms]");
410  time_real_.setYTitle(y_title_ms.c_str());
411 
413  {
414  allocated_ = booker.book1D(
415  name + " allocated",
416  title + " allocated memory",
417  mem_bins, 0., ranges.memory_range);
418  allocated_.setXTitle("memory [kB]");
419  allocated_.setYTitle(y_title_kB.c_str());
420 
421  deallocated_ = booker.book1D(
422  name + " deallocated",
423  title + " deallocated memory",
424  mem_bins, 0., ranges.memory_range);
425  deallocated_.setXTitle("memory [kB]");
426  deallocated_.setYTitle(y_title_kB.c_str());
427  }
428 
429  if (not byls)
430  return;
431 
432  time_thread_byls_ = booker.bookProfile(
433  name + " time_thread_byls",
434  title + " processing time (cpu) vs. lumisection",
435  lumisections, 0.5, lumisections + 0.5,
436  time_bins, 0., std::numeric_limits<double>::infinity(),
437  " ");
438  time_thread_byls_.setXTitle("lumisection");
439  time_thread_byls_.setYTitle("processing time [ms]");
440 
441  time_real_byls_ = booker.bookProfile(
442  name + " time_real_byls",
443  title + " processing time (real) vs. lumisection",
444  lumisections, 0.5, lumisections + 0.5,
445  time_bins, 0., std::numeric_limits<double>::infinity(),
446  " ");
447  time_real_byls_.setXTitle("lumisection");
448  time_real_byls_.setYTitle("processing time [ms]");
449 
451  {
452  allocated_byls_ = booker.bookProfile(
453  name + " allocated_byls",
454  title + " allocated memory vs. lumisection",
455  lumisections, 0.5, lumisections + 0.5,
457  " ");
458  allocated_byls_.setXTitle("lumisection");
459  allocated_byls_.setYTitle("memory [kB]");
460 
461  deallocated_byls_ = booker.bookProfile(
462  name + " deallocated_byls",
463  title + " deallocated memory vs. lumisection",
464  lumisections, 0.5, lumisections + 0.5,
466  " ");
467  deallocated_byls_.setXTitle("lumisection");
468  deallocated_byls_.setYTitle("memory [kB]");
469  }
470 }
471 
472 void
473 FastTimerService::PlotsPerElement::fill(Resources const& data, unsigned int lumisection)
474 {
475  // enable underflows and overflows in the computation of mean and rms
476  TH1::StatOverflows(true);
477 
478  if (time_thread_)
479  time_thread_.fill(ms(data.time_thread));
480 
481  if (time_thread_byls_)
482  time_thread_byls_.fill(lumisection, ms(data.time_thread));
483 
484  if (time_real_)
485  time_real_.fill(ms(data.time_real));
486 
487  if (time_real_byls_)
488  time_real_byls_.fill(lumisection, ms(data.time_real));
489 
490  if (allocated_)
491  allocated_.fill(kB(data.allocated));
492 
493  if (allocated_byls_)
494  allocated_byls_.fill(lumisection, kB(data.allocated));
495 
496  if (deallocated_)
497  deallocated_.fill(kB(data.deallocated));
498 
499  if (deallocated_byls_)
500  deallocated_byls_.fill(lumisection, kB(data.deallocated));
501 }
502 
503 void
505 {
506  // enable underflows and overflows in the computation of mean and rms
507  TH1::StatOverflows(true);
508 
509  if (time_thread_)
510  time_thread_.fill(ms(boost::chrono::nanoseconds(data.time_thread.load())));
511 
512  if (time_thread_byls_)
513  time_thread_byls_.fill(lumisection, ms(boost::chrono::nanoseconds(data.time_thread.load())));
514 
515  if (time_real_)
516  time_real_.fill(ms(boost::chrono::nanoseconds(data.time_real.load())));
517 
518  if (time_real_byls_)
519  time_real_byls_.fill(lumisection, ms(boost::chrono::nanoseconds(data.time_real.load())));
520 
521  if (allocated_)
522  allocated_.fill(kB(data.allocated));
523 
524  if (allocated_byls_)
525  allocated_byls_.fill(lumisection, kB(data.allocated));
526 
527  if (deallocated_)
528  deallocated_.fill(kB(data.deallocated));
529 
530  if (deallocated_byls_)
531  deallocated_byls_.fill(lumisection, kB(data.deallocated));
532 }
533 
534 void
536 {
537  // enable underflows and overflows in the computation of mean and rms
538  TH1::StatOverflows(true);
539 
540  float total;
541  float fraction;
542 
543  total = ms(data.time_thread);
544  fraction = (total > 0.) ? (ms(part.time_thread) / total) : 0.;
545  if (time_thread_)
546  time_thread_.fill(total, fraction);
547 
548  if (time_thread_byls_)
549  time_thread_byls_.fill(lumisection, total, fraction);
550 
551  total = ms(data.time_real);
552  fraction = (total > 0.) ? (ms(part.time_real) / total) : 0.;
553  if (time_real_)
554  time_real_.fill(total, fraction);
555 
556  if (time_real_byls_)
557  time_real_byls_.fill(lumisection, total, fraction);
558 
559  total = kB(data.allocated);
560  fraction = (total > 0.) ? (kB(part.allocated) / total) : 0.;
561  if (allocated_)
562  allocated_.fill(total, fraction);
563 
564  if (allocated_byls_)
565  allocated_byls_.fill(lumisection, total, fraction);
566 
567  total = kB(data.deallocated);
568  fraction = (total > 0.) ? (kB(part.deallocated) / total) : 0.;
569  if (deallocated_)
570  deallocated_.fill(total, fraction);
571 
572  if (deallocated_byls_)
573  deallocated_byls_.fill(lumisection, total, fraction);
574 }
575 
576 
577 void
580  std::string const & prefixDir,
581  ProcessCallGraph const& job,
583  PlotRanges const& ranges,
584  unsigned int lumisections,
585  bool byls)
586 {
587  const std::string basedir = booker.pwd();
588  // booker.setCurrentFolder(basedir + "/path " + path.name_);
589  booker.setCurrentFolder(basedir + "/" + prefixDir + path.name_);
590 
591  total_.book(booker, "path", path.name_, ranges, lumisections, byls);
592 
593  unsigned int bins = path.modules_and_dependencies_.size();
594  module_counter_ = booker.book1DD(
595  "module_counter",
596  "module counter",
597  bins + 1, -0.5, bins + 0.5);
598  module_counter_.setYTitle("events");
599  module_time_thread_total_ = booker.book1DD(
600  "module_time_thread_total",
601  "total module time (cpu)",
602  bins, -0.5, bins - 0.5);
603  module_time_thread_total_.setYTitle("processing time [ms]");
604  module_time_real_total_ = booker.book1DD(
605  "module_time_real_total",
606  "total module time (real)",
607  bins, -0.5, bins - 0.5);
608  module_time_real_total_.setYTitle("processing time [ms]");
610  {
611  module_allocated_total_ = booker.book1DD(
612  "module_allocated_total",
613  "total allocated memory",
614  bins, -0.5, bins - 0.5);
615  module_allocated_total_.setYTitle("memory [kB]");
616  module_deallocated_total_ = booker.book1DD(
617  "module_deallocated_total",
618  "total deallocated memory",
619  bins, -0.5, bins - 0.5);
620  module_deallocated_total_.setYTitle("memory [kB]");
621  }
622  for (unsigned int bin: boost::irange(0u, bins)) {
623  auto const& module = job[path.modules_and_dependencies_[bin]];
624  std::string const& label = module.scheduled_ ? module.module_.moduleLabel() : module.module_.moduleLabel() + " (unscheduled)";
625  module_counter_ .setBinLabel(bin + 1, label.c_str());
626  module_time_thread_total_.setBinLabel(bin + 1, label.c_str());
627  module_time_real_total_ .setBinLabel(bin + 1, label.c_str());
629  {
630  module_allocated_total_ .setBinLabel(bin + 1, label.c_str());
631  module_deallocated_total_.setBinLabel(bin + 1, label.c_str());
632  }
633  }
634  module_counter_.setBinLabel(bins + 1, "");
635 
636  booker.setCurrentFolder(basedir);
637 }
638 
639 void
641 {
642  // fill the total path time
643  total_.fill(path.total, ls);
644 
645  // fill the modules that actually ran and the total time spent in each od them
646  for (unsigned int i = 0; i < path.last; ++i) {
647  auto const& module = data.modules[description.modules_and_dependencies_[i]];
648  if (module_counter_)
649  module_counter_.fill(i);
650 
651  if (module_time_thread_total_)
652  module_time_thread_total_.fill(i, ms(module.total.time_thread));
653 
654  if (module_time_real_total_)
655  module_time_real_total_.fill(i, ms(module.total.time_real));
656 
657  if (module_allocated_total_)
658  module_allocated_total_.fill(i, kB(module.total.allocated));
659 
660  if (module_deallocated_total_)
661  module_deallocated_total_.fill(i, kB(module.total.deallocated));
662  }
663  if (module_counter_ and path.status)
664  module_counter_.fill(path.last);
665 }
666 
667 
669  event_(),
670  paths_(process.paths_.size()),
671  endpaths_(process.endPaths_.size())
672 {
673 }
674 
675 void
678  ProcessCallGraph const& job,
680  PlotRanges const& event_ranges,
681  PlotRanges const& path_ranges,
682  unsigned int lumisections,
683  bool bypath,
684  bool byls)
685 {
686  const std::string basedir = booker.pwd();
687  event_.book(booker,
688  "process " + process.name_, "process " + process.name_,
689  event_ranges,
690  lumisections,
691  byls);
692  if (bypath) {
693  booker.setCurrentFolder(basedir + "/process " + process.name_ + " paths");
694  for (unsigned int id: boost::irange(0ul, paths_.size()))
695  {
696  paths_[id].book(booker,"path ",
697  job, process.paths_[id],
698  path_ranges,
699  lumisections,
700  byls);
701  }
702  for (unsigned int id: boost::irange(0ul, endpaths_.size()))
703  {
704  endpaths_[id].book(booker,"endpath ",
705  job, process.endPaths_[id],
706  path_ranges,
707  lumisections,
708  byls);
709  }
710  booker.setCurrentFolder(basedir);
711  }
712 }
713 
714 void
716 {
717  // fill process event plots
718  event_.fill(process.total, ls);
719 
720  // fill all paths plots
721  for (unsigned int id: boost::irange(0ul, paths_.size()))
722  paths_[id].fill(description.paths_[id], data, process.paths[id], ls);
723 
724  // fill all endpaths plots
725  for (unsigned int id: boost::irange(0ul, endpaths_.size()))
726  endpaths_[id].fill(description.endPaths_[id], data, process.endpaths[id], ls);
727 }
728 
729 FastTimerService::PlotsPerJob::PlotsPerJob(ProcessCallGraph const& job, std::vector<GroupOfModules> const& groups) :
730  event_(),
731  event_ex_(),
732  overhead_(),
733  highlight_(groups.size()),
734  modules_(job.size()),
735  processes_()
736 {
737  processes_.reserve(job.processes().size());
738  for (auto const& process: job.processes())
739  processes_.emplace_back(process);
740 }
741 
742 void
745  ProcessCallGraph const& job,
746  std::vector<GroupOfModules> const& groups,
747  PlotRanges const& event_ranges,
748  PlotRanges const& path_ranges,
749  PlotRanges const& module_ranges,
750  unsigned int lumisections,
751  bool bymodule,
752  bool bypath,
753  bool byls,
754  bool transitions)
755 {
756  const std::string basedir = booker.pwd();
757 
758  // event summary plots
759  event_.book(booker,
760  "event", "Event",
761  event_ranges,
762  lumisections,
763  byls);
764 
765  event_ex_.book(booker,
766  "explicit", "Event (explicit)",
767  event_ranges,
768  lumisections,
769  byls);
770 
771  overhead_.book(booker,
772  "overhead", "Overhead",
773  event_ranges,
774  lumisections,
775  byls);
776 
777  modules_[job.source().id()].book(booker,
778  "source", "Source",
779  module_ranges,
780  lumisections,
781  byls);
782 
783  if (transitions) {
784  lumi_.book(booker,
785  "lumi", "LumiSection transitions",
786  event_ranges,
787  lumisections,
788  byls);
789 
790  run_.book(booker,
791  "run", "Run transtions",
792  event_ranges,
793  lumisections,
794  false);
795  }
796 
797  // plot the time spent in few given groups of modules
798  for (unsigned int group: boost::irange(0ul, groups.size())) {
799  auto const & label = groups[group].label;
800  highlight_[group].book(booker,
801  "highlight " + label, "Highlight " + label,
802  event_ranges,
803  lumisections,
804  byls);
805  }
806 
807  // plots per subprocess (event, modules, paths and endpaths)
808  for (unsigned int pid: boost::irange(0ul, job.processes().size())) {
809  auto const& process = job.processDescription(pid);
810  processes_[pid].book(booker,
811  job, process,
812  event_ranges,
813  path_ranges,
814  lumisections,
815  bypath,
816  byls);
817 
818  if (bymodule) {
819  booker.setCurrentFolder(basedir + "/process " + process.name_ + " modules");
820  for (unsigned int id: process.modules_)
821  {
822  auto const& module_name = job.module(id).moduleLabel();
823  modules_[id].book(booker,
825  module_ranges,
826  lumisections,
827  byls);
828  }
829  booker.setCurrentFolder(basedir);
830  }
831  }
832 }
833 
834 void
836 {
837  // fill total event plots
838  event_.fill(data.total, ls);
839  event_ex_.fill(data.event, ls);
840  overhead_.fill(data.overhead, ls);
841 
842  // fill highltight plots
843  for (unsigned int group: boost::irange(0ul, highlight_.size()))
844  highlight_[group].fill_fraction(data.total, data.highlight[group], ls);
845 
846  // fill modules plots
847  for (unsigned int id: boost::irange(0ul, modules_.size()))
848  modules_[id].fill(data.modules[id].total, ls);
849 
850  for (unsigned int pid: boost::irange(0ul, processes_.size()))
851  processes_[pid].fill(job.processDescription(pid), data, data.processes[pid], ls);
852 }
853 
854 void
856 {
857  // fill run transition plots
858  run_.fill(data, 0);
859 }
860 
861 void
863 {
864  // fill lumisection transition plots
865  lumi_.fill(data, ls);
866 }
867 
869 
871  // configuration
872  callgraph_(),
873  // job configuration
874  concurrent_lumis_( 0 ),
875  concurrent_runs_( 0 ),
876  concurrent_streams_( 0 ),
877  concurrent_threads_( 0 ),
878  print_event_summary_( config.getUntrackedParameter<bool>( "printEventSummary" ) ),
879  print_run_summary_( config.getUntrackedParameter<bool>( "printRunSummary" ) ),
880  print_job_summary_( config.getUntrackedParameter<bool>( "printJobSummary" ) ),
881  // dqm configuration
882  enable_dqm_( config.getUntrackedParameter<bool>( "enableDQM" ) ),
883  enable_dqm_bymodule_( config.getUntrackedParameter<bool>( "enableDQMbyModule" ) ),
884  enable_dqm_bypath_( config.getUntrackedParameter<bool>( "enableDQMbyPath" ) ),
885  enable_dqm_byls_( config.getUntrackedParameter<bool>( "enableDQMbyLumiSection" ) ),
886  enable_dqm_bynproc_( config.getUntrackedParameter<bool>( "enableDQMbyProcesses" ) ),
887  enable_dqm_transitions_( config.getUntrackedParameter<bool>( "enableDQMTransitions" ) ),
888  dqm_event_ranges_( { config.getUntrackedParameter<double>( "dqmTimeRange" ), // ms
889  config.getUntrackedParameter<double>( "dqmTimeResolution" ), // ms
890  config.getUntrackedParameter<double>( "dqmMemoryRange" ), // kB
891  config.getUntrackedParameter<double>( "dqmMemoryResolution" ) } ), // kB
892  dqm_path_ranges_( { config.getUntrackedParameter<double>( "dqmPathTimeRange" ), // ms
893  config.getUntrackedParameter<double>( "dqmPathTimeResolution" ), // ms
894  config.getUntrackedParameter<double>( "dqmPathMemoryRange" ), // kB
895  config.getUntrackedParameter<double>( "dqmPathMemoryResolution" ) } ), // kB
896  dqm_module_ranges_( { config.getUntrackedParameter<double>( "dqmModuleTimeRange" ), // ms
897  config.getUntrackedParameter<double>( "dqmModuleTimeResolution" ), // ms
898  config.getUntrackedParameter<double>( "dqmModuleMemoryRange" ), // kB
899  config.getUntrackedParameter<double>( "dqmModuleMemoryResolution") } ), // kB
900  dqm_lumisections_range_( config.getUntrackedParameter<unsigned int>( "dqmLumiSectionsRange" ) ),
901  dqm_path_( config.getUntrackedParameter<std::string>("dqmPath" ) ),
902  // highlight configuration
903  highlight_module_psets_( config.getUntrackedParameter<std::vector<edm::ParameterSet>>("highlightModules") ),
904  highlight_modules_( highlight_module_psets_.size()) // filled in postBeginJob()
905 {
906  // start observing when a thread enters or leaves the TBB global thread arena
907  tbb::task_scheduler_observer::observe();
908 
909  // register EDM call backs
910  registry.watchPreallocate( this, & FastTimerService::preallocate );
911  registry.watchPreBeginJob( this, & FastTimerService::preBeginJob );
912  registry.watchPostBeginJob( this, & FastTimerService::postBeginJob );
913  registry.watchPostEndJob( this, & FastTimerService::postEndJob );
914  registry.watchPreGlobalBeginRun( this, & FastTimerService::preGlobalBeginRun );
915 //registry.watchPostGlobalBeginRun( this, & FastTimerService::postGlobalBeginRun );
916 //registry.watchPreGlobalEndRun( this, & FastTimerService::preGlobalEndRun );
917  registry.watchPostGlobalEndRun( this, & FastTimerService::postGlobalEndRun );
918  registry.watchPreStreamBeginRun( this, & FastTimerService::preStreamBeginRun );
919 //registry.watchPostStreamBeginRun( this, & FastTimerService::postStreamBeginRun );
920 //registry.watchPreStreamEndRun( this, & FastTimerService::preStreamEndRun );
921  registry.watchPostStreamEndRun( this, & FastTimerService::postStreamEndRun );
922  registry.watchPreGlobalBeginLumi( this, & FastTimerService::preGlobalBeginLumi );
923 //registry.watchPostGlobalBeginLumi( this, & FastTimerService::postGlobalBeginLumi );
924 //registry.watchPreGlobalEndLumi( this, & FastTimerService::preGlobalEndLumi );
925  registry.watchPostGlobalEndLumi( this, & FastTimerService::postGlobalEndLumi );
926  registry.watchPreStreamBeginLumi( this, & FastTimerService::preStreamBeginLumi );
927 //registry.watchPostStreamBeginLumi( this, & FastTimerService::postStreamBeginLumi );
928 //registry.watchPreStreamEndLumi( this, & FastTimerService::preStreamEndLumi );
929  registry.watchPostStreamEndLumi( this, & FastTimerService::postStreamEndLumi );
930  registry.watchPreEvent( this, & FastTimerService::preEvent );
931  registry.watchPostEvent( this, & FastTimerService::postEvent );
932  registry.watchPrePathEvent( this, & FastTimerService::prePathEvent );
933  registry.watchPostPathEvent( this, & FastTimerService::postPathEvent );
934  registry.watchPreSourceConstruction( this, & FastTimerService::preSourceConstruction);
935 //registry.watchPostSourceConstruction( this, & FastTimerService::postSourceConstruction);
936  registry.watchPreSourceRun( this, & FastTimerService::preSourceRun );
937  registry.watchPostSourceRun( this, & FastTimerService::postSourceRun );
938  registry.watchPreSourceLumi( this, & FastTimerService::preSourceLumi );
939  registry.watchPostSourceLumi( this, & FastTimerService::postSourceLumi );
940  registry.watchPreSourceEvent( this, & FastTimerService::preSourceEvent );
941  registry.watchPostSourceEvent( this, & FastTimerService::postSourceEvent );
942 //registry.watchPreModuleConstruction( this, & FastTimerService::preModuleConstruction);
943 //registry.watchPostModuleConstruction( this, & FastTimerService::postModuleConstruction);
944 //registry.watchPreModuleBeginJob( this, & FastTimerService::preModuleBeginJob );
945 //registry.watchPostModuleBeginJob( this, & FastTimerService::postModuleBeginJob );
946 //registry.watchPreModuleEndJob( this, & FastTimerService::preModuleEndJob );
947 //registry.watchPostModuleEndJob( this, & FastTimerService::postModuleEndJob );
948 //registry.watchPreModuleBeginStream( this, & FastTimerService::preModuleBeginStream );
949 //registry.watchPostModuleBeginStream( this, & FastTimerService::postModuleBeginStream );
950 //registry.watchPreModuleEndStream( this, & FastTimerService::preModuleEndStream );
951 //registry.watchPostModuleEndStream( this, & FastTimerService::postModuleEndStream );
952  registry.watchPreModuleGlobalBeginRun( this, & FastTimerService::preModuleGlobalBeginRun );
953  registry.watchPostModuleGlobalBeginRun( this, & FastTimerService::postModuleGlobalBeginRun );
954  registry.watchPreModuleGlobalEndRun( this, & FastTimerService::preModuleGlobalEndRun );
955  registry.watchPostModuleGlobalEndRun( this, & FastTimerService::postModuleGlobalEndRun );
956  registry.watchPreModuleGlobalBeginLumi( this, & FastTimerService::preModuleGlobalBeginLumi );
957  registry.watchPostModuleGlobalBeginLumi( this, & FastTimerService::postModuleGlobalBeginLumi );
958  registry.watchPreModuleGlobalEndLumi( this, & FastTimerService::preModuleGlobalEndLumi );
959  registry.watchPostModuleGlobalEndLumi( this, & FastTimerService::postModuleGlobalEndLumi );
960  registry.watchPreModuleStreamBeginRun( this, & FastTimerService::preModuleStreamBeginRun );
961  registry.watchPostModuleStreamBeginRun( this, & FastTimerService::postModuleStreamBeginRun );
962  registry.watchPreModuleStreamEndRun( this, & FastTimerService::preModuleStreamEndRun );
963  registry.watchPostModuleStreamEndRun( this, & FastTimerService::postModuleStreamEndRun );
964  registry.watchPreModuleStreamBeginLumi( this, & FastTimerService::preModuleStreamBeginLumi );
965  registry.watchPostModuleStreamBeginLumi( this, & FastTimerService::postModuleStreamBeginLumi );
966  registry.watchPreModuleStreamEndLumi( this, & FastTimerService::preModuleStreamEndLumi );
967  registry.watchPostModuleStreamEndLumi( this, & FastTimerService::postModuleStreamEndLumi );
968 //registry.watchPreModuleEventPrefetching( this, & FastTimerService::preModuleEventPrefetching );
969 //registry.watchPostModuleEventPrefetching( this, & FastTimerService::postModuleEventPrefetching );
970  registry.watchPreModuleEventAcquire( this, & FastTimerService::preModuleEventAcquire );
971  registry.watchPostModuleEventAcquire( this, & FastTimerService::postModuleEventAcquire );
972  registry.watchPreModuleEvent( this, & FastTimerService::preModuleEvent );
973  registry.watchPostModuleEvent( this, & FastTimerService::postModuleEvent );
974  registry.watchPreModuleEventDelayedGet( this, & FastTimerService::preModuleEventDelayedGet );
975  registry.watchPostModuleEventDelayedGet( this, & FastTimerService::postModuleEventDelayedGet );
976 //registry.watchPreEventReadFromSource( this, & FastTimerService::preEventReadFromSource );
977 //registry.watchPostEventReadFromSource( this, & FastTimerService::postEventReadFromSource );
978 }
979 
980 void
982 {
983  LogDebug("FastTimerService") << "The FastTimerService received is currently not monitoring the signal \"" << signal << "\".\n";
984 }
985 
986 void
988 {
989  // warn about each signal only once per job
990  if (unsupported_signals_.insert(signal).second)
991  edm::LogWarning("FastTimerService") << "The FastTimerService received the unsupported signal \"" << signal << "\".\n"
992  << "Please report how to reproduce the issue to cms-hlt@cern.ch .";
993 }
994 
995 void
997 {
998  ignoredSignal(__func__);
999 
1000  // reset the run counters only during the main process being run
1001  if (isFirstSubprocess(gc)) {
1002  auto index = gc.runIndex();
1004  run_transition_[index].reset();
1005  run_summary_[index].reset();
1006 
1007  // book the DQM plots
1008  if (enable_dqm_) {
1009  // define a callback to book the MonitorElements
1010  auto bookTransactionCallback = [&, this] (DQMStore::ConcurrentBooker & booker)
1011  {
1012  booker.setCurrentFolder(dqm_path_);
1013  plots_->book(booker, callgraph_,
1023  };
1024 
1025  // book MonitorElements for this stream
1026  edm::Service<DQMStore>()->bookConcurrentTransaction(bookTransactionCallback, gc.luminosityBlockID().run());
1027  }
1028  }
1029 }
1030 
1031 void
1033 {
1034  ignoredSignal(__func__);
1035 }
1036 
1037 void
1039 {
1040  ignoredSignal(__func__);
1041 }
1042 
1043 void
1045 {
1050 
1051  if (enable_dqm_bynproc_)
1052  dqm_path_ += (boost::format("/Running on %s with %d streams on %d threads") % processor_model % concurrent_streams_ % concurrent_threads_).str();
1053 
1054  // clean characters that are deemed unsafe for DQM
1055  // see the definition of `s_safe` in DQMServices/Core/src/DQMStore.cc
1056  auto safe_for_dqm = "/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+=_()# "s;
1057  for (auto & c: dqm_path_)
1058  if (safe_for_dqm.find(c) == std::string::npos)
1059  c = '_';
1060 
1061  // allocate atomic variables to keep track of the completion of each step, process by process
1062  subprocess_event_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_streams_);
1063  for (unsigned int i = 0; i < concurrent_streams_; ++i)
1065  subprocess_global_run_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_runs_);
1066  for (unsigned int i = 0; i < concurrent_runs_; ++i)
1068  subprocess_global_lumi_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_lumis_);
1069  for (unsigned int i = 0; i < concurrent_lumis_; ++i)
1071 
1072  // allocate buffers to keep track of the resources spent in the lumi and run transitions
1073  lumi_transition_.resize(concurrent_lumis_);
1074  run_transition_.resize(concurrent_runs_);
1075 }
1076 
1077 void
1080 }
1081 
1082 void
1084  callgraph_.preBeginJob(pathsAndConsumes, context);
1085 }
1086 
1087 void
1089  unsigned int modules = callgraph_.size();
1090 
1091  // module highlights
1092  for (unsigned int group: boost::irange(0ul, highlight_module_psets_.size())) {
1093  // copy and sort for faster search via std::binary_search
1094  auto labels = highlight_module_psets_[group].getUntrackedParameter<std::vector<std::string>>("modules");
1095  std::sort(labels.begin(), labels.end());
1096 
1097  highlight_modules_[group].label = highlight_module_psets_[group].getUntrackedParameter<std::string>("label");
1098  highlight_modules_[group].modules.reserve(labels.size());
1099  // convert the module labels in module ids
1100  for (unsigned int i = 0; i < modules; ++i) {
1101  auto const & label = callgraph_.module(i).moduleLabel();
1102  if (std::binary_search(labels.begin(), labels.end(), label))
1103  highlight_modules_[group].modules.push_back(i);
1104  }
1105  }
1106  highlight_module_psets_.clear();
1107 
1108  // allocate the resource counters for each stream, process, path and module
1110  streams_.resize(concurrent_streams_, temp);
1111  run_summary_.resize(concurrent_runs_, temp);
1112  job_summary_ = temp;
1113 
1114  // check that the DQMStore service is available
1115  if (enable_dqm_ and not edm::Service<DQMStore>().isAvailable()) {
1116  // the DQMStore is not available, disable all DQM plots
1117  enable_dqm_ = false;
1118  // FIXME issue a LogWarning ?
1119  }
1120 
1121  // allocate the structures to hold pointers to the DQM plots
1122  if (enable_dqm_) {
1123  plots_ = std::make_unique<PlotsPerJob>(callgraph_, highlight_modules_);
1124  }
1125 
1126 }
1127 
1128 void
1130 {
1131  ignoredSignal(__func__);
1132 }
1133 
1134 void
1136 {
1137  ignoredSignal(__func__);
1138 }
1139 
1140 void
1142 {
1143  ignoredSignal(__func__);
1144 }
1145 
1146 void
1148 {
1149  ignoredSignal(__func__);
1150 
1151  // reset the lumi counters only during the main process being run
1152  if (isFirstSubprocess(gc)) {
1153  auto index = gc.luminosityBlockIndex();
1155  lumi_transition_[index].reset();
1156  }
1157 }
1158 
1159 void
1161 {
1162  ignoredSignal(__func__);
1163 }
1164 
1165 void
1167 {
1168  ignoredSignal(__func__);
1169 }
1170 
1171 void
1173 {
1174  ignoredSignal(__func__);
1175 
1176  // handle the summaries only after the last subprocess has run
1177  auto index = gc.luminosityBlockIndex();
1179  if (not last)
1180  return;
1181 
1182  edm::LogVerbatim out("FastReport");
1183  auto const& label = (boost::format("run %d, lumisection %d") % gc.luminosityBlockID().run() % gc.luminosityBlockID().luminosityBlock()).str();
1184  printTransition(out, lumi_transition_[index], label);
1185 
1187  plots_->fill_lumi(lumi_transition_[index], gc.luminosityBlockID().luminosityBlock());
1188  }
1189 }
1190 
1191 void
1193 {
1194  ignoredSignal(__func__);
1195 }
1196 
1197 void
1199 {
1200  ignoredSignal(__func__);
1201 }
1202 
1203 void
1205 {
1206  ignoredSignal(__func__);
1207 }
1208 
1209 void
1211  ignoredSignal(__func__);
1212 }
1213 
1214 void
1216 {
1217  ignoredSignal(__func__);
1218 }
1219 
1220 void
1222 {
1223  ignoredSignal(__func__);
1224 
1225  // handle the summaries only after the last subprocess has run
1226  auto index = gc.runIndex();
1228  if (not last)
1229  return;
1230 
1231  edm::LogVerbatim out("FastReport");
1232  auto const& label = (boost::format("Run %d") % gc.luminosityBlockID().run()).str();
1233  if (print_run_summary_) {
1234  printSummary(out, run_summary_[index], label);
1235  }
1236  printTransition(out, run_transition_[index], label);
1237 
1239  plots_->fill_run(run_transition_[index]);
1240  }
1241 }
1242 
1243 void
1245 {
1247 }
1248 
1249 void
1251 {
1253 }
1254 
1255 void
1257 {
1259 }
1260 
1261 void
1263 {
1265 }
1266 
1267 void
1269 {
1270  if (print_job_summary_) {
1271  edm::LogVerbatim out("FastReport");
1272  printSummary(out, job_summary_, "Job");
1273  }
1274 }
1275 
1276 
1277 template <typename T>
1279 {
1280  out << "FastReport ";
1281  if (label.size() < 60)
1282  for (unsigned int i = (60-label.size()) / 2; i > 0; --i)
1283  out << '-';
1284  out << ' ' << label << " Summary ";
1285  if (label.size() < 60)
1286  for (unsigned int i = (59-label.size()) / 2; i > 0; --i)
1287  out << '-';
1288  out << '\n';
1289 }
1290 
1291 template <typename T>
1293 {
1294  out << "FastReport CPU time Real time Allocated Deallocated " << label << "\n";
1295  // FastReport ########.# ms ########.# ms +######### kB -######### kB ...
1296 }
1297 
1298 template <typename T>
1300 {
1301  out << boost::format("FastReport %10.1f ms %10.1f ms %+10d kB %+10d kB %s\n")
1302  % ms(data.time_thread)
1303  % ms(data.time_real)
1304  % +static_cast<int64_t>(kB(data.allocated))
1305  % -static_cast<int64_t>(kB(data.deallocated))
1306  % label;
1307 }
1308 
1309 template <typename T>
1311 {
1312  out << boost::format("FastReport %10.1f ms %10.1f ms %+10d kB %+10d kB %s\n")
1313  % ms(boost::chrono::nanoseconds(data.time_thread.load()))
1314  % ms(boost::chrono::nanoseconds(data.time_real.load()))
1315  % +static_cast<int64_t>(kB(data.allocated))
1316  % -static_cast<int64_t>(kB(data.deallocated))
1317  % label;
1318 }
1319 
1320 template <typename T>
1322 {
1323  printHeader(out, "Event");
1324  printEventHeader(out, "Modules");
1325  auto const& source_d = callgraph_.source();
1326  auto const& source = data.modules[source_d.id()];
1327  printEventLine(out, source.total, source_d.moduleLabel());
1328  for (unsigned int i = 0; i < callgraph_.processes().size(); ++i) {
1329  auto const& proc_d = callgraph_.processDescription(i);
1330  auto const& proc = data.processes[i];
1331  printEventLine(out, proc.total, "process " + proc_d.name_);
1332  for (unsigned int m: proc_d.modules_) {
1333  auto const& module_d = callgraph_.module(m);
1334  auto const& module = data.modules[m];
1335  printEventLine(out, module.total, " " + module_d.moduleLabel());
1336  }
1337  }
1338  printEventLine(out, data.total, "total");
1339  out << '\n';
1340  printEventHeader(out, "Processes and Paths");
1341  printEventLine(out, source.total, source_d.moduleLabel());
1342  for (unsigned int i = 0; i < callgraph_.processes().size(); ++i) {
1343  auto const& proc_d = callgraph_.processDescription(i);
1344  auto const& proc = data.processes[i];
1345  printEventLine(out, proc.total, "process " + proc_d.name_);
1346  for (unsigned int p = 0; p < proc.paths.size(); ++p) {
1347  auto const& name = proc_d.paths_[p].name_;
1348  auto const& path = proc.paths[p];
1349  printEventLine(out, path.active, name + " (only scheduled modules)");
1350  printEventLine(out, path.total, name + " (including dependencies)");
1351  }
1352  for (unsigned int p = 0; p < proc.endpaths.size(); ++p) {
1353  auto const& name = proc_d.endPaths_[p].name_;
1354  auto const& path = proc.endpaths[p];
1355  printEventLine(out, path.active, name + " (only scheduled modules)");
1356  printEventLine(out, path.total, name + " (including dependencies)");
1357  }
1358  }
1359  printEventLine(out, data.total, "total");
1360  out << '\n';
1361  for (unsigned int group: boost::irange(0ul, highlight_modules_.size())) {
1362  printEventHeader(out, "Highlighted modules");
1363  for (unsigned int m: highlight_modules_[group].modules) {
1364  auto const& module_d = callgraph_.module(m);
1365  auto const& module = data.modules[m];
1366  printEventLine(out, module.total, " " + module_d.moduleLabel());
1367  }
1369  out << '\n';
1370  }
1371 }
1372 
1373 template <typename T>
1374 void FastTimerService::printSummaryHeader(T& out, std::string const& label, bool detailed) const
1375 {
1376  if (detailed)
1377  out << "FastReport CPU time avg. when run Real time avg. when run Alloc. avg. when run Dealloc. avg. when run ";
1378  // FastReport ########.# ms ########.# ms ########.# ms ########.# ms +######### kB +######### kB -######### kB -######### kB ...
1379  else
1380  out << "FastReport CPU time avg. Real time avg. Alloc. avg. Dealloc. avg. ";
1381  // FastReport ########.# ms ########.# ms +######### kB -######### kB ...
1382  out << label << '\n';
1383 }
1384 
1385 template <typename T>
1387 {
1388  out << "FastReport CPU time sched. / depend. Real time sched. / depend. Alloc. sched. / depend. Dealloc. sched. / depend. ";
1389  // FastReport ########.# ms ########.# ms ########.# ms ########.# ms +######### kB +######### kB -######### kB -######### kB ...
1390  out << label << '\n';
1391 }
1392 
1393 template <typename T>
1395 {
1396  out << boost::format("FastReport %10.1f ms %10.1f ms %+10d kB %+10d kB %s\n")
1397  % (events ? ms(data.time_thread) / events : 0)
1398  % (events ? ms(data.time_real) / events : 0)
1399  % (events ? +static_cast<int64_t>(kB(data.allocated) / events) : 0)
1400  % (events ? -static_cast<int64_t>(kB(data.deallocated) / events) : 0)
1401  % label;
1402 }
1403 
1404 template <typename T>
1406 {
1407  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")
1408  % (events ? ms(data.time_thread) / events : 0) % (active ? ms(data.time_thread) / active : 0)
1409  % (events ? ms(data.time_real) / events : 0) % (active ? ms(data.time_real) / active : 0)
1410  % (events ? +static_cast<int64_t>(kB(data.allocated) / events) : 0) % (active ? +static_cast<int64_t>(kB(data.allocated) / active) : 0)
1411  % (events ? -static_cast<int64_t>(kB(data.deallocated) / events) : 0) % (active ? -static_cast<int64_t>(kB(data.deallocated) / active) : 0)
1412  % label;
1413 }
1414 
1415 template <typename T>
1417 {
1418  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")
1419  % (events ? ms(data.time_thread) / events : 0) % (events ? ms(total.time_thread) / events : 0)
1420  % (events ? ms(data.time_real) / events : 0) % (events ? ms(total.time_real) / events : 0)
1421  % (events ? +static_cast<int64_t>(kB(data.allocated) / events) : 0) % (events ? +static_cast<int64_t>(kB(total.allocated) / events) : 0)
1422  % (events ? -static_cast<int64_t>(kB(data.deallocated) / events) : 0) % (events ? -static_cast<int64_t>(kB(total.deallocated) / events) : 0)
1423  % label;
1424 }
1425 
1426 template <typename T>
1428 {
1429  printHeader(out, label);
1430  printSummaryHeader(out, "Modules", true);
1431  auto const& source_d = callgraph_.source();
1432  auto const& source = data.modules[source_d.id()];
1433  printSummaryLine(out, source.total, data.events, source.events, source_d.moduleLabel());
1434  for (unsigned int i = 0; i < callgraph_.processes().size(); ++i) {
1435  auto const& proc_d = callgraph_.processDescription(i);
1436  auto const& proc = data.processes[i];
1437  printSummaryLine(out, proc.total, data.events, "process " + proc_d.name_);
1438  for (unsigned int m: proc_d.modules_) {
1439  auto const& module_d = callgraph_.module(m);
1440  auto const& module = data.modules[m];
1441  printSummaryLine(out, module.total, data.events, module.events, " " + module_d.moduleLabel());
1442  }
1443  }
1444  printSummaryLine(out, data.total, data.events, "total");
1445  out << '\n';
1446  printPathSummaryHeader(out, "Processes and Paths");
1447  printSummaryLine(out, source.total, data.events, source_d.moduleLabel());
1448  for (unsigned int i = 0; i < callgraph_.processes().size(); ++i) {
1449  auto const& proc_d = callgraph_.processDescription(i);
1450  auto const& proc = data.processes[i];
1451  printSummaryLine(out, proc.total, data.events, "process " + proc_d.name_);
1452  for (unsigned int p = 0; p < proc.paths.size(); ++p) {
1453  auto const& name = proc_d.paths_[p].name_;
1454  auto const& path = proc.paths[p];
1455  printPathSummaryLine(out, path.active, path.total, data.events, " " + name);
1456  }
1457  for (unsigned int p = 0; p < proc.endpaths.size(); ++p) {
1458  auto const& name = proc_d.endPaths_[p].name_;
1459  auto const& path = proc.endpaths[p];
1460  printPathSummaryLine(out, path.active, path.total, data.events, " " + name);
1461  }
1462  }
1463  printSummaryLine(out, data.total, data.events, "total");
1464  out << '\n';
1465  for (unsigned int group: boost::irange(0ul, highlight_modules_.size())) {
1466  printSummaryHeader(out, "Highlighted modules", true);
1467  for (unsigned int m: highlight_modules_[group].modules) {
1468  auto const& module_d = callgraph_.module(m);
1469  auto const& module = data.modules[m];
1470  printSummaryLine(out, module.total, data.events, module.events, module_d.moduleLabel());
1471  }
1472  printSummaryLine(out, data.highlight[group], data.events, highlight_modules_[group].label);
1473  out << '\n';
1474  }
1475 }
1476 
1477 template <typename T>
1479 {
1480  printEventHeader(out, "Transition");
1481  printEventLine(out, data, label);
1482 }
1483 
1484 // check if this is the first process being signalled
1485 bool
1487 {
1488  return (not sc.processContext()->isSubProcess());
1489 }
1490 
1491 bool
1493 {
1494  return (not gc.processContext()->isSubProcess());
1495 }
1496 
1497 // check if this is the last process being signalled
1498 bool
1499 FastTimerService::isLastSubprocess(std::atomic<unsigned int>& check)
1500 {
1501  // release-acquire semantic guarantees that all writes in this and other threads are visible
1502  // after this operation; full sequentially-consistent ordering is (probably) not needed.
1503  unsigned int old_value = check.fetch_add(1, std::memory_order_acq_rel);
1504  return (old_value == callgraph_.processes().size() - 1);
1505 }
1506 
1507 void
1509 {
1510  ignoredSignal(__func__);
1511 }
1512 
1513 void
1515 {
1516  ignoredSignal(__func__);
1517 
1518  unsigned int pid = callgraph_.processId(* sc.processContext());
1519  unsigned int sid = sc.streamID();
1520  auto & stream = streams_[sid];
1521  auto & process = callgraph_.processDescription(pid);
1522 
1523  // measure the event resources as the sum of all modules' resources
1524  auto & data = stream.processes[pid].total;
1525  for (unsigned int i: process.modules_)
1526  data += stream.modules[i].total;
1527  stream.total += data;
1528 
1529  // handle the summaries and fill the plots only after the last subprocess has run
1531  if (not last)
1532  return;
1533 
1534  // measure the event resources explicitly
1535  stream.event_measurement.measure_and_store(stream.event);
1536 
1537  // highlighted modules
1538  for (unsigned int group: boost::irange(0ul, highlight_modules_.size()))
1539  for (unsigned int i: highlight_modules_[group].modules)
1540  stream.highlight[group] += stream.modules[i].total;
1541 
1542  // avoid concurrent access to the summary objects
1543  {
1544  std::lock_guard<std::mutex> guard(summary_mutex_);
1545  job_summary_ += stream;
1546  run_summary_[sc.runIndex()] += stream;
1547  }
1548 
1549  if (print_event_summary_) {
1550  edm::LogVerbatim out("FastReport");
1551  printEvent(out, stream);
1552  }
1553 
1554  if (enable_dqm_) {
1555  plots_->fill(callgraph_, stream, sc.eventID().luminosityBlock());
1556  }
1557 }
1558 
1559 void
1561 {
1562  // clear the event counters
1563  auto & stream = streams_[sid];
1564  stream.reset();
1565  ++stream.events;
1566 
1567  subprocess_event_check_[sid] = 0;
1568 
1569  // reuse the same measurement for the Source module and for the explicit begin of the Event
1570  auto & measurement = thread();
1571  measurement.measure_and_accumulate(stream.overhead);
1572  stream.event_measurement = measurement;
1573 }
1574 
1575 void
1577 {
1579  unsigned int id = md.id();
1580  auto & stream = streams_[sid];
1581 
1582  thread().measure_and_store(stream.modules[id].total);
1583  ++stream.modules[id].events;
1584 }
1585 
1586 void
1588 {
1589  unsigned int sid = sc.streamID().value();
1590  unsigned int pid = callgraph_.processId(* sc.processContext());
1591  unsigned int id = pc.pathID();
1592  auto & stream = streams_[sid];
1593  auto & data = pc.isEndPath() ? stream.processes[pid].endpaths[id] : stream.processes[pid].paths[id];
1594  data.status = false;
1595  data.last = 0;
1596 }
1597 
1598 void
1600 {
1601  unsigned int sid = sc.streamID().value();
1602  unsigned int pid = callgraph_.processId(* sc.processContext());
1603  unsigned int id = pc.pathID();
1604  auto & stream = streams_[sid];
1605  auto & data = pc.isEndPath() ? stream.processes[pid].endpaths[id] : stream.processes[pid].paths[id];
1606 
1608  unsigned int index = path.modules_on_path_.empty() ? 0 : status.index() + 1;
1609  data.last = path.modules_on_path_.empty() ? 0 : path.last_dependency_of_module_[status.index()];
1610 
1611  for (unsigned int i = 0; i < index; ++i) {
1612  auto const& module = stream.modules[path.modules_on_path_[i]];
1613  data.active += module.total;
1614  }
1615  for (unsigned int i = 0; i < data.last; ++i) {
1616  auto const& module = stream.modules[path.modules_and_dependencies_[i]];
1617  data.total += module.total;
1618  }
1619 }
1620 
1621 void
1623 {
1624  unsigned int sid = sc.streamID().value();
1625  auto & stream = streams_[sid];
1626  thread().measure_and_accumulate(stream.overhead);
1627 }
1628 
1629 void
1631 {
1632  edm::ModuleDescription const& md = * mcc.moduleDescription();
1633  unsigned int id = md.id();
1634  unsigned int sid = sc.streamID().value();
1635  auto & stream = streams_[sid];
1636  auto & module = stream.modules[id];
1637 
1638  module.has_acquire = true;
1639  thread().measure_and_store(module.total);
1640 }
1641 
1642 void
1644 {
1645  unsigned int sid = sc.streamID().value();
1646  auto & stream = streams_[sid];
1647  thread().measure_and_accumulate(stream.overhead);
1648 }
1649 
1650 void
1652 {
1653  edm::ModuleDescription const& md = * mcc.moduleDescription();
1654  unsigned int id = md.id();
1655  unsigned int sid = sc.streamID().value();
1656  auto & stream = streams_[sid];
1657  auto & module = stream.modules[id];
1658 
1659  if (module.has_acquire) {
1661  } else {
1662  thread().measure_and_store(module.total);
1663  }
1664  ++module.events;
1665 }
1666 
1667 void
1669 {
1670  unsupportedSignal(__func__);
1671 }
1672 
1673 void
1675 {
1676  unsupportedSignal(__func__);
1677 }
1678 
1679 void
1681 {
1682  ignoredSignal(__func__);
1683 }
1684 
1685 void
1687 {
1688  ignoredSignal(__func__);
1689 }
1690 
1691 void
1693 {
1694  ignoredSignal(__func__);
1695 }
1696 
1697 void
1699 {
1700  ignoredSignal(__func__);
1701 }
1702 
1703 void
1705 {
1707 }
1708 
1709 void
1711 {
1712  auto index = gc.runIndex();
1714 }
1715 
1716 void
1718 {
1720 }
1721 
1722 void
1724 {
1725  auto index = gc.runIndex();
1727 }
1728 
1729 void
1731 {
1733 }
1734 
1735 void
1737 {
1738  auto index = gc.luminosityBlockIndex();
1740 }
1741 
1742 void
1744 {
1746 }
1747 
1748 void
1750 {
1751  auto index = gc.luminosityBlockIndex();
1753 }
1754 
1755 void
1757 {
1759 }
1760 
1761 void
1763 {
1764  auto index = sc.runIndex();
1766 }
1767 
1768 void
1770 {
1772 }
1773 
1774 void
1776 {
1777  auto index = sc.runIndex();
1779 }
1780 
1781 void
1783 {
1785 }
1786 
1787 void
1789 {
1790  auto index = sc.luminosityBlockIndex();
1792 }
1793 
1794 void
1796 {
1798 }
1799 
1800 void
1802 {
1803  auto index = sc.luminosityBlockIndex();
1805 }
1806 
1807 void
1809 {
1810  // initialise the measurement point for a thread that has newly joining the TBB pool
1811  thread().measure();
1812 }
1813 
1814 void
1816 {
1817  // account any resources used or freed by the thread before leaving the TBB pool
1819 }
1820 
1823 {
1824  return threads_.local();
1825 }
1826 
1827 
1828 // describe the module's configuration
1829 void
1831 {
1833  desc.addUntracked<bool>( "printEventSummary", false);
1834  desc.addUntracked<bool>( "printRunSummary", true);
1835  desc.addUntracked<bool>( "printJobSummary", true);
1836  desc.addUntracked<bool>( "enableDQM", true);
1837  desc.addUntracked<bool>( "enableDQMbyModule", false);
1838  desc.addUntracked<bool>( "enableDQMbyPath", false);
1839  desc.addUntracked<bool>( "enableDQMbyLumiSection", false);
1840  desc.addUntracked<bool>( "enableDQMbyProcesses", false);
1841  desc.addUntracked<bool>( "enableDQMTransitions", false);
1842  desc.addUntracked<double>( "dqmTimeRange", 1000. ); // ms
1843  desc.addUntracked<double>( "dqmTimeResolution", 5. ); // ms
1844  desc.addUntracked<double>( "dqmMemoryRange", 1000000. ); // kB
1845  desc.addUntracked<double>( "dqmMemoryResolution", 5000. ); // kB
1846  desc.addUntracked<double>( "dqmPathTimeRange", 100. ); // ms
1847  desc.addUntracked<double>( "dqmPathTimeResolution", 0.5); // ms
1848  desc.addUntracked<double>( "dqmPathMemoryRange", 1000000. ); // kB
1849  desc.addUntracked<double>( "dqmPathMemoryResolution", 5000. ); // kB
1850  desc.addUntracked<double>( "dqmModuleTimeRange", 40. ); // ms
1851  desc.addUntracked<double>( "dqmModuleTimeResolution", 0.2); // ms
1852  desc.addUntracked<double>( "dqmModuleMemoryRange", 100000. ); // kB
1853  desc.addUntracked<double>( "dqmModuleMemoryResolution", 500. ); // kB
1854  desc.addUntracked<unsigned>( "dqmLumiSectionsRange", 2500 ); // ~ 16 hours
1855  desc.addUntracked<std::string>( "dqmPath", "HLT/TimerService");
1856 
1857  edm::ParameterSetDescription highlightModulesDescription;
1858  highlightModulesDescription.addUntracked<std::vector<std::string>>("modules", {});
1859  highlightModulesDescription.addUntracked<std::string>("label", "producers");
1860  desc.addVPSetUntracked("highlightModules", highlightModulesDescription, {});
1861 
1862  // # OBSOLETE - these parameters are ignored, they are left only not to break old configurations
1863  // they will not be printed in the generated cfi.py file
1864  desc.addOptionalNode(edm::ParameterDescription<bool>("useRealTimeClock", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1865  desc.addOptionalNode(edm::ParameterDescription<bool>("enableTimingPaths", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1866  desc.addOptionalNode(edm::ParameterDescription<bool>("enableTimingModules", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1867  desc.addOptionalNode(edm::ParameterDescription<bool>("enableTimingExclusive", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1868  desc.addOptionalNode(edm::ParameterDescription<bool>("enableTimingSummary", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1869  desc.addOptionalNode(edm::ParameterDescription<bool>("skipFirstPath", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1870  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathActive", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1871  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathTotal", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1872  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathOverhead", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1873  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathDetails", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1874  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathCounters", true, false), false)->setComment("This parameter is obsolete and will be ignored.");
1875  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyPathExclusive", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1876  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMbyModuleType", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1877  desc.addOptionalNode(edm::ParameterDescription<bool>("enableDQMSummary", false, false), false)->setComment("This parameter is obsolete and will be ignored.");
1878 
1879  descriptions.add("FastTimerService", desc);
1880 }
1881 
1882 
1883 // declare FastTimerService as a framework Service
#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 &)
LuminosityBlockIndex const & luminosityBlockIndex() const
Definition: StreamContext.h:65
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 preSourceLumi(edm::LuminosityBlockIndex)
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
const PlotRanges dqm_event_ranges_
void postModuleGlobalEndRun(edm::GlobalContext const &, edm::ModuleCallingContext const &)
void preSourceRun(edm::RunIndex)
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
LuminosityBlockID const & luminosityBlockID() const
Definition: GlobalContext.h:57
AtomicResources overhead_
bool isFirstSubprocess(edm::StreamContext const &)
const bool enable_dqm_bynproc_
unsigned int concurrent_runs_
boost::chrono::nanoseconds time_real
#define noexcept
std::atomic< uint64_t > deallocated
std::unique_ptr< std::atomic< unsigned int >[]> subprocess_global_run_check_
void postSourceRun(edm::RunIndex)
std::vector< ResourcesPerJob > streams_
std::atomic< uint64_t > allocated
RunIndex const & runIndex() const
Definition: StreamContext.h:64
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:58
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)
void prePathEvent(edm::StreamContext const &, edm::PathContext const &)
LuminosityBlockIndex const & luminosityBlockIndex() const
Definition: GlobalContext.h:59
std::vector< ResourcesPerJob > run_summary_
void printEventHeader(T &out, std::string const &label) const
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
static void 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:67
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
#define DEFINE_FWK_SERVICE(type)
Definition: ServiceMaker.h:113
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 postModuleEventAcquire(edm::StreamContext const &, edm::ModuleCallingContext const &)
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:274
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 &)
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:282
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:61
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
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 preModuleEventAcquire(edm::StreamContext const &, edm::ModuleCallingContext 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:63
void postSourceLumi(edm::LuminosityBlockIndex)
void postModuleGlobalBeginRun(edm::GlobalContext const &, edm::ModuleCallingContext const &)
std::vector< ResourcesPerProcess > processes
static Interceptor::Registry registry("Interceptor")
boost::date_time::subsecond_duration< boost::posix_time::time_duration, 1000000000 > nanoseconds
AtomicResources & operator=(AtomicResources const &other)
def check(config)
Definition: trackerTree.py:14
#define str(s)
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)
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 measure_and_accumulate(Resources &store)
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