GraphChi  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Macros
metrics.hpp
Go to the documentation of this file.
1 
30 #ifndef DEF_METRICS_HPP
31 #define DEF_METRICS_HPP
32 
33 #include <cstring>
34 #include <map>
35 #include <vector>
36 #include <limits>
37 #include <assert.h>
38 #include <sys/time.h>
39 
40 #include "util/pthread_tools.hpp"
41 #include "util/cmdopts.hpp"
42 
43 namespace graphchi {
44 
45 
46  enum metrictype {REAL, INTEGER, TIME, STRING, VECTOR};
47 
48  // Data structure for storing metric entries
49  // NOTE: This data structure is not very optimal, should
50  // of course use inheritance. But for this purpose,
51  // it works fine as the number of metrics entry is small.
52  struct metrics_entry {
53  size_t count;
54  double value;
55  double minvalue;
56  double cumvalue;
57  double maxvalue;
58  metrictype valtype;
59  std::string stringval;
60  std::vector<double> v;
61  timeval start_time;
62  double lasttime;
63 
64  metrics_entry() {}
65 
66  inline metrics_entry(double firstvalue, metrictype _valtype) {
67  minvalue = firstvalue;
68  maxvalue = firstvalue;
69  value = firstvalue;
70  valtype = _valtype;
71  cumvalue = value;
72  count = 1;
73  if (valtype == VECTOR) v.push_back(firstvalue);
74  };
75  inline metrics_entry(std::string svalue) {
76  valtype = STRING;
77  stringval = svalue;
78  }
79  inline metrics_entry(metrictype _valtype) {
80  valtype = _valtype;
81  count = 0;
82  cumvalue = 0;
83  value = 0;
84  minvalue = std::numeric_limits<double>::max();
85  maxvalue = std::numeric_limits<double>::min();
86  }
87  inline void adj(double v) {
88  if (count == 0) {
89  minvalue = v;
90  maxvalue = v;
91  } else {
92  minvalue = std::min(v,minvalue);
93  maxvalue = std::max(v,maxvalue);
94  }
95  }
96 
97 
98  inline void add(double x) {
99  adj(x);
100  value += x;
101  cumvalue += x;
102  ++count;
103  if (valtype == VECTOR) {
104  v.push_back(x);
105  }
106  }
107 
108 
109 
110 
111  inline void set(double v) {
112  adj(v);
113  value = v;
114  cumvalue += v;
115  }
116  inline void set(std::string s) {
117  stringval = s;
118  }
119 
120  inline void add_vector_entry(size_t i, double x) {
121  if (v.size() < i + 1) v.resize(i + 1);
122  count = v.size();
123  value += x;
124  cumvalue += x;
125  v[i] += x;
126  adj(v[i]);
127  }
128 
129  inline void set_vector_entry(size_t i, double x) {
130  if (v.size() < i + 1) v.resize(i + 1);
131  count = v.size();
132  value = value - v[i] + x;
133  cumvalue = cumvalue - v[i] + x;
134  v[i] = x;
135 
136  minvalue = x; maxvalue = x;
137  for (size_t i = 0; i < v.size(); ++i) {
138  adj(v[i]);
139  }
140  }
141 
142  inline void timer_start() {
143  gettimeofday(&start_time, NULL);
144 
145  }
146  inline void timer_stop() {
147  timeval end;
148  gettimeofday(&end, NULL);
149  lasttime = end.tv_sec - start_time.tv_sec + ((double)(end.tv_usec - start_time.tv_usec)) / 1.0E6;
150  add(lasttime);
151  }
152  };
153 
154  class imetrics_reporter {
155 
156  public:
157  virtual ~imetrics_reporter() {}
158  virtual void do_report(std::string name, std::string id, std::map<std::string, metrics_entry> & entries) = 0;
159  };
160 
165  class metrics {
166 
167  std::string name, ident;
168  std::map<std::string, metrics_entry> entries;
169  mutex mlock;
170 
171  public:
172  inline metrics(std::string _name = "", std::string _id = "") : name(_name), ident (_id) {
173  }
174 
175  inline void clear() {
176  entries.clear();
177  }
178 
179 
180  inline std::string iterkey(std::string key, int iter) {
181  char s[256];
182  sprintf(s, "%s.%d", key.c_str(), iter);
183  return std::string(s);
184  }
185 
189  inline void add(std::string key, double value, metrictype type = REAL) {
190  mlock.lock();
191  if (entries.count(key) == 0) {
192  entries[key] = metrics_entry(value, type);
193  } else {
194  entries[key].add(value);
195  }
196  mlock.unlock();
197  }
198 
199  inline void add_to_vector(std::string key, double value) {
200  if (entries.count(key) == 0) {
201  entries[key] = metrics_entry(value, VECTOR);
202  } else {
203  entries[key].add(value);
204  }
205  }
206 
207  inline void add_vector_entry(std::string key, size_t idx, double value) {
208  if (entries.count(key) == 0) {
209  entries[key] = metrics_entry(VECTOR);
210  }
211  entries[key].add_vector_entry(idx, value);
212  }
213 
214  inline void set(std::string key, size_t value) {
215  set(key, (double)value, INTEGER);
216  }
217 
218 
219  inline void set(std::string key, int value) {
220  set(key, (double)value, INTEGER);
221  }
222 
223  inline void set(std::string key, double value, metrictype type = REAL) {
224  if (entries.count(key) == 0) {
225  entries[key] = metrics_entry(value, type);
226  } else {
227  entries[key].set(value);
228  }
229  }
230 
231  inline void set_integer(std::string key, size_t value) {
232  if (entries.count(key) == 0) {
233  entries[key] = metrics_entry((double)value, INTEGER);
234  } else {
235  entries[key].set((double)value);
236  }
237  }
238 
239  inline void set(std::string key, std::string s) {
240  if (entries.count(key) == 0) {
241  entries[key] = metrics_entry(s);
242  } else {
243  entries[key].set(s);
244  }
245  }
246 
247  inline void set_vector_entry_integer(std::string key, size_t idx, size_t value) {
248  set_vector_entry(key, idx, (double)(value));
249  }
250 
251  inline void set_vector_entry(std::string key, size_t idx, double value) {
252  mlock.lock();
253 
254  if (entries.count(key) == 0) {
255  entries[key] = metrics_entry(VECTOR);
256  }
257  entries[key].set_vector_entry(idx, value);
258  mlock.unlock();
259  }
260 
261  inline void start_time(std::string key) {
262  mlock.lock();
263 
264  if (entries.count(key) == 0) {
265  entries[key] = metrics_entry(TIME);
266  }
267  entries[key].timer_start();
268  mlock.unlock();
269 
270  }
271 
272  metrics_entry start_time() {
273  metrics_entry me(TIME);
274  me.timer_start();
275  return me;
276  }
277 
278 
279 
280  inline void stop_time(metrics_entry me, std::string key, bool show=false) {
281  me.timer_stop();
282  mlock.lock();
283 
284  if (entries.count(key) == 0) {
285  entries[key] = metrics_entry(TIME);
286  }
287  entries[key].add(me.lasttime); // not thread safe
288  if (show)
289  std::cout << key << ": " << me.lasttime << " secs." << std::endl;
290  mlock.unlock();
291 
292  }
293 
294  inline void stop_time(metrics_entry me, std::string key, int iternum, bool show=false) {
295  me.timer_stop();
296  mlock.lock();
297 
298  double t = me.lasttime;
299  if (entries.count(key) == 0) {
300  entries[key] = metrics_entry(TIME);
301  }
302  entries[key].add(t); // not thread safe
303  if (show)
304  std::cout << key << ": " << me.lasttime << " secs." << std::endl;
305 
306  char s[256];
307  sprintf(s, "%s.%d", key.c_str(), iternum);
308  std::string ikey(s);
309  if (entries.count(ikey) == 0) {
310  entries[ikey] = metrics_entry(TIME);
311  }
312  entries[ikey].add(t);
313 
314  mlock.unlock();
315 
316  }
317 
318 
319  inline void stop_time(std::string key, bool show = false) {
320  if (show)
321  std::cout << key << ": " << entries[key].lasttime << " secs." << std::endl;
322  entries[key].timer_stop();
323  }
324 
325  inline metrics_entry get(std::string key) {
326  return entries[key];
327  }
328 
329  void report(imetrics_reporter & reporter) {
330  if (name != "") {
331  reporter.do_report(name, ident, entries);
332  }
333  }
334 
335  };
336 
337 
338 
339 };
340 
341 
342 
343 
344 
345 
346 #endif
347