OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
performance_util.hpp
1 /*
2  * performance_util.hpp
3  *
4  * Created on: Jul 21, 2019
5  * Author: i-bird
6  */
7 
8 #ifndef PERFORMANCE_UTIL_HPP_
9 #define PERFORMANCE_UTIL_HPP_
10 
11 #include <boost/lexical_cast.hpp>
12 #include <boost/filesystem.hpp>
13 #include <boost/property_tree/ptree.hpp>
14 #include <boost/property_tree/xml_parser.hpp>
15 #include <fstream>
16 
17 static void addUpdateTime(GoogleChart & cg, int np, const std::string & base, const std::string & filename)
18 {
19  time_t t = time(0); // get time now
20  struct tm * now = localtime( & t );
21 
22  std::stringstream str;
23 
24  std::string commit;
25 
26  std::system("git rev-parse HEAD >test.txt"); // execute the UNIX command "ls -l >test.txt"
27  std::ifstream("test.txt") >> commit;
28 
29  std::string prev_commit;
30 
31  std::system(std::string("cat commit_f_" + base + " > test.txt").c_str()); // execute the UNIX command "ls -l >test.txt"
32  std::ifstream("test.txt") >> prev_commit;
33 
34  str << "<h3>Updated: " << now->tm_mday << "/" << now->tm_mon + 1 << "/" << now->tm_year+1900 << " " << now->tm_hour << ":" << now->tm_min << ":"
35  << now->tm_sec << " commit: " << commit << " run with: " << np << " processes<br>previous: <a href=\"" << filename << "_" << prev_commit << ".html\">here</a>" << "</h3>" << std::endl;
36 
37  cg.addHTML(str.str());
38 }
39 
40 static void createCommitFile(const std::string & tmp)
41 {
42  time_t t = time(0); // get time now
43  struct tm * now = localtime( & t );
44 
45  std::stringstream str;
46 
47  std::string commit;
48  commit = exec("git rev-parse HEAD");
49  std::cout << tmp << " " << commit << std::endl;
50 
51  std::ofstream f("commit_f_" + tmp);
52  f << commit << std::endl;
53 
54  f.close();
55 }
56 
57 static inline void warning_set(int & warning_level, double mean, double mean_ref, double sigma)
58 {
59  int warning_level_candidate;
60 
61  if (mean - mean_ref < -2.0*sigma )
62  warning_level_candidate = -1;
63  else if (mean - mean_ref < 2.0*sigma)
64  warning_level_candidate = 0;
65  else if (mean - mean_ref < 3.0*sigma)
66  warning_level_candidate = 1;
67  else
68  warning_level_candidate = 2;
69 
70  if (warning_level_candidate > warning_level)
71  warning_level = warning_level_candidate;
72 }
73 
74 static inline void addchartarea(std::string & chart_area, int lvl)
75 {
76  std::string color;
77 
78  if (lvl == -1)
79  {
80  chart_area = std::string(",chartArea: {\
81  backgroundColor: {\
82  stroke: '#00FF00',\
83  strokeWidth: 6\
84  }\
85  }");
86  }
87  else if (lvl == 0)
88  {
89  // NOTHING TO DO
90  }
91  else if (lvl == 1)
92  {
93  chart_area = std::string(",chartArea: {\
94  backgroundColor: {\
95  stroke: '#FFFF00',\
96  strokeWidth: 6\
97  }\
98  }");
99  }
100  else if (lvl == 2)
101  {
102  chart_area = std::string(",chartArea: {\
103  backgroundColor: {\
104  stroke: '#FF0000',\
105  strokeWidth: 6\
106  }\
107  }");
108  }
109 
110 }
111 
117 static bool isFloat(const std::string &someString)
118 {
119  using boost::lexical_cast;
120  using boost::bad_lexical_cast;
121 
122  try
123  {boost::lexical_cast<float>(someString);}
124  catch (bad_lexical_cast &)
125  {return false;}
126 
127  return true;
128 }
129 
130 static void StandardXMLPerformanceGraph(std::string file_xml,
131  std::string file_xml_ref,
132  GoogleChart & cg,
133  const double deviationMultiplier = 3.0)
134 {
135  // Create empty property tree object
136  boost::property_tree::ptree tree_measure;
137 
138  // Parse the XML into the property tree.
139  boost::property_tree::read_xml(file_xml, tree_measure);
140 
141  // Create empty property tree object
142  boost::property_tree::ptree tree_reference;
143 
144  // We check if exist the reference file. If does not exist copy the file_xml into the report folder
145  if (boost::filesystem::exists(file_xml_ref) == false )
146  {
147  boost::filesystem::copy_file(file_xml,file_xml_ref);
148  }
149 
150  // Parse the JSON into the property tree.
151  boost::property_tree::read_xml(file_xml_ref, tree_reference);
152 
153  // First we check for graphs
154 
155 // try
156  {
157  boost::property_tree::ptree childs = tree_measure.get_child("graphs");
158 
159  for (auto & c: childs)
160  {
161  std::string type = c.second.template get<std::string>("type","");
162  // discorver the number of points
163  int number = 0;
165 
166  while (1)
167  {
168  if (c.second.template get<std::string>("y.data(" + std::to_string(number) + ").title","") == "")
169  {break;}
170  yn.add(c.second.template get<std::string>("y.data(" + std::to_string(number) + ").title",
171  "line" + std::to_string(number)));
172  yn.add("interval");
173  yn.add("interval");
174  number++;
175  }
176 
177  bool is_log_x = c.second.template get<bool>("options.log_x",false);
178  bool is_log_y = c.second.template get<bool>("options.log_y",false);
179 
180  // We process the graph
181  std::string title = c.second.template get<std::string>("title","");
182  std::string x_title = c.second.template get<std::string>("x.title","");
183  std::string y_title = c.second.template get<std::string>("y.title","");
184 
185  // This is optional
186 
187  std::string preHTML = c.second.template get<std::string>("preHTML","");
188  std::string postHTML = c.second.template get<std::string>("postHTML","");
189 
193 
197 
198  int warning_level = -1;
199  bool is_literal_x = false;
200 
201  for (size_t i = 0 ; i < number ; i++)
202  {
203  x.add();
204  xs.add();
205  y.add();
206 
207  x_ref.add();
208  y_ref_up.add();
209  y_ref_dw.add();
210 
211  std::string xv = c.second.template get<std::string>("x.data(" + std::to_string(i) + ").source","");
212  std::string yv = c.second.template get<std::string>("y.data(" + std::to_string(i) + ").source","");
213 
214  // Get the numbers
215 
216  int j = 0;
217  while (1)
218  {
219  std::string xv_ = xv;
220  std::string yv_ = yv;
221 
222  int xpos = xv_.find("#");
223  int ypos = yv_.find("#");
224 
225  xv_.replace(xpos,1,std::to_string(j));
226  yv_.replace(ypos,1,std::to_string(j));
227 
228  if (tree_measure.template get<std::string>(xv_,"") == "")
229  {
230  if (j == 0)
231  {
232  std::cout << "WARNING: Not found " << xv_ << " in file: " << file_xml << std::endl;
233  }
234  break;
235  }
236 
237  std::string tmp = tree_measure.template get<std::string>(xv_,"");
238 
239  double x_val;
240  std::string x_val_str;
241  if (isFloat(tmp) == true)
242  {x_val = tree_measure.template get<double>(xv_,0.0);}
243  else
244  {
245  is_literal_x = true;
246  xs.last().add(tmp);
247  }
248 
249  double y_val = tree_measure.template get<double>(yv_,0.0);
250 
251  double x_val_ref = tree_reference.template get<double>(xv_,0.0);
252  double y_val_ref = tree_reference.template get<double>(yv_,0.0);
253 
254  if (y_val_ref == 0.0)
255  {
256  std::cout << "WARNING: " << yv_ << " does not exist on the reference file: " << file_xml_ref << std::endl;
257  }
258 
259  ypos = yv_.find(".mean");
260  std::string yv_dev = yv_.replace(ypos,5,".dev");
261  double y_val_dev_ref = tree_reference.template get<double>(yv_,0.0);
262 
263  if (y_val_dev_ref == 0.0)
264  {
265  std::cout << "WARNING: " << yv_ << " does not exist on the reference file: " << file_xml_ref << std::endl;
266  }
267 
268  x.last().add(x_val);
269  y.last().add(y_val);
270 
271  x_ref.last().add(x_val_ref);
272  y_ref_dw.last().add(y_val_ref - deviationMultiplier * y_val_dev_ref);
273  y_ref_up.last().add(y_val_ref + deviationMultiplier * y_val_dev_ref);
274 
275  warning_set(warning_level,y_val,y_val_ref,y_val_dev_ref);
276 
277  j++;
278  }
279  }
280 
281  if (type == "line")
282  {
283  GCoptions opt;
284 
285  std::string chart_area;
286  addchartarea(chart_area,warning_level);
287  opt.curveType = c.second.template get<std::string>("interpolation","function");
288 // opt.curveType = c.second.template get<std::string>("interpolation","none");
289 
290  if (is_log_x == true)
291  {
292  opt.more = GC_X_LOG + "," + GC_ZOOM + chart_area;
293  }
294  else
295  {
296  opt.more = GC_ZOOM + chart_area;
297  }
298 
299  if (is_log_y == true)
300  {
301  opt.more = GC_Y_LOG + "," + GC_ZOOM + chart_area;
302  }
303  else
304  {
305  opt.more = GC_ZOOM + chart_area;
306  }
307 
308  opt.title = title;
309  opt.xAxis = x_title;
310  opt.yAxis = y_title;
311 
312  if (is_literal_x == false)
313  {
314  if (x.size() == 1)
315  {
316  cg.AddLines(yn,opt,x.get(0),y.get(0),
317  x_ref.get(0),y_ref_dw.get(0),
318  x_ref.get(0),y_ref_up.get(0));
319  }
320  if (x.size() == 2)
321  {
322  cg.AddLines(yn,opt,x.get(0),y.get(0),
323  x_ref.get(0),y_ref_dw.get(0),x_ref.get(0),y_ref_up.get(0),
324  x.get(1),y.get(1),
325  x_ref.get(1),y_ref_dw.get(1),x_ref.get(1),y_ref_up.get(1));
326  }
327  if (x.size() == 3)
328  {
329  cg.AddLines(yn,opt,x.get(0),y.get(0),
330  x_ref.get(0),y_ref_dw.get(0),x_ref.get(0),y_ref_up.get(0),
331  x.get(1),y.get(1),
332  x_ref.get(1),y_ref_dw.get(1),x_ref.get(1),y_ref_up.get(1),
333  x.get(2),y.get(2),
334  x_ref.get(2),y_ref_dw.get(2),x_ref.get(2),y_ref_up.get(2));
335  }
336  if (x.size() == 4)
337  {
338  cg.AddLines(yn,opt,x.get(0),y.get(0),
339  x_ref.get(0),y_ref_dw.get(0),x_ref.get(0),y_ref_up.get(0),
340  x.get(1),y.get(1),
341  x_ref.get(1),y_ref_dw.get(1),x_ref.get(1),y_ref_up.get(1),
342  x.get(2),y.get(2),
343  x_ref.get(2),y_ref_dw.get(2),x_ref.get(2),y_ref_up.get(2),
344  x.get(3),y.get(3),
345  x_ref.get(3),y_ref_dw.get(3),x_ref.get(3),y_ref_up.get(3));
346  }
347  if (x.size() == 5)
348  {
349  cg.AddLines(yn,opt,x.get(0),y.get(0),
350  x_ref.get(0),y_ref_dw.get(0),x_ref.get(0),y_ref_up.get(0),
351  x.get(1),y.get(1),
352  x_ref.get(1),y_ref_dw.get(1),x_ref.get(1),y_ref_up.get(1),
353  x.get(2),y.get(2),
354  x_ref.get(2),y_ref_dw.get(2),x_ref.get(2),y_ref_up.get(2),
355  x.get(3),y.get(3),
356  x_ref.get(3),y_ref_dw.get(3),x_ref.get(3),y_ref_up.get(3),
357  x.get(4),y.get(4),
358  x_ref.get(4),y_ref_dw.get(4),x_ref.get(4),y_ref_up.get(4));
359  }
360  if (x.size() == 6)
361  {
362  cg.AddLines(yn,opt,x.get(0),y.get(0),
363  x_ref.get(0),y_ref_dw.get(0),x_ref.get(0),y_ref_up.get(0),
364  x.get(1),y.get(1),
365  x_ref.get(1),y_ref_dw.get(1),x_ref.get(1),y_ref_up.get(1),
366  x.get(2),y.get(2),
367  x_ref.get(2),y_ref_dw.get(2),x_ref.get(2),y_ref_up.get(2),
368  x.get(3),y.get(3),
369  x_ref.get(3),y_ref_dw.get(3),x_ref.get(3),y_ref_up.get(3),
370  x.get(4),y.get(4),
371  x_ref.get(4),y_ref_dw.get(4),x_ref.get(4),y_ref_up.get(4),
372  x.get(5),y.get(5),
373  x_ref.get(5),y_ref_dw.get(5),x_ref.get(5),y_ref_up.get(5));
374  }
375  }
376  else
377  {
379 
380  y_tmp.resize(x.get(0).size());
381 
382  for (size_t i = 0 ; i < x.size() ; i++)
383  {
384  for (size_t j = 0 ; j < x.get(i).size() ; j++)
385  {
386  y_tmp.get(j).add(y.get(i).get(j));
387  y_tmp.get(j).add(y_ref_dw.get(i).get(j));
388  y_tmp.get(j).add(y_ref_up.get(i).get(j));
389  }
390  }
391 
392  cg.AddLinesGraph(xs.get(0),y_tmp,yn,opt);
393  }
394  }
395  }
396  }
397 // catch (std::exception e)
398 // {
399 // std::cout << __FILE__ << ":" << __LINE__ << " Error: invalid xml for performance test " << e.what() << std::endl;
400 // }
401 
402 }
403 
404 
405 #endif /* PERFORMANCE_UTIL_HPP_ */
std::string curveType
curve type
Definition: GoogleChart.hpp:70
void addHTML(const std::string &html)
Add HTML text.
void AddLinesGraph(openfpm::vector< X > &x, openfpm::vector< Y > &y, const GCoptions &opt)
Add a simple lines graph.
std::string title
Title of the chart.
Definition: GoogleChart.hpp:28
std::string more
more
Definition: GoogleChart.hpp:67
std::string yAxis
Y axis name.
Definition: GoogleChart.hpp:30
void AddLines(const openfpm::vector< std::string > &yn, const GCoptions &opt, X ... xy)
Add lines graph.
Small class to produce graph with Google chart in HTML.
std::string xAxis
X axis name.
Definition: GoogleChart.hpp:32
Google chart options.
Definition: GoogleChart.hpp:25