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
21BOOST_AUTO_TEST_SUITE( dec_optimizer_test )
22
23BOOST_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
59BOOST_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
135BOOST_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
208BOOST_AUTO_TEST_SUITE_END()
209
210
211#endif /* DEC_OPTIMIZE_HPP_ */
212