OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
cell_list_part_reorder.hpp
1 /*
2  * vector_dist_cl_performance_tests.hpp
3  *
4  *
5  * Created on: Mar 22, 2016
6  * Author: Yaroslav Zaluzhnyi
7  */
8 
9 #ifndef SRC_VECTOR_VECTOR_DIST_CL_PERFORMANCE_TESTS_HPP_
10 #define SRC_VECTOR_VECTOR_DIST_CL_PERFORMANCE_TESTS_HPP_
11 
12 #include "Vector/vector_dist.hpp"
13 #include "data_type/aggregate.hpp"
14 #include "Plot/GoogleChart.hpp"
15 #include <functional>
16 
17 // Property tree
19 {
20  boost::property_tree::ptree graphs;
21 };
22 
23 report_cell_list_preord_tests report_cl_preo;
24 
25 BOOST_AUTO_TEST_SUITE( celllist_part_reorder_performance_test )
26 
27 
29 // Cut-off radiuses. Can be put different number of values
30 openfpm::vector<float> r_cutoff {0.004, 0.007, 0.01};
31 // Orders of a curve. Can be put different number of values
32 openfpm::vector<size_t> orders = {1,2,3};
33 // Number of steps of moving the particles
34 size_t n_moving = 8;
35 // Moving distance (step size)
36 double dist = 0.03;
37 // The starting amount of particles (remember that this number is multiplied by number of processors you use for testing)
38 size_t k_start = 100000;
39 // The minimal amount of particles
40 size_t k_min = 15000;
41 
43 
44 // Numbers of particles vector
45 openfpm::vector<size_t> n_particles;
46 
47 
51 template<unsigned int dim> void cell_list_part_reorder_random_benchmark(size_t cl_k_start,
52  size_t cl_k_min,
53  openfpm::vector<float> & cl_r_cutoff,
54  openfpm::vector<size_t> & cl_n_particles)
55 {
56  std::string str("Testing " + std::to_string(dim) + "D vector, no-order, Cell-list");
57  print_test_v(str,0);
58 
59  {
60  //For different r_cut
61  for (size_t r = 0; r < cl_r_cutoff.size(); r++ )
62  {
63  Vcluster<> & v_cl = create_vcluster();
64 
65  //Cut-off radius
66  float r_cut = cl_r_cutoff.get(r);
67 
68  report_cl_preo.graphs.put("performance.celllist.calc_forces_reordered" + std::to_string(dim) + "D(" + std::to_string(r) + ").rcut",r_cut);
69 
70  //Number of particles
71  size_t k = cl_k_start * v_cl.getProcessingUnits();
72 
73  //Counter number for amounts of particles
74  size_t k_count = 1 + log2(k/cl_k_min);
75 
76  int c = 0;
77 
78  //For different number of particles
79  for (size_t k_int = k ; k_int >= cl_k_min ; k_int/=2 )
80  {
81  BOOST_TEST_CHECKPOINT( "Testing " << dim << "D vector without an Hilbert curve reordering k=" << k_int );
82 
83  report_cl_preo.graphs.put("performance.celllist.calc_forces_reordered" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").n",k_int);
84 
85  if (cl_n_particles.size() < k_count)
86  cl_n_particles.add(k_int);
87 
88  Box<dim,float> box;
89 
90  for (size_t i = 0; i < dim; i++)
91  {
92  box.setLow(i,0.0);
93  box.setHigh(i,1.0);
94  }
95 
96  // Boundary conditions
97  size_t bc[dim];
98 
99  for (size_t i = 0; i < dim; i++)
100  bc[i] = PERIODIC;
101 
103 
104  // Initialize a dist vector
105  vd_initialize<dim>(vd, v_cl);
106 
107  vd.template ghost_get<0>();
108 
109  //Get a cell list
110 
111  auto NN = vd.getCellList(r_cut);
112  double sum_fr_mean = 0;
113  double sum_fr_dev = 0;
114 
115  benchmark_get_celllist(NN,vd,r_cut);
116 
117  //Calculate forces
118  size_t l = 0;
119 
120  openfpm::vector<double> measures;
121  for ( ; l < N_STAT_TEST; l++)
122  {measures.add(benchmark_calc_forces<dim>(NN,vd,r_cut));}
123  standard_deviation(measures,sum_fr_mean,sum_fr_dev);
124 
125  report_cl_preo.graphs.put("performance.celllist.calc_forces_reordered" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").mean",sum_fr_mean);
126  report_cl_preo.graphs.put("performance.celllist.calc_forces_reordered" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").dev",sum_fr_dev);
127 
128  if (v_cl.getProcessUnitID() == 0)
129  {std::cout << "Cut-off = " << r_cut << ", Particles = " << k_int << " time to calculate forces: " << sum_fr_mean << " dev: " << sum_fr_dev << std::endl;}
130 
131  c++;
132  }
133  }
134  }
135 }
136 
137 
141 template<unsigned int dim> void cell_list_part_reorder_hilbert_benchmark(size_t cl_k_start,
142  size_t cl_k_min,
143  size_t n_moving,
144  double dist,
145  openfpm::vector<float> & cl_r_cutoff,
146  openfpm::vector<size_t> & cl_n_particles,
147  openfpm::vector<size_t> &cl_orders)
148 {
149  {
150  // Print test
151  std::string str("Testing " + std::to_string(dim) + "D vector, Hilbert curve reordering, Cell-List");
152  print_test_v(str,0);
153 
154  // For different r_cut
155  for (size_t r = 0; r < cl_r_cutoff.size(); r++ )
156  {
157  Vcluster<> & v_cl = create_vcluster();
158 
159  // Cut-off radius
160  float r_cut = cl_r_cutoff.get(r);
161 
162  // Number of particles
163  size_t k = cl_k_start * v_cl.getProcessingUnits();
164 
165  //For different curve orders
166  for ( size_t i = 0; i < cl_orders.size(); i++)
167  {
168  size_t m = cl_orders.get(i);
169  size_t part = 0;
170 
171  int c = 0;
172 
173  for (size_t k_int = k ; k_int >= cl_k_min ; k_int/=2, part++ )
174  {
175  BOOST_TEST_CHECKPOINT( "Testing " << dim << "D vector with an Hilbert curve reordering k=" << k_int );
176 
177  report_cl_preo.graphs.put("performance.celllist.calc_forces_hilb(" + std::to_string(m) + ")_reordered" + std::to_string(dim) + "D(" + std::to_string(r) + ").rcut",r_cut);
178  report_cl_preo.graphs.put("performance.celllist.calc_forces_hilb(" + std::to_string(m) + ")_reordered" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").n",k_int);
179 
180  Box<dim,float> box;
181 
182  for (size_t i = 0; i < dim; i++)
183  {
184  box.setLow(i,0.0);
185  box.setHigh(i,1.0);
186  }
187 
188  // Boundary conditions
189  size_t bc[dim];
190 
191  for (size_t i = 0; i < dim; i++)
192  {bc[i] = PERIODIC;}
193 
195 
196  // Initialize a dist vector
197 
198  vd_initialize<dim>(vd, v_cl);
199  //Reorder a vector
200 
201  double sum_reorder_mean = 0;
202  double sum_reorder_dev = 0;
203 
204  openfpm::vector<double> measures;
205  for (size_t h = 0 ; h < N_STAT_TEST; h++)
206  {measures.add(benchmark_reorder(vd,m));}
207  standard_deviation(measures,sum_reorder_mean,sum_reorder_dev);
208 
209  vd.template ghost_get<0>();
210 
211  //Get cell list
212 
213  auto NN = vd.getCellList(r_cut);
214  benchmark_get_celllist(NN,vd,r_cut);
215 
216  //Calculate forces
217 
218  double sum_fr_mean = 0;
219  double sum_fr_dev = 0;
220  measures.clear();
221 
222  for (size_t l = 0 ; l < N_STAT_TEST ; l++)
223  {measures.add(benchmark_calc_forces<dim>(NN,vd,r_cut));}
224  standard_deviation(measures,sum_fr_mean,sum_fr_dev);
225 
226  report_cl_preo.graphs.put("performance.celllist.calc_forces_hilb(" + std::to_string(m) + ")_reordered" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").mean",sum_fr_mean);
227  report_cl_preo.graphs.put("performance.celllist.calc_forces_hilb(" + std::to_string(m) + ")_reordered" + std::to_string(dim) + "D(" + std::to_string(r) + ").npart(" + std::to_string(c) + ").dev",sum_fr_dev);
228 
229  if (v_cl.getProcessUnitID() == 0)
230  {std::cout << "Cut-off = " << r_cut << ", Particles = " << k_int << ". Time to reorder: " << sum_reorder_mean << " dev: " << sum_reorder_dev << " time calculate forces: " << sum_fr_mean << " dev: " << sum_fr_dev << std::endl;}
231 
232  c++;
233  }
234  }
235  }
236  }
237 }
238 
239 
240 BOOST_AUTO_TEST_CASE( vector_dist_cl_random_test )
241 {
242  //Benchmark test for 2D and 3D
243  cell_list_part_reorder_random_benchmark<3>(k_start,k_min,r_cutoff,n_particles);
244  cell_list_part_reorder_random_benchmark<2>(k_start,k_min,r_cutoff,n_particles);
245 }
246 
247 BOOST_AUTO_TEST_CASE( vector_dist_cl_hilbert_test )
248 {
249  //Benchmark test for 2D and 3D
250  cell_list_part_reorder_hilbert_benchmark<3>(k_start,
251  k_min,
252  n_moving,
253  dist,
254  r_cutoff,
255  n_particles,
256  orders);
257 
258  cell_list_part_reorder_hilbert_benchmark<2>(k_start,
259  k_min,
260  n_moving,
261  dist,
262  r_cutoff,
263  n_particles,
264  orders);
265 }
266 
267 BOOST_AUTO_TEST_CASE(vector_dist_cl_performance_write_report)
268 {
269  // Create a graphs
270 
271  //For different r_cut
272  for (size_t r = 0; r < r_cutoff.size(); r++ )
273  {
274  report_cl_preo.graphs.put("graphs.graph(" + std::to_string(r) + ").type","line");
275  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r) + ").title","calc_force 3D with reordered particles performance r_cut=" + std::to_string(r_cutoff.get(r)));
276  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r) + ").x.title","number of particles");
277  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r) + ").y.title","Time seconds");
278  for (size_t i = 0 ; i < orders.size() ; i++)
279  {
280  size_t m = orders.get(i);
281  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r) + ").y.data(" + std::to_string(i+1) + ").source","performance.celllist.calc_forces_hilb(" + std::to_string(m) + ")_reordered3D(" + std::to_string(r) + ").npart(#).mean");
282  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r) + ").x.data(" + std::to_string(i+1) + ").source","performance.celllist.calc_forces_hilb(" + std::to_string(m) + ")_reordered3D(" + std::to_string(r) + ").npart(#).n");
283  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r) + ").y.data(" + std::to_string(i+1) + ").title","Hilbert(" + std::to_string(m) + ") reorder");
284  }
285  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r) + ").y.data(0).source","performance.celllist.calc_forces_reordered3D(" + std::to_string(r) + ").npart(#).mean");
286  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r) + ").x.data(0).source","performance.celllist.calc_forces_reordered3D(" + std::to_string(r) + ").npart(#).n");
287  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r) + ").y.data(0).title","Random reorder");
288  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r) + ").options.log_y","true");
289  }
290 
291  //For different r_cut
292  for (size_t r = 0; r < r_cutoff.size(); r++ )
293  {
294  report_cl_preo.graphs.put("graphs.graph(" + std::to_string(r + r_cutoff.size()) + ").type","line");
295  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r + r_cutoff.size()) + ").title","calc_force 2D with reordered particles performance r_cut=" + std::to_string(r_cutoff.get(r)));
296  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r + r_cutoff.size()) + ").x.title","number of particles");
297  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r + r_cutoff.size()) + ").y.title","Time seconds");
298  for (size_t i = 0 ; i < orders.size() ; i++)
299  {
300  size_t m = orders.get(i);
301  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r + r_cutoff.size()) + ").y.data(" + std::to_string(i+1) + ").source","performance.celllist.calc_forces_hilb(" + std::to_string(m) + ")_reordered2D(" + std::to_string(r) + ").npart(#).mean");
302  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r + r_cutoff.size()) + ").x.data(" + std::to_string(i+1) + ").source","performance.celllist.calc_forces_hilb(" + std::to_string(m) + ")_reordered2D(" + std::to_string(r) + ").npart(#).n");
303  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r + r_cutoff.size()) + ").y.data(" + std::to_string(i+1) + ").title","Hilbert(" + std::to_string(m) + ") reorder");
304  }
305  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r + r_cutoff.size()) + ").y.data(0).source","performance.celllist.calc_forces_reordered2D(" + std::to_string(r) + ").npart(#).mean");
306  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r + r_cutoff.size()) + ").x.data(0).source","performance.celllist.calc_forces_reordered2D(" + std::to_string(r) + ").npart(#).n");
307  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r + r_cutoff.size()) + ").y.data(0).title","Random reorder");
308  report_cl_preo.graphs.add("graphs.graph(" + std::to_string(r + r_cutoff.size()) + ").options.log_y","true");
309  }
310 
311  if (create_vcluster().rank() == 0)
312  {
313  boost::property_tree::xml_writer_settings<std::string> settings(' ', 4);
314  boost::property_tree::write_xml("celllist_partreo_performance.xml", report_cl_preo.graphs,std::locale(),settings);
315 
316  std::string file_xml_ref(test_dir);
317  file_xml_ref += std::string("/openfpm_pdata/celllist_partreo_performance_ref.xml");
318 
319  GoogleChart cg;
320 
321  StandardXMLPerformanceGraph("celllist_partreo_performance.xml",file_xml_ref,cg);
322 
323  addUpdateTime(cg,create_vcluster().size(),"pdata","celllist_part_ord");
324 
325  if (create_vcluster().getProcessUnitID() == 0)
326  {cg.write("celllist_part_ord.html");}
327  }
328 }
329 
330 BOOST_AUTO_TEST_SUITE_END()
331 
332 #endif /* SRC_VECTOR_VECTOR_DIST_CL_PERFORMANCE_TESTS_HPP_ */
size_t getProcessUnitID()
Get the process unit id.
size_t size()
Stub size.
Definition: map_vector.hpp:211
Definition: Ghost.hpp:39
Implementation of VCluster class.
Definition: VCluster.hpp:58
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition: Box.hpp:544
Small class to produce graph with Google chart in HTML.
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition: Box.hpp:533
size_t getProcessingUnits()
Get the total number of processors.
This class represent an N-dimensional box.
Definition: Box.hpp:60
void write(std::string file)
It write the graphs on file in html format using Google charts.
Distributed vector.
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:202