1 | /* |
2 | * dec_optimize.hpp |
3 | * |
4 | * Created on: Jan 16, 2015 |
5 | * Author: Pietro Incardona |
6 | */ |
7 | |
8 | #ifndef DEC_OPTIMIZE_HPP_ |
9 | #define DEC_OPTIMIZE_HPP_ |
10 | |
11 | |
12 | #include "Graph/CartesianGraphFactory.hpp" |
13 | #include "Graph/map_graph.hpp" |
14 | #include "Decomposition/Distribution/metis_util.hpp" |
15 | #include "dec_optimizer.hpp" |
16 | #include "util/SimpleRNG.hpp" |
17 | |
18 | #undef GS_SIZE |
19 | #define GS_SIZE 8 |
20 | |
21 | BOOST_AUTO_TEST_SUITE( dec_optimizer_test ) |
22 | |
23 | BOOST_AUTO_TEST_CASE( dec_optimizer_test_use_np) |
24 | { |
25 | CartesianGraphFactory<3,Graph_CSR<nm_v<3>,nm_e>> g_factory; |
26 | CartesianGraphFactory<3,Graph_CSR<nm_part_v,nm_part_e>> g_factory_part; |
27 | |
28 | // Cartesian grid |
29 | size_t sz[3] = {GS_SIZE,GS_SIZE,GS_SIZE}; |
30 | |
31 | // Box |
32 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
33 | |
34 | // Boundary conditions, non periodic |
35 | size_t bc[] = {NON_PERIODIC,NON_PERIODIC,NON_PERIODIC}; |
36 | |
37 | // Graph to decompose |
38 | Graph_CSR<nm_v<3>,nm_e> g = g_factory.construct<nm_e::communication,NO_VERTEX_ID,float,2,0>(sz,box,bc); |
39 | |
40 | // Processor graph |
41 | Graph_CSR<nm_part_v,nm_part_e> gp = g_factory_part.construct<NO_EDGE,NO_VERTEX_ID,float,2>(sz,box,bc); |
42 | |
43 | // Convert the graph to metis |
44 | Metis<Graph_CSR<nm_v<3>,nm_e>> met(g,16); |
45 | |
46 | // decompose |
47 | met.decompose<nm_part_v::id>(gp); |
48 | met.decompose<nm_v_id>(); |
49 | |
50 | // optimize |
51 | dec_optimizer<3,Graph_CSR<nm_v<3>,nm_e>> d_o(g,sz); |
52 | |
53 | Ghost<3,size_t> ghe(1); |
54 | |
55 | grid_key_dx<3> keyZero(0,0,0); |
56 | d_o.optimize<nm_v_sub_id,nm_v_id>(keyZero,g,ghe,bc); |
57 | } |
58 | |
59 | BOOST_AUTO_TEST_CASE( dec_optimizer_test_use_p) |
60 | { |
61 | CartesianGraphFactory<3,Graph_CSR<nm_v<3>,nm_e>> g_factory; |
62 | CartesianGraphFactory<3,Graph_CSR<nm_part_v,nm_part_e>> g_factory_part; |
63 | |
64 | // Cartesian grid |
65 | size_t sz[3] = {GS_SIZE,GS_SIZE,GS_SIZE}; |
66 | |
67 | //! Grid info |
68 | grid_sm<3,void> gs(sz); |
69 | |
70 | // Box |
71 | Box<3,float> box({0.0,0.0,0.0},{1.0,1.0,1.0}); |
72 | |
73 | // Boundary conditions, non periodic |
74 | size_t bc[] = {PERIODIC,PERIODIC,PERIODIC}; |
75 | |
76 | // Graph to decompose |
77 | Graph_CSR<nm_v<3>,nm_e> g = g_factory.construct<nm_e::communication,NO_VERTEX_ID,float,2,0>(sz,box,bc); |
78 | |
79 | // Processor graph |
80 | Graph_CSR<nm_part_v,nm_part_e> gp = g_factory_part.construct<NO_EDGE,NO_VERTEX_ID,float,2>(sz,box,bc); |
81 | |
82 | bool p[3]; |
83 | |
84 | // Divide in 8 parts your graph |
85 | |
86 | // decompose |
87 | for (size_t i = 0 ; i < GS_SIZE ; i++) |
88 | { |
89 | p[0] = (i < GS_SIZE/2)?false:true; |
90 | for (size_t j = 0 ; j < GS_SIZE ; j++) |
91 | { |
92 | p[1] = (j < GS_SIZE/2)?false:true; |
93 | for (size_t k = 0 ; k < GS_SIZE ; k++) |
94 | { |
95 | p[2] = (k < GS_SIZE/2)?false:true; |
96 | size_t id = 4*p[2] + 2*p[1] + p[0]; |
97 | |
98 | grid_key_dx<3> key(i,j,k); |
99 | gp.vertex(gs.LinId(key)).get<nm_part_v::id>() = id; |
100 | g.vertex(gs.LinId(key)).get<nm_v_id>() = id; |
101 | } |
102 | } |
103 | } |
104 | |
105 | // optimize |
106 | dec_optimizer<3,Graph_CSR<nm_v<3>,nm_e>> d_o(g,sz); |
107 | |
108 | grid_key_dx<3> keyZero(0,0,0); |
109 | |
110 | // Set of sub-domain produced by dec-optimizer |
111 | openfpm::vector<Box<3,size_t>> dec_o; |
112 | |
113 | // For each sub-domain check the neighborhood processors |
114 | openfpm::vector< openfpm::vector<size_t> > box_nn_processor; |
115 | |
116 | Ghost<3,size_t> ghe(1); |
117 | |
118 | // gp,p_id,loc_box,box_nn_processor,bc |
119 | d_o.optimize<nm_v_sub_id,nm_v_id>(g,-1,dec_o,box_nn_processor,ghe,bc); |
120 | |
121 | BOOST_REQUIRE_EQUAL(box_nn_processor.size(),8ul); |
122 | |
123 | for(size_t i = 0 ; i < box_nn_processor.size() ; i++) |
124 | { |
125 | BOOST_REQUIRE_EQUAL(box_nn_processor.get(i).size(),8ul); |
126 | for (size_t j = 0 ; j < box_nn_processor.get(i).size(); j++) |
127 | { |
128 | BOOST_REQUIRE(box_nn_processor.get(i).get(j) < 8); |
129 | } |
130 | } |
131 | |
132 | // check |
133 | } |
134 | |
135 | BOOST_AUTO_TEST_CASE( dec_optimizer_disconnected_subdomains_np) |
136 | { |
137 | // Vcluster |
138 | Vcluster<> & vcl = create_vcluster(); |
139 | |
140 | // Test for only 3 processors |
141 | if (vcl.getProcessingUnits() != 3) |
142 | return; |
143 | |
144 | CartesianGraphFactory<2,Graph_CSR<nm_v<2>,nm_e>> g_factory; |
145 | |
146 | // Cartesian grid |
147 | size_t sz[2] = {GS_SIZE,GS_SIZE}; |
148 | |
149 | // Box |
150 | Box<2,float> box({0.0,0.0},{1.0,1.0}); |
151 | |
152 | // Boundary conditions, non periodic |
153 | size_t bc[] = {NON_PERIODIC,NON_PERIODIC}; |
154 | |
155 | // Graph to decompose |
156 | Graph_CSR<nm_v<2>,nm_e> g = g_factory.construct<nm_e::communication,NO_VERTEX_ID,float,1,0>(sz,box,bc); |
157 | |
158 | SimpleRNG rng; |
159 | |
160 | auto vit = g.getVertexIterator(); |
161 | |
162 | while (vit.isNext()) |
163 | { |
164 | auto vk = vit.get(); |
165 | |
166 | g.vertex_p<nm_v_proc_id>(vk) = rng.GetUniform() * 2.9999; |
167 | g.vertex_p<nm_v_sub_id>(vk) = 100; |
168 | |
169 | ++vit; |
170 | } |
171 | |
172 | // optimize |
173 | dec_optimizer<2,Graph_CSR<nm_v<2>,nm_e>> d_o(g,sz); |
174 | |
175 | // set of Boxes produced by the decomposition optimizer |
176 | openfpm::vector<::Box<2, size_t>> loc_box; |
177 | |
178 | //! for each sub-domain, contain the list of the neighborhood processors |
179 | openfpm::vector<openfpm::vector<long unsigned int> > box_nn_processor; |
180 | |
181 | Ghost<2,size_t> ghe(1); |
182 | d_o.optimize<nm_v_sub_id, nm_v_proc_id>(g, vcl.getProcessUnitID(), loc_box, box_nn_processor,ghe,bc); |
183 | |
184 | std::stringstream str_g; |
185 | str_g << "dec_optimizer_disc_graph" << vcl.getProcessUnitID() << ".vtk" ; |
186 | std::stringstream str_gt; |
187 | str_gt << "src/Decomposition/Distribution/test_data/dec_optimizer_disc_graph" << vcl.getProcessUnitID() << "_test.vtk" ; |
188 | |
189 | std::stringstream str_s; |
190 | str_s << "dec_optimizer_disc_sub" << vcl.getProcessUnitID() << ".vtk" ; |
191 | std::stringstream str_st; |
192 | str_st << "src/Decomposition/Distribution/test_data/dec_optimizer_disc_sub" << vcl.getProcessUnitID() << "_test.vtk" ; |
193 | |
194 | VTKWriter<Graph_CSR<nm_v<2>,nm_e>,VTK_GRAPH> wrt(g); |
195 | wrt.write("dec_optimizer_disc_graph" + std::to_string(vcl.getProcessUnitID()) + ".vtk" ); |
196 | |
197 | VTKWriter<openfpm::vector<::Box<2, size_t>>, VECTOR_BOX> vtk_box1; |
198 | vtk_box1.add(loc_box); |
199 | vtk_box1.write("dec_optimizer_disc_sub" + std::to_string(vcl.getProcessUnitID()) + std::string(".vtk" )); |
200 | |
201 | bool test = compare(str_g.str(), str_gt.str()); |
202 | BOOST_REQUIRE_EQUAL(true,test); |
203 | |
204 | test = compare(str_s.str(),str_st.str()); |
205 | BOOST_REQUIRE_EQUAL(true,test); |
206 | } |
207 | |
208 | BOOST_AUTO_TEST_SUITE_END() |
209 | |
210 | |
211 | #endif /* DEC_OPTIMIZE_HPP_ */ |
212 | |