OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
grid_dist_id_iterators_unit_tests.hpp
1 /*
2  * grid_dist_id_iterators_unit_tests.hpp
3  *
4  * Created on: Jan 4, 2017
5  * Author: i-bird
6  */
7 
8 #ifndef SRC_GRID_ITERATORS_GRID_DIST_ID_ITERATORS_UNIT_TESTS_HPP_
9 #define SRC_GRID_ITERATORS_GRID_DIST_ID_ITERATORS_UNIT_TESTS_HPP_
10 
11 #include "grid_dist_id_iterator_dec_skin.hpp"
12 
13 BOOST_AUTO_TEST_SUITE( grid_dist_id_iterators_test )
14 
15 void print_test(std::string test, size_t sz)
16 {
17  if (create_vcluster().getProcessUnitID() == 0)
18  std::cout << test << " " << sz << "\n";
19 }
20 
21 void Test2D_sub(const Box<2,float> & domain, long int k)
22 {
23  long int big_step = k / 30;
24  big_step = (big_step == 0)?1:big_step;
25  long int small_step = 21;
26 
27  // this test is only performed when the number of processor is <= 32
28  if (create_vcluster().getProcessingUnits() > 32)
29  return;
30 
31  print_test( "Testing 2D grid sub iterator k<=",k);
32 
33  // 2D test
34  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
35  {
36  BOOST_TEST_CHECKPOINT( "Testing 2D grid k=" << k );
37 
38  // grid size
39  size_t sz[2];
40  sz[0] = k;
41  sz[1] = k;
42 
43  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/2.0f);
44 
45  // Ghost
46  Ghost<2,float> g(0.01 / factor);
47 
48  // Distributed grid with id decomposition
49  grid_dist_id<2, float, aggregate<float>> g_dist(sz,domain,g);
50 
51  // check the consistency of the decomposition
52  bool val = g_dist.getDecomposition().check_consistency();
53  BOOST_REQUIRE_EQUAL(val,true);
54 
55  size_t count;
56 
57  // Grid sm
58  grid_sm<2,void> info(sz);
59 
60  {
62 
63  grid_key_dx<2> one(1,1);
64  grid_key_dx<2> one_end(k-2,k-2);
65 
66  bool check = true;
67  count = 0;
68 
69  // get the sub-domain iterator
70  auto dom = g_dist.getSubDomainIterator(one,one_end);
71 
72  while (dom.isNext())
73  {
74  auto key = dom.get();
75  auto key_g = g_dist.getGKey(key);
76 
77  // key_g should never be 1 or k-1
78  check &= (key_g.get(0) == 0 || key_g.get(0) == k-1)?false:true;
79  check &= (key_g.get(1) == 0 || key_g.get(1) == k-1)?false:true;
80 
81  g_dist.template get<0>(key) = info.LinId(key_g);
82 
83  // Count the point
84  count++;
85 
86  ++dom;
87  }
88 
89  BOOST_REQUIRE_EQUAL(check,true);
90 
92 
93  }
94 
95  // Get the virtual cluster machine
96  Vcluster & vcl = g_dist.getVC();
97 
98  // reduce
99  vcl.sum(count);
100  vcl.execute();
101 
102  // Check
103  BOOST_REQUIRE_EQUAL(count,(size_t)(k-2)*(k-2));
104 
105  // check with a 1x1 square
106 
107  {
108 
109  grid_key_dx<2> one(k/2,k/2);
110  grid_key_dx<2> one_end(k/2,k/2);
111 
112  count = 0;
113 
114  // get the sub-domain iterator
115  auto dom = g_dist.getSubDomainIterator(one,one_end);
116 
117  while (dom.isNext())
118  {
119  auto key = dom.get();
120  auto key_g = g_dist.getGKey(key);
121 
122  // key_g
123  BOOST_REQUIRE_EQUAL(key_g.get(0),k/2);
124  BOOST_REQUIRE_EQUAL(key_g.get(1),k/2);
125 
126  auto key_s_it = dom.getGKey(key);
127 
128  BOOST_REQUIRE_EQUAL(key_g.get(0),key_s_it.get(0));
129  BOOST_REQUIRE_EQUAL(key_g.get(1),key_s_it.get(1));
130 
131  // Count the point
132  count++;
133 
134  ++dom;
135  }
136 
137  // reduce
138  vcl.sum(count);
139  vcl.execute();
140 
141  BOOST_REQUIRE_EQUAL(count,1ul);
142  }
143  }
144 }
145 
146 // Test decomposition grid iterator
147 
148 void Test3D_decit(const Box<3,float> & domain, long int k)
149 {
150  size_t k_bck = k;
151  {
152  Vcluster & v_cl = create_vcluster();
153 
154  if ( v_cl.getProcessingUnits() > 32 )
155  return;
156 
157  long int big_step = k / 30;
158  big_step = (big_step == 0)?1:big_step;
159  long int small_step = 21;
160 
161  print_test( "Testing grid iterator from decomposition k<=",k);
162 
163  // 3D test
164  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
165  {
166  BOOST_TEST_CHECKPOINT( "Testing grid iterator from decomposition k<=" << k );
167 
168  // grid size
169  size_t sz[3];
170  sz[0] = k;
171  sz[1] = k;
172  sz[2] = k;
173 
174  // factor
175  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
176 
177  // Ghost
178  Ghost<3,float> g(0.01 / factor);
179 
180  // Distributed grid with id decomposition
182 
183  // check the consistency of the decomposition
184  bool val = g_dist.getDecomposition().check_consistency();
185  BOOST_REQUIRE_EQUAL(val,true);
186 
187  // Grid sm
188  grid_sm<3,void> info(sz);
189 
190  auto dom = g_dist.getDomainIterator();
191 
192  bool match = true;
193 
194  // create a grid iterator from the decomposition
195 
196  grid_dist_id_iterator_dec<CartDecomposition<3,float>> it_dec(g_dist.getDecomposition(),g_dist.getGridInfoVoid().getSize());
197 
198  while (dom.isNext())
199  {
200  auto key = dom.get();
201  auto key_g = g_dist.getGKey(key);
202 
203  auto key_dec = it_dec.get();
204 
205  // Check if the two keys match
206  match &= (key_dec == key_g);
207 
208  ++dom;
209  ++it_dec;
210  }
211 
212  BOOST_REQUIRE_EQUAL(match,true);
213  }
214  }
215 
216  k = k_bck;
217 
218  {
219  Vcluster & v_cl = create_vcluster();
220 
221  if ( v_cl.getProcessingUnits() > 32 )
222  return;
223 
224  long int big_step = k / 30;
225  big_step = (big_step == 0)?1:big_step;
226  long int small_step = 21;
227 
228  print_test( "Testing grid iterator from decomposition subset k<=",k);
229 
230  // 3D test
231  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
232  {
233  BOOST_TEST_CHECKPOINT( "Testing grid iterator from decomposition k<=" << k );
234 
235  // grid size
236  size_t sz[3];
237  sz[0] = k;
238  sz[1] = k;
239  sz[2] = k;
240 
241  // factor
242  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
243 
244  // Ghost
245  Ghost<3,float> g(0.01 / factor);
246 
247  // Distributed grid with id decomposition
249 
250  // check the consistency of the decomposition
251  bool val = g_dist.getDecomposition().check_consistency();
252  BOOST_REQUIRE_EQUAL(val,true);
253 
254  // Grid sm
255  grid_sm<3,void> info(sz);
256 
257  auto dom = g_dist.getSubDomainIterator({0,0,0},{(long int)sz[0]-2,(long int)sz[1]-2,(long int)sz[2]-2});
258 
259  bool match = true;
260 
261  // create a grid iterator from the decomposition
262 
263  grid_dist_id_iterator_dec<CartDecomposition<3,float>> it_dec(g_dist.getDecomposition(),sz,{0,0,0},{(long int)sz[0]-2,(long int)sz[1]-2,(long int)sz[2]-2});
264 
265  while (dom.isNext())
266  {
267  auto key = dom.get();
268  auto key_g = g_dist.getGKey(key);
269 
270  auto key_dec = it_dec.get();
271 
272  // Check if the two keys match
273  match &= (key_dec == key_g);
274 
275  ++dom;
276  ++it_dec;
277  }
278 
279  BOOST_REQUIRE_EQUAL(match,true);
280  }
281  }
282 }
283 
284 void Test3D_stencil(const Box<3,float> & domain, long int k)
285 {
286  grid_key_dx<3> star_stencil_3D[7] = {{0,0,0},
287  {0,0,-1},
288  {0,0,1},
289  {0,-1,0},
290  {0,1,0},
291  {-1,0,0},
292  {1,0,0}};
293 
294  {
295  Vcluster & v_cl = create_vcluster();
296 
297  if ( v_cl.getProcessingUnits() > 32 )
298  return;
299 
300  long int big_step = k / 30;
301  big_step = (big_step == 0)?1:big_step;
302  long int small_step = 21;
303 
304  print_test( "Testing grid stencil iterator k<=",k);
305 
306  // 3D test
307  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
308  {
309  BOOST_TEST_CHECKPOINT( "Testing grid skin iterator from decomposition k<=" << k );
310 
311  // grid size
312  size_t sz[3];
313  sz[0] = k;
314  sz[1] = k;
315  sz[2] = k;
316 
317  if (k <= 9)
318  continue;
319 
320  Ghost<3,long int> g(1);
321 
322  // Distributed grid with id decomposition
324 
325  // fill the grid with values
326 
327  auto it = g_dist.getDomainGhostIterator();
328 
329  while (it.isNext())
330  {
331  auto p = it.get();
332  auto gkey = it.getGKey(p);
333 
334  g_dist.template get<0>(p) = gkey.get(0) + gkey.get(1) + gkey.get(2);
335 
336  ++it;
337  }
338 
339  g_dist.ghost_get<0>();
340 
341  auto st_it = g_dist.getDomainIteratorStencil(star_stencil_3D);
342 
343  bool ret = true;
344 
345  while (st_it.isNext())
346  {
347  auto key = st_it.get();
348 
349  // center point
350  auto Cp = st_it.getStencil<0>();
351 
352  // plus,minus X,Y,Z
353  auto mx = st_it.getStencil<1>();
354  auto px = st_it.getStencil<2>();
355  auto my = st_it.getStencil<3>();
356  auto py = st_it.getStencil<4>();
357  auto mz = st_it.getStencil<5>();
358  auto pz = st_it.getStencil<6>();
359 
360  size_t sum = 6*g_dist.template get<0>(Cp) -
361  g_dist.template get<0>(mx) -
362  g_dist.template get<0>(px) -
363  g_dist.template get<0>(my) -
364  g_dist.template get<0>(py) -
365  g_dist.template get<0>(mz) -
366  g_dist.template get<0>(pz);
367 
368  ret &= (sum == 0);
369 
370  // get the local grid info
371 
372  grid_sm<3,void> info = g_dist.get_loc_grid(key.getSub()).getGrid();
373 
374  ret &= info.LinId(key.getKey()) == (long int)Cp.getKey();
375 
376  ++st_it;
377  }
378 
379  BOOST_REQUIRE_EQUAL(ret,true);
380  }
381 
382  }
383 }
384 
385 void Test3D_fast_vect(const Box<3,float> & domain, long int k)
386 {
387  grid_key_dx<3> star_stencil_3D[7] = {{0,0,0},
388  {0,0,-1},
389  {0,0,1},
390  {0,-1,0},
391  {0,1,0},
392  {-1,0,0},
393  {1,0,0}};
394 
395  {
396  Vcluster & v_cl = create_vcluster();
397 
398  if ( v_cl.getProcessingUnits() > 32 )
399  return;
400 
401  long int big_step = k / 30;
402  big_step = (big_step == 0)?1:big_step;
403  long int small_step = 21;
404 
405  print_test( "Testing grid 3D fast stencil k<=",k);
406 
407  // 3D test
408  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
409  {
410  BOOST_TEST_CHECKPOINT( "Testing grid skin iterator from decomposition k<=" << k );
411 
412  // grid size
413  size_t sz[3];
414  sz[0] = k;
415  sz[1] = k;
416  sz[2] = k;
417 
418  if (k <= 9)
419  continue;
420 
421  Ghost<3,long int> g(1);
422 
423  // Distributed grid with id decomposition
425 
426  // fill the grid with values
427 
428  auto it = g_dist.getDomainGhostIterator();
429 
430  while (it.isNext())
431  {
432  auto p = it.get();
433  auto gkey = it.getGKey(p);
434 
435  g_dist.template get<0>(p) = gkey.get(0)*gkey.get(0) + gkey.get(1)*gkey.get(1) + gkey.get(2)*gkey.get(2);
436 
437  ++it;
438  }
439 
440  g_dist.ghost_get<0>();
441 
442  size_t ret = true;
443 
444  WHILE_M(g_dist,star_stencil_3D)
445  auto & gstl = GET_GRID_M(g_dist);
446  ITERATE_3D_M(1)
447  // center point
448  auto Cp = it.getStencil<0>();
449 
450  // plus,minus X,Y,Z
451  auto mx = it.getStencil<1>();
452  auto px = it.getStencil<2>();
453  auto my = it.getStencil<3>();
454  auto py = it.getStencil<4>();
455  auto mz = it.getStencil<5>();
456  auto pz = it.getStencil<6>();
457 
458  long int sum = -6*gstl.template get<0>(Cp) +
459  gstl.template get<0>(mx) +
460  gstl.template get<0>(px) +
461  gstl.template get<0>(my) +
462  gstl.template get<0>(py) +
463  gstl.template get<0>(mz) +
464  gstl.template get<0>(pz);
465 
466  ret &= (sum == 6);
467 
468  END_LOOP_M(1)
469 
470  BOOST_REQUIRE_EQUAL(ret,true);
471  }
472 
473  }
474 }
475 
476 // Test decomposition grid iterator
477 
478 void Test3D_decskinit(const Box<3,float> & domain, long int k)
479 {
480  {
481  Vcluster & v_cl = create_vcluster();
482 
483  if ( v_cl.getProcessingUnits() > 32 )
484  return;
485 
486  long int big_step = k / 30;
487  big_step = (big_step == 0)?1:big_step;
488  long int small_step = 21;
489 
490  print_test( "Testing grid skin iterator from decomposition k<=",k);
491 
492  // 3D test
493  for ( ; k >= 2 ; k-= (k > 2*big_step)?big_step:small_step )
494  {
495  BOOST_TEST_CHECKPOINT( "Testing grid skin iterator from decomposition k<=" << k );
496 
497  // grid size
498  size_t sz[3];
499  sz[0] = k;
500  sz[1] = k;
501  sz[2] = k;
502 
503  if (k <= 9)
504  continue;
505 
506  // factor
507  float factor = pow(create_vcluster().getProcessingUnits()/2.0f,1.0f/3.0f);
508 
509  // Ghost
510  Ghost<3,float> g(0.01 / factor);
511 
512  // Distributed grid with id decomposition
514 
515  // check the consistency of the decomposition
516  bool val = g_dist.getDecomposition().check_consistency();
517  BOOST_REQUIRE_EQUAL(val,true);
518 
519  // Grid sm
520  grid_sm<3,void> info(sz);
521 
522  // create a grid skin iterator from the decomposition
523 
524  Box<3,size_t> A({3,3,3},{(size_t)k-3,(size_t)k-3,(size_t)k-3});
525  Box<3,size_t> B = A;
526 
527  if (A.isValid() == false)
528  continue;
529 
530  size_t bc[3] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC};
531  grid_dist_id_iterator_dec_skin<CartDecomposition<3,float>> it_dec(g_dist.getDecomposition(),g_dist.getGridInfoVoid(),A,B,bc);
532 
533  size_t cnt = 0;
534 
535  bool tot_good = true;
536  while (it_dec.isNext())
537  {
538  auto key_dec = it_dec.get();
539 
540  // one of the coordinate has to be or 3 or 8, none of
541  // None of the coordinates must be bigger that
542 
543  bool eight_or_three = false;
544  bool good = true;
545  for (size_t i = 0; i < 3 ; i++)
546  {
547  if (key_dec.get(i) == 3 || key_dec.get(i) == k - 3)
548  eight_or_three = true;
549 
550  if (key_dec.get(i) > k - 3 || key_dec.get(i) < 3 )
551  good = false;
552  }
553 
554  tot_good &= (eight_or_three) || good;
555 
556  cnt++;
557  ++it_dec;
558  }
559 
560  create_vcluster().sum(cnt);
561  create_vcluster().execute();
562 
563  BOOST_REQUIRE_EQUAL(cnt,(size_t)((k-5)*(k-5)*(k-5) - (k-7)*(k-7)*(k-7)));
564  BOOST_REQUIRE_EQUAL(tot_good,true);
565  }
566  }
567 }
568 
569 BOOST_AUTO_TEST_CASE( grid_dist_id_sub_iterator_test_use)
570 {
571  // Domain
572  Box<2,float> domain({0.0,0.0},{1.0,1.0});
573 
574  long int k = 1024*1024*create_vcluster().getProcessingUnits();
575  k = std::pow(k, 1/2.);
576 
577  Test2D_sub(domain,k);
578 }
579 
580 BOOST_AUTO_TEST_CASE( grid_dist_id_decomposition_iterator )
581 {
582  // Domain
583  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
584 
585  size_t k = 128*128*128*create_vcluster().getProcessingUnits();
586  k = std::pow(k, 1/3.);
587  Test3D_decit(domain3,k);
588 }
589 
590 BOOST_AUTO_TEST_CASE( grid_dist_id_iterator_stencil )
591 {
592  // Domain
593  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
594 
595  size_t k = 128*128*128*create_vcluster().getProcessingUnits();
596  k = std::pow(k, 1/3.);
597  Test3D_stencil(domain3,k);
598 }
599 
600 
601 BOOST_AUTO_TEST_CASE( grid_dist_it_iterators_skin_test )
602 {
603  // Domain
604  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
605 
606  size_t k = 128*128*128*create_vcluster().getProcessingUnits();
607  k = std::pow(k, 1/3.);
608  Test3D_decskinit(domain3,k);
609 }
610 
611 BOOST_AUTO_TEST_CASE( grid_dist_it_iterators_3D_fast )
612 {
613  // Domain
614  Box<3,float> domain3({0.0,0.0,0.0},{1.0,1.0,1.0});
615 
616  size_t k = 128*128*128*create_vcluster().getProcessingUnits();
617  k = std::pow(k, 1/3.);
618  Test3D_fast_vect(domain3,k);
619 }
620 
621 BOOST_AUTO_TEST_SUITE_END()
622 
623 #endif /* SRC_GRID_ITERATORS_GRID_DIST_ID_ITERATORS_UNIT_TESTS_HPP_ */
void sum(T &num)
Sum the numbers across all processors and get the result.
mem_id LinId(const grid_key_dx< N > &gk, const char sum_id[N]) const
Linearization of the grid_key_dx with a specified shift.
Definition: grid_sm.hpp:337
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
void execute()
Execute all the requests.
Given the decomposition it create an iterator.
Definition: Ghost.hpp:39
Implementation of VCluster class.
Definition: VCluster.hpp:36
This class decompose a space into sub-sub-domains and distribute them across processors.
This is a distributed grid.
This class represent an N-dimensional box.
Definition: Box.hpp:56
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
Declaration grid_sm.
Definition: grid_sm.hpp:71
It model an expression expr1 + ... exprn.
Definition: sum.hpp:92
size_t getProcessingUnits()
Get the total number of processors.
Given the decomposition it create an iterator.