OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
dec_optimizer_unit_test.hpp
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 {
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,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,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
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 {
63 
64  // Cartesian grid
65  size_t sz[3] = {GS_SIZE,GS_SIZE,GS_SIZE};
66 
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,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
107 
108  grid_key_dx<3> keyZero(0,0,0);
109 
110  // Set of sub-domain produced by dec-optimizer
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 
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,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
174 
175  // set of Boxes produced by the decomposition optimizer
177 
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,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_ */
auto getVertexIterator() const -> decltype(v.getIterator())
Get the vertex iterator.
Definition: map_graph.hpp:1005
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
size_t getProcessUnitID()
Get the process unit id.
static const unsigned int communication
computation property id in boost::fusion::vector
Helper class to define Metis graph.
Definition: metis_util.hpp:73
auto vertex_p(size_t id) -> decltype(v.template get< i >(id))
operator to access the vertex
Definition: map_graph.hpp:574
Definition: Ghost.hpp:39
Implementation of VCluster class.
Definition: VCluster.hpp:36
SimpleRNG is a simple random number generator based on George Marsaglia's MWC (multiply with carry) g...
Definition: SimpleRNG.hpp:18
This class construct a cartesian graph.
static const unsigned int sub_id
sub_id property id in boost::fusion::vector
static const unsigned int id
partition id in the boost::fusion::vector
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
auto vertex(size_t id) -> decltype(v.get(id))
Function to access the vertex.
Definition: map_graph.hpp:600
static const unsigned int id
id property id in boost::fusion::vector
Declaration grid_sm.
Definition: grid_sm.hpp:71
This class take a graph representing the space decomposition and produce a simplified version...
static Graph construct(const size_t(&sz)[dim], Box< dim, T > dom, const size_t(&bc)[dim])
Construct a cartesian graph, with V and E edge properties.
static const unsigned int proc_id
proc_id property id in boost::fusion::vector
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:61
size_t getProcessingUnits()
Get the total number of processors.