LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
writeSummary.cc
Go to the documentation of this file.
2 // vim: set sw=2 expandtab :
3 
9 #include "cetlib/cpu_timer.h"
11 
12 #include <iomanip>
13 #include <vector>
14 
15 using mf::LogPrint;
16 using std::fixed;
17 using std::setprecision;
18 using std::setw;
19 
20 namespace {
21 
22  struct SummaryCounts {
23  std::size_t total{};
24  std::size_t passed{};
25  std::size_t failed{};
26  };
27 
28  struct TriggerCounts {
29  std::string path_name{};
30  std::size_t run{};
31  std::size_t passed{};
32  std::size_t failed{};
33  std::size_t except{};
34  };
35 
36  struct EndPathCounts {
37  std::size_t run{};
38  std::size_t success{};
39  std::size_t except{};
40  };
41 
42  struct WorkerInPathCounts {
43  std::string moduleLabel{};
44  std::size_t visited{};
45  std::size_t passed{};
46  std::size_t failed{};
47  std::size_t except{};
48  };
49 
50  struct ModuleCounts {
51  std::size_t visited{};
52  std::size_t run{};
53  std::size_t passed{};
54  std::size_t failed{};
55  std::size_t except{};
56  };
57 
58  using WorkersInPath = std::vector<art::WorkerInPath>;
59  using WorkersInPathCounts = std::vector<WorkerInPathCounts>;
60 
61  void
62  workersInPathTriggerReport(art::PathID const path_id,
63  WorkersInPathCounts const& workersInPathCounts)
64  {
65  for (auto const& wip_counts : workersInPathCounts) {
66  LogPrint("ArtSummary")
67  << "TrigReport " << std::right << setw(10) << to_string(path_id) << " "
68  << std::right << setw(10) << wip_counts.visited << " " << std::right
69  << setw(10) << wip_counts.passed << " " << std::right << setw(10)
70  << wip_counts.failed << " " << std::right << setw(10)
71  << wip_counts.except << " " << wip_counts.moduleLabel;
72  }
73  }
74 
75  void
76  workersInEndPathTriggerReport(WorkersInPathCounts const& workersInPathCounts)
77  {
78  for (auto const& wip_counts : workersInPathCounts) {
79  LogPrint("ArtSummary")
80  << "TrigReport " << std::right << setw(10) << wip_counts.visited << " "
81  << std::right << setw(10) << wip_counts.passed << " " << std::right
82  << setw(10) << wip_counts.except << " " << wip_counts.moduleLabel;
83  }
84  }
85 
86 } // unnamed namespace
87 
88 void
90  bool const wantSummary,
91  cet::cpu_timer const& jobTimer)
92 {
93  auto const& epis = pm.endPathInfo();
94  auto const& tpis = pm.triggerPathsInfo();
95  LogPrint("ArtSummary") << "";
96  triggerReport(epis, tpis, wantSummary);
97  LogPrint("ArtSummary") << "";
98  timeReport(jobTimer);
99  LogPrint("ArtSummary") << "";
100  memoryReport();
101 }
102 
103 void
106  bool const wantSummary)
107 {
108  // Checking the first element is sufficient since the path
109  // structures are identical across schedules/end-path executors.
110  auto observers_enabled = !epis[ScheduleID::first()].paths().empty();
111 
112  SummaryCounts total_counts{};
113  for (auto const& tpi : tpis) {
114  total_counts.total += tpi.totalEvents();
115  total_counts.passed += tpi.passedEvents();
116  total_counts.failed += tpi.failedEvents();
117  }
118  // The trigger report (pass/fail etc.):
119  // Printed even if summary not requested, per issue #1864.
120  LogPrint("ArtSummary") << "TrigReport "
121  << "---------- Event summary -------------";
122  LogPrint("ArtSummary") << "TrigReport"
123  << " Events total = " << total_counts.total
124  << " passed = " << total_counts.passed
125  << " failed = " << total_counts.failed;
126 
127  if (wantSummary) {
128  LogPrint("ArtSummary") << "";
129  LogPrint("ArtSummary") << "TrigReport "
130  << "---------- Trigger-path summary ------------";
131  LogPrint("ArtSummary") << "TrigReport " << std::right << setw(10)
132  << "Path ID"
133  << " " << std::right << setw(10) << "Run"
134  << " " << std::right << setw(10) << "Passed"
135  << " " << std::right << setw(10) << "Failed"
136  << " " << std::right << setw(10) << "Error"
137  << " "
138  << "Name";
139  std::map<PathID, TriggerCounts> counts_per_path{};
140  for (auto const& tpi : tpis) {
141  for (auto const& path : tpi.paths()) {
142  auto& counts = counts_per_path[path.pathID()];
143  counts.path_name = path.name(); // No increment!
144  counts.run += path.timesRun();
145  counts.passed += path.timesPassed();
146  counts.failed += path.timesFailed();
147  counts.except += path.timesExcept();
148  }
149  }
150  for (auto const& [pathID, counts] : counts_per_path) {
151  LogPrint("ArtSummary")
152  << "TrigReport " << std::right << setw(10) << to_string(pathID) << " "
153  << std::right << setw(10) << counts.run << " " << std::right << setw(10)
154  << counts.passed << " " << std::right << setw(10) << counts.failed
155  << " " << std::right << setw(10) << counts.except << " "
156  << counts.path_name;
157  }
158 
159  LogPrint("ArtSummary") << "";
160  LogPrint("ArtSummary") << "TrigReport "
161  << "---------- End-path summary ---------";
162  LogPrint("ArtSummary") << "TrigReport"
163  << " " << std::right << setw(10) << "Run"
164  << " " << std::right << setw(10) << "Success"
165  << " " << std::right << setw(10) << "Error";
166 
167  if (observers_enabled) {
168  EndPathCounts epCounts{};
169  for (auto const& epi : epis) {
170  for (auto const& path : epi.paths()) {
171  epCounts.run += path.timesRun();
172  epCounts.success += path.timesPassed();
173  epCounts.except += path.timesExcept();
174  }
175  }
176  LogPrint("ArtSummary")
177  << "TrigReport " << std::right << setw(10) << epCounts.run << " "
178  << std::right << setw(10) << epCounts.success << " " << std::right
179  << setw(10) << epCounts.except;
180  }
181 
182  std::map<PathSpec, WorkersInPathCounts> counts_per_worker_in_path;
183  for (auto const& tpi : tpis) {
184  for (auto const& path : tpi.paths()) {
185  auto& counts_per_worker = counts_per_worker_in_path[path.pathSpec()];
186  if (counts_per_worker.empty() && !path.workersInPath().empty()) {
187  counts_per_worker.resize(path.workersInPath().size());
188  }
189  std::size_t i{};
190  for (auto const& workerInPath : path.workersInPath()) {
191  auto const* worker = workerInPath.getWorker();
192  auto& counts = counts_per_worker[i];
193  if (counts.moduleLabel.empty()) {
194  counts.moduleLabel = worker->description().moduleLabel();
195  }
196  counts.visited += workerInPath.timesVisited();
197  counts.passed += workerInPath.timesPassed();
198  counts.failed += workerInPath.timesFailed();
199  counts.except += workerInPath.timesExcept();
200  ++i;
201  }
202  }
203  }
204  for (auto const& [path_spec, worker_in_path_counts] :
205  counts_per_worker_in_path) {
206  LogPrint("ArtSummary") << "";
207  LogPrint("ArtSummary")
208  << "TrigReport "
209  << "---------- Modules in path: " << path_spec.name << " ------------";
210  LogPrint("ArtSummary")
211  << "TrigReport " << std::right << setw(10) << "Path ID"
212  << " " << std::right << setw(10) << "Visited"
213  << " " << std::right << setw(10) << "Passed"
214  << " " << std::right << setw(10) << "Failed"
215  << " " << std::right << setw(10) << "Error"
216  << " "
217  << "Name";
218  workersInPathTriggerReport(path_spec.path_id, worker_in_path_counts);
219  }
220  }
221 
222  // Printed even if summary not requested, per issue #1864.
223  WorkersInPathCounts endPathWIPCounts;
224  for (auto const& epi : epis) {
225  for (auto const& path : epi.paths()) {
226  if (endPathWIPCounts.empty() && !path.workersInPath().empty()) {
227  endPathWIPCounts.resize(path.workersInPath().size());
228  }
229  std::size_t i{};
230  for (auto const& workerInPath : path.workersInPath()) {
231  auto const* worker = workerInPath.getWorker();
232  auto& counts = endPathWIPCounts[i];
233  if (counts.moduleLabel.empty()) {
234  counts.moduleLabel = worker->description().moduleLabel();
235  }
236  counts.visited += worker->timesRun(); // proxy for 'visited'
237  counts.passed += worker->timesPassed();
238  counts.except += worker->timesExcept();
239  ++i;
240  }
241  }
242  }
243 
244  if (observers_enabled) {
245  LogPrint("ArtSummary") << "";
246  LogPrint("ArtSummary") << "TrigReport "
247  << "---------- Modules in End-path ----------";
248  LogPrint("ArtSummary") << "TrigReport"
249  << " " << std::right << setw(10) << "Run"
250  << " " << std::right << setw(10) << "Success"
251  << " " << std::right << setw(10) << "Error"
252  << " "
253  << "Name";
254  workersInEndPathTriggerReport(endPathWIPCounts);
255  }
256 
257  if (wantSummary) {
258  // This table can arguably be removed since all summary
259  // information is better described above.
260  LogPrint("ArtSummary") << "";
261  LogPrint("ArtSummary") << "TrigReport "
262  << "---------- Module summary ------------";
263  LogPrint("ArtSummary") << "TrigReport " << std::right << setw(10)
264  << "Visited"
265  << " " << std::right << setw(10) << "Run"
266  << " " << std::right << setw(10) << "Passed"
267  << " " << std::right << setw(10) << "Failed"
268  << " " << std::right << setw(10) << "Error"
269  << " "
270  << "Name";
271  std::map<std::string, ModuleCounts> counts_per_module;
272  auto update_counts = [&counts_per_module](auto const& pathInfos) {
273  for (auto const& pi : pathInfos) {
274  for (auto const& [module_label, module_counts] : pi.workers()) {
275  auto& counts = counts_per_module[module_label];
276  counts.visited += module_counts->timesVisited();
277  counts.run += module_counts->timesRun();
278  counts.passed += module_counts->timesPassed();
279  counts.failed += module_counts->timesFailed();
280  counts.except += module_counts->timesExcept();
281  }
282  }
283  };
284  update_counts(tpis);
285  update_counts(epis);
286  for (auto const& [module_label, module_counts] : counts_per_module) {
287  LogPrint("ArtSummary")
288  << "TrigReport " << std::right << setw(10) << module_counts.visited
289  << " " << std::right << setw(10) << module_counts.run << " "
290  << std::right << setw(10) << module_counts.passed << " " << std::right
291  << setw(10) << module_counts.failed << " " << std::right << setw(10)
292  << module_counts.except << " " << module_label;
293  }
294  }
295 }
296 
297 void
298 art::detail::timeReport(cet::cpu_timer const& timer)
299 {
300  LogPrint("ArtSummary") << "TimeReport "
301  << "---------- Time summary [sec] -------";
302  LogPrint("ArtSummary") << "TimeReport " << setprecision(6) << fixed
303  << "CPU = " << timer.cpuTime()
304  << " Real = " << timer.realTime();
305 }
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
PathID path_id
Definition: PathSpec.h:49
void triggerReport(PerScheduleContainer< PathsInfo > const &endPathInfo, PerScheduleContainer< PathsInfo > const &triggerPathsInfo, bool wantSummary)
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
void writeSummary(PathManager &pm, bool wantSummary, cet::cpu_timer const &timer)
Definition: writeSummary.cc:89
counts_as<> counts
Number of ADC counts, represented by signed short int.
Definition: electronics.h:112
PathsInfo & triggerPathsInfo(ScheduleID)
Definition: PathManager.cc:272
std::string name
Definition: PathSpec.h:48
PathsInfo & endPathInfo(ScheduleID)
Definition: PathManager.cc:284
void timeReport(cet::cpu_timer const &timer)
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
PathSpec path_spec(std::string const &path_spec)
Definition: PathSpec.cc:22
MaybeLogger_< ELseverityLevel::ELsev_warning, true > LogPrint