OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
SpaceDistributionWeight.hpp
1 /*
2  * SpaceDistributionWeight.hpp
3  *
4  * Created on: Apr 5, 2017
5  * Author: i-bird
6  */
7 
8 #ifndef SRC_DECOMPOSITION_DISTRIBUTION_SPACEDISTRIBUTIONWEIGHT_HPP_
9 #define SRC_DECOMPOSITION_DISTRIBUTION_SPACEDISTRIBUTIONWEIGHT_HPP_
10 
11 #if 0
12 
13 #include "util/mathutil.hpp"
14 #include "NN/CellList/CellDecomposer.hpp"
15 
24 template<unsigned int dim, typename T>
25 class SpaceDistributionWeight
26 {
28  Vcluster & v_cl;
29 
32 
34  Box<dim, T> domain;
35 
38 
39 
42 
43 public:
44 
49  SpaceDistributionWeight(Vcluster & v_cl)
50  :v_cl(v_cl)
51  {
52  }
53 
59  SpaceDistributionWeight(SpaceDistributionWeight<dim,T> && pm)
60  {
61  this->operator=(pm);
62  }
63 
69  void createCartGraph(grid_sm<dim, void> & grid, Box<dim, T> dom)
70  {
71  size_t bc[dim];
72 
73  for (size_t i = 0 ; i < dim ; i++)
74  bc[i] = NON_PERIODIC;
75 
76  // Set grid and domain
77  gr = grid;
78  domain = dom;
79 
80  // Create a cartesian grid graph
82  gp = g_factory_part.template construct<NO_EDGE, nm_v::id, T, dim - 1, 0>(gr.getSize(), domain, bc);
83 
84  // Init to 0.0 axis z (to fix in graphFactory)
85  if (dim < 3)
86  {
87  for (size_t i = 0; i < gp.getNVertex(); i++)
88  gp.vertex(i).template get<nm_v::x>()[2] = 0.0;
89  }
90  for (size_t i = 0; i < gp.getNVertex(); i++)
91  gp.vertex(i).template get<nm_v::global_id>() = i;
92 
93  }
94 
98  Graph_CSR<nm_v, nm_e> & getGraph()
99  {
100  return gp;
101  }
102 
106  void decompose()
107  {
108  // collect all the weight on the graph index + weight on master
109 
111  v_cl.SGather(id_w,0);
112 
113  // Calculate the total weight
114  v_cl.sum();
115  v_cl.execute();
116 
117  tot /= v_cl.getProcessingUnits();
118 
119  // only master compute
120  if (v_cl.getProcessUnitID() == 0)
121  {
122  for (size_t i = 0 ; i < id_w.size() ; i++)
123  gp.template vertex_p<nm_v::computation>(id_w.get(i).id) = id_w.get(i).w;
124 
125  // Get the maximum along dimensions and take the smallest n number
126  // such that 2^n < m. n it will be order of the hilbert curve
127 
128  size_t max = 0;
129 
130  for (size_t i = 0; i < dim ; i++)
131  {
132  if (max < gr.size(i))
133  max = gr.size(i);
134  }
135 
136  // Get the order of the hilbert-curve
137  size_t order = openfpm::math::log2_64(max);
138  if (1ul << order < max)
139  order += 1;
140 
141  size_t n = 1 << order;
142 
143  // Create the CellDecomoser
144 
145  CellDecomposer_sm<dim,T> cd_sm;
146  cd_sm.setDimensions(domain, gr.getSize(), 0);
147 
148  // create the hilbert curve
149 
150  //hilbert curve iterator
152 
153  T spacing[dim];
154 
155  // Calculate the hilbert curve spacing
156  for (size_t i = 0 ; i < dim ; i++)
157  spacing[i] = (domain.getHigh(i) - domain.getLow(i)) / n;
158 
159  // Small grid to detect already assigned sub-sub-domains
160  grid_cpu<dim,aggregate<long int>> g(gr.getSize());
161  g.setMemory();
162 
163  // Reset the grid to -1
165  while (it.isNext())
166  {
167  auto key = it.get();
168 
169  g.template get<0>(key) = -1;
170 
171  ++it;
172  }
173 
174  // Go along the hilbert-curve and divide the space
175  size_t proc_d = 0;
176  size_t ele_d = 0;
177  while (h_it.isNext())
178  {
179  auto key = h_it.get();
180 
181  // Point p
182  Point<dim,T> p;
183 
184  for (size_t i = 0 ; i < dim ; i++)
185  p.get(i) = key.get(i) * spacing[i] + spacing[i] / 2;
186 
187  grid_key_dx<dim> sp = cd_sm.getCellGrid(p);
188 
189  if (g.template get<0>(sp) == -1)
190  {
191  g.template get<0>(sp) = proc_d;
192  ele_d++;
193 
194  if (ele_d >= avg)
195  proc_d++;
196  }
197 
198  ++h_it;
199  }
200 
201  // Fill from the grid to the graph
202 
203  // Reset the grid to -1
205  while (it2.isNext())
206  {
207  auto key = it2.get();
208 
209  gp.template vertex_p<nm_v::proc_id>(gr.LinId(key)) = g.template get<0>(key);
210 
211  id_w.get(g.template get<1>(key)) = g.template get<1>(key);
212 
213  ++it2;
214  }
215  }
216 
217  // Broadcast the result to all the processors.
218 
219  v_cl.Bcast(id_w);
220  v_cl.execute();
221 
222  //
223 
224  return;
225  }
226 
232  void refine()
233  {
234  decompose();
235  }
236 
241  float getUnbalance()
242  {
243  return gr.size() % v_cl.getProcessingUnits();
244  }
245 
252  void getSubSubDomainPosition(size_t id, T (&pos)[dim])
253  {
254 #ifdef SE_CLASS1
255  if (id >= gp.getNVertex())
256  std::cerr << __FILE__ << ":" << __LINE__ << "Such vertex doesn't exist (id = " << id << ", " << "total size = " << gp.getNVertex() << ")\n";
257 #endif
258 
259  // Copy the geometrical informations inside the pos vector
260  pos[0] = gp.vertex(id).template get<nm_v::x>()[0];
261  pos[1] = gp.vertex(id).template get<nm_v::x>()[1];
262  if (dim == 3)
263  pos[2] = gp.vertex(id).template get<nm_v::x>()[2];
264  }
265 
272  inline void setComputationCost(size_t id, size_t weight)
273  {
274  std::cout << __FILE__ << ":" << __LINE__ << " You are trying to set the computation cost on a fixed decomposition, this operation has no effect" << std::endl;
275  }
276 
281  bool weightsAreUsed()
282  {
283  return false;
284  }
285 
291  size_t getSubSubDomainComputationCost(size_t id)
292  {
293  return 1.0;
294  }
295 
300  size_t getProcessorLoad()
301  {
302  // Get the number of processing units
303  size_t Np = v_cl.getProcessingUnits();
304 
305  // Calculate the best number of sub-domains for each
306  // processor
307  size_t N_tot = gr.size();
308  size_t N_best_each = N_tot / Np;
309  size_t N_rest = N_tot % Np;
310 
311  if (v_cl.getProcessUnitID() < N_rest)
312  N_best_each += 1;
313 
314  return N_best_each;
315  }
316 
322  void setMigrationCost(size_t id, size_t migration)
323  {
324  }
325 
332  void setCommunicationCost(size_t v_id, size_t e, size_t communication)
333  {
334  }
335 
339  size_t getNSubSubDomains()
340  {
341  return gp.getNVertex();
342  }
343 
348  size_t getNSubSubDomainNeighbors(size_t id)
349  {
350  return gp.getNChilds(id);
351  }
352 
358  void write(const std::string & file)
359  {
360  VTKWriter<Graph_CSR<nm_v, nm_e>, VTK_GRAPH> gv2(gp);
361  gv2.write(std::to_string(v_cl.getProcessUnitID()) + "_" + file + ".vtk");
362  }
363 
364  const SpaceDistribution<dim,T> & operator=(const SpaceDistribution<dim,T> & dist)
365  {
366  gr = dist.gr;
367  domain = dist.domain;
368  gp = dist.gp;
369 
370  return *this;
371  }
372 
373  const SpaceDistribution<dim,T> & operator=(SpaceDistribution<dim,T> && dist)
374  {
375  v_cl = dist.v_cl;
376  gr = dist.gr;
377  domain = dist.domain;
378  gp.swap(dist.gp);
379 
380  return *this;
381  }
382 
390  size_t get_ndec()
391  {
392  return 0;
393  }
394 };
395 
396 #endif
397 
398 #endif /* SRC_DECOMPOSITION_DISTRIBUTION_SPACEDISTRIBUTIONWEIGHT_HPP_ */
grid_key_dx is the key to access any element in the grid
Definition: grid_key.hpp:18
Class that distribute sub-sub-domains across processors using an hilbert curve to divide the space...
size_t size()
Stub size.
Definition: map_vector.hpp:70
This class implement the point shape in an N-dimensional space.
Definition: Point.hpp:22
Implementation of VCluster class.
Definition: VCluster.hpp:36
This class construct a cartesian graph.
Graph_CSR< nm_v, nm_e > gp
Global sub-sub-domain graph.
Box< dim, T > domain
rectangular domain to decompose
const T & get(size_t i) const
Get coordinate.
Definition: Point.hpp:142
This class represent an N-dimensional box.
Definition: Box.hpp:56
This class is a trick to indicate the compiler a specific specialization pattern. ...
Definition: memory_c.hpp:201
static const unsigned int id
id property id in boost::fusion::vector
grid_sm< dim, void > gr
Structure that store the cartesian grid information.
Implementation of 1-D std::vector like structure.
Definition: map_vector.hpp:61