OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
MemoryProfiler.cpp
Go to the documentation of this file.
1 #include "MemoryProfiler.h"
2 
3 #ifdef __linux__
4 #include <sys/types.h>
5 #include <unistd.h>
6 #endif
7 
8 #include "Utilities/Timer.h"
12 
13 #include <boost/filesystem.hpp>
14 
15 #include "Ippl.h"
16 
17 #include <sstream>
18 
19 MemoryProfiler::MemoryProfiler(const std::string& fname, bool restart)
20  : SDDSWriter(fname, restart)
21 {
22  procinfo_m = {
23  {"VmPeak:", VirtualMemory::VMPEAK},
24  {"VmSize:", VirtualMemory::VMSIZE},
25  {"VmHWM:", VirtualMemory::VMHWM},
26  {"VmRSS:", VirtualMemory::VMRSS},
27  {"VmStk:", VirtualMemory::VMSTK},
28  {"VmData:", VirtualMemory::VMDATA},
29  {"VmExe:", VirtualMemory::VMEXE},
30  {"VmLck:", VirtualMemory::VMLCK},
31  {"VmPin:", VirtualMemory::VMPIN},
32  {"VmLib:", VirtualMemory::VMLIB},
33  {"VmPTE:", VirtualMemory::VMPTE},
34  {"VmPMD:", VirtualMemory::VMPMD},
35  {"VmSwap:", VirtualMemory::VMSWAP}
36  };
37 
38  vmem_m.resize(procinfo_m.size());
39  unit_m.resize(procinfo_m.size());
40 }
41 
42 
44 
45  if (this->hasColumns()) {
46  return;
47  }
48 
49  columns_m.addColumn("t", "double", "ns", "Time");
50 
51  columns_m.addColumn("s", "double", "m", "Path length");
52 
53  // peak virtual memory size
54  columns_m.addColumn("VmPeak-Min", "double", unit_m[VirtualMemory::VMPEAK],
55  "Minimum peak virtual memory size");
56 
57  columns_m.addColumn("VmPeak-Max", "double", unit_m[VirtualMemory::VMPEAK],
58  "Maximum peak virtual memory size");
59 
60  columns_m.addColumn("VmPeak-Avg", "double", unit_m[VirtualMemory::VMPEAK],
61  "Average peak virtual memory size");
62 
63  // virtual memory size
64  columns_m.addColumn("VmSize-Min", "double", unit_m[VirtualMemory::VMSIZE],
65  "Minimum virtual memory size");
66 
67  columns_m.addColumn("VmSize-Max", "double", unit_m[VirtualMemory::VMSIZE],
68  "Maximum virtual memory size");
69 
70  columns_m.addColumn("VmSize-Avg", "double", unit_m[VirtualMemory::VMSIZE],
71  "Average virtual memory size");
72 
73  // peak resident set size ("high water mark")
74  columns_m.addColumn("VmHWM-Min", "double", unit_m[VirtualMemory::VMHWM],
75  "Minimum peak resident set size");
76 
77  columns_m.addColumn("VmHWM-Max", "double", unit_m[VirtualMemory::VMHWM],
78  "Maximum peak resident set size");
79 
80  columns_m.addColumn("VmHWM-Avg", "double", unit_m[VirtualMemory::VMHWM],
81  "Average peak resident set size");
82 
83  // resident set size
84  columns_m.addColumn("VmRSS-Min", "double", unit_m[VirtualMemory::VMRSS],
85  "Minimum resident set size");
86 
87  columns_m.addColumn("VmRSS-Max", "double", unit_m[VirtualMemory::VMRSS],
88  "Maximum resident set size");
89 
90  columns_m.addColumn("VmRSS-Avg", "double", unit_m[VirtualMemory::VMRSS],
91  "Average resident set size");
92 
93  // stack size
94  columns_m.addColumn("VmStk-Min", "double", unit_m[VirtualMemory::VMSTK],
95  "Minimum stack size");
96 
97  columns_m.addColumn("VmStk-Max", "double", unit_m[VirtualMemory::VMSTK],
98  "Maximum stack size");
99 
100  columns_m.addColumn("VmStk-Avg", "double", unit_m[VirtualMemory::VMSTK],
101  "Average stack size");
102 
103  if ( mode_m == std::ios::app )
104  return;
105 
106  OPALTimer::Timer simtimer;
107 
108  std::string dateStr(simtimer.date());
109  std::string timeStr(simtimer.time());
110 
111  std::stringstream ss;
112  ss << "Memory statistics '"
113  << OpalData::getInstance()->getInputFn() << "' "
114  << dateStr << "" << timeStr;
115 
116  this->addDescription(ss.str(), "memory info");
117 
118  this->addDefaultParameters();
119 
120  this->addInfo("ascii", 1);
121 }
122 
123 
125 #ifdef __linux__
126  static pid_t pid = getpid();
127  std::string fname = "/proc/" + std::to_string(pid) + "/status";
128 
129  if ( !boost::filesystem::exists(fname) ) {
130  throw OpalException("MemoryProfiler::update()",
131  "File '" + fname + "' doesn't exist.");
132  }
133 
134  std::ifstream ifs(fname.c_str());
135 
136  if ( !ifs.is_open() ) {
137  throw OpalException("MemoryProfiler::update()",
138  "Failed to open '" + fname + "'.");
139  }
140 
141  std::string token = "";
142  while (ifs >> token) {
143  if ( !procinfo_m.count(token) ) {
144  continue;
145  }
146  int idx = procinfo_m[token];
147  ifs >> vmem_m[idx]
148  >> unit_m[idx];
149  }
150 
151  ifs.close();
152 #endif
153 }
154 
155 
157  vm_t& vmMax,
158  vm_t& vmAvg)
159 {
160  if ( Ippl::getNodes() == 1 ) {
161  for (unsigned int i = 0; i < vmem_m.size(); ++i) {
162  vmMin[i] = vmMax[i] = vmAvg[i] = vmem_m[i];
163  }
164  return;
165  }
166 
167  new_reduce(vmem_m.data(), vmAvg.data(), vmem_m.size(), std::plus<double>());
168 
169  double inodes = 1.0 / double(Ippl::getNodes());
170  for (auto& vm : vmAvg) {
171  vm *= inodes;
172  }
173 
174  new_reduce(vmem_m.data(), vmMin.data(), vmem_m.size(), std::less<double>());
175  new_reduce(vmem_m.data(), vmMax.data(), vmem_m.size(), std::greater<double>());
176 }
177 
178 
180 
181  this->update();
182 
183  vm_t vmMin(vmem_m.size());
184  vm_t vmMax(vmem_m.size());
185  vm_t vmAvg(vmem_m.size());
186 
187  this->compute(vmMin, vmMax, vmAvg);
188 
189  if ( Ippl::myNode() != 0 ) {
190  return;
191  }
192 
193  double pathLength = beam->get_sPos();
194 
195  header();
196 
197  this->open();
198 
199  this->writeHeader();
200 
201  columns_m.addColumnValue("t", beam->getT() * 1e9); // 1
202  columns_m.addColumnValue("s", pathLength); // 2
203 
204  // boost::variant can't overload double and long double. By using a
205  // string this shortcoming can be bypassed.
206  columns_m.addColumnValue("VmPeak-Min", toString(vmMin[VMPEAK]));
207  columns_m.addColumnValue("VmPeak-Max", toString(vmMax[VMPEAK]));
208  columns_m.addColumnValue("VmPeak-Avg", toString(vmAvg[VMPEAK]));
209 
210  columns_m.addColumnValue("VmSize-Min", toString(vmMin[VMSIZE]));
211  columns_m.addColumnValue("VmSize-Max", toString(vmMax[VMSIZE]));
212  columns_m.addColumnValue("VmSize-Avg", toString(vmAvg[VMSIZE]));
213 
214  columns_m.addColumnValue("VmHWM-Min", toString(vmMin[VMHWM]));
215  columns_m.addColumnValue("VmHWM-Max", toString(vmMax[VMHWM]));
216  columns_m.addColumnValue("VmHWM-Avg", toString(vmAvg[VMHWM]));
217 
218  columns_m.addColumnValue("VmRSS-Min", toString(vmMin[VMRSS]));
219  columns_m.addColumnValue("VmRSS-Max", toString(vmMax[VMRSS]));
220  columns_m.addColumnValue("VmRSS-Avg", toString(vmAvg[VMRSS]));
221 
222  columns_m.addColumnValue("VmStk-Min", toString(vmMin[VMSTK]));
223  columns_m.addColumnValue("VmStk-Max", toString(vmMax[VMSTK]));
224  columns_m.addColumnValue("VmStk-Avg", toString(vmAvg[VMSTK]));
225 
226  this->writeRow();
227 
228  this->close();
229 }
static int getNodes()
Definition: IpplInfo.cpp:773
double getT() const
bool hasColumns() const
Definition: SDDSWriter.h:190
void writeHeader()
Write SDDS header.
Definition: SDDSWriter.cpp:130
void writeRow()
Definition: SDDSWriter.h:175
The base class for all OPAL exceptions.
Definition: OpalException.h:28
static int myNode()
Definition: IpplInfo.cpp:794
void close()
Definition: SDDSWriter.cpp:123
void addDescription(const std::string &text, const std::string &content)
Definition: SDDSWriter.h:147
SDDSColumnSet columns_m
Definition: SDDSWriter.h:109
std::string date() const
Return date.
Definition: Timer.cpp:35
MemoryProfiler(const std::string &fname, bool restart)
void compute(vm_t &vmMin, vm_t &vmMax, vm_t &vmAvg)
static OpalData * getInstance()
Definition: OpalData.cpp:209
std::string getInputFn()
get opals input filename
Definition: OpalData.cpp:713
void addColumnValue(const std::string &name, const T &val)
Definition: SDDSColumnSet.h:46
void write(PartBunchBase< double, 3 > *beam) override
std::ios_base::openmode mode_m
First write to the statistics output file.
Definition: SDDSWriter.h:107
std::string toString(const T &val)
Definition: SDDSWriter.h:181
std::string time() const
Return time.
Definition: Timer.cpp:42
std::map< std::string, int > procinfo_m
void addColumn(const std::string &name, const std::string &type, const std::string &unit, const std::string &desc, std::ios_base::fmtflags flags=std::ios_base::scientific, unsigned short precision=15)
void open()
Definition: SDDSWriter.cpp:113
void addDefaultParameters()
Definition: SDDSWriter.cpp:190
std::vector< long double > vm_t
void new_reduce(const T *input, T *output, int count, Op op, int root=0)
Definition: GlobalComm.hpp:477
void addInfo(const std::string &mode, const size_t &no_row_counts)
Definition: SDDSWriter.h:168