OpenFPM_pdata  1.1.0
Project that contain the implementation of distributed structures
 All Data Structures Namespaces Functions Variables Typedefs Enumerations Friends Pages
DistGraphFactory.hpp
1 /*
2  * DistGraphFactory.hpp
3  *
4  * Created on: Dec 03, 2015
5  * Author: Antonio Leo
6  */
7 
8 #ifndef DISTGRAPHFACTORYOLD_HPP_
9 #define DISTGRAPHFACTORYOLD_HPP_
10 
11 #include "VCluster/VCluster.hpp"
12 #include "Vector/map_vector.hpp"
13 #include "Graph/map_graph.hpp"
14 #include "Grid/grid_sm.hpp"
15 #include "Space/Shape/Box.hpp"
16 #include "Space/Shape/HyperCube.hpp"
17 #include "parmetis.h"
18 
47 template<unsigned int dim, typename dT, typename G_v, typename v, int impl>
49 {
51  const dT (&szd)[dim];
52 
55 
57  G_v & g_v;
58 
61 
62 public:
63 
65  fill_prop_v(G_v & g_v, const dT (&szd)[dim], grid_key_dx<dim> & gk, const grid_sm<dim, void> & gs) :
66  szd(szd), gk(gk), g_v(g_v), gs(gs)
67  {
68  }
69 
71  template<typename T>
72  void operator()(T& t) const
73  {
74  typedef typename boost::fusion::result_of::at<v, boost::mpl::int_<T::value>>::type t_val;
75 
76  g_v.template get<t_val::value>() = gk.get(T::value) * szd[T::value];
77  }
78 };
79 
80 
107 template<unsigned int dim, typename dT, typename G_v, typename v>
108 class fill_prop_v<dim, dT, G_v, v, 0>
109 {
110 
111 public:
112 
114  fill_prop_v(G_v & g_v, const dT (&szd)[dim], grid_key_dx<dim> & gk, const grid_sm<dim, void> & gs)
115  {
116  }
117 
119  template<typename T>
120  void operator()(T& t) const
121  {
122  }
123 };
124 
151 template<unsigned int dim, typename dT, typename G_v, typename v>
152 class fill_prop_v<dim, dT, G_v, v, 2>
153 {
154 
156  const dT (&szd)[dim];
157 
160 
162  G_v & g_v;
163 
166 
167 public:
168 
170  fill_prop_v(G_v & g_v, const dT (&szd)[dim], grid_key_dx<dim> & gk, const grid_sm<dim, void> & gs)
171  :szd(szd), gk(gk), g_v(g_v), gs(gs)
172  {
173  }
174 
176  template<typename T>
177  void operator()(T& t) const
178  {
179  typedef typename boost::fusion::result_of::at<v, boost::mpl::int_<0>>::type t_val;
180  typedef typename boost::mpl::at<typename G_v::T_type::type,t_val>::type s_type;
181 
182  for (size_t i = 0 ; i < std::extent<s_type>::value ; i++)
183  g_v.template get<t_val::value>()[i] = 0.0;
184 
185  for (size_t i = 0 ; i < dim ; i++)
186  g_v.template get<t_val::value>()[i] = gk.get(i) * static_cast<float>(szd[i]);
187  }
188 };
189 
197 template<int i, typename p, typename Graph, int ... pos>
199 {
200 
201  typedef typename boost::mpl::at<p, boost::mpl::int_<0>>::type v_element;
202  typedef typename boost::mpl::at<typename Graph::V_type::type, v_element>::type pos_prop_type;
203 
204  enum
205  {
206  value = ((sizeof...(pos) != 0) * (std::is_array<pos_prop_type>::value + 1))
207  };
208 
209 };
210 
218 template<typename p, typename Graph, int ... pos>
219 struct fill_prop_v_by_type<0, p, Graph, pos...>
220 {
221  enum
222  {
223  value = 0
224  };
225 
226 };
227 
236 template<unsigned int dim, typename Graph, int se, typename T, unsigned int dim_c, int ... pos>
238 {
239 public:
241  static Graph construct(const size_t (&sz)[dim], Box<dim, T> dom)
242  {
243  Vcluster &v_cl = create_vcluster();
244 
245  // Calculate the size of the hyper-cubes on each dimension
246  T szd[dim];
247 
248  for (size_t i = 0; i < dim; i++)
249  {
250  szd[i] = (dom.getHigh(i) - dom.getLow(i)) / sz[i];
251  }
252 
254 
255  HyperCube<dim> hc;
256 
257  // Construct a grid info
258 
259  grid_sm<dim, void> g(sz);
260 
262  size_t p_id = v_cl.getProcessUnitID();
263 
265  size_t Np = v_cl.getProcessingUnits();
266 
270  size_t mod_v = g.size() % Np;
271  size_t div_v = g.size() / Np;
272 
274  openfpm::vector<idx_t> vtxdist(v_cl.getProcessingUnits() + 1);
275 
276  for (int i = 0; i <= Np; i++)
277  {
278  if (i < mod_v)
279  vtxdist.get(i) = (div_v + 1) * (i);
280  else
281  vtxdist.get(i) = (div_v) * (i) + mod_v;
282  }
283 
285  size_t gp_size = vtxdist.get(p_id + 1) - vtxdist.get(p_id);
286 
288  Graph gp(gp_size);
289 
291  gp.initDistributionVector(vtxdist);
292 
293  /******************
294  *
295  * Create the edges and fill spatial
296  * information properties
297  *
298  ******************/
299 
302 
304  size_t local_it = 0;
305 
307 
308  while (k_it.isNext())
309  {
310  size_t v_id = g.LinId(k_it.get());
311 
312  if (v_id < vtxdist.get(p_id + 1) && v_id >= vtxdist.get(p_id))
313  {
314 
315  grid_key_dx<dim> key = k_it.get();
316 
317  // Vertex object
318 
319  auto obj = gp.vertex(local_it);
320 
321  typedef typename to_boost_vmpl<pos...>::type p;
322 
323  // vertex spatial properties functor
324 
325  fill_prop_v<dim, T, decltype(gp.vertex(local_it)), typename to_boost_vmpl<pos...>::type, fill_prop_v_by_type<sizeof...(pos), p, Graph, pos...>::value> flp(obj, szd, key, g);
326 
327  // fill properties
328 
329  boost::mpl::for_each<boost::mpl::range_c<int, 0, sizeof...(pos)> >(flp);
330 
331  // set map global to local in the graph, needed because vertex is already created without addVertex method
332 
333  gp.setGlobalMap(v_id, local_it, v_id);
334 
335  // Get the combinations of dimension d
336 
337  for (size_t d = dim - 1; d >= dim_c; d--)
338  {
339  // create the edges for that dimension
340 
341  std::vector<comb<dim>> c = hc.getCombinations_R(d);
342 
343  // for each combination calculate a safe linearization and create an edge
344 
345  for (size_t j = 0; j < c.size(); j++)
346  {
347  // Calculate the element size
348 
349  T ele_sz = 0;
350 
351  // for each dimension multiply and reduce
352 
353  for (size_t s = 0; s < dim; s++)
354  {
355  ele_sz += szd[s] * abs(c[j][s]);
356  }
357 
358  // Calculate the end point vertex id
359  // Calculate the start point id
360 
361  size_t start_v = local_it;
362  size_t end_v = g.template LinId<CheckExistence>(key, c[j].getComb());
363 
364  // check if the end_v is valid globally
365  if (end_v < g.size())
366  {
367  // Add an edge and set the the edge property to the size of the face (communication weight)
368  gp.template addEdge<NoCheck>(start_v, end_v).template get<se>() = ele_sz;
369  }
370  }
371  }
372  ++local_it;
373  }
374  ++k_it;
375  }
376 
377  return gp;
378  }
379 };
380 
390 template<unsigned int dim, typename Graph, typename T, unsigned int dim_c, int ... pos>
391 class DistGraph_constr_impl<dim, Graph, NO_EDGE, T, dim_c, pos...>
392 {
393 public:
395  static Graph construct(const size_t (&sz)[dim], Box<dim, T> dom)
396  {
397  Vcluster &v_cl = create_vcluster();
398 
399  // Calculate the size of the hyper-cubes on each dimension
400 
401  T szd[dim];
402 
403  for (size_t i = 0; i < dim; i++)
404  {
405  szd[i] = (dom.getHigh(i) - dom.getLow(i)) / sz[i];
406  }
407 
409 
410  HyperCube<dim> hc;
411 
412  // Construct a grid info
413 
414  grid_sm<dim, void> g(sz);
415 
417  size_t p_id = v_cl.getProcessUnitID();
418 
420  size_t Np = v_cl.getProcessingUnits();
421 
425  size_t mod_v = g.size() % Np;
426  size_t div_v = g.size() / Np;
427 
429  openfpm::vector<idx_t> vtxdist(v_cl.getProcessingUnits() + 1);
430 
431  for (size_t i = 0; i <= Np; i++)
432  {
433  if (i < mod_v)
434  vtxdist.get(i) = (div_v + 1) * (i);
435  else
436  vtxdist.get(i) = (div_v) * (i) + mod_v;
437  }
438 
439  size_t gp_size = vtxdist.get(p_id + 1) - vtxdist.get(p_id);
440 
442  Graph gp(gp_size);
443 
445  gp.initDistributionVector(vtxdist);
446 
447  /******************
448  *
449  * Create the edges and fill spatial
450  * information properties
451  *
452  ******************/
453 
456 
458  size_t local_it = 0;
459 
461 
462  while (k_it.isNext())
463  {
464  size_t v_id = g.LinId(k_it.get());
465 
466  if (v_id < (size_t)vtxdist.get(p_id + 1) && v_id >= (size_t)vtxdist.get(p_id))
467  {
468  grid_key_dx<dim> key = k_it.get();
469 
470  // Vertex object
471  auto obj = gp.vertex(local_it);
472 
473  typedef typename to_boost_vmpl<pos...>::type p;
474 
475  // vertex spatial properties functor
476 
477  fill_prop_v<dim, T, decltype(gp.vertex(local_it)), typename to_boost_vmpl<pos...>::type, fill_prop_v_by_type<sizeof...(pos), p, Graph, pos...>::value> flp(obj, szd, key, g);
478 
479  // fill properties
480 
481  boost::mpl::for_each<boost::mpl::range_c<int, 0, sizeof...(pos)> >(flp);
482 
483  // set map global to local in the graph, needed because vertex is already created without addVertex method
484 
485  gp.setGlobalMap(v_id, local_it, v_id);
486 
487  // Get the combinations of dimension d
488 
489  for (size_t d = dim - 1; d >= dim_c; d--)
490  {
491  // create the edges for that dimension
492 
493  std::vector<comb<dim>> c = hc.getCombinations_R(d);
494 
495  // for each combination calculate a safe linearization and create an edge
496 
497  for (size_t j = 0; j < c.size(); j++)
498  {
499  // Calculate the element size
500 
501  T ele_sz = 0;
502 
503  // for each dimension multiply and reduce
504 
505  for (size_t s = 0; s < dim; s++)
506  {
507  ele_sz += szd[s] * abs(c[j][s]);
508  }
509 
510  // Calculate the end point vertex id
511  // Calculate the start point id
512 
513  size_t start_v = local_it;
514  size_t end_v = g.template LinId<CheckExistence>(key, c[j].getComb());
515 
516  // check if the end_v is valid globally
517  if (end_v < g.size())
518  {
519  // Add an edge and set the the edge property to the size of the face (communication weight)
520  gp.addEdge(start_v, end_v, v_id, end_v);
521  }
522  }
523  }
524  ++local_it;
525  }
526  ++k_it;
527  }
528  return gp;
529  }
530 };
531 
540 template<unsigned int dim, typename Graph>
542 {
543 
544 public:
545 
565  template<int se, typename T, unsigned int dim_c, int ... pos>
566  static Graph construct(const size_t (&sz)[dim], Box<dim, T> dom)
567  {
569  }
570 };
571 
572 #endif /* DISTGRAPHFACTORY_HPP_ */
G_v & g_v
Vertex object to fill.
mem_id LinId(const grid_key_dx< N > &gk, const char sum_id[N]) const
Linearization of the grid_key_dx with a specified shift.
Definition: grid_sm.hpp:337
This class work as a functor.
static std::vector< comb< dim > > getCombinations_R(size_t d)
Definition: HyperCube.hpp:100
T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition: Box.hpp:479
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.
size_t size() const
Return the size of the grid.
Definition: grid_sm.hpp:572
static Graph construct(const size_t(&sz)[dim], Box< dim, T > dom)
Construct Cartesian graph.
Operator for vector and scalar property.
T getHigh(int i) const
get the high interval of the box
Definition: Box.hpp:490
static Graph construct(const size_t(&sz)[dim], Box< dim, T > dom)
Construct Cartesian graph.
void operator()(T &t) const
It call the function for each property we want to copy.
static Graph construct(const size_t(&sz)[dim], Box< dim, T > dom)
Construct a cartesian graph, with V and E edge properties.
grid_key_dx< dim > & gk
grid_key_dx Reference containing the actual position
Implementation of VCluster class.
Definition: VCluster.hpp:36
to_boost_vmpl_impl< id...>::type type
constrict an mpl vector from the variadic
const grid_key_dx< dim > & get() const
Get the actual key.
bool isNext()
Check if there is the next element.
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
grid_key_dx< dim > & gk
grid_key_dx Reference containing the actual position
This class construct a cartesian graph.
fill_prop_v(G_v &g_v, const dT(&szd)[dim], grid_key_dx< dim > &gk, const grid_sm< dim, void > &gs)
Fill the object from where to take the properties.
void operator()(T &t) const
It call the function for each property we want to copy.
fill_prop_v(G_v &g_v, const dT(&szd)[dim], grid_key_dx< dim > &gk, const grid_sm< dim, void > &gs)
Fill the object from where to take the properties.
G_v & g_v
Vertex object to fill.
This class calculate elements of the hyper-cube.
Definition: HyperCube.hpp:57
Graph constructor function specialization.
void operator()(T &t) const
It call the function for each property we want to copy.
const dT(& szd)[dim]
Reference to an array containing the spacing.
const grid_sm< dim, void > & gs
grid info
fill_prop_v(G_v &g_v, const dT(&szd)[dim], grid_key_dx< dim > &gk, const grid_sm< dim, void > &gs)
Fill the object from where to take the properties.
size_t getProcessingUnits()
Get the total number of processors.
const grid_sm< dim, void > & gs
grid info