10 #include <unordered_map>
11 #include <unordered_set>
14 #include <boost/range/irange.hpp>
17 #include <fmt/printf.h>
20 #include <nlohmann/json.hpp>
43 using namespace std::literals;
50 template <
class Rep,
class Period>
51 double ms(std::chrono::duration<Rep, Period> duration) {
52 return std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(duration).
count();
56 template <
class Rep,
class Period>
57 double ms(boost::chrono::duration<Rep, Period> duration) {
58 return boost::chrono::duration_cast<boost::chrono::duration<double, boost::milli>>(duration).
count();
62 double ms(std::atomic<boost::chrono::nanoseconds::rep>
const& duration) {
63 return boost::chrono::duration_cast<boost::chrono::duration<double, boost::milli>>(
72 uint64_t kB(std::atomic<uint64_t>
const& bytes) {
return bytes.load() / 1024; }
96 time_thread +=
other.time_thread;
97 time_real +=
other.time_real;
98 allocated +=
other.allocated;
99 deallocated +=
other.deallocated;
106 allocated +=
other.allocated.load();
107 deallocated +=
other.deallocated.load();
129 : time_thread(0ul), time_real(0ul), allocated(0ul), deallocated(0ul) {}
145 time_thread =
other.time_thread.load();
146 time_real =
other.time_real.load();
147 allocated =
other.allocated.load();
148 deallocated =
other.deallocated.load();
153 time_thread +=
other.time_thread.load();
154 time_real +=
other.time_real.load();
155 allocated +=
other.allocated.load();
156 deallocated +=
other.deallocated.load();
161 time_thread +=
other.time_thread.count();
162 time_real +=
other.time_real.count();
163 allocated +=
other.allocated;
164 deallocated +=
other.deallocated;
175 return other + *
this;
191 has_acquire = has_acquire
or other.has_acquire;
212 active +=
other.active;
234 for (
auto&
path : endpaths)
242 for (
unsigned int i : boost::irange(0ul,
paths.size()))
245 for (
unsigned int i : boost::irange(0ul, endpaths.size()))
246 endpaths[
i] +=
other.endpaths[
i];
260 std::vector<GroupOfModules>
const& groups)
271 for (
auto&
module : highlight)
282 overhead +=
other.overhead;
283 event +=
other.event;
284 assert(highlight.size() ==
other.highlight.size());
285 for (
unsigned int i : boost::irange(0ul, highlight.size()))
286 highlight[
i] +=
other.highlight[
i];
288 for (
unsigned int i : boost::irange(0ul,
modules.size()))
291 for (
unsigned int i : boost::irange(0ul,
processes.size()))
310 #ifdef DEBUG_THREAD_CONCURRENCY
311 id = std::this_thread::get_id();
312 #endif // DEBUG_THREAD_CONCURRENCY
320 #ifdef DEBUG_THREAD_CONCURRENCY
321 assert(std::this_thread::get_id() ==
id);
322 #endif // DEBUG_THREAD_CONCURRENCY
327 store.time_thread = new_time_thread - time_thread;
328 store.time_real = new_time_real - time_real;
329 store.allocated = new_allocated - allocated;
330 store.deallocated = new_deallocated - deallocated;
331 time_thread = new_time_thread;
332 time_real = new_time_real;
333 allocated = new_allocated;
334 deallocated = new_deallocated;
338 #ifdef DEBUG_THREAD_CONCURRENCY
339 assert(std::this_thread::get_id() ==
id);
340 #endif // DEBUG_THREAD_CONCURRENCY
345 store.time_thread += new_time_thread - time_thread;
346 store.time_real += new_time_real - time_real;
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;
356 #ifdef DEBUG_THREAD_CONCURRENCY
357 assert(std::this_thread::get_id() ==
id);
358 #endif // DEBUG_THREAD_CONCURRENCY
363 store.time_thread += boost::chrono::duration_cast<boost::chrono::nanoseconds>(new_time_thread - time_thread).count();
364 store.time_real += boost::chrono::duration_cast<boost::chrono::nanoseconds>(new_time_real - time_real).count();
365 store.allocated += new_allocated - allocated;
366 store.deallocated += new_deallocated - deallocated;
367 time_thread = new_time_thread;
368 time_real = new_time_real;
369 allocated = new_allocated;
370 deallocated = new_deallocated;
379 unsigned int lumisections,
383 std::string y_title_ms = fmt::sprintf(
"events / %.1f ms",
ranges.time_resolution);
384 std::string y_title_kB = fmt::sprintf(
"events / %.1f kB",
ranges.memory_resolution);
388 booker.
book1D(
name +
" time_thread",
title +
" processing time (cpu)", time_bins, 0.,
ranges.time_range);
389 time_thread_->
setXTitle(
"processing time [ms]");
390 time_thread_->setYTitle(y_title_ms);
391 time_thread_->setStatOverflows(kTRUE);
393 time_real_ = booker.
book1D(
name +
" time_real",
title +
" processing time (real)", time_bins, 0.,
ranges.time_range);
394 time_real_->
setXTitle(
"processing time [ms]");
395 time_real_->setYTitle(y_title_ms);
396 time_real_->setStatOverflows(kTRUE);
399 allocated_ = booker.
book1D(
name +
" allocated",
title +
" allocated memory", mem_bins, 0.,
ranges.memory_range);
401 allocated_->setYTitle(y_title_kB);
402 allocated_->setStatOverflows(kTRUE);
405 booker.
book1D(
name +
" deallocated",
title +
" deallocated memory", mem_bins, 0.,
ranges.memory_range);
407 deallocated_->setYTitle(y_title_kB);
408 deallocated_->setStatOverflows(kTRUE);
415 title +
" processing time (cpu) vs. lumisection",
423 time_thread_byls_->
setXTitle(
"lumisection");
424 time_thread_byls_->setYTitle(
"processing time [ms]");
425 time_thread_byls_->setStatOverflows(kTRUE);
428 title +
" processing time (real) vs. lumisection",
436 time_real_byls_->
setXTitle(
"lumisection");
437 time_real_byls_->setYTitle(
"processing time [ms]");
438 time_real_byls_->setStatOverflows(kTRUE);
442 title +
" allocated memory vs. lumisection",
450 allocated_byls_->
setXTitle(
"lumisection");
451 allocated_byls_->setYTitle(
"memory [kB]");
452 allocated_byls_->setStatOverflows(kTRUE);
455 title +
" deallocated memory vs. lumisection",
463 deallocated_byls_->
setXTitle(
"lumisection");
464 deallocated_byls_->setYTitle(
"memory [kB]");
465 deallocated_byls_->setStatOverflows(kTRUE);
471 time_thread_->Fill(ms(
data.time_thread));
473 if (time_thread_byls_)
474 time_thread_byls_->Fill(lumisection, ms(
data.time_thread));
477 time_real_->Fill(ms(
data.time_real));
480 time_real_byls_->Fill(lumisection, ms(
data.time_real));
483 allocated_->Fill(kB(
data.allocated));
486 allocated_byls_->Fill(lumisection, kB(
data.allocated));
489 deallocated_->Fill(kB(
data.deallocated));
491 if (deallocated_byls_)
492 deallocated_byls_->Fill(lumisection, kB(
data.deallocated));
499 if (time_thread_byls_)
509 allocated_->Fill(kB(
data.allocated));
512 allocated_byls_->Fill(lumisection, kB(
data.allocated));
515 deallocated_->Fill(kB(
data.deallocated));
517 if (deallocated_byls_)
518 deallocated_byls_->Fill(lumisection, kB(
data.deallocated));
523 unsigned int lumisection) {
532 if (time_thread_byls_)
556 if (deallocated_byls_)
565 unsigned int lumisections,
570 total_.book(booker,
"path",
path.name_,
ranges, lumisections, byls);
573 unsigned int bins =
path.modules_and_dependencies_.size();
574 module_counter_ = booker.
book1DD(
"module_counter",
"module counter",
bins + 1, -0.5,
bins + 0.5);
576 module_counter_->setStatOverflows(kTRUE);
577 module_time_thread_total_ =
578 booker.
book1DD(
"module_time_thread_total",
"total module time (cpu)",
bins, -0.5,
bins - 0.5);
579 module_time_thread_total_->
setYTitle(
"processing time [ms]");
580 module_time_thread_total_->setStatOverflows(kTRUE);
581 module_time_real_total_ =
582 booker.
book1DD(
"module_time_real_total",
"total module time (real)",
bins, -0.5,
bins - 0.5);
583 module_time_real_total_->
setYTitle(
"processing time [ms]");
584 module_time_real_total_->setStatOverflows(kTRUE);
586 module_allocated_total_ =
587 booker.
book1DD(
"module_allocated_total",
"total allocated memory",
bins, -0.5,
bins - 0.5);
588 module_allocated_total_->
setYTitle(
"memory [kB]");
589 module_allocated_total_->setStatOverflows(kTRUE);
590 module_deallocated_total_ =
591 booker.
book1DD(
"module_deallocated_total",
"total deallocated memory",
bins, -0.5,
bins - 0.5);
592 module_deallocated_total_->
setYTitle(
"memory [kB]");
593 module_deallocated_total_->setStatOverflows(kTRUE);
595 for (
unsigned int bin : boost::irange(0u,
bins)) {
596 auto const&
module = job[
path.modules_and_dependencies_[
bin]];
598 module.scheduled_ ?
module.module_.moduleLabel() :
module.module_.moduleLabel() +
" (unscheduled)";
599 module_counter_->setBinLabel(
bin + 1,
label);
600 module_time_thread_total_->setBinLabel(
bin + 1,
label);
601 module_time_real_total_->setBinLabel(
bin + 1,
label);
603 module_allocated_total_->setBinLabel(
bin + 1,
label);
604 module_deallocated_total_->setBinLabel(
bin + 1,
label);
607 module_counter_->setBinLabel(
bins + 1,
"");
617 total_.fill(
path.total,
ls);
620 for (
unsigned int i = 0;
i <
path.last; ++
i) {
623 module_counter_->Fill(
i);
625 if (module_time_thread_total_)
626 module_time_thread_total_->Fill(
i, ms(
module.total.time_thread));
628 if (module_time_real_total_)
629 module_time_real_total_->Fill(
i, ms(
module.total.time_real));
631 if (module_allocated_total_)
632 module_allocated_total_->Fill(
i, kB(
module.total.allocated));
634 if (module_deallocated_total_)
635 module_deallocated_total_->Fill(
i, kB(
module.total.deallocated));
637 if (module_counter_ and
path.status)
638 module_counter_->Fill(
path.last);
649 unsigned int lumisections,
653 event_.book(booker,
"process " +
process.name_,
"process " +
process.name_, event_ranges, lumisections, byls);
656 for (
unsigned int id : boost::irange(0ul, paths_.size())) {
657 paths_[
id].book(booker,
"path ", job,
process.paths_[
id], path_ranges, lumisections, byls);
659 for (
unsigned int id : boost::irange(0ul, endpaths_.size())) {
660 endpaths_[
id].book(booker,
"endpath ", job,
process.endPaths_[
id], path_ranges, lumisections, byls);
674 for (
unsigned int id : boost::irange(0ul, paths_.size()))
678 for (
unsigned int id : boost::irange(0ul, endpaths_.size()))
691 std::vector<GroupOfModules>
const& groups,
695 unsigned int lumisections,
703 event_.book(booker,
"event",
"Event", event_ranges, lumisections, byls);
705 event_ex_.book(booker,
"explicit",
"Event (explicit)", event_ranges, lumisections, byls);
707 overhead_.book(booker,
"overhead",
"Overhead", event_ranges, lumisections, byls);
709 modules_[job.
source().
id()].book(booker,
"source",
"Source", module_ranges, lumisections, byls);
712 lumi_.book(booker,
"lumi",
"LumiSection transitions", event_ranges, lumisections, byls);
714 run_.book(booker,
"run",
"Run transtions", event_ranges, lumisections,
false);
718 for (
unsigned int group : boost::irange(0ul, groups.size())) {
720 highlight_[
group].book(booker,
"highlight " +
label,
"Highlight " +
label, event_ranges, lumisections, byls);
724 for (
unsigned int pid : boost::irange(0ul, job.
processes().size())) {
726 processes_[pid].book(booker, job,
process, event_ranges, path_ranges, lumisections, bypath, byls);
730 for (
unsigned int id :
process.modules_) {
742 event_ex_.fill(
data.event,
ls);
746 for (
unsigned int group : boost::irange(0ul, highlight_.size()))
750 for (
unsigned int id : boost::irange(0ul, modules_.size()))
751 modules_[
id].fill(
data.modules[
id].total,
ls);
753 for (
unsigned int pid : boost::irange(0ul, processes_.size()))
794 config.getUntrackedParameter<
double>(
"dqmTimeResolution"),
795 config.getUntrackedParameter<
double>(
"dqmMemoryRange"),
796 config.getUntrackedParameter<
double>(
"dqmMemoryResolution")}),
797 dqm_path_ranges_({
config.getUntrackedParameter<
double>(
"dqmPathTimeRange"),
798 config.getUntrackedParameter<
double>(
"dqmPathTimeResolution"),
799 config.getUntrackedParameter<
double>(
"dqmPathMemoryRange"),
800 config.getUntrackedParameter<
double>(
"dqmPathMemoryResolution")}),
801 dqm_module_ranges_({
config.getUntrackedParameter<
double>(
"dqmModuleTimeRange"),
802 config.getUntrackedParameter<
double>(
"dqmModuleTimeResolution"),
803 config.getUntrackedParameter<
double>(
"dqmModuleMemoryRange"),
804 config.getUntrackedParameter<
double>(
"dqmModuleMemoryResolution")}),
805 dqm_lumisections_range_(
config.getUntrackedParameter<
unsigned int>(
"dqmLumiSectionsRange")),
808 highlight_module_psets_(
config.getUntrackedParameter<std::vector<edm::ParameterSet>>(
"highlightModules")),
809 highlight_modules_(highlight_module_psets_.size())
812 tbb::task_scheduler_observer::observe();
886 LogDebug(
"FastTimerService") <<
"The FastTimerService received is currently not monitoring the signal \"" << signal
892 if (unsupported_signals_.insert(signal).second)
893 edm::LogWarning(
"FastTimerService") <<
"The FastTimerService received the unsupported signal \"" << signal
895 <<
"Please report how to reproduce the issue to cms-hlt@cern.ch .";
899 ignoredSignal(__func__);
902 if (isFirstSubprocess(gc)) {
904 subprocess_global_run_check_[
index] = 0;
905 run_transition_[
index].reset();
906 run_summary_[
index].reset();
923 dqm_lumisections_range_,
924 enable_dqm_bymodule_,
927 enable_dqm_transitions_);
946 if (enable_dqm_bynproc_)
947 dqm_path_ += fmt::sprintf(
948 "/Running on %s with %d streams on %d threads",
processor_model, concurrent_streams_, concurrent_threads_);
952 auto safe_for_dqm =
"/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+=_()# "s;
953 for (
auto&
c : dqm_path_)
954 if (safe_for_dqm.find(
c) == std::string::npos)
958 subprocess_event_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_streams_);
959 for (
unsigned int i = 0;
i < concurrent_streams_; ++
i)
960 subprocess_event_check_[
i] = 0;
961 subprocess_global_run_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_runs_);
962 for (
unsigned int i = 0;
i < concurrent_runs_; ++
i)
963 subprocess_global_run_check_[
i] = 0;
964 subprocess_global_lumi_check_ = std::make_unique<std::atomic<unsigned int>[]>(concurrent_lumis_);
965 for (
unsigned int i = 0;
i < concurrent_lumis_; ++
i)
966 subprocess_global_lumi_check_[
i] = 0;
969 lumi_transition_.resize(concurrent_lumis_);
970 run_transition_.resize(concurrent_runs_);
974 callgraph_.preSourceConstruction(
module);
979 callgraph_.preBeginJob(pathsAndConsumes,
context);
983 unsigned int modules = callgraph_.size();
986 for (
unsigned int group : boost::irange(0ul, highlight_module_psets_.size())) {
988 auto labels = highlight_module_psets_[
group].getUntrackedParameter<std::vector<std::string>>(
"modules");
991 highlight_modules_[
group].label = highlight_module_psets_[
group].getUntrackedParameter<
std::string>(
"label");
992 highlight_modules_[
group].modules.reserve(
labels.size());
995 auto const&
label = callgraph_.module(
i).moduleLabel();
997 highlight_modules_[
group].modules.push_back(
i);
1000 highlight_module_psets_.clear();
1004 streams_.resize(concurrent_streams_,
temp);
1005 run_summary_.resize(concurrent_runs_,
temp);
1006 job_summary_ =
temp;
1011 enable_dqm_ =
false;
1012 edm::LogWarning(
"FastTimerService") <<
"The DQMStore is not avalable, the DQM plots will not be generated";
1017 plots_ = std::make_unique<PlotsPerJob>(callgraph_, highlight_modules_);
1028 ignoredSignal(__func__);
1031 if (isFirstSubprocess(gc)) {
1033 subprocess_global_lumi_check_[
index] = 0;
1034 lumi_transition_[
index].reset();
1043 ignoredSignal(__func__);
1047 bool last = isLastSubprocess(subprocess_global_lumi_check_[
index]);
1056 if (enable_dqm_transitions_) {
1072 ignoredSignal(__func__);
1076 bool last = isLastSubprocess(subprocess_global_run_check_[
index]);
1082 if (print_run_summary_) {
1087 if (enable_dqm_transitions_) {
1088 plots_->fill_run(run_transition_[
index]);
1099 thread().measure_and_accumulate(lumi_transition_[
index]);
1104 tbb::task_scheduler_observer::observe(
false);
1106 if (print_job_summary_) {
1110 if (write_json_summary_) {
1111 writeSummaryJSON(job_summary_, json_filename_);
1115 template <
typename T>
1117 out <<
"FastReport ";
1118 if (
label.size() < 60)
1119 for (
unsigned int i = (60 -
label.size()) / 2;
i > 0; --
i)
1121 out <<
' ' <<
label <<
" Summary ";
1122 if (
label.size() < 60)
1123 for (
unsigned int i = (59 -
label.size()) / 2;
i > 0; --
i)
1128 template <
typename T>
1130 out <<
"FastReport CPU time Real time Allocated Deallocated " <<
label <<
"\n";
1134 template <
typename T>
1136 out << fmt::sprintf(
"FastReport %10.1f ms %10.1f ms %+10d kB %+10d kB %s\n",
1137 ms(
data.time_thread),
1139 +static_cast<int64_t>(kB(
data.allocated)),
1140 -static_cast<int64_t>(kB(
data.deallocated)),
1144 template <
typename T>
1146 out << fmt::sprintf(
"FastReport %10.1f ms %10.1f ms %+10d kB %+10d kB %s\n",
1149 +static_cast<int64_t>(kB(
data.allocated)),
1150 -static_cast<int64_t>(kB(
data.deallocated)),
1154 template <
typename T>
1156 printHeader(
out,
"Event");
1157 printEventHeader(
out,
"Modules");
1158 auto const& source_d = callgraph_.source();
1159 auto const&
source =
data.modules[source_d.id()];
1160 printEventLine(
out,
source.total, source_d.moduleLabel());
1161 for (
unsigned int i = 0;
i < callgraph_.processes().size(); ++
i) {
1162 auto const& proc_d = callgraph_.processDescription(
i);
1164 printEventLine(
out,
proc.total,
"process " + proc_d.name_);
1165 for (
unsigned int m : proc_d.modules_) {
1166 auto const& module_d = callgraph_.module(
m);
1168 printEventLine(
out,
module.total,
" " + module_d.moduleLabel());
1171 printEventLine(
out,
data.total,
"total");
1173 printEventHeader(
out,
"Processes and Paths");
1174 printEventLine(
out,
source.total, source_d.moduleLabel());
1175 for (
unsigned int i = 0;
i < callgraph_.processes().size(); ++
i) {
1176 auto const& proc_d = callgraph_.processDescription(
i);
1178 printEventLine(
out,
proc.total,
"process " + proc_d.name_);
1179 for (
unsigned int p = 0;
p <
proc.paths.size(); ++
p) {
1180 auto const&
name = proc_d.paths_[
p].name_;
1182 printEventLine(
out,
path.active,
name +
" (only scheduled modules)");
1183 printEventLine(
out,
path.total,
name +
" (including dependencies)");
1185 for (
unsigned int p = 0;
p <
proc.endpaths.size(); ++
p) {
1186 auto const&
name = proc_d.endPaths_[
p].name_;
1188 printEventLine(
out,
path.active,
name +
" (only scheduled modules)");
1189 printEventLine(
out,
path.total,
name +
" (including dependencies)");
1192 printEventLine(
out,
data.total,
"total");
1194 for (
unsigned int group : boost::irange(0ul, highlight_modules_.size())) {
1195 printEventHeader(
out,
"Highlighted modules");
1197 auto const& module_d = callgraph_.module(
m);
1199 printEventLine(
out,
module.total,
" " + module_d.moduleLabel());
1206 template <
typename T>
1210 out <<
"FastReport CPU time avg. when run Real time avg. when run Alloc. avg. when run Dealloc. avg. when run ";
1213 out <<
"FastReport CPU time avg. Real time avg. Alloc. avg. Dealloc. avg. ";
1219 template <
typename T>
1222 out <<
"FastReport CPU time sched. / depend. Real time sched. / depend. Alloc. sched. / depend. Dealloc. sched. / depend. ";
1228 template <
typename T>
1230 out << fmt::sprintf(
1232 "FastReport %10.1f ms %10.1f ms %+10d kB %+10d kB %s\n",
1241 template <
typename T>
1244 out << fmt::sprintf(
1246 "FastReport %10.1f ms %10.1f ms %10.1f ms %10.1f ms %+10d kB %+10d kB %+10d kB %+10d kB %s\n",
1249 (active ? ms(
data.time_thread) / active : 0),
1251 (active ? ms(
data.time_real) / active : 0),
1253 (active ? +static_cast<int64_t>(kB(
data.allocated) / active) : 0),
1255 (active ? -static_cast<int64_t>(kB(
data.deallocated) / active) : 0),
1259 template <
typename T>
1264 out << fmt::sprintf(
1266 "FastReport %10.1f ms %10.1f ms %+10d kB %+10d kB %s\n",
1275 template <
typename T>
1278 out << fmt::sprintf(
1279 "FastReport %10.1f ms %10.1f ms %10.1f ms %10.1f ms %+10d kB %+10d kB %+10d kB %+10d kB %s\n",
1281 (active ? ms(
data.time_thread) / active : 0),
1283 (active ? ms(
data.time_real) / active : 0),
1285 (active ? +static_cast<int64_t>(kB(
data.allocated) / active) : 0),
1287 (active ? -static_cast<int64_t>(kB(
data.deallocated) / active) : 0),
1291 template <
typename T>
1294 out << fmt::sprintf(
1295 "FastReport %10.1f ms %10.1f ms %10.1f ms %10.1f ms %+10d kB %+10d kB %+10d kB %+10d kB %s\n",
1307 template <
typename T>
1310 printSummaryHeader(
out,
"Modules",
true);
1311 auto const& source_d = callgraph_.source();
1312 auto const&
source =
data.modules[source_d.id()];
1314 for (
unsigned int i = 0;
i < callgraph_.processes().size(); ++
i) {
1315 auto const& proc_d = callgraph_.processDescription(
i);
1317 printSummaryLine(
out,
proc.total,
data.events,
"process " + proc_d.name_);
1318 for (
unsigned int m : proc_d.modules_) {
1319 auto const& module_d = callgraph_.module(
m);
1321 printSummaryLine(
out,
module.total,
data.events,
module.events,
" " + module_d.moduleLabel());
1324 printSummaryLine(
out,
data.total,
data.events,
"total");
1325 printSummaryLine(
out,
data.overhead,
data.events,
"other");
1327 printPathSummaryHeader(
out,
"Processes and Paths");
1328 printSummaryLine(
out,
source.total,
data.events, source_d.moduleLabel());
1329 for (
unsigned int i = 0;
i < callgraph_.processes().size(); ++
i) {
1330 auto const& proc_d = callgraph_.processDescription(
i);
1332 printSummaryLine(
out,
proc.total,
data.events,
"process " + proc_d.name_);
1333 for (
unsigned int p = 0;
p <
proc.paths.size(); ++
p) {
1334 auto const&
name = proc_d.paths_[
p].name_;
1338 for (
unsigned int p = 0;
p <
proc.endpaths.size(); ++
p) {
1339 auto const&
name = proc_d.endPaths_[
p].name_;
1344 printSummaryLine(
out,
data.total,
data.events,
"total");
1345 printSummaryLine(
out,
data.overhead,
data.events,
"other");
1347 for (
unsigned int group : boost::irange(0ul, highlight_modules_.size())) {
1348 printSummaryHeader(
out,
"Highlighted modules",
true);
1350 auto const& module_d = callgraph_.module(
m);
1359 template <
typename T>
1361 printEventHeader(
out,
"Transition");
1365 template <
typename T>
1369 T const&
data)
const {
1373 {
"time_thread", ms(
data.time_thread)},
1374 {
"time_real", ms(
data.time_real)},
1375 {
"mem_alloc", kB(
data.allocated)},
1376 {
"mem_free", kB(
data.deallocated)}};
1388 json{{
"time_thread",
"cpu time"}},
1389 json{{
"mem_alloc",
"allocated memory"}},
1390 json{{
"mem_free",
"deallocated memory"}}});
1393 j[
"total"] = encodeToJSON(
"Job", callgraph_.processDescription(0).name_,
data.events,
data.total +
data.overhead);
1397 for (
unsigned int i = 0;
i < callgraph_.size(); ++
i) {
1398 auto const&
module = callgraph_.module(
i);
1399 auto const& data_m =
data.modules[
i];
1400 j[
"modules"].push_back(encodeToJSON(
module, data_m));
1404 j[
"modules"].push_back(encodeToJSON(
"other",
"other",
data.events,
data.overhead));
1407 out << std::setw(2) <<
j << std::flush;
1423 unsigned int old_value =
check.fetch_add(1, std::memory_order_acq_rel);
1424 return (old_value == callgraph_.processes().size() - 1);
1430 ignoredSignal(__func__);
1434 auto&
stream = streams_[sid];
1435 auto&
process = callgraph_.processDescription(pid);
1439 for (
unsigned int id :
process.modules_)
1444 bool last = isLastSubprocess(subprocess_event_check_[sid]);
1449 stream.event_measurement.measure_and_store(
stream.event);
1452 unsigned int id = 0;
1456 for (
unsigned int group : boost::irange(0ul, highlight_modules_.size()))
1462 std::lock_guard<std::mutex> guard(summary_mutex_);
1467 if (print_event_summary_) {
1479 auto&
stream = streams_[sid];
1483 subprocess_event_check_[sid] = 0;
1486 auto& measurement = thread();
1487 measurement.measure_and_accumulate(
stream.overhead);
1488 stream.event_measurement = measurement;
1493 unsigned int id = md.
id();
1494 auto&
stream = streams_[sid];
1497 thread().measure_and_store(
module.total);
1504 unsigned int id = pc.
pathID();
1505 auto&
stream = streams_[sid];
1507 data.status =
false;
1516 unsigned int id = pc.
pathID();
1517 auto&
stream = streams_[sid];
1521 pc.
isEndPath() ? callgraph_.processDescription(pid).endPaths_[
id] : callgraph_.processDescription(pid).paths_[
id];
1522 unsigned int index =
path.modules_on_path_.empty() ? 0 :
status.index() + 1;
1523 data.last =
path.modules_on_path_.empty() ? 0 :
path.last_dependency_of_module_[
status.index()];
1525 for (
unsigned int i = 0;
i <
index; ++
i) {
1529 for (
unsigned int i = 0;
i <
data.last; ++
i) {
1537 auto&
stream = streams_[sid];
1538 thread().measure_and_accumulate(
stream.overhead);
1543 unsigned int id = md.
id();
1545 auto&
stream = streams_[sid];
1548 module.has_acquire =
true;
1549 thread().measure_and_store(
module.total);
1554 auto&
stream = streams_[sid];
1555 thread().measure_and_accumulate(
stream.overhead);
1560 unsigned int id = md.
id();
1562 auto&
stream = streams_[sid];
1565 if (
module.has_acquire) {
1566 thread().measure_and_accumulate(
module.total);
1568 thread().measure_and_store(
module.total);
1574 unsupportedSignal(__func__);
1578 unsupportedSignal(__func__);
1582 ignoredSignal(__func__);
1586 ignoredSignal(__func__);
1590 ignoredSignal(__func__);
1594 ignoredSignal(__func__);
1598 thread().measure_and_accumulate(overhead_);
1603 thread().measure_and_accumulate(run_transition_[
index]);
1607 thread().measure_and_accumulate(overhead_);
1612 thread().measure_and_accumulate(run_transition_[
index]);
1616 thread().measure_and_accumulate(overhead_);
1621 thread().measure_and_accumulate(lumi_transition_[
index]);
1625 thread().measure_and_accumulate(overhead_);
1630 thread().measure_and_accumulate(lumi_transition_[
index]);
1634 thread().measure_and_accumulate(overhead_);
1639 thread().measure_and_accumulate(run_transition_[
index]);
1643 thread().measure_and_accumulate(overhead_);
1648 thread().measure_and_accumulate(run_transition_[
index]);
1652 thread().measure_and_accumulate(overhead_);
1657 thread().measure_and_accumulate(lumi_transition_[
index]);
1661 thread().measure_and_accumulate(overhead_);
1666 thread().measure_and_accumulate(lumi_transition_[
index]);
1672 throw cms::Exception(
"FastTimerService") <<
"ThreadGuard key creation failed: " << ::strerror(
err);
1678 auto ptr = ::pthread_getspecific(key_);
1681 auto p = thread_resources_.emplace_back(std::make_shared<specific_t>(
r));
1682 auto pp =
new std::shared_ptr<specific_t>(*
p);
1683 auto err = ::pthread_setspecific(key_,
pp);
1685 throw cms::Exception(
"FastTimerService") <<
"ThreadGuard pthread_setspecific failed: " << ::strerror(
err);
1693 return static_cast<std::shared_ptr<specific_t>*
>(
p);
1699 auto expected =
true;
1700 if ((*ps)->live_.compare_exchange_strong(expected,
false)) {
1702 (*ps)->measurement_.measure_and_accumulate((*ps)->resource_);
1709 for (
auto&
p : thread_resources_) {
1710 auto expected =
true;
1711 if (
p->live_.compare_exchange_strong(expected,
false)) {
1712 p->measurement_.measure_and_accumulate(
p->resource_);
1718 return (*ptr(::pthread_getspecific(key_)))->measurement_;
1735 desc.addUntracked<
bool>(
"printEventSummary",
false);
1736 desc.addUntracked<
bool>(
"printRunSummary",
true);
1737 desc.addUntracked<
bool>(
"printJobSummary",
true);
1742 desc.addUntracked<
bool>(
"writeJSONSummary",
false);
1745 desc.addUntracked<
bool>(
"enableDQM",
true);
1746 desc.addUntracked<
bool>(
"enableDQMbyModule",
false);
1747 desc.addUntracked<
bool>(
"enableDQMbyPath",
false);
1748 desc.addUntracked<
bool>(
"enableDQMbyLumiSection",
false);
1749 desc.addUntracked<
bool>(
"enableDQMbyProcesses",
false);
1750 desc.addUntracked<
bool>(
"enableDQMTransitions",
false);
1751 desc.addUntracked<
double>(
"dqmTimeRange", 1000.);
1752 desc.addUntracked<
double>(
"dqmTimeResolution", 5.);
1753 desc.addUntracked<
double>(
"dqmMemoryRange", 1000000.);
1754 desc.addUntracked<
double>(
"dqmMemoryResolution", 5000.);
1755 desc.addUntracked<
double>(
"dqmPathTimeRange", 100.);
1756 desc.addUntracked<
double>(
"dqmPathTimeResolution", 0.5);
1757 desc.addUntracked<
double>(
"dqmPathMemoryRange", 1000000.);
1758 desc.addUntracked<
double>(
"dqmPathMemoryResolution", 5000.);
1759 desc.addUntracked<
double>(
"dqmModuleTimeRange", 40.);
1760 desc.addUntracked<
double>(
"dqmModuleTimeResolution", 0.2);
1761 desc.addUntracked<
double>(
"dqmModuleMemoryRange", 100000.);
1762 desc.addUntracked<
double>(
"dqmModuleMemoryResolution", 500.);
1763 desc.addUntracked<
unsigned>(
"dqmLumiSectionsRange", 2500);
1767 highlightModulesDescription.
addUntracked<std::vector<std::string>>(
"modules", {});
1768 highlightModulesDescription.addUntracked<
std::string>(
"label",
"producers");
1769 desc.addVPSetUntracked(
"highlightModules", highlightModulesDescription, {});
1774 ->setComment(
"This parameter is obsolete and will be ignored.");
1776 ->setComment(
"This parameter is obsolete and will be ignored.");
1778 ->setComment(
"This parameter is obsolete and will be ignored.");
1780 ->setComment(
"This parameter is obsolete and will be ignored.");
1782 ->setComment(
"This parameter is obsolete and will be ignored.");
1784 ->setComment(
"This parameter is obsolete and will be ignored.");
1786 ->setComment(
"This parameter is obsolete and will be ignored.");
1788 ->setComment(
"This parameter is obsolete and will be ignored.");
1790 ->setComment(
"This parameter is obsolete and will be ignored.");
1792 ->setComment(
"This parameter is obsolete and will be ignored.");
1794 ->setComment(
"This parameter is obsolete and will be ignored.");
1796 ->setComment(
"This parameter is obsolete and will be ignored.");
1798 ->setComment(
"This parameter is obsolete and will be ignored.");
1800 ->setComment(
"This parameter is obsolete and will be ignored.");
1802 descriptions.
add(
"FastTimerService",
desc);