1 | /* |
2 | * vector_dist_NN_tests.hpp |
3 | * |
4 | * Created on: Aug 20, 2016 |
5 | * Author: i-bird |
6 | */ |
7 | |
8 | #define BOOST_TEST_DYN_LINK |
9 | #include <boost/test/unit_test.hpp> |
10 | |
11 | #include "VCluster/VCluster.hpp" |
12 | #include "Vector/vector_dist.hpp" |
13 | |
14 | extern void print_test_v(std::string test, size_t sz); |
15 | |
16 | template<typename VerletList> |
17 | void test_full_nn(long int k) |
18 | { |
19 | Vcluster<> & v_cl = create_vcluster(); |
20 | |
21 | if (v_cl.getProcessingUnits() > 12) |
22 | return; |
23 | |
24 | // set the seed |
25 | // create the random generator engine |
26 | std::srand(v_cl.getProcessUnitID()); |
27 | std::default_random_engine eg; |
28 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
29 | |
30 | long int big_step = k / 4; |
31 | big_step = (big_step == 0)?1:big_step; |
32 | |
33 | print_test_v("Testing 3D full NN search k=" ,k); |
34 | BOOST_TEST_CHECKPOINT( "Testing 3D full NN search k=" << k ); |
35 | |
36 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
37 | |
38 | // Boundary conditions |
39 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
40 | |
41 | for (double r_cut = 0.1 ; r_cut < 1.0; r_cut += 0.1) |
42 | { |
43 | // ghost |
44 | Ghost<3,float> ghost(r_cut*1.001); |
45 | |
46 | typedef aggregate<float> part_prop; |
47 | |
48 | // Distributed vector |
49 | vector_dist<3,float, part_prop > vd(k,box,bc,ghost); |
50 | |
51 | auto it = vd.getIterator(); |
52 | |
53 | while (it.isNext()) |
54 | { |
55 | auto key = it.get(); |
56 | |
57 | vd.getPos(key)[0] = ud(eg); |
58 | vd.getPos(key)[1] = ud(eg); |
59 | vd.getPos(key)[2] = ud(eg); |
60 | |
61 | // Fill some properties randomly |
62 | |
63 | vd.getProp<0>(key) = 0.0; |
64 | |
65 | ++it; |
66 | } |
67 | |
68 | vd.map(); |
69 | |
70 | // sync the ghost |
71 | vd.ghost_get<0>(); |
72 | |
73 | openfpm::vector<openfpm::vector<size_t>> list_idx; |
74 | openfpm::vector<openfpm::vector<size_t>> list_idx2; |
75 | |
76 | list_idx.resize(vd.size_local()); |
77 | list_idx2.resize(vd.size_local()); |
78 | |
79 | for (size_t i = 0 ; i < vd.size_local() ; i++) |
80 | { |
81 | Point<3,float> p = vd.getPos(i); |
82 | |
83 | for (size_t j = 0 ; j < vd.size_local_with_ghost(); j++) |
84 | { |
85 | Point<3,float> q = vd.getPos(j); |
86 | |
87 | if (p.distance2(q) < r_cut * r_cut) |
88 | list_idx.get(i).add(j); |
89 | } |
90 | |
91 | list_idx.get(i).sort(); |
92 | } |
93 | |
94 | auto NN = vd.getCellList(r_cut); |
95 | |
96 | it = vd.getDomainIterator(); |
97 | |
98 | while (it.isNext()) |
99 | { |
100 | Point<3,float> xp = vd.getPos(it.get()); |
101 | auto Np = NN.getNNIterator<NO_CHECK>(NN.getCell(xp)); |
102 | |
103 | while (Np.isNext()) |
104 | { |
105 | auto q = Np.get(); |
106 | |
107 | Point<3,float> xq = vd.getPos(q); |
108 | |
109 | if (xp.distance2(xq) < r_cut * r_cut) |
110 | list_idx2.get(it.get().getKey()).add(q); |
111 | |
112 | ++Np; |
113 | } |
114 | |
115 | list_idx2.get(it.get().getKey()).sort(); |
116 | |
117 | ++it; |
118 | } |
119 | |
120 | BOOST_REQUIRE_EQUAL(list_idx.size(),list_idx2.size()); |
121 | |
122 | bool ret; |
123 | for (size_t i = 0 ; i < list_idx.size() ; i++) |
124 | { |
125 | BOOST_REQUIRE_EQUAL(list_idx.get(i).size(),list_idx2.get(i).size()); |
126 | |
127 | ret = true; |
128 | for (size_t j = 0 ; j < list_idx.get(i).size() ; j++) |
129 | ret &= list_idx.get(i).get(j) == list_idx2.get(i).get(j); |
130 | |
131 | BOOST_REQUIRE_EQUAL(ret,true); |
132 | } |
133 | |
134 | /////////////////////////////////// |
135 | |
136 | auto NNv = vd.template getVerlet<VerletList>(r_cut*1.0001); |
137 | |
138 | it = vd.getDomainIterator(); |
139 | |
140 | while (it.isNext()) |
141 | { |
142 | Point<3,float> xp = vd.getPos(it.get()); |
143 | auto Np = NNv.template getNNIterator<NO_CHECK>(it.get().getKey()); |
144 | |
145 | list_idx2.get(it.get().getKey()).clear(); |
146 | |
147 | while (Np.isNext()) |
148 | { |
149 | auto q = Np.get(); |
150 | |
151 | Point<3,float> xq = vd.getPos(q); |
152 | |
153 | if (xp.distance2(xq) < r_cut * r_cut) |
154 | list_idx2.get(it.get().getKey()).add(q); |
155 | |
156 | ++Np; |
157 | } |
158 | |
159 | list_idx2.get(it.get().getKey()).sort(); |
160 | |
161 | ++it; |
162 | } |
163 | |
164 | BOOST_REQUIRE_EQUAL(list_idx.size(),list_idx2.size()); |
165 | |
166 | for (size_t i = 0 ; i < list_idx.size() ; i++) |
167 | { |
168 | BOOST_REQUIRE_EQUAL(list_idx.get(i).size(),list_idx2.get(i).size()); |
169 | |
170 | ret = true; |
171 | for (size_t j = 0 ; j < list_idx.get(i).size() ; j++) |
172 | ret &= list_idx.get(i).get(j) == list_idx2.get(i).get(j); |
173 | |
174 | BOOST_REQUIRE_EQUAL(ret,true); |
175 | } |
176 | |
177 | ////////////////////////////////////////// |
178 | |
179 | NNv.clear(); |
180 | vd.updateVerlet(NNv,r_cut*1.0001); |
181 | |
182 | it = vd.getDomainIterator(); |
183 | |
184 | while (it.isNext()) |
185 | { |
186 | Point<3,float> xp = vd.getPos(it.get()); |
187 | auto Np = NNv.template getNNIterator<NO_CHECK>(it.get().getKey()); |
188 | |
189 | list_idx2.get(it.get().getKey()).clear(); |
190 | |
191 | while (Np.isNext()) |
192 | { |
193 | auto q = Np.get(); |
194 | |
195 | Point<3,float> xq = vd.getPos(q); |
196 | |
197 | if (xp.distance2(xq) < r_cut * r_cut) |
198 | list_idx2.get(it.get().getKey()).add(q); |
199 | |
200 | ++Np; |
201 | } |
202 | |
203 | list_idx2.get(it.get().getKey()).sort(); |
204 | |
205 | ++it; |
206 | } |
207 | |
208 | BOOST_REQUIRE_EQUAL(list_idx.size(),list_idx2.size()); |
209 | |
210 | for (size_t i = 0 ; i < list_idx.size() ; i++) |
211 | { |
212 | BOOST_REQUIRE_EQUAL(list_idx.get(i).size(),list_idx2.get(i).size()); |
213 | |
214 | ret = true; |
215 | for (size_t j = 0 ; j < list_idx.get(i).size() ; j++) |
216 | ret &= list_idx.get(i).get(j) == list_idx2.get(i).get(j); |
217 | |
218 | BOOST_REQUIRE_EQUAL(ret,true); |
219 | } |
220 | } |
221 | } |
222 | |
223 | BOOST_AUTO_TEST_CASE( vector_dist_full_NN ) |
224 | { |
225 | auto & v_cl = create_vcluster(); |
226 | |
227 | #ifdef TEST_COVERAGE_MODE |
228 | long int k = 50 * v_cl.getProcessingUnits(); |
229 | #else |
230 | long int k = 750 * v_cl.getProcessingUnits(); |
231 | #endif |
232 | |
233 | test_full_nn<VERLET_MEMFAST(3,float)>(k); |
234 | |
235 | k /= 2; |
236 | test_full_nn<VERLET_MEMBAL(3,float)>(k); |
237 | k /= 2; |
238 | test_full_nn<VERLET_MEMMW(3,float)>(k); |
239 | } |
240 | |
241 | BOOST_AUTO_TEST_CASE( vector_dist_particle_iteration ) |
242 | { |
243 | Vcluster<> & v_cl = create_vcluster(); |
244 | |
245 | if (v_cl.getProcessingUnits() > 12) |
246 | return; |
247 | |
248 | // set the seed |
249 | // create the random generator engine |
250 | std::srand(v_cl.getProcessUnitID()); |
251 | std::default_random_engine eg; |
252 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
253 | |
254 | long int k = 750 * v_cl.getProcessingUnits(); |
255 | |
256 | print_test_v("Testing 3D particle cell iterator=" ,k); |
257 | BOOST_TEST_CHECKPOINT( "Testing 3D full NN search k=" << k ); |
258 | |
259 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
260 | |
261 | // Boundary conditions |
262 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
263 | |
264 | float r_cut = 0.1; |
265 | |
266 | // ghost |
267 | Ghost<3,float> ghost(r_cut); |
268 | |
269 | typedef aggregate<float> part_prop; |
270 | |
271 | // Distributed vector |
272 | vector_dist<3,float, part_prop > vd(k,box,bc,ghost,BIND_DEC_TO_GHOST); |
273 | |
274 | auto it = vd.getIterator(); |
275 | |
276 | while (it.isNext()) |
277 | { |
278 | auto key = it.get(); |
279 | |
280 | vd.getPos(key)[0] = ud(eg); |
281 | vd.getPos(key)[1] = ud(eg); |
282 | vd.getPos(key)[2] = ud(eg); |
283 | |
284 | // Fill some properties randomly |
285 | |
286 | vd.getProp<0>(key) = 0.0; |
287 | |
288 | ++it; |
289 | } |
290 | |
291 | vd.map(); |
292 | |
293 | // sync the ghost |
294 | vd.ghost_get<0>(); |
295 | |
296 | openfpm::vector<size_t> ids; |
297 | ids.resize(vd.size_local()); |
298 | |
299 | auto NN = vd.getCellListSym(r_cut); |
300 | |
301 | auto it_pcell = vd.getDomainIteratorCells(NN); |
302 | |
303 | size_t count = 0; |
304 | while (it_pcell.isNext()) |
305 | { |
306 | count++; |
307 | |
308 | size_t id = it_pcell.get(); |
309 | ids.get(id) = 1; |
310 | |
311 | BOOST_REQUIRE(id < vd.size_local()); |
312 | |
313 | ++it_pcell; |
314 | } |
315 | |
316 | v_cl.sum(count); |
317 | v_cl.execute(); |
318 | |
319 | BOOST_REQUIRE_EQUAL((long int)count,k); |
320 | } |
321 | |
322 | BOOST_AUTO_TEST_CASE( vector_dist_particle_NN_update_with_limit ) |
323 | { |
324 | Vcluster<> & v_cl = create_vcluster(); |
325 | |
326 | if (v_cl.getProcessingUnits() > 12) |
327 | return; |
328 | |
329 | // set the seed |
330 | // create the random generator engine |
331 | std::srand(v_cl.getProcessUnitID()); |
332 | std::default_random_engine eg; |
333 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
334 | |
335 | long int k = 750 * v_cl.getProcessingUnits(); |
336 | |
337 | print_test_v("Testing 3D particle cell-list with radius at limit= " ,k); |
338 | BOOST_TEST_CHECKPOINT( "Testing 3D particle cell-list with radius at limit= " << k ); |
339 | |
340 | Box<3,float> box({0.0,0.0,0.0},{0.1,0.39,0.39}); |
341 | |
342 | // Boundary conditions |
343 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
344 | |
345 | float r_cut = 0.1; |
346 | |
347 | // ghost |
348 | Ghost<3,float> ghost(r_cut); |
349 | |
350 | typedef aggregate<float> part_prop; |
351 | |
352 | // Distributed vector |
353 | vector_dist<3,float, part_prop > vd(k,box,bc,ghost); |
354 | |
355 | auto it = vd.getIterator(); |
356 | |
357 | while (it.isNext()) |
358 | { |
359 | auto key = it.get(); |
360 | |
361 | vd.getPos(key)[0] = ud(eg); |
362 | vd.getPos(key)[1] = ud(eg); |
363 | vd.getPos(key)[2] = ud(eg); |
364 | |
365 | // Fill some properties randomly |
366 | |
367 | vd.getProp<0>(key) = 0.0; |
368 | |
369 | ++it; |
370 | } |
371 | |
372 | vd.map(); |
373 | |
374 | // sync the ghost |
375 | vd.ghost_get<0>(); |
376 | |
377 | auto NN = vd.getCellListSym(r_cut); |
378 | |
379 | auto cell1 = NN.getCellBox(); |
380 | |
381 | vd.getDecomposition().decompose(); |
382 | vd.map(); |
383 | |
384 | vd.updateCellListSym(NN); |
385 | |
386 | auto cell2 = NN.getCellBox(); |
387 | |
388 | BOOST_REQUIRE_EQUAL(cell1.getHigh(0),cell2.getHigh(0)); |
389 | BOOST_REQUIRE_EQUAL(cell1.getHigh(1),cell2.getHigh(1)); |
390 | BOOST_REQUIRE_EQUAL(cell1.getHigh(2),cell2.getHigh(2)); |
391 | } |
392 | |
393 | BOOST_AUTO_TEST_CASE( vector_dist_particle_getCellListSym_with_div ) |
394 | { |
395 | Vcluster<> & v_cl = create_vcluster(); |
396 | |
397 | if (v_cl.getProcessingUnits() > 12) |
398 | return; |
399 | |
400 | // set the seed |
401 | // create the random generator engine |
402 | std::srand(v_cl.getProcessUnitID()); |
403 | std::default_random_engine eg; |
404 | std::uniform_real_distribution<float> ud(0.0f, 1.0f); |
405 | |
406 | long int k = 750 * v_cl.getProcessingUnits(); |
407 | |
408 | print_test_v("Testing 3D particle getCellListSym with div =" ,k); |
409 | BOOST_TEST_CHECKPOINT( "Testing 3D particle getCellListSym with div = " << k ); |
410 | |
411 | Box<3,float> box({0.0,0.0,0.0},{0.1,0.39,0.39}); |
412 | |
413 | // Boundary conditions |
414 | size_t bc[3]={PERIODIC,PERIODIC,PERIODIC}; |
415 | |
416 | float r_cut = 0.1; |
417 | |
418 | // ghost |
419 | Ghost<3,float> ghost(r_cut); |
420 | |
421 | typedef aggregate<float> part_prop; |
422 | |
423 | // Distributed vector |
424 | vector_dist<3,float, part_prop > vd(k,box,bc,ghost); |
425 | |
426 | auto it = vd.getIterator(); |
427 | |
428 | while (it.isNext()) |
429 | { |
430 | auto key = it.get(); |
431 | |
432 | vd.getPos(key)[0] = ud(eg); |
433 | vd.getPos(key)[1] = ud(eg); |
434 | vd.getPos(key)[2] = ud(eg); |
435 | |
436 | // Fill some properties randomly |
437 | |
438 | vd.getProp<0>(key) = 0.0; |
439 | |
440 | ++it; |
441 | } |
442 | |
443 | vd.map(); |
444 | |
445 | // sync the ghost |
446 | vd.ghost_get<0>(); |
447 | |
448 | auto NN1 = vd.getCellListSym(r_cut); |
449 | |
450 | size_t div_wp[3] = {NN1.getDivWP()[0],NN1.getDivWP()[1],NN1.getDivWP()[2]}; |
451 | size_t pad[3] = {NN1.getPadding()[0],NN1.getPadding()[1],NN1.getPadding()[2]}; |
452 | |
453 | auto NN2 = vd.getCellListSym(div_wp,pad); |
454 | |
455 | // Check that the two Cell list are identical |
456 | |
457 | // grid info |
458 | size_t div[3] = {NN1.getInternalGrid().getSize()[0], |
459 | NN1.getInternalGrid().getSize()[1], |
460 | NN1.getInternalGrid().getSize()[2]}; |
461 | |
462 | grid_sm<3,void> g_info(div); |
463 | |
464 | bool match = true; |
465 | |
466 | // Create a grid iterator |
467 | grid_key_dx_iterator<3> g_it(g_info); |
468 | |
469 | while (g_it.isNext()) |
470 | { |
471 | size_t cell = g_info.LinId(g_it.get()); |
472 | size_t n_ele1 = NN1.getNelements(cell); |
473 | size_t n_ele2 = NN2.getNelements(cell); |
474 | |
475 | match &= n_ele1 == n_ele2; |
476 | |
477 | ++g_it; |
478 | } |
479 | |
480 | BOOST_REQUIRE_EQUAL(match,true); |
481 | } |
482 | |