OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
verlet_performance_tests.hpp
1 /*
2  * vector_dist_verlet_performance_tests.hpp
3  *
4  * Created on: Mar 9, 2016
5  * Author: Yaroslav Zaluzhnyi
6  */
7 
8 #ifndef SRC_VECTOR_VECTOR_DIST_VERLET_PERFORMANCE_TESTS_HPP_
9 #define SRC_VECTOR_VECTOR_DIST_VERLET_PERFORMANCE_TESTS_HPP_
10 
17 void print_test_v(std::string test, size_t sz)
18 {
19  if (create_vcluster().getProcessUnitID() == 0)
20  std::cout << test << " " << sz << "\n";
21 }
22 
23 BOOST_AUTO_TEST_SUITE( verletlist_part_reorder_performance_test )
24 
25 
27 // Cut-off radiuses. Can be put different number of values
28 openfpm::vector<float> r_cutoff {0.004, 0.007, 0.01};
29 // Orders of a curve. Can be put different number of values
30 // The starting amount of particles (remember that this number is multiplied by number of processors you use for testing)
31 size_t k_start = 100000;
32 // The minimal amount of particles
33 size_t k_min = 15000;
34 // Ghost part of distributed vector
35 
37 
38 // Numbers of particles vector
39 openfpm::vector<size_t> n_particles;
40 // Vectors to store the data for 2D
45 
46 // Vectors to store the data for 3D
49 openfpm::vector<openfpm::vector<double>> time_create_mean_2;
51 
55 template<unsigned int dim> void vd_verlet_random_benchmark(size_t k_start,
56  size_t k_min,
57  openfpm::vector<float> & r_cutoff,
58  openfpm::vector<size_t> & n_particles,
59  openfpm::vector<openfpm::vector<double>> & time_force_mean,
60  openfpm::vector<openfpm::vector<double>> & time_create_mean,
61  openfpm::vector<openfpm::vector<double>> & time_force_dev,
62  openfpm::vector<openfpm::vector<double>> & time_create_dev)
63 {
64  time_force_mean.resize(r_cutoff.size());
65  time_create_mean.resize(r_cutoff.size());
66  time_force_dev.resize(r_cutoff.size());
67  time_create_dev.resize(r_cutoff.size());
68 
69  std::string str("Testing " + std::to_string(dim) + "D vector no-order, Verlet-list");
70  print_test_v(str,0);
71 
72  {
73  //For different r_cut
74  for (size_t r = 0; r < r_cutoff.size(); r++ )
75  {
76  Vcluster & v_cl = create_vcluster();
77 
78  //Cut-off radius
79  float r_cut = r_cutoff.get(r);
80 
81  //Number of particles
82  size_t k = k_start * v_cl.getProcessingUnits();
83 
84  //Counter number for amounts of particles
85  size_t k_count = 1 + log2(k/k_min);
86 
87  for (size_t k_int = k ; k_int >= k_min ; k_int/=2 )
88  {
89  BOOST_TEST_CHECKPOINT( "Testing " << dim << "D vector without an Hilbert curve reordering k=" << k_int );
90 
91  if (n_particles.size() < k_count)
92  n_particles.add(k_int);
93 
94  Box<dim,float> box;
95 
96  for (size_t i = 0; i < dim; i++)
97  {
98  box.setLow(i,0.0);
99  box.setHigh(i,1.0);
100  }
101 
102  // Boundary conditions
103  size_t bc[dim];
104  for (size_t i = 0; i < dim; i++)
105  bc[i] = PERIODIC;
106 
108 
109  // Initialize a dist vector
110  vd_initialize<dim>(vd, v_cl, k_int);
111 
112  vd.template ghost_get<0>();
113 
114  //Get verlet list
115 
116  openfpm::vector<double> measures;
117  double sum_verlet_mean = 0;
118  double sum_verlet_dev = 0;
119  for (size_t n = 0 ; n < N_STAT_TEST; n++)
120  measures.add(benchmark_get_verlet(vd,r_cut));
121  standard_deviation(measures,sum_verlet_mean,sum_verlet_dev);
122 
123  //Average total time
124  time_create_mean.get(r).add(sum_verlet_mean);
125  time_create_dev.get(r).add(sum_verlet_dev);
126 
127  //Calculate forces
128 
129  auto NN = vd.getCellList(r_cut);
130  double sum_fr_mean = 0;
131  double sum_fr_dev = 0;
132 
133  measures.clear();
134  for (size_t l = 0 ; l < N_STAT_TEST ; l++)
135  measures.add(benchmark_calc_forces<dim>(NN,vd,r_cut));
136  standard_deviation(measures,sum_fr_mean,sum_fr_dev);
137  time_force_mean.get(r).add(sum_fr_mean);
138  time_force_dev.get(r).add(sum_fr_dev);
139 
140  if (v_cl.getProcessUnitID() == 0)
141  std::cout << "Particles: " << k_int << "," << "cut-off: " << r_cut << " time to construct a Verlet list = " << sum_verlet_mean << " dev: " << sum_verlet_dev << " calculate force = " << sum_fr_mean << " dev: " << sum_fr_dev << std::endl;
142  }
143  }
144  }
145 }
146 
150 template<unsigned int dim> void vd_verlet_hilbert_benchmark(size_t k_start, size_t k_min, double ghost_part,openfpm::vector<float> & r_cutoff, openfpm::vector<size_t> & n_particles, openfpm::vector<size_t> &orders, openfpm::vector<openfpm::vector<openfpm::vector<double>>> &time_hilb, openfpm::vector<openfpm::vector<openfpm::vector<double>>> &time_total_hilb)
151 {
152  time_hilb.resize(r_cutoff.size());
153  for (size_t r = 0; r < time_hilb.size(); r++)
154  {
155  time_hilb.get(r).resize(n_particles.size());
156  for (size_t k = 0; k < time_hilb.get(r).size(); k++)
157  {
158  time_hilb.get(r).get(k).resize(orders.size());
159  }
160  }
161 
162  time_total_hilb.resize(r_cutoff.size());
163  for (size_t r = 0; r < time_total_hilb.size(); r++)
164  {
165  time_total_hilb.get(r).resize(n_particles.size());
166  for (size_t k = 0; k < time_total_hilb.get(r).size(); k++)
167  {
168  time_total_hilb.get(r).get(k).resize(orders.size());
169  }
170  }
171 
172  std::string str("Testing " + std::to_string(dim) + "D vector, Hilbert curve reordering, Verlet-list");
173  print_test_v(str,0);
174 
175  // For different r_cut
176  for (size_t r = 0; r < r_cutoff.size(); r++ )
177  {
178  Vcluster & v_cl = create_vcluster();
179 
180  //Cut-off radius
181  float r_cut = r_cutoff.get(r);
182 
183  // Number of particles
184  size_t k = k_start * v_cl.getProcessingUnits();
185 
186  //For different curve orders
187  for ( size_t i = 0; i < orders.size(); i++)
188  {
189  size_t m = orders.get(i);
190  size_t part = 0;
191 
192  for (size_t k_int = k ; k_int >= k_min ; k_int/=2, part++ )
193  {
194  BOOST_TEST_CHECKPOINT( "Testing " << dim << "D vector with an Hilbert curve reordering k=" << k_int );
195 
196  Box<dim,float> box;
197 
198  for (size_t i = 0; i < dim; i++)
199  {
200  box.setLow(i,0.0);
201  box.setHigh(i,1.0);
202  }
203 
204  // Boundary conditions
205  size_t bc[dim];
206 
207  for (size_t i = 0; i < dim; i++)
208  bc[i] = PERIODIC;
209 
211 
212  // Initialize a dist vector
213  vd_initialize<dim>(vd, v_cl, k_int);
214 
215  vd.template ghost_get<0>();
216 
217  //Reorder a vector
218 
219  double sum_reorder = 0;
220  for (size_t h = 0 ; h < N_VERLET_TEST; h++)
221  sum_reorder += benchmark_reorder(vd,m);
222  sum_reorder /= N_VERLET_TEST;
223 
224  //Get verlet list
225 
226  double sum_verlet = 0;
227 
228  for (size_t n = 0 ; n < N_VERLET_TEST; n++)
229  sum_verlet += benchmark_get_verlet(vd,r_cut);
230  sum_verlet /= N_VERLET_TEST;
231  //Average total time
232  time_total_hilb.get(r).get(part).get(i) = sum_verlet;
233 
234  //Calculate forces
235 
236  auto NN = vd.getCellList(r_cut);
237  double sum_forces = 0;
238 
239  for (size_t l = 0 ; l < N_VERLET_TEST; l++)
240  sum_forces += benchmark_calc_forces<dim>(NN,vd,r_cut);
241  sum_forces /= N_VERLET_TEST;
242  time_hilb.get(r).get(part).get(i) = sum_forces;
243 
244  if (v_cl.getProcessUnitID() == 0)
245  std::cout << "Order = " << m << ", Cut-off = " << r_cut << ", Particles = " << k_int << ". Time to reorder: " << sum_reorder << " time to get the verlet-list: " << sum_verlet << " time to calculate forces: " << sum_forces << std::endl;
246  }
247  }
248  }
249 }
250 
251 
255 template<unsigned int dim> void vd_verlet_performance_write_report(GoogleChart & cg,
256  openfpm::vector<float> & r_cutoff,
257  openfpm::vector<size_t> & n_particles,
258  openfpm::vector<openfpm::vector<double>> time_force_mean,
260  openfpm::vector<openfpm::vector<double>> time_create_mean,
261  openfpm::vector<openfpm::vector<double>> time_create_dev)
262 {
263  {
264  std::string file_mean(test_dir);
265  std::string file_var(test_dir);
266  file_mean += std::string("/openfpm_pdata/verlet_comp_force_mean_" + std::to_string(dim) + std::string("_ref"));
267  file_var += std::string("/openfpm_pdata/verlet_comp_force_dev_" + std::to_string(dim) + std::string("_ref"));
268 
269  std::string file_mean_save = std::string("verlet_comp_force_mean_" + std::to_string(dim) + std::to_string("_ref"));
270  std::string file_var_save = std::string("verlet_comp_force_dev_" + std::to_string(dim) + std::to_string("_ref"));
271 
272  openfpm::vector<size_t> xp = n_particles;
273 
276 
279 
280  yp_mean.resize(time_force_mean.size());
281  yp_dev.resize(time_force_dev.size());
282  for (size_t i = 0 ; i < yp_mean.size() ; i++)
283  {
284  yp_mean.get(i).resize(time_force_mean.get(i).size());
285  yp_dev.get(i).resize(time_force_dev.get(i).size());
286 
287  for (size_t j = 0 ; j < yp_mean.get(i).size() ; j++)
288  {
289  yp_mean.get(i).get(j).resize(1);
290  yp_dev.get(i).get(j).resize(1);
291 
292  yp_mean.get(i).get(j).get(0) = time_force_mean.get(i).get(j);
293  yp_dev.get(i).get(j).get(0) = time_force_dev.get(i).get(j);
294  }
295  }
296 
297  names.add("Force verlet");
298 
299  for (size_t i = 0 ; i < r_cutoff.size() ; i++)
300  gnames.add("Verlet-list performance, cut-off radius: " + std::to_string(r_cutoff.get(i)));
301 
302  std::string y_string = std::string("Time to calculate forces (s)");
303  std::string x_string = std::string("Number of particles");
304 
305  std::string str("<h1>Verlet-list " + std::to_string(dim) + "-D performance test force calculation: </h1>");
306  cg.addHTML(str);
307 
308  StandardPerformanceGraph(file_mean,
309  file_var,
310  file_mean_save,
311  file_var_save,
312  cg,
313  xp,
314  yp_mean,
315  yp_dev,
316  names,
317  gnames,
318  x_string,
319  y_string,
320  true);
321  }
323 
324  {
325  std::string file_mean(test_dir);
326  std::string file_var(test_dir);
327  file_mean += std::string("/openfpm_pdata/verlet_comp_create_mean_" + std::to_string(dim) + std::string("_ref"));
328  file_var += std::string("/openfpm_pdata/verlet_comp_create_dev_" + std::to_string(dim) + std::string("_ref"));
329 
330  std::string file_mean_save = std::string("verlet_comp_create_mean_" + std::to_string(dim) + std::to_string("_ref"));
331  std::string file_var_save = std::string("verlet_comp_create_dev_" + std::to_string(dim) + std::to_string("_ref"));
332 
333  openfpm::vector<size_t> xp = n_particles;
334 
337 
340 
341  yp_mean.resize(time_create_mean.size());
342  yp_dev.resize(time_create_dev.size());
343  for (size_t i = 0 ; i < yp_mean.size() ; i++)
344  {
345  yp_mean.get(i).resize(time_create_mean.get(i).size());
346  yp_dev.get(i).resize(time_create_dev.get(i).size());
347 
348  for (size_t j = 0 ; j < yp_mean.get(i).size() ; j++)
349  {
350  yp_mean.get(i).get(j).resize(1);
351  yp_dev.get(i).get(j).resize(1);
352 
353  yp_mean.get(i).get(j).get(0) = time_create_mean.get(i).get(j);
354  yp_dev.get(i).get(j).get(0) = time_create_dev.get(i).get(j);
355  }
356  }
357 
358  names.add("Create verlet");
359 
360  for (size_t i = 0 ; i < r_cutoff.size() ; i++)
361  gnames.add("Verlet-list performance, cut-off radius: " + std::to_string(r_cutoff.get(i)));
362 
363  std::string y_string = std::string("Time to construct a verlet-list (s)");
364  std::string x_string = std::string("Number of particles");
365 
366  std::string str("<h1>Verlet-list " + std::to_string(dim) + "-D performance test force calculation: </h1>");
367  cg.addHTML(str);
368 
369  StandardPerformanceGraph(file_mean,
370  file_var,
371  file_mean_save,
372  file_var_save,
373  cg,
374  xp,
375  yp_mean,
376  yp_dev,
377  names,
378  gnames,
379  x_string,
380  y_string,
381  true);
382  }
383 }
384 
385 BOOST_AUTO_TEST_CASE( vector_dist_verlet_test )
386 {
387  //Benchmark test for 2D and 3D
388  vd_verlet_random_benchmark<3>(k_start,k_min,r_cutoff,n_particles,time_force_mean,time_create_mean,time_force_dev,time_create_dev);
389  vd_verlet_random_benchmark<2>(k_start,k_min,r_cutoff,n_particles,time_force_mean_2,time_create_mean_2,time_force_dev_2,time_create_dev_2);
390 }
391 
392 BOOST_AUTO_TEST_CASE(vector_dist_verlet_performance_write_report)
393 {
394  GoogleChart cg;
395 
396  //Write report for 2D and 3D
397  vd_verlet_performance_write_report<3>(cg,r_cutoff,n_particles,time_force_mean,time_force_dev,time_create_mean,time_create_dev);
398  vd_verlet_performance_write_report<2>(cg,r_cutoff,n_particles,time_force_mean_2,time_force_dev_2,time_create_mean_2,time_create_dev_2);
399 
400  if (create_vcluster().getProcessUnitID() == 0)
401  {
402  addUpdtateTime(cg);
403 
404  cg.write("Verletlist_comp.html");
405  }
406 }
407 
408 BOOST_AUTO_TEST_SUITE_END()
409 
410 #endif /* SRC_VECTOR_VECTOR_DIST_VERLET_PERFORMANCE_TESTS_HPP_ */
void addHTML(const std::string &html)
Add HTML text.
void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:467
size_t size()
Stub size.
Definition: map_vector.hpp:70
Definition: Ghost.hpp:39
Implementation of VCluster class.
Definition: VCluster.hpp:36
Small class to produce graph with Google chart in HTML.
This class decompose a space into sub-sub-domains and distribute them across processors.
void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:456
This class represent an N-dimensional box.
Definition: Box.hpp:56
Distributed vector.
size_t getProcessingUnits()
Get the total number of processors.