ATLAS Offline Software
PerfMonMTSvc.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /*
6  * @authors: Alaettin Serhan Mete, Hasan Ozturk - alaettin.serhan.mete@cern.ch, haozturk@cern.ch
7  */
8 
9 // Thread-safety-checker
11 
12 // Framework includes
13 #include "GaudiKernel/IIncidentSvc.h"
14 #include "GaudiKernel/ThreadLocalContext.h"
15 
16 // PerfMonComps includes
17 #include "PerfMonMTSvc.h"
18 #include "PerfMonUtils.h"
19 
20 // STD includes
21 #include <algorithm>
22 #include <cmath>
23 #include <fstream>
24 #include <iomanip>
25 #include <filesystem>
26 #include <format>
27 
28 // TBB
29 #include "tbb/task_arena.h"
30 
31 /*
32  * Constructor
33  */
34 PerfMonMTSvc::PerfMonMTSvc(const std::string& name, ISvcLocator* pSvcLocator)
35  : base_class(name, pSvcLocator), m_isFirstEvent{false}, m_eventCounter{0}, m_eventLoopMsgCounter{0}, m_checkPointTime{0}, m_isEvtLoopStopped{false} {
36  // Five main snapshots : Configure, Initialize, FirstEvent, Execute, and Finalize
37  m_motherPID = getpid();
38  m_snapshotData.resize(NSNAPSHOTS); // Default construct
39 
40  // Initial capture upon construction
41  m_measurementSnapshots.capture();
42  m_snapshotData[CONFIGURE].addPointStop(m_measurementSnapshots);
43  m_snapshotData[INITIALIZE].addPointStart(m_measurementSnapshots);
44 }
45 
46 /*
47  * Initialize the Service
48  */
50  // Print where we are
51  ATH_MSG_INFO("Initializing " << name());
52 
53  // Set to be listener to SvcPostFinalize
54  ServiceHandle<IIncidentSvc> incSvc("IncidentSvc/IncidentSvc", name());
55  ATH_CHECK(incSvc.retrieve());
56  const long highestPriority = static_cast<long>(-1);
57  const long lowestPriority = 0;
58  incSvc->addListener(this, IncidentType::BeginEvent, highestPriority);
59  incSvc->addListener(this, "EndAlgorithms", lowestPriority);
60  incSvc->addListener(this, "EndEvtLoop", highestPriority);
61  incSvc->addListener(this, IncidentType::SvcPostFinalize);
62 
63  // Check if /proc exists, if not memory statistics are not available
64  const bool procExists = PMonMT::doesDirectoryExist("/proc");
65  if(!procExists) {
66  ATH_MSG_INFO("The system doesn't support /proc. Therefore, memory measurements are not available");
67  }
68 
69  // Print some information minimal information about our configuration
70  ATH_MSG_INFO("Service is configured for [" << m_numberOfThreads.toString() << "] threads " <<
71  "analyzing [" << m_numberOfSlots.toString() << "] events concurrently");
72  ATH_MSG_INFO("Component-level measurements are [" << (m_doComponentLevelMonitoring ? "Enabled" : "Disabled") << "]");
74  ATH_MSG_INFO(" >> Component-level memory monitoring in the event-loop is disabled in jobs with more than 1 thread");
75  }
76 
77  // Thread specific component-level data map
78  m_compLevelDataMapVec.resize(m_numberOfThreads+1); // Default construct
79 
80  // Set wall time offset
82  if (m_wallTimeOffset > 0) {
83  m_snapshotData[CONFIGURE].add2DeltaWall(-m_wallTimeOffset);
84  }
85 
87  if (!PerfMon::makeAuditor("PerfMonMTAuditor", auditorSvc(), msg()).isSuccess()) {
88  ATH_MSG_ERROR("Could not register auditor [PerfMonMTAuditor]!");
89  return StatusCode::FAILURE;
90  }
91  return StatusCode::SUCCESS;
92 }
93 
94 /*
95  * Finalize the Service
96  */
98  // Print where we are
99  ATH_MSG_INFO("Finalizing " << name());
100 
101  return StatusCode::SUCCESS;
102 }
103 
104 /*
105  * Handle relevant incidents
106  */
107 void PerfMonMTSvc::handle(const Incident& inc) {
108  // Begin event processing
109  if (inc.type() == IncidentType::BeginEvent) {
110  // Lock for data integrity
111  std::lock_guard<std::mutex> lock(m_mutex_capture);
112 
113  // Increment the internal counter
114  m_eventCounter++;
115 
116  // Get current time in seconds
117  double currentTime = PMonMT::get_wall_time()*0.001;
118 
119  // Monitor
121  // Overwrite the last measurement time
122  m_checkPointTime = currentTime;
123 
124  // Capture
127  // Report instantly - no more than m_eventLoopMsgLimit times
131  }
132  }
133  }
134  // End event processing (as signaled by SG clean-up)
135  // By convention the first event is executed serially
136  // Therefore, we treat it a little bit differently
137  else if (m_eventCounter == 1 && inc.type() == "EndAlgorithms") {
138  // In AthenaMP w/ fork-after-initialize, the loop starts
139  // in the mother process but the first event is actually
140  // executed in the worker. Here, we try to work around this
141  // by resetting the first event measurement if we think
142  // we're in AthenaMP. This is not an ideal approach but
143  // gets the job done for the fork-after-initialize case.
144  if (m_motherPID != getpid()) {
145  m_snapshotData[FIRSTEVENT].m_tmp_cpu = 0;
146  m_snapshotData[FIRSTEVENT].m_memMonTmpMap["vmem"] = 0;
147  m_snapshotData[FIRSTEVENT].m_memMonTmpMap["pss"] = 0;
148  m_snapshotData[FIRSTEVENT].m_memMonTmpMap["rss"] = 0;
149  m_snapshotData[FIRSTEVENT].m_memMonTmpMap["swap"] = 0;
150  }
154  // Normally this flag is set in stopCompAud but we don't
155  // go in there unless m_doComponentLevelMonitoring is true.
156  // If it's false, we toggle it here but
157  // this is mostly for completeness since in that mode
158  // this flag is not really used at the moment.
160  m_isFirstEvent = false;
161  }
162  }
163  // This incident is fired by only some loop managers to signal the end of event processing
164  else if (inc.type() == "EndEvtLoop") {
165  m_isEvtLoopStopped = true;
168  }
169  // Finalize ourself and print the metrics in SvcPostFinalize
170  else if (inc.type() == IncidentType::SvcPostFinalize) {
171  // Final capture upon post-finalization
174 
175  // Report everything
176  report();
177  }
178  return;
179 }
180 /*
181  * Start Auditing
182  */
183 void PerfMonMTSvc::startAud(const std::string& stepName, const std::string& compName) {
184  // Snapshots, i.e. Initialize, Event Loop, etc.
185  startSnapshotAud(stepName, compName);
186 
187  /*
188  * Perform component monitoring only if the user asked for it.
189  * By default we don't monitor a set of common components.
190  * Once we adopt C++20, we can switch this from count to contains.
191  */
193  // Start component auditing
194  auto const &ctx = Gaudi::Hive::currentContext();
195  startCompAud(stepName, compName, ctx);
196  }
197 }
198 
199 /*
200  * Stop Auditing
201  */
202 void PerfMonMTSvc::stopAud(const std::string& stepName, const std::string& compName) {
203  // Snapshots, i.e. Initialize, Event Loop, etc.
204  stopSnapshotAud(stepName, compName);
205 
206  // Check if we should monitor this component
208  // Stop component auditing
209  auto const &ctx = Gaudi::Hive::currentContext();
210  stopCompAud(stepName, compName, ctx);
211  }
212 }
213 
214 /*
215  * Start Snapshot Auditing
216  */
217 void PerfMonMTSvc::startSnapshotAud(const std::string& stepName, const std::string& compName) {
218  // Last thing to be called before the event loop begins
219  if (compName == "AthOutSeq" && stepName == "Start") {
222  m_isFirstEvent = true;
223  }
224 
225  // Last thing to be called before finalize step begins
226  if (compName == "AthMasterSeq" && stepName == "Finalize") {
229  }
230 }
231 
232 /*
233  * Stop Snapshot Auditing
234  */
235 void PerfMonMTSvc::stopSnapshotAud(const std::string& stepName, const std::string& compName) {
236  // First thing to be called after the initialize step ends
237  if (compName == "AthMasterSeq" && stepName == "Initialize") {
240  }
241 
242  // First thing to be called after the event loop ends
243  // Some loop managers fire a dedicated incident to signal the end of the event loop
244  // That preceeds the AthMasterSeq Stop and if it is already handled we don't do anything here
245  if (compName == "AthMasterSeq" && stepName == "Stop" && m_eventCounter > 0 && !m_isEvtLoopStopped) {
248  }
249 }
250 
251 /*
252  * Start Component Auditing
253  */
254 void PerfMonMTSvc::startCompAud(const std::string& stepName, const std::string& compName, const EventContext& ctx) {
255  // Get the thread index
256  const unsigned int ithread = (ctx.valid() && tbb::this_task_arena::current_thread_index() > -1) ? tbb::this_task_arena::current_thread_index() : 0;
257 
258  // Memory measurement is only done outside the loop except when there is only a single thread
259  const bool doMem = !ctx.valid() || (m_numberOfThreads == 1);
260 
261  // Generate State
262  PMonMT::StepComp currentState = generate_state(stepName, compName);
263 
264  // Check if this is the first time calling if so create the mesurement data if not use the existing one.
265  // Metrics are collected per thread then aggregated before reporting
266  data_map_unique_t& compLevelDataMap = m_compLevelDataMapVec[ithread];
267  if(compLevelDataMap.find(currentState) == compLevelDataMap.end()) {
268  compLevelDataMap.insert({currentState, std::make_unique<PMonMT::ComponentData>()});
269  }
270 
271  // Capture and store
273  meas.capture(); // No memory in the event-loop
274  if (doMem) {
275  // we made sure this is only run outside event loop or single-threaded
276  [[maybe_unused]] bool dummy ATLAS_THREAD_SAFE = meas.capture_memory();
277  }
278 
279  compLevelDataMap[currentState]->addPointStart(meas, doMem);
280 
281  // Debug
282  ATH_MSG_DEBUG("Start Audit - Component " << compName << " , "
283  "Step " << stepName << " , "
284  "Event " << ctx.evt() << " , "
285  "Slot " << ctx.slot() << " , "
286  "Context " << ctx.valid() << " , "
287  "Thread " << ithread << " , "
288  "Cpu " << meas.cpu_time << " ms, "
289  "Wall " << meas.wall_time << " ms, "
290  "Vmem " << meas.vmem << " kb, "
291  "Malloc " << meas.malloc << " kb");
292 }
293 
294 /*
295  * Stop Component Auditing
296  */
297 void PerfMonMTSvc::stopCompAud(const std::string& stepName, const std::string& compName, const EventContext& ctx) {
298  // Get the thread index
299  const unsigned int ithread = (ctx.valid() && tbb::this_task_arena::current_thread_index() > -1) ? tbb::this_task_arena::current_thread_index() : 0;
300 
301  // Memory measurement is only done outside the loop except when there is only a single thread
302  const bool doMem = !ctx.valid() || (m_numberOfThreads == 1);
303 
304  // Capture
306  meas.capture(); // No memory in the event-loop
307  if (doMem) {
308  // we made sure this is only run outside event loop or single-threaded
309  [[maybe_unused]] bool dummy ATLAS_THREAD_SAFE = meas.capture_memory();
310  }
311 
312  // Generate State
313  PMonMT::StepComp currentState = generate_state(stepName, compName);
314 
315  // Store
316  data_map_unique_t& compLevelDataMap = m_compLevelDataMapVec[ithread];
317  compLevelDataMap[currentState]->addPointStop(meas, doMem);
318 
319  // Once the first time IncidentProcAlg3 is excuted, toggle m_isFirstEvent to false.
320  // Doing it this way, instead of at EndAlgorithms incident, makes sure there is no
321  // mismatch in start-stop calls to IncidentProcAlg3.
322  // It's a little ad-hoc but I don't think this workflow will change much anytime soon.
323  if ( m_isFirstEvent && compName == "IncidentProcAlg3" && stepName == "Execute") {
324  m_isFirstEvent = false;
325  }
326 
327  // Debug
328  ATH_MSG_DEBUG("Stop Audit - Component " << compName << " , "
329  "Step " << stepName << " , "
330  "Event " << ctx.evt() << " , "
331  "Slot " << ctx.slot() << " , "
332  "Context " << ctx.valid() << " , "
333  "Thread " << ithread << " , "
334  "Cpu (" << compLevelDataMap[currentState]->m_tmp_cpu << ":"
335  << meas.cpu_time << ":"
336  << (meas.cpu_time - compLevelDataMap[currentState]->m_tmp_cpu) << ":"
337  << compLevelDataMap[currentState]->m_delta_cpu << ") ms, "
338  "Wall (" << compLevelDataMap[currentState]->m_tmp_wall << ":"
339  << meas.wall_time << ":"
340  << (meas.wall_time - compLevelDataMap[currentState]->m_tmp_wall) << ":"
341  << compLevelDataMap[currentState]->m_delta_wall << ") ms, "
342  "Vmem (" << compLevelDataMap[currentState]->m_tmp_vmem << ":"
343  << meas.vmem << ":"
344  << (meas.vmem - compLevelDataMap[currentState]->m_tmp_vmem) << ":"
345  << compLevelDataMap[currentState]->m_delta_vmem << ") kb, "
346  "Malloc (" << compLevelDataMap[currentState]->m_tmp_malloc << ":"
347  << meas.malloc << ":"
348  << (meas.malloc - compLevelDataMap[currentState]->m_tmp_malloc) << ":"
349  << compLevelDataMap[currentState]->m_delta_malloc << ") kb");
350 }
351 
352 /*
353  * Helper finction to estimate CPU efficiency
354  */
356 
357  // In AthenaMT only the event-loop is executed concurrently
358  // In this metric, we scale the event-loop wall-time by
359  // the number of slots to take the concurrency into account
360  // Then we divide the total cpu-time by this number
361  // It's A metric not THE metric...
362 
363  const double totalCpuTime =
364  m_snapshotData[CONFIGURE].getDeltaCPU() +
365  m_snapshotData[INITIALIZE].getDeltaCPU() +
366  m_snapshotData[FIRSTEVENT].getDeltaCPU() +
367  m_snapshotData[EXECUTE].getDeltaCPU() +
368  m_snapshotData[FINALIZE].getDeltaCPU();
369 
370  const double scaledWallTime =
371  m_snapshotData[CONFIGURE].getDeltaWall() * 1. +
372  m_snapshotData[INITIALIZE].getDeltaWall() * 1. +
373  m_snapshotData[FIRSTEVENT].getDeltaWall() * 1. +
374  m_snapshotData[EXECUTE].getDeltaWall() * m_numberOfSlots +
375  m_snapshotData[FINALIZE].getDeltaWall() * 1.;
376 
377  return ( scaledWallTime > 0 ? totalCpuTime / scaledWallTime * 100. : 0 );
378 
379 }
380 
381 /*
382  * Report the results to the log and the JSON file
383  */
385  // Write into log file
386  report2Log();
387 
388  // Write into JSON
389  if (m_reportResultsToJSON) {
390  report2JsonFile();
391  }
392 }
393 
394 /*
395  * Log reporting
396  */
398  // Header
400 
401  // Component-level
404  }
405 
406  // Event-level
409  }
410 
411  // Summary and system information
415 }
416 
417 /*
418  * Report header to log
419  */
421  ATH_MSG_INFO("=======================================================================================");
422  ATH_MSG_INFO(" PerfMonMTSvc Report ");
423  ATH_MSG_INFO("=======================================================================================");
424  if (m_reportResultsToJSON) {
425  ATH_MSG_INFO("*** Full set of information can also be found in: " << m_jsonFileName.toString());
426  ATH_MSG_INFO("*** In order to make plots using the results run the following commands:");
427  ATH_MSG_INFO("*** $ perfmonmt-plotter.py -i " << m_jsonFileName.toString());
428  ATH_MSG_INFO("*** In order to print tables using the results run the following commands:");
429  ATH_MSG_INFO("*** $ perfmonmt-printer.py -i " << m_jsonFileName.toString());
430  ATH_MSG_INFO("=======================================================================================");
431  }
432 }
433 
434 /*
435  * Report component-level information to log
436  */
438 
439  ATH_MSG_INFO("=======================================================================================");
440  ATH_MSG_INFO(" Component Level Monitoring ");
441  ATH_MSG_INFO("=======================================================================================");
442 
443  ATH_MSG_INFO(std::format("{:<10} {:<15} {:<25} {:<40} {:<55} {:<75}","Step", "Count", "CPU Time [ms]",
444  "Vmem [kB]", "Malloc [kB]", "Component"));
445 
446  ATH_MSG_INFO("---------------------------------------------------------------------------------------");
447 
448  aggregateSlotData(); // aggregate data from slots
449  divideData2Steps(); // divive data into steps for ordered printing
450 
451  for (auto vec_itr : m_stdoutVec_serial) {
452  // Sort the results by CPU time for the time being
453  std::vector<std::pair<PMonMT::StepComp, PMonMT::ComponentData*>> pairs;
454  for (auto itr = vec_itr.begin(); itr != vec_itr.end(); ++itr) pairs.push_back(*itr);
455 
456  sort(pairs.begin(), pairs.end(),
457  [=](std::pair<PMonMT::StepComp, PMonMT::ComponentData*>& a,
458  std::pair<PMonMT::StepComp, PMonMT::ComponentData*>& b) {
459  return a.second->getDeltaCPU() > b.second->getDeltaCPU();
460  });
461 
462  int counter = 0;
463  for (auto it : pairs) {
464  // Only write out a certian number of components
465  if (counter >= m_printNComps) {
466  break;
467  }
468  counter++;
469 
470  ATH_MSG_INFO(std::format("{:<10} {:<15} {:<25.2f} {:<40.0f} {:<55.0f} {:<75}",it.first.stepName,
471  it.second->getCallCount(),it.second->getDeltaCPU(),it.second->getDeltaVmem(),
472  it.second->getDeltaMalloc(),it.first.compName));
473  }
474  if(counter>0) {
475  ATH_MSG_INFO("=======================================================================================");
476  }
477  }
478 }
479 
480 /*
481  * Report event-level information to log as we capture it
482  */
486 
487  int64_t vmem = m_eventLevelData.getEventLevelMemory(m_eventCounter, "vmem");
491 
492  ATH_MSG_INFO("Event [" << std::setw(5) << m_eventCounter << "] CPU Time: " << scaleTime(cpu_time) <<
493  ", Wall Time: " << scaleTime(wall_time) << ", Vmem: " << scaleMem(vmem) <<
494  ", Rss: " << scaleMem(rss) << ", Pss: " << scaleMem(pss) << ", Swap: " << scaleMem(swap));
495 }
496 
497 /*
498  * Report event-level information to log
499  */
501 
502  ATH_MSG_INFO(" Event Level Monitoring ");
503  ATH_MSG_INFO(" (Only the first " << m_eventLoopMsgLimit.toString() <<
504  " and the last measurements are explicitly printed)");
505  ATH_MSG_INFO("=======================================================================================");
506 
507  ATH_MSG_INFO(std::format("{:<16} {:<12} {:<12} {:<12} {:<12} {:<12} {:<12}","Event", "CPU [s]",
508  "Wall [s]", "Vmem [kB]", "Rss [kB]", "Pss [kB]", "Swap [kB]"));
509 
510  ATH_MSG_INFO("---------------------------------------------------------------------------------------");
511 
512  m_eventLoopMsgCounter = 0; // reset counter
513  uint64_t nMeasurements = m_eventLevelData.getNMeasurements();
514 
515  for (const auto& it : m_eventLevelData.getEventLevelData()) {
516  // Print
517  if(m_eventLoopMsgCounter < m_eventLoopMsgLimit || m_eventLoopMsgCounter == nMeasurements - 1) {
519  ATH_MSG_INFO(std::format("{:=<87}", "..."));
520  }
521  ATH_MSG_INFO(std::format("{:<16} {:>12.2f} {:>12.2f} {:>12} {:>12} {:>12} {:>12}", it.first,
522  it.second.cpu_time * 0.001,it.second.wall_time * 0.001,it.second.mem_stats.at("vmem"),
523  it.second.mem_stats.at("rss"),it.second.mem_stats.at("pss"),it.second.mem_stats.at("swap")));
524  }
526  // Add to leak estimate
527  if (it.first >= m_memFitLowerLimit) {
528  m_fit_vmem.addPoint(it.first, it.second.mem_stats.at("vmem"));
529  m_fit_pss.addPoint(it.first, it.second.mem_stats.at("pss"));
530  }
531  }
532  ATH_MSG_INFO("=======================================================================================");
533 }
534 
535 /*
536  * Report summary information to log
537  */
539 
540  ATH_MSG_INFO(" Snapshots Summary ");
541  ATH_MSG_INFO("=======================================================================================");
542 
543  ATH_MSG_INFO(std::format("{:<13} {:<12} {:<12} {:<7} {:<11} {:<11} {:<11} {:<11}","Step",
544  "dCPU [s]","dWall [s]","<CPU>","dVmem [kB]","dRss [kB]","dPss [kB]","dSwap [kB]"));
545 
546  ATH_MSG_INFO("---------------------------------------------------------------------------------------");
547 
548  for (unsigned int idx = 0; idx < NSNAPSHOTS; idx++) {
549  ATH_MSG_INFO(std::format("{:<13} {:<12.2f} {:<12.2f} {:<7.2f} {:<11} {:<11} {:<11} {:<11}",
550  m_snapshotStepNames[idx], m_snapshotData[idx].getDeltaCPU() * 0.001,
551  m_snapshotData[idx].getDeltaWall() * 0.001,
552  m_snapshotData[idx].getDeltaCPU() / m_snapshotData[idx].getDeltaWall(),
553  m_snapshotData[idx].getMemMonDeltaMap("vmem"),m_snapshotData[idx].getMemMonDeltaMap("rss"),
554  m_snapshotData[idx].getMemMonDeltaMap("pss"),m_snapshotData[idx].getMemMonDeltaMap("swap")));
555  }
556 
557  ATH_MSG_INFO("***************************************************************************************");
558  const double cpu_exec_total = m_snapshotData[FIRSTEVENT].getDeltaCPU() + m_snapshotData[EXECUTE].getDeltaCPU();
559  const double wall_exec_total = m_snapshotData[FIRSTEVENT].getDeltaWall() + m_snapshotData[EXECUTE].getDeltaWall();
560 
561  ATH_MSG_INFO(std::format("{:<35} {}", "Number of events processed:", static_cast<int>(m_eventCounter)));
562  ATH_MSG_INFO(std::format("{:<35} {:.0f}", "CPU usage per event [ms]:",
563  (m_eventCounter > 0 ? cpu_exec_total / m_eventCounter : 0)));
564  ATH_MSG_INFO(std::format("{:<35} {:.3f}", "Events per second:",
565  (wall_exec_total > 0 ? m_eventCounter / wall_exec_total * 1000. : 0)));
566  ATH_MSG_INFO(std::format("{:<35} {}", "CPU utilization efficiency [%]:", getCpuEfficiency()));
568  ATH_MSG_INFO("***************************************************************************************");
569  ATH_MSG_INFO(std::format("{:<35} {}", "Max Vmem:", scaleMem(m_eventLevelData.getEventLevelMemoryMax("vmem"))));
570  ATH_MSG_INFO(std::format("{:<35} {}", "Max Rss:", scaleMem(m_eventLevelData.getEventLevelMemoryMax("rss"))));
571  ATH_MSG_INFO(std::format("{:<35} {}", "Max Pss:", scaleMem(m_eventLevelData.getEventLevelMemoryMax("pss"))));
572  ATH_MSG_INFO(std::format("{:<35} {}", "Max Swap:", scaleMem(m_eventLevelData.getEventLevelMemoryMax("swap"))));
573  ATH_MSG_INFO("***************************************************************************************");
574  ATH_MSG_INFO(std::format("{:<35} {}", "Leak estimate per event Vmem:", scaleMem(m_fit_vmem.slope())));
575  ATH_MSG_INFO(std::format("{:<35} {}", "Leak estimate per event Pss:", scaleMem(m_fit_pss.slope())));
576  ATH_MSG_INFO(" >> Estimated using the last " << m_fit_vmem.nPoints()
577  << " measurements from the Event Level Monitoring");
578  ATH_MSG_INFO(" >> Events prior to the first " << m_memFitLowerLimit.toString() << " are omitted...");
579  }
580 
581  ATH_MSG_INFO("=======================================================================================");
582 }
583 
584 /*
585  * Report CPU information to log
586  */
588 
589  ATH_MSG_INFO(" System Information ");
590  ATH_MSG_INFO("=======================================================================================");
591 
592  ATH_MSG_INFO(std::format("{:<34} {}", "CPU Model:", get_cpu_model_info()));
593  ATH_MSG_INFO(std::format("{:<35} {}", "Number of Available Cores:", get_cpu_core_info()));
594  ATH_MSG_INFO(std::format("{:<35} {}", "Total Memory:", scaleMem(get_memory_info())));
595  ATH_MSG_INFO("=======================================================================================");
596 }
597 
598 /*
599  * Report run-time enviroment information
600  */
602 
603  ATH_MSG_INFO(" Environment Information ");
604  ATH_MSG_INFO("=======================================================================================");
605 
606  ATH_MSG_INFO(std::format("{:<35} {}","Malloc Library:", std::filesystem::path(PMonMT::symb2lib("malloc")).filename().string()));
607  ATH_MSG_INFO(std::format("{:<35} {}","Math Library:", std::filesystem::path(PMonMT::symb2lib("atan2")).filename().string()));
608 
609  ATH_MSG_INFO("=======================================================================================");
610 
611 }
612 
613 /*
614  * Report data to JSON
615  */
617  nlohmann::json j;
618 
619  // CPU and Wall-time
620  report2JsonFile_Summary(j); // Snapshots
621 
622  // Memory
624  report2JsonFile_ComponentLevel(j); // Component-level
625  }
627  report2JsonFile_EventLevel(j); // Event-level
628  }
629 
630  // Write and close the JSON file
631  std::ofstream o(m_jsonFileName);
632  o << std::setw(4) << j << std::endl;
633  o.close();
634 
635  // Compress the JSON file into tar.gz
636  auto cmd = "tar -czf " + m_jsonFileName + ".tar.gz " + m_jsonFileName + ";";
637  int rc = std::system(cmd.c_str());
638  if(rc!=0) {
639  ATH_MSG_WARNING("Couldn't compress the JSON file...");
640  return;
641  }
642 
643  // Remove the uncompressed JSON file to save disk-space
644  rc = std::remove(m_jsonFileName.toString().c_str());
645  if(rc!=0) {
646  ATH_MSG_WARNING("Couldn't remove the uncompressed JSON file...");
647  return;
648  }
649 }
650 
651 /*
652  * Report summary data to JSON
653  */
655 
656  // Report snapshot level results
657  for(int i=0; i < NSNAPSHOTS; i++){
658 
659  const std::string step = m_snapshotStepNames[i];
660  const double dCPU = m_snapshotData[i].getDeltaCPU();
661  const double dWall = m_snapshotData[i].getDeltaWall();
662  const double cpuUtil = dCPU / dWall;
663  const int64_t dVmem = m_snapshotData[i].getMemMonDeltaMap("vmem");
664  const int64_t dRss = m_snapshotData[i].getMemMonDeltaMap("rss");
665  const int64_t dPss = m_snapshotData[i].getMemMonDeltaMap("pss");
666  const int64_t dSwap = m_snapshotData[i].getMemMonDeltaMap("swap");
667 
668  j["summary"]["snapshotLevel"][step] = {{"dCPU", dCPU},
669  {"dWall", dWall},
670  {"cpuUtil", cpuUtil},
671  {"dVmem", dVmem},
672  {"dRss", dRss},
673  {"dPss", dPss},
674  {"dSwap", dSwap}};
675 
676  }
677 
678  // Report the total number of events
679  const int64_t nEvents = m_eventCounter;
680  j["summary"]["nEvents"] = nEvents;
681 
682  // Report Peaks
683  const int64_t vmemPeak = m_eventLevelData.getEventLevelMemoryMax("vmem");
684  const int64_t rssPeak = m_eventLevelData.getEventLevelMemoryMax("rss");
685  const int64_t pssPeak = m_eventLevelData.getEventLevelMemoryMax("pss");
686  const int64_t swapPeak = m_eventLevelData.getEventLevelMemoryMax("swap");
687 
688  j["summary"]["peaks"] = {{"vmemPeak", vmemPeak},
689  {"rssPeak", rssPeak},
690  {"pssPeak", pssPeak},
691  {"swapPeak", swapPeak}};
692 
693  // Report leak estimates
694  const int64_t vmemLeak = m_fit_vmem.slope();
695  const int64_t pssLeak = m_fit_pss.slope();
696  const int64_t nPoints = m_fit_vmem.nPoints();
697 
698  j["summary"]["leakEstimates"] = {{"vmemLeak", vmemLeak},
699  {"pssLeak", pssLeak},
700  {"nPoints", nPoints}};
701 
702  // Report Sys info
703  const std::string cpuModel = get_cpu_model_info();
704  const int coreNum = get_cpu_core_info();
705  const int64_t totMem = get_memory_info();
706 
707  j["summary"]["sysInfo"] = {{"cpuModel", cpuModel},
708  {"coreNum", coreNum},
709  {"totMem", totMem}};
710 
711  // Report Enviroment info
712  const std::string mallocLib = std::filesystem::path(PMonMT::symb2lib("malloc")).filename().string();
713  const std::string mathLib = std::filesystem::path(PMonMT::symb2lib("atan2")).filename().string();
714 
715  j["summary"]["envInfo"] = {{"mallocLib", mallocLib},
716  {"mathLib", mathLib}};
717 
718  // Report CPU utilization efficiency;
719  const int cpuUtilEff = getCpuEfficiency();
720  j["summary"]["misc"] = {{"cpuUtilEff", cpuUtilEff}};
721 
722 }
723 
725 
726  for (const auto& dataMapPerStep : m_stdoutVec_serial) {
727 
728  for(const auto& meas : dataMapPerStep){
729 
730  const std::string step = meas.first.stepName;
731  const std::string component = meas.first.compName;
732  const uint64_t count = meas.second->getCallCount();
733  const double cpuTime = meas.second->getDeltaCPU();
734  const double wallTime = meas.second->getDeltaWall();
735  const int64_t vmem = meas.second->getDeltaVmem();
736  const int64_t mall = meas.second->getDeltaMalloc();
737 
738  j["componentLevel"][step][component] = {{"count", count},
739  {"cpuTime", cpuTime},
740  {"wallTime", wallTime},
741  {"vmem", vmem},
742  {"malloc", mall}};
743  }
744 
745  }
746 
747 }
748 
750 
751  for (const auto& it : m_eventLevelData.getEventLevelData()) {
752 
753  const uint64_t event = it.first;
754  const double cpuTime = it.second.cpu_time;
755  const double wallTime = it.second.wall_time;
756  const int64_t vmem = it.second.mem_stats.at("vmem");
757  const int64_t rss = it.second.mem_stats.at("rss");
758  const int64_t pss = it.second.mem_stats.at("pss");
759  const int64_t swap = it.second.mem_stats.at("swap");
760 
761  j["eventLevel"][std::to_string(event)] = {{"cpuTime", cpuTime},
762  {"wallTime", wallTime},
763  {"vmem", vmem},
764  {"rss", rss},
765  {"pss", pss},
766  {"swap", swap}};
767 
768 
769  }
770 }
771 
772 /*
773  * Generate a "state" that is use as a key for the component-level data
774  */
775 PMonMT::StepComp PerfMonMTSvc::generate_state(const std::string& stepName, const std::string& compName) const {
776  PMonMT::StepComp currentState;
777  currentState.stepName = (m_isFirstEvent && stepName == "Execute") ? "FirstEvent" : stepName;
778  currentState.compName = compName;
779  return currentState;
780 }
781 
782 /*
783  * Aggregate component-level data from all slots
784  */
786  // Loop over data from all slots
787  for (const auto& slotData : m_compLevelDataMapVec) {
788  for (const auto& it : slotData) {
789  // Copy the first slot data and sum the rest
790  if(m_compLevelDataMap.find(it.first) == m_compLevelDataMap.end()) {
791  m_compLevelDataMap.insert({it.first, it.second.get()});
792  } else {
793  m_compLevelDataMap[it.first]->add2CallCount(it.second->getCallCount());
794  m_compLevelDataMap[it.first]->add2DeltaCPU(it.second->getDeltaCPU());
795  m_compLevelDataMap[it.first]->add2DeltaWall(it.second->getDeltaWall());
796  m_compLevelDataMap[it.first]->add2DeltaVmem(it.second->getDeltaVmem());
797  m_compLevelDataMap[it.first]->add2DeltaMalloc(it.second->getDeltaMalloc());
798  }
799  // Do a quick consistency check here and print any suspicious measurements.
800  // Timing measurements should always be positive definite
801  if(it.second->getDeltaCPU() < 0) {
802  ATH_MSG_WARNING("Negative CPU-time measurement of " << it.second->getDeltaCPU() <<
803  " ms for component " << it.first.compName <<
804  " in step " << it.first.stepName);
805  }
806  if(it.second->getDeltaWall() < 0) {
807  ATH_MSG_WARNING("Negative Wall-time measurement of " << it.second->getDeltaWall() <<
808  " ms for component " << it.first.compName <<
809  " in step " << it.first.stepName);
810  }
811  }
812  }
813 }
814 
815 /*
816  * Divide component-level data into steps, for printing
817  */
819  for (const auto &it : m_compLevelDataMap) {
820  if (it.first.stepName == "Initialize")
821  m_compLevelDataMap_ini[it.first] = it.second;
822  else if (it.first.stepName == "FirstEvent")
823  m_compLevelDataMap_1stevt[it.first] = it.second;
824  else if (it.first.stepName == "Execute")
825  m_compLevelDataMap_evt[it.first] = it.second;
826  else if (it.first.stepName == "Finalize")
827  m_compLevelDataMap_fin[it.first] = it.second;
828  else if (it.first.stepName == "preLoadProxy")
829  m_compLevelDataMap_plp[it.first] = it.second;
830  else if (it.first.stepName == "Callback")
831  m_compLevelDataMap_cbk[it.first] = it.second;
832  }
839 }
840 
841 std::string PerfMonMTSvc::scaleTime(double timeMeas) const {
842  // Not a huge fan of this, we should eventually unify the types
843  // Just want to be explicit about what's happening
844  auto ms = static_cast<int64_t>(timeMeas);
845 
846  // Compute hrs and offset
847  auto hrs = ms / 3600000;
848  ms -= hrs * 3600000;
849  // Compute mins and offset
850  auto mins = ms / 60000;
851  ms -= mins * 60000;
852  // Compute secs and offset
853  auto secs = ms / 1000;
854  ms -= secs * 1000;
855 
856  // Primarily care about H:M:S
857  std::stringstream ss;
858  ss.fill('0');
859  ss << std::setw(2) << hrs << "h" <<
860  std::setw(2) << mins << "m" <<
861  std::setw(2) << secs << "s";
862  return ss.str();
863 }
864 
865 std::string PerfMonMTSvc::scaleMem(int64_t memMeas) const {
866 
867  // Check if there is anything to be done
868  if (memMeas == 0) {
869  return "0.00 KB" ;
870  }
871 
872  // Prepare for the result
873  std::ostringstream ss;
874  ss << std::fixed;
875  ss << std::setprecision(2);
876 
877  // The input is in KB
878  std::vector<std::string> significance = {"KB", "MB", "GB", "TB"};
879 
880  // Get the absolute value
881  int64_t absMemMeas = std::abs(memMeas);
882  // Find the order, note that this is an int operation
883  int64_t order = std::log(absMemMeas)/std::log(1024);
884  // Compute the final value preserving the sign
885  double value = memMeas/std::pow(1024, order);
886  // Convert the result to a string
887  ss << value;
888 
889  return ss.str() + " " + significance[order];
890 }
891 
892 /*
893  * Collect some hardware information
894  */
895 std::string PerfMonMTSvc::get_info_from_file(const std::string& fileName,
896  const std::string& fieldName) const {
897  // Helper function to read files of type Key : Value
898  // Returns the last instance if there are multiple matches
899  // This is because we use this method to get the processor count
900  std::string result{""};
901 
902  std::ifstream file{fileName};
903  std::string line{""};
904 
905  while (std::getline(file, line)) {
906  if (line.empty()) continue;
907  size_t splitIdx = line.find(':');
908  if (splitIdx != std::string::npos) {
909  std::string val = line.substr(splitIdx + 1);
910  if (val.empty()) continue;
911  if (line.size() >= fieldName.size() &&
912  line.compare(0, fieldName.size(), fieldName) == 0) {
913  result = val;
914  }
915  }
916  }
917 
918  file.close();
919 
920  return result;
921 }
922 
923 std::string PerfMonMTSvc::get_cpu_model_info() const {
924  return get_info_from_file("/proc/cpuinfo","model name") +
925  get_info_from_file("/proc/cpuinfo","cache size");
926 }
927 
929  std::string val = get_info_from_file("/proc/cpuinfo","processor");
930  if (val.empty()) return 0;
931  return std::stoi(val) + 1;
932 }
933 
935  std::string val = get_info_from_file("/proc/meminfo","MemTotal");
936  if (val.empty()) return 0;
937  val.resize(val.size() - 3); // strip the trailing kB
938  return std::stoull(val);
939 }
PerfMonMTSvc::m_doComponentLevelMonitoring
Gaudi::Property< bool > m_doComponentLevelMonitoring
Do component level monitoring.
Definition: PerfMonMTSvc.h:120
PerfMonMTSvc::report2JsonFile
void report2JsonFile()
Report to the JSON File.
Definition: PerfMonMTSvc.cxx:616
PerfMonMTSvc::m_isFirstEvent
std::atomic< bool > m_isFirstEvent
Definition: PerfMonMTSvc.h:172
PerfMonMTSvc::stopSnapshotAud
void stopSnapshotAud(const std::string &stepName, const std::string &compName)
Definition: PerfMonMTSvc.cxx:235
PerfMonMTSvc::report2Log_Description
void report2Log_Description() const
Definition: PerfMonMTSvc.cxx:420
PerfMonMTSvc::divideData2Steps
void divideData2Steps()
Definition: PerfMonMTSvc.cxx:818
PerfMonMTSvc::getCpuEfficiency
int getCpuEfficiency() const
Definition: PerfMonMTSvc.cxx:355
AddEmptyComponent.compName
compName
Definition: AddEmptyComponent.py:32
checkFileSG.line
line
Definition: checkFileSG.py:75
PerfMonMTSvc::report2Log_ComponentLevel
void report2Log_ComponentLevel()
Definition: PerfMonMTSvc.cxx:437
get_generator_info.result
result
Definition: get_generator_info.py:21
PMonMT::symb2lib
const char * symb2lib(const char *symbol, const char *failstr)
Definition: PerfMonMTUtils.h:436
PerfMonMTSvc::m_compLevelDataMap_fin
data_map_t m_compLevelDataMap_fin
Definition: PerfMonMTSvc.h:202
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
PerfMonMTSvc::m_numberOfThreads
Gaudi::Property< int > m_numberOfThreads
Get the number of threads.
Definition: PerfMonMTSvc.h:146
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
PerfMonMTSvc::m_measurementSnapshots
PMonMT::SnapshotMeasurement m_measurementSnapshots
Measurement to capture snapshots.
Definition: PerfMonMTSvc.h:109
PerfMonMTSvc::m_compLevelDataMap
data_map_t m_compLevelDataMap
Definition: PerfMonMTSvc.h:194
vtune_athena.format
format
Definition: vtune_athena.py:14
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PerfMon::LinFitSglPass::addPoint
void addPoint(const double &, const double &)
Definition: LinFitSglPass.h:56
PerfMon::makeAuditor
StatusCode makeAuditor(const std::string &audName, IAuditorSvc *audSvc, MsgStream &msg)
simple function to factorize boring things such as asking the AuditorSvc if an auditor is there (and ...
Definition: PerfMonUtils.cxx:32
PerfMonMTSvc::m_motherPID
int m_motherPID
Snapshots data.
Definition: PerfMonMTSvc.h:160
PerfMonMTSvc::report2Log_CpuInfo
void report2Log_CpuInfo() const
Definition: PerfMonMTSvc.cxx:587
PerfMonMTSvc::report2Log_EnvInfo
void report2Log_EnvInfo() const
Definition: PerfMonMTSvc.cxx:601
json
nlohmann::json json
Definition: HistogramDef.cxx:9
PerfMonMTSvc::initialize
virtual StatusCode initialize() override
Standard Gaudi Service initialization.
Definition: PerfMonMTSvc.cxx:49
PerfMonMTSvc::m_eventCounter
std::atomic< uint64_t > m_eventCounter
Definition: PerfMonMTSvc.h:175
PerfMonMTSvc::get_cpu_core_info
int get_cpu_core_info() const
Definition: PerfMonMTSvc.cxx:928
rerun_display.cmd
string cmd
Definition: rerun_display.py:67
PerfMonMTSvc::m_checkPointTime
std::atomic< double > m_checkPointTime
Definition: PerfMonMTSvc.h:181
PerfMonMTSvc::m_wallTimeOffset
Gaudi::Property< double > m_wallTimeOffset
Offset for the wall-time, comes from configuration.
Definition: PerfMonMTSvc.h:141
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
PerfMonMTSvc::report2JsonFile_ComponentLevel
void report2JsonFile_ComponentLevel(nlohmann::json &j) const
Definition: PerfMonMTSvc.cxx:724
skel.it
it
Definition: skel.GENtoEVGEN.py:396
PerfMonMTSvc::m_fit_vmem
PerfMon::LinFitSglPass m_fit_vmem
Definition: PerfMonMTSvc.h:209
PerfMonMTSvc::handle
virtual void handle(const Incident &incident) override
Incident service handle for post-finalize.
Definition: PerfMonMTSvc.cxx:107
PMonMT::StepComp
Definition: PerfMonMTUtils.h:64
PerfMonMTSvc::get_cpu_model_info
std::string get_cpu_model_info() const
Definition: PerfMonMTSvc.cxx:923
PerfMonMTSvc::stopCompAud
void stopCompAud(const std::string &stepName, const std::string &compName, const EventContext &ctx)
Definition: PerfMonMTSvc.cxx:297
PerfMonMTSvc::CONFIGURE
@ CONFIGURE
Definition: PerfMonMTSvc.h:163
PerfMonMTSvc::m_measurementEvents
PMonMT::SnapshotMeasurement m_measurementEvents
Measurement to capture events.
Definition: PerfMonMTSvc.h:112
athena.value
value
Definition: athena.py:124
PerfMonMTSvc::m_eventLoopMsgLimit
Gaudi::Property< uint64_t > m_eventLoopMsgLimit
Set the number of messages for the event-level report.
Definition: PerfMonMTSvc.h:150
PerfMonMTSvc::FINALIZE
@ FINALIZE
Definition: PerfMonMTSvc.h:163
PerfMonMTSvc::report2Log_EventLevel
void report2Log_EventLevel()
Definition: PerfMonMTSvc.cxx:500
PerfMonMTSvc::startSnapshotAud
void startSnapshotAud(const std::string &stepName, const std::string &compName)
Snapshot Auditing: Take snapshots at the beginning and at the end of each step.
Definition: PerfMonMTSvc.cxx:217
python.SystemOfUnits.ms
int ms
Definition: SystemOfUnits.py:132
PerfMonMTSvc::m_isEvtLoopStopped
std::atomic< bool > m_isEvtLoopStopped
Definition: PerfMonMTSvc.h:184
PerfMonMTSvc::report2Log_Summary
void report2Log_Summary()
Definition: PerfMonMTSvc.cxx:538
PerfMonMTSvc::m_compLevelDataMap_ini
data_map_t m_compLevelDataMap_ini
Definition: PerfMonMTSvc.h:199
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
PMonMT::ComponentMeasurement::cpu_time
double cpu_time
Definition: PerfMonMTUtils.h:78
PerfMonMTSvc::m_compLevelDataMap_evt
data_map_t m_compLevelDataMap_evt
Definition: PerfMonMTSvc.h:201
python.CreateTierZeroArgdict.pairs
pairs
Definition: CreateTierZeroArgdict.py:201
PerfMonMTSvc::m_snapshotData
std::vector< PMonMT::SnapshotData > m_snapshotData
Definition: PerfMonMTSvc.h:161
PMonMT::ComponentMeasurement
Definition: PerfMonMTUtils.h:75
PerfMonMTSvc::INITIALIZE
@ INITIALIZE
Definition: PerfMonMTSvc.h:163
PerfMonMTSvc::report2Log_EventLevel_instant
void report2Log_EventLevel_instant() const
Definition: PerfMonMTSvc.cxx:483
PixelModuleFeMask_create_db.remove
string remove
Definition: PixelModuleFeMask_create_db.py:83
PMonMT::get_wall_time
double get_wall_time()
Definition: PerfMonMTUtils.h:331
PMonMT::EventLevelData::getEventLevelData
const EventMeasMap_t & getEventLevelData() const
Definition: PerfMonMTUtils.h:221
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
PerfMonMTSvc::startAud
virtual void startAud(const std::string &stepName, const std::string &compName) override
Start Auditing.
Definition: PerfMonMTSvc.cxx:183
PerfMonMTSvc::m_fit_pss
PerfMon::LinFitSglPass m_fit_pss
Definition: PerfMonMTSvc.h:210
PerfMonMTSvc::report2Log
void report2Log()
Report to log.
Definition: PerfMonMTSvc.cxx:397
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
PMonMT::ComponentMeasurement::wall_time
double wall_time
Definition: PerfMonMTUtils.h:78
lumiFormat.i
int i
Definition: lumiFormat.py:85
PMonMT::EventLevelData::getEventLevelMemoryMax
int64_t getEventLevelMemoryMax(const std::string &stat) const
Definition: PerfMonMTUtils.h:242
PerfMonMTSvc::m_reportResultsToJSON
Gaudi::Property< bool > m_reportResultsToJSON
Report results to JSON.
Definition: PerfMonMTSvc.h:125
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
mc.order
order
Configure Herwig7.
Definition: mc.Herwig7_Dijet.py:12
PerfMonMTSvc::m_jsonFileName
Gaudi::Property< std::string > m_jsonFileName
Name of the JSON file.
Definition: PerfMonMTSvc.h:127
taskman.fieldName
fieldName
Definition: taskman.py:492
PerfMonMTSvc::finalize
virtual StatusCode finalize() override
Standard Gaudi Service finalization.
Definition: PerfMonMTSvc.cxx:97
PerfMonMTSvc::report2JsonFile_EventLevel
void report2JsonFile_EventLevel(nlohmann::json &j) const
Definition: PerfMonMTSvc.cxx:749
file
TFile * file
Definition: tile_monitor.h:29
PerfMonMTSvc::m_eventLoopMsgCounter
std::atomic< uint64_t > m_eventLoopMsgCounter
Definition: PerfMonMTSvc.h:178
PerfMonUtils.h
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
python.xAODType.dummy
dummy
Definition: xAODType.py:4
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
nEvents
int nEvents
Definition: fbtTestBasics.cxx:79
PMonMT::SnapshotMeasurement::capture
void capture()
Definition: PerfMonMTUtils.h:178
PerfMonMTSvc::scaleMem
std::string scaleMem(int64_t memMeas) const
Definition: PerfMonMTSvc.cxx:865
PerfMonMTSvc::scaleTime
std::string scaleTime(double timeMeas) const
Definition: PerfMonMTSvc.cxx:841
PerfMonMTSvc::get_memory_info
uint64_t get_memory_info() const
Definition: PerfMonMTSvc.cxx:934
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
PerfMonMTSvc::NSNAPSHOTS
@ NSNAPSHOTS
Definition: PerfMonMTSvc.h:163
PerfMon::LinFitSglPass::nPoints
unsigned nPoints() const
Definition: LinFitSglPass.h:31
PerfMonMTSvc::stopAud
virtual void stopAud(const std::string &stepName, const std::string &compName) override
Stop Auditing.
Definition: PerfMonMTSvc.cxx:202
PerfMonMTSvc::report2JsonFile_Summary
void report2JsonFile_Summary(nlohmann::json &j) const
Definition: PerfMonMTSvc.cxx:654
PMonMT::StepComp::stepName
std::string stepName
Definition: PerfMonMTUtils.h:65
PerfMonMTSvc.h
PerfMonMTSvc::m_snapshotStepNames
std::vector< std::string > m_snapshotStepNames
Definition: PerfMonMTSvc.h:162
PerfMonMTSvc::m_exclusionSet
const std::set< std::string > m_exclusionSet
Exclude some common components from monitoring In the future this might be converted to a inclusion s...
Definition: PerfMonMTSvc.h:155
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
PMonMT::EventLevelData::getEventLevelMemory
int64_t getEventLevelMemory(const uint64_t event_count, const std::string &stat) const
Definition: PerfMonMTUtils.h:237
PerfMonMTSvc::m_mutex_capture
std::mutex m_mutex_capture
Definition: PerfMonMTSvc.h:169
PMonMT::ComponentMeasurement::vmem
double vmem
Definition: PerfMonMTUtils.h:79
PerfMonMTSvc::m_numberOfSlots
Gaudi::Property< int > m_numberOfSlots
Get the number of slots.
Definition: PerfMonMTSvc.h:148
PerfMonMTSvc::m_printNComps
Gaudi::Property< int > m_printNComps
Print the top N components.
Definition: PerfMonMTSvc.h:143
PerfMonMTSvc::m_printDetailedTables
Gaudi::Property< bool > m_printDetailedTables
Print detailed tables.
Definition: PerfMonMTSvc.h:130
PerfMonMTSvc::aggregateSlotData
void aggregateSlotData()
A few helper functions.
Definition: PerfMonMTSvc.cxx:785
PMonMT::EventLevelData::set_wall_time_offset
void set_wall_time_offset(const double wall_time_offset)
Definition: PerfMonMTUtils.h:219
PerfMonMTSvc::m_stdoutVec_serial
std::vector< data_map_t > m_stdoutVec_serial
Definition: PerfMonMTSvc.h:206
PerfMonMTSvc::m_eventLevelData
PMonMT::EventLevelData m_eventLevelData
Definition: PerfMonMTSvc.h:166
PerfMonMTSvc::PerfMonMTSvc
PerfMonMTSvc(const std::string &name, ISvcLocator *pSvcLocator)
Standard Gaudi Service constructor.
Definition: PerfMonMTSvc.cxx:34
a
TList * a
Definition: liststreamerinfos.cxx:10
PMonMT::EventLevelData::getNMeasurements
uint64_t getNMeasurements() const
Definition: PerfMonMTUtils.h:225
PerfMonMTSvc::m_doEventLoopMonitoring
Gaudi::Property< bool > m_doEventLoopMonitoring
Do event loop monitoring.
Definition: PerfMonMTSvc.h:115
PerfMonMTSvc::EXECUTE
@ EXECUTE
Definition: PerfMonMTSvc.h:163
PerfMonMTSvc::m_checkPointThreshold
Gaudi::Property< uint64_t > m_checkPointThreshold
Frequency of event level monitoring.
Definition: PerfMonMTSvc.h:137
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
PMonMT::ComponentMeasurement::malloc
double malloc
Definition: PerfMonMTUtils.h:79
PerfMon::LinFitSglPass::slope
double slope() const
Definition: LinFitSglPass.h:75
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
PerfMonMTSvc::m_compLevelDataMap_1stevt
data_map_t m_compLevelDataMap_1stevt
Definition: PerfMonMTSvc.h:200
PerfMonMTSvc::m_memFitLowerLimit
Gaudi::Property< uint64_t > m_memFitLowerLimit
Lower limit (in number of events) for the memory fit.
Definition: PerfMonMTSvc.h:133
LArCellBinning.step
step
Definition: LArCellBinning.py:158
PMonMT::StepComp::compName
std::string compName
Definition: PerfMonMTUtils.h:66
PerfMonMTSvc::FIRSTEVENT
@ FIRSTEVENT
Definition: PerfMonMTSvc.h:163
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211
test_pyathena.counter
counter
Definition: test_pyathena.py:15
checker_macros.h
Define macros for attributes used to control the static checker.
PerfMonMTSvc::get_info_from_file
std::string get_info_from_file(const std::string &fileName, const std::string &fieldName) const
A few helper methods to get system information These should be carried to PerfMonMTUtils at some poin...
Definition: PerfMonMTSvc.cxx:895
PMonMT::doesDirectoryExist
bool doesDirectoryExist(const std::string &dir)
Definition: PerfMonMTUtils.h:416
PerfMonMTSvc::m_compLevelDataMapVec
std::vector< data_map_unique_t > m_compLevelDataMapVec
Definition: PerfMonMTSvc.h:198
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
PerfMonMTSvc::m_compLevelDataMap_cbk
data_map_t m_compLevelDataMap_cbk
Definition: PerfMonMTSvc.h:204
PerfMonMTSvc::data_map_unique_t
std::map< PMonMT::StepComp, std::unique_ptr< PMonMT::ComponentData > > data_map_unique_t
Definition: PerfMonMTSvc.h:190
PerfMonMTSvc::generate_state
PMonMT::StepComp generate_state(const std::string &stepName, const std::string &compName) const
Definition: PerfMonMTSvc.cxx:775
PMonMT::ComponentMeasurement::capture
void capture()
Definition: PerfMonMTUtils.h:82
PerfMonMTSvc::report
void report()
Report the results.
Definition: PerfMonMTSvc.cxx:384
PerfMonMTSvc::startCompAud
void startCompAud(const std::string &stepName, const std::string &compName, const EventContext &ctx)
Component Level Auditing: Take measurements at the beginning and at the end of each component call.
Definition: PerfMonMTSvc.cxx:254
PMonMT::EventLevelData::getEventLevelWallTime
double getEventLevelWallTime(const uint64_t event_count) const
Definition: PerfMonMTUtils.h:233
PerfMonMTSvc::m_compLevelDataMap_plp
data_map_t m_compLevelDataMap_plp
Definition: PerfMonMTSvc.h:203
PMonMT::EventLevelData::recordEvent
void recordEvent(const SnapshotMeasurement &meas, const int eventCount)
Definition: PerfMonMTUtils.h:204
PMonMT::EventLevelData::getEventLevelCpuTime
double getEventLevelCpuTime(const uint64_t event_count) const
Definition: PerfMonMTUtils.h:229
ServiceHandle< IIncidentSvc >