1#ifndef DIST_MAP_GRAPH_UNIT_TEST_HPP
2#define DIST_MAP_GRAPH_UNIT_TEST_HPP
3
4#include "Graph/DistGraphFactory.hpp"
5#include "Graph/dist_map_graph.hpp"
6#include "Packer_Unpacker/Packer.hpp"
7#include "Packer_Unpacker/Unpacker.hpp"
8
9#define DGRAPH_GS_SIZE 4
10
11struct vx
12{
13 typedef boost::fusion::vector<float[3]> type;
14
15 //! Attributes name
16 struct attributes
17 {
18 static const std::string name[];
19 };
20
21 //! type of the positional field
22 typedef float s_type;
23
24 //! The data
25 type data;
26
27 //! x property id in boost::fusion::vector
28 static const unsigned int x = 0;
29 //! total number of properties boost::fusion::vector
30 static const unsigned int max_prop = 1;
31
32 vx()
33 {
34
35 }
36
37 inline vx(const vx & p)
38 {
39 boost::fusion::at_c<0>(data)[0] = boost::fusion::at_c<0>(p.data)[0];
40 boost::fusion::at_c<0>(data)[1] = boost::fusion::at_c<0>(p.data)[1];
41 boost::fusion::at_c<0>(data)[2] = boost::fusion::at_c<0>(p.data)[2];
42 }
43
44 template<unsigned int id> inline auto get() -> decltype(boost::fusion::at_c < id > (data))
45 {
46 return boost::fusion::at_c<id>(data);
47 }
48
49 template<unsigned int id> inline auto get() const -> const decltype(boost::fusion::at_c < id > (data))
50 {
51 return boost::fusion::at_c<id>(data);
52 }
53
54 template<unsigned int dim, typename Mem> inline vx(const encapc<dim, vx, Mem> & p)
55 {
56 this->operator=(p);
57 }
58
59 template<unsigned int dim, typename Mem> inline vx & operator=(const encapc<dim, vx, Mem> & p)
60 {
61 boost::fusion::at_c<0>(data)[0] = p.template get<0>()[0];
62 boost::fusion::at_c<0>(data)[1] = p.template get<0>()[1];
63 boost::fusion::at_c<0>(data)[2] = p.template get<0>()[2];
64
65 return *this;
66 }
67
68 static bool noPointers()
69 {
70 return true;
71 }
72};
73
74const std::string vx::attributes::name[] = { "x" };
75
76struct ed
77{
78 typedef boost::fusion::vector<size_t> type;
79
80 //! Attributes name
81 struct attributes
82 {
83 static const std::string name[];
84 };
85
86 //! The data
87 type data;
88
89 //! srcgid property id in boost::fusion::vector
90 static const unsigned int prop = 0;
91 //! total number of properties boost::fusion::vector
92 static const unsigned int max_prop = 1;
93
94 ed()
95 {
96
97 }
98
99 template<unsigned int id> inline auto get() -> decltype(boost::fusion::at_c < id > (data))
100 {
101 return boost::fusion::at_c<id>(data);
102 }
103
104 template<unsigned int dim, typename Mem> inline ed(const encapc<dim, ed, Mem> & p)
105 {
106 this->operator=(p);
107 }
108
109 template<unsigned int dim, typename Mem> inline ed & operator=(const encapc<dim, ed, Mem> & p)
110 {
111 boost::fusion::at_c<0>(data) = p.template get<0>();
112
113 return *this;
114 }
115
116 static bool noPointers()
117 {
118 return true;
119 }
120};
121
122const std::string ed::attributes::name[] = { "prop" };
123
124BOOST_AUTO_TEST_SUITE (dist_map_graph_test)
125
126BOOST_AUTO_TEST_CASE( dist_map_graph_use)
127{
128
129 //! Vcluster
130 Vcluster<> & vcl = create_vcluster();
131
132 if(vcl.getProcessingUnits() != 4)
133 return;
134
135 //! Cartesian grid
136 size_t sz[2] = { DGRAPH_GS_SIZE, DGRAPH_GS_SIZE };
137
138 //! Box
139 Box<2, float> box( { 0.0, 0.0 }, { 1.0, 1.0 });
140
141 //! Distributed graph factory
142 DistGraphFactory<2, DistGraph_CSR<vx, ed>> g_factory;
143
144 //! Distributed graph
145 DistGraph_CSR<vx, ed> gd = g_factory.construct<NO_EDGE, float, 2 - 1, 0, 1, 2>(sz, box);
146
147 //! [Request some vertices given global ids]
148
149 gd.reqVertex(13);
150 gd.reqVertex(1);
151 gd.reqVertex(14);
152 gd.sync();
153
154 gd.reqVertex(15);
155 gd.reqVertex(2);
156 gd.reqVertex(10);
157 gd.sync();
158
159 gd.deleteGhosts();
160
161 //! [Exchange n vertices and edges packed]
162
163 if(vcl.getProcessUnitID() == 0)
164 {
165 for(size_t i = 0; i < 4; i++)
166 gd.q_move(i, 1);
167 }
168
169 if(vcl.getProcessUnitID() == 1)
170 {
171 for(size_t i = 0; i < 4; i++)
172 gd.q_move(i, 0);
173 }
174
175 if(vcl.getProcessUnitID() == 2)
176 {
177 for(size_t i = 0; i < 2; i++)
178 gd.q_move(i, 3);
179 }
180
181 if(vcl.getProcessUnitID() == 3)
182 {
183 for(size_t i = 0; i < 4; i++)
184 gd.q_move(i, 2);
185 }
186
187 //! Redistribute
188 gd.redistribute();
189
190 if(vcl.getProcessUnitID() == 0)
191 {
192 BOOST_REQUIRE_EQUAL(gd.getVertexId(0), 0ul);
193 BOOST_REQUIRE_EQUAL(gd.getVertexId(1), 1ul);
194 BOOST_REQUIRE_EQUAL(gd.getVertexId(2), 2ul);
195 BOOST_REQUIRE_EQUAL(gd.getVertexId(3), 3ul);
196 BOOST_REQUIRE_EQUAL(gd.getNChilds(0), 3ul);
197 BOOST_REQUIRE_EQUAL(gd.getChild(0,0), 1ul);
198 BOOST_REQUIRE_EQUAL(gd.getChild(0,1), 14ul);
199 BOOST_REQUIRE_EQUAL(gd.getChild(0,2), 4ul);
200 BOOST_REQUIRE_EQUAL(gd.getNChilds(1), 4ul);
201 BOOST_REQUIRE_EQUAL(gd.getChild(1,0), 2ul);
202 BOOST_REQUIRE_EQUAL(gd.getChild(1,1), 0ul);
203 BOOST_REQUIRE_EQUAL(gd.getChild(1,2), 15ul);
204 BOOST_REQUIRE_EQUAL(gd.getChild(1,3), 5ul);
205 BOOST_REQUIRE_EQUAL(gd.getNChilds(2), 4ul);
206 BOOST_REQUIRE_EQUAL(gd.getChild(2,0), 3ul);
207 BOOST_REQUIRE_EQUAL(gd.getChild(2,1), 1ul);
208 BOOST_REQUIRE_EQUAL(gd.getChild(2,2), 8ul);
209 BOOST_REQUIRE_EQUAL(gd.getChild(2,3), 6ul);
210 BOOST_REQUIRE_EQUAL(gd.getNChilds(3), 3ul);
211 BOOST_REQUIRE_EQUAL(gd.getChild(3,0), 2ul);
212 BOOST_REQUIRE_EQUAL(gd.getChild(3,1), 9ul);
213 BOOST_REQUIRE_EQUAL(gd.getChild(3,2), 7ul);
214 }
215
216 if(vcl.getProcessUnitID() == 1)
217 {
218 BOOST_REQUIRE_EQUAL(gd.getVertexId(0), 4ul);
219 BOOST_REQUIRE_EQUAL(gd.getVertexId(1), 5ul);
220 BOOST_REQUIRE_EQUAL(gd.getVertexId(2), 6ul);
221 BOOST_REQUIRE_EQUAL(gd.getVertexId(3), 7ul);
222 }
223
224 if(vcl.getProcessUnitID() == 2)
225 {
226 BOOST_REQUIRE_EQUAL(gd.getVertexId(0), 8ul);
227 BOOST_REQUIRE_EQUAL(gd.getVertexId(1), 9ul);
228 BOOST_REQUIRE_EQUAL(gd.getVertexId(2), 10ul);
229 BOOST_REQUIRE_EQUAL(gd.getVertexId(3), 11ul);
230 BOOST_REQUIRE_EQUAL(gd.getVertexId(4), 12ul);
231 BOOST_REQUIRE_EQUAL(gd.getVertexId(5), 13ul);
232 }
233
234 if(vcl.getProcessUnitID() == 3)
235 {
236 BOOST_REQUIRE_EQUAL(gd.getVertexId(0), 14ul);
237 BOOST_REQUIRE_EQUAL(gd.getVertexId(1), 15ul);
238 }
239}
240
241BOOST_AUTO_TEST_CASE( dist_map_graph_use_redistribution)
242{
243 //! Vcluster
244 Vcluster<> & vcl = create_vcluster();
245
246 if(vcl.getProcessingUnits() != 4)
247 return;
248
249 //! Cartesian grid
250 size_t sz[2] = { 4, 4 };
251
252 //! Box
253 Box<2, float> box( { 0.0, 0.0 }, { 1.0, 1.0 });
254
255 //! Distributed graph factory
256 DistGraphFactory<2, DistGraph_CSR<vx, ed>> g_factory;
257
258 //! Distributed graph
259 DistGraph_CSR<vx, ed> gd = g_factory.construct<NO_EDGE, float, 2 - 1, 0, 1, 2>(sz, box);
260
261 for(size_t i=0; i< gd.getNVertex(); i++)
262 gd.vertex(i).get<vx::x>()[2] = 0;
263
264 if (vcl.getProcessUnitID() == 0)
265 {
266 gd.q_move(0,1);
267 gd.q_move(1,1);
268 }
269
270 if (vcl.getProcessUnitID() == 1)
271 {
272 gd.q_move(2,0);
273 gd.q_move(3,0);
274 }
275
276 if (vcl.getProcessUnitID() == 2)
277 {
278 gd.q_move(0,3);
279 gd.q_move(1,3);
280 }
281
282 if (vcl.getProcessUnitID() == 3)
283 {
284 gd.q_move(2,2);
285 gd.q_move(3,2);
286 }
287
288 gd.redistribute();
289
290 VTKWriter<DistGraph_CSR<vx, ed>, DIST_GRAPH> gv2(gd);
291 gv2.write("dist_graph_redistribution_0.vtk");
292
293 if(vcl.getProcessUnitID() == 0)
294 {
295 bool test = compare("dist_graph_redistribution_0.vtk", "src/Graph/test_data/dist_graph_redistribution_0_test.vtk");
296 BOOST_REQUIRE_EQUAL(true,test);
297 }
298
299 if (vcl.getProcessUnitID() == 2)
300 {
301 gd.q_move(0,0);
302 gd.q_move(1,0);
303 }
304
305 if (vcl.getProcessUnitID() == 3)
306 {
307 gd.q_move(0,0);
308 gd.q_move(2,0);
309 }
310
311 gd.redistribute();
312
313 gv2.write("dist_graph_redistribution_1.vtk");
314
315 if(vcl.getProcessUnitID() == 0)
316 {
317 bool test = compare("dist_graph_redistribution_1.vtk","src/Graph/test_data/dist_graph_redistribution_1_test.vtk");
318 BOOST_REQUIRE_EQUAL(true,test);
319 }
320
321}
322
323
324BOOST_AUTO_TEST_CASE( dist_map_graph_use_free_add)
325{
326 // Vcluster
327 Vcluster<> & vcl = create_vcluster();
328
329 if(vcl.getProcessingUnits() != 4)
330 return;
331
332 // [create graph adding freely the vertices and the edges ]
333
334 // Distributed graph
335 DistGraph_CSR<vx, ed> gd;
336
337 // Add vertices
338 for (size_t i = 0; i < 4; ++i)
339 {
340 vx v;
341 v.get<vx::x>()[0] = vcl.getProcessUnitID();
342 v.get<vx::x>()[1] = i;
343 v.get<vx::x>()[2] = 0;
344 size_t gid = vcl.getProcessUnitID()*4 + i;
345 gd.add_vertex(v, gid);
346 }
347
348 // This method must be called after adding vertices
349 gd.init();
350
351 // Add edges
352 if(vcl.getProcessUnitID()==0)
353 {
354 gd.add_edge(0,1);
355 gd.add_edge(1,2);
356 gd.add_edge(2,3);
357 gd.add_edge(0,4);
358 gd.add_edge(1,5);
359 gd.add_edge(2,6);
360 gd.add_edge(3,7);
361 }
362
363 if(vcl.getProcessUnitID()==1)
364 {
365 gd.add_edge(4,5);
366 gd.add_edge(5,6);
367 gd.add_edge(6,7);
368 gd.add_edge(4,8);
369 gd.add_edge(5,9);
370 gd.add_edge(6,10);
371 gd.add_edge(7,11);
372 }
373
374 if(vcl.getProcessUnitID()==2)
375 {
376 gd.add_edge(8,9);
377 gd.add_edge(9,10);
378 gd.add_edge(10,11);
379 gd.add_edge(8,12);
380 gd.add_edge(9,13);
381 gd.add_edge(10,14);
382 gd.add_edge(11,15);
383 }
384
385 if(vcl.getProcessUnitID()==3)
386 {
387 gd.add_edge(12,13);
388 gd.add_edge(13,14);
389 gd.add_edge(14,15);
390 }
391
392 gd.syncEdge();
393
394 //! [create graph adding freely the vertices and the edges ]
395
396 if(vcl.getProcessUnitID() == 0)
397 {
398 for (size_t i = 0; i < 4; ++i)
399 {
400 BOOST_REQUIRE_EQUAL(gd.getVertexId(i), i);
401 }
402 }
403
404 if(vcl.getProcessUnitID() == 2)
405 {
406 for (size_t i = 8, j = 0; i < 12 && j < gd.getNVertex(); ++i, ++j)
407 {
408 BOOST_REQUIRE_EQUAL(gd.getVertexId(j), i);
409 }
410 }
411
412 if(vcl.getProcessUnitID() == 0)
413 gd.reqVertex(5);
414
415 gd.sync();
416
417 if(vcl.getProcessUnitID() == 0)
418 BOOST_REQUIRE_EQUAL(gd.getVertexId(4), 5ul);
419
420 gd.deleteGhosts();
421
422 if (vcl.getProcessUnitID() == 0)
423 {
424 gd.q_move(0,1);
425 gd.q_move(1,1);
426 }
427
428 if (vcl.getProcessUnitID() == 1)
429 {
430 gd.q_move(2,0);
431 gd.q_move(3,0);
432 }
433
434 if (vcl.getProcessUnitID() == 2)
435 {
436 gd.q_move(0,3);
437 gd.q_move(1,3);
438 }
439
440 if (vcl.getProcessUnitID() == 3)
441 {
442 gd.q_move(2,2);
443 gd.q_move(3,2);
444 }
445
446 gd.redistribute();
447
448 VTKWriter<DistGraph_CSR<vx, ed>, DIST_GRAPH> gv2(gd);
449 gv2.write("dist_graph_free_0.vtk");
450
451 if(vcl.getProcessUnitID() == 0)
452 {
453 bool test = compare("dist_graph_free_0.vtk", "src/Graph/test_data/dist_graph_free_0_test.vtk");
454 BOOST_REQUIRE_EQUAL(true,test);
455 }
456
457 if (vcl.getProcessUnitID() == 2)
458 {
459 gd.q_move(0,0);
460 gd.q_move(1,0);
461 }
462
463 if (vcl.getProcessUnitID() == 3)
464 {
465 gd.q_move(0,0);
466 gd.q_move(2,0);
467 }
468
469 gd.redistribute();
470
471 gv2.write("dist_graph_free_1.vtk");
472
473 if(vcl.getProcessUnitID() == 0)
474 {
475 bool test = compare("dist_graph_free_1.vtk", "src/Graph/test_data/dist_graph_free_1_test.vtk");
476 BOOST_REQUIRE_EQUAL(true,test);
477 }
478}
479
480BOOST_AUTO_TEST_CASE( dist_map_graph_use_multi_free_add)
481{
482 // Vcluster
483 Vcluster<> & vcl = create_vcluster();
484
485 if(vcl.getProcessingUnits() != 4)
486 return;
487
488 // Distributed graph
489 DistGraph_CSR<vx, ed> gd;
490
491 // Add vertices
492 if(vcl.getProcessUnitID()==0)
493 {
494 vx v;
495 gd.add_vertex(v, 0);
496 gd.add_vertex(v, 1);
497 gd.add_vertex(v, 2);
498 gd.add_vertex(v, 3);
499 }
500
501 if(vcl.getProcessUnitID()==1)
502 {
503 vx v;
504 gd.add_vertex(v, 4);
505 gd.add_vertex(v, 5);
506 gd.add_vertex(v, 6);
507 gd.add_vertex(v, 7);
508 }
509
510 // This method must be called ALWAYS after adding vertices
511 gd.init();
512
513 if(vcl.getProcessUnitID()==2)
514 {
515 vx v;
516 gd.add_vertex(v, 8);
517 gd.add_vertex(v, 9);
518 gd.add_vertex(v, 10);
519 gd.add_vertex(v, 11);
520 }
521
522 if(vcl.getProcessUnitID()==3)
523 {
524 vx v;
525 gd.add_vertex(v, 12);
526 gd.add_vertex(v, 13);
527 gd.add_vertex(v, 14);
528 gd.add_vertex(v, 15);
529 }
530
531 // This method must be called ALWAYS after adding vertices
532 gd.init();
533
534 gd.reqVertex(15);
535
536 gd.sync();
537
538 BOOST_REQUIRE_EQUAL(gd.getVertexId(gd.getNVertex()-1), 15ul);
539}
540
541BOOST_AUTO_TEST_SUITE_END()
542
543#endif
544