ndmspc  v1.2.0-0.1.rc3
NResourceMonitor.cxx
1 #include <THnSparse.h>
2 #include <TROOT.h>
3 #include "NLogger.h"
4 #include "NUtils.h"
5 #include "NResourceMonitor.h"
6 
10 
11 namespace Ndmspc {
14 void NResourceMonitor::Print(Option_t * /*option*/) const
15 {
19  double userStart = timevalToDouble(fUsageStart.ru_utime);
20  double sysStart = timevalToDouble(fUsageStart.ru_stime);
21  double userEnd = timevalToDouble(fUsageEnd.ru_utime);
22  double sysEnd = timevalToDouble(fUsageEnd.ru_stime);
23 
24  double wallStart = std::chrono::duration<double>(fWallStart.time_since_epoch()).count();
25  double wallEnd = std::chrono::duration<double>(fWallEnd.time_since_epoch()).count();
26 
27  NLogInfo("Resource usage:");
28  NLogInfo(" User time: %.6f s", userEnd - userStart);
29  NLogInfo(" System time: %.6f s", sysEnd - sysStart);
30  NLogInfo(" Wall time: %.6f s", wallEnd - wallStart);
31 
32  // calculate effective CPU usage
33  NLogInfo(" CPU usage: %.2f %%", GetCpuUsage());
34 
35  NLogInfo(" Min RSS: %ld KB", fUsageStart.ru_maxrss);
36  NLogInfo(" Max RSS: %ld KB", fUsageEnd.ru_maxrss);
37  NLogInfo(" Diff RSS: %ld KB", fUsageEnd.ru_maxrss - fUsageStart.ru_maxrss);
38  // NLogInfo(" Minor faults: %ld", fUsageEnd.ru_minflt - fUsageStart.ru_minflt);
39  // NLogInfo(" Major faults: %ld", fUsageEnd.ru_majflt - fUsageStart.ru_majflt);
40 }
41 
42 THnSparse * NResourceMonitor::Initialize(THnSparse * hns)
43 {
47  std::vector<TAxis *> axes;
48  int nThreads = ROOT::GetThreadPoolSize();
49  if (nThreads <= 0) nThreads = 1;
50 
51  NLogTrace("NResourceMonitor::Initialize: Initializing resource monitor for %d threads", nThreads);
52 
53  TAxis * threadAxis = new TAxis(nThreads, 0, nThreads);
54  threadAxis->SetNameTitle("thread", "Thread");
55  // set labels for thread axis
56  for (int i = 0; i < nThreads; ++i) {
57  threadAxis->SetBinLabel(i + 1, TString::Format("%d", i).Data());
58  }
59  axes.push_back(threadAxis);
60  TAxis * aStat = NUtils::CreateAxisFromLabels("stat", "Stat", fNames);
61  axes.push_back(aStat);
62 
63  if (fHnSparse) {
64  NLogWarning("NResourceMonitor::Initialize: THnSparse is already initialized, overwriting ...");
65  SafeDelete(fHnSparse);
66  }
67 
68  fHnSparse = NUtils::ReshapeSparseAxes(hns, {}, axes);
69  fHnSparse->SetNameTitle("resource_monitor", "Resource Monitor");
70 
71  return fHnSparse;
72 }
73 
74 void NResourceMonitor::Fill(Int_t * coords, int threadId)
75 {
80  auto statBinCoords = std::make_unique<Int_t[]>(fHnSparse->GetNdimensions());
81  // Int_t statBinCoords[fHnSparse->GetNdimensions()];
82  // set statBinCoords from statHnSparse
83  for (Int_t i = 0; i < fHnSparse->GetNdimensions() - 2; ++i) {
84  statBinCoords[i] = coords[i];
85  }
86  Long64_t statBin;
87 
88  // Set thread id coordinate
89  statBinCoords[fHnSparse->GetNdimensions() - 2] = threadId + 1;
90 
91  statBinCoords[fHnSparse->GetNdimensions() - 1] = 1;
92  statBin = fHnSparse->GetBin(statBinCoords.get());
93  fHnSparse->SetBinContent(statBin, GetTimeDiffInSeconds());
94 
95  // Set CPU usage
96  statBinCoords[fHnSparse->GetNdimensions() - 1] = 2;
97  statBin = fHnSparse->GetBin(statBinCoords.get());
98  fHnSparse->SetBinContent(statBin, GetCpuUsage());
99 
100  // Set Memory usage
101  statBinCoords[fHnSparse->GetNdimensions() - 1] = 3;
102  statBin = fHnSparse->GetBin(statBinCoords.get());
103  fHnSparse->SetBinContent(statBin, GetMemoryUsageDiff());
104 }
105 
107 {
108  fWallStart = std::chrono::high_resolution_clock::now();
109  // gather start resource usage
110  if (getrusage(RUSAGE_SELF, &fUsageStart) == -1) {
111  NLogError("NResourceMonitor::Start: getrusage failed at start");
112  }
113 }
114 
116 {
117  fWallEnd = std::chrono::high_resolution_clock::now();
118  // gather resource usage after processing
119  if (getrusage(RUSAGE_SELF, &fUsageEnd) == -1) {
120  NLogError("NResourceMonitor::End: getrusage failed at end");
121  }
122 }
124 {
125  std::chrono::duration<double> diff = fWallEnd - fWallStart;
126  return diff.count();
127 }
128 
130 {
131 
132  double userStart = timevalToDouble(fUsageStart.ru_utime);
133  double sysStart = timevalToDouble(fUsageStart.ru_stime);
134  double userEnd = timevalToDouble(fUsageEnd.ru_utime);
135  double sysEnd = timevalToDouble(fUsageEnd.ru_stime);
136 
137  double wallStart = std::chrono::duration<double>(fWallStart.time_since_epoch()).count();
138  double wallEnd = std::chrono::duration<double>(fWallEnd.time_since_epoch()).count();
139 
140  double usage = ((userEnd - userStart) + (sysEnd - sysStart)) / (wallEnd - wallStart) * 100.0;
141  return usage;
142 }
143 
144 } // namespace Ndmspc
Monitors and records resource usage (CPU, memory, wall time) for processes or threads.
void Start()
Records the starting resource usage and wall time.
THnSparse * fHnSparse
THnSparse histogram for resource data.
virtual void Print(Option_t *option="") const
Prints the resource monitor information.
double GetTimeDiffInSeconds() const
Returns the time difference in seconds since the last measurement or reset.
std::chrono::high_resolution_clock::time_point fWallStart
Wall clock start time.
void End()
Records the ending resource usage and wall time.
virtual ~NResourceMonitor()
Destructor.
double timevalToDouble(const timeval &tv) const
Helper function to convert timeval to double seconds.
std::vector< std::string > fNames
Axis names.
void Fill(Int_t *coords, int threadId)
Fills resource usage data into the histogram.
double GetCpuUsage() const
Calculates and returns the CPU usage between Start and End.
THnSparse * Initialize(THnSparse *hns)
Initializes the THnSparse histogram for resource data.
NResourceMonitor()
Default constructor.
rusage fUsageStart
Resource usage at start.
rusage fUsageEnd
Resource usage at end.
std::chrono::high_resolution_clock::time_point fWallEnd
Wall clock end time.
long GetMemoryUsageDiff() const
Returns the difference in memory usage (in kilobytes) between Start and End.
static THnSparse * ReshapeSparseAxes(THnSparse *hns, std::vector< int > order, std::vector< TAxis * > newAxes={}, std::vector< int > newPoint={}, Option_t *option="E")
Reshape axes of THnSparse.
Definition: NUtils.cxx:452
static TAxis * CreateAxisFromLabels(const std::string &name, const std::string &title, const std::vector< std::string > &labels)
Create a TAxis from a list of labels.
Definition: NUtils.cxx:185