OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
47template<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
62public:
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
107template<unsigned int dim, typename dT, typename G_v, typename v>
108class fill_prop_v<dim, dT, G_v, v, 0>
109{
110
111public:
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
151template<unsigned int dim, typename dT, typename G_v, typename v>
152class 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
167public:
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
197template<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
218template<typename p, typename Graph, int ... pos>
219struct fill_prop_v_by_type<0, p, Graph, pos...>
220{
221 enum
222 {
223 value = 0
224 };
225
226};
227
236template<unsigned int dim, typename Graph, int se, typename T, unsigned int dim_c, int ... pos>
238{
239public:
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
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
390template<unsigned int dim, typename Graph, typename T, unsigned int dim_c, int ... pos>
391class DistGraph_constr_impl<dim, Graph, NO_EDGE, T, dim_c, pos...>
392{
393public:
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
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
540template<unsigned int dim, typename Graph>
542{
543
544public:
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_ */
This class represent an N-dimensional box.
Definition Box.hpp:61
__device__ __host__ T getLow(int i) const
get the i-coordinate of the low bound interval of the box
Definition Box.hpp:556
__device__ __host__ T getHigh(int i) const
get the high interval of the box
Definition Box.hpp:567
This class construct a cartesian graph.
static Graph construct(const size_t(&sz)[dim], Box< dim, T > dom)
Construct a cartesian graph, with V and E edge properties.
static Graph construct(const size_t(&sz)[dim], Box< dim, T > dom)
Construct Cartesian graph.
Graph constructor function specialization.
static Graph construct(const size_t(&sz)[dim], Box< dim, T > dom)
Construct Cartesian graph.
This class calculate elements of the hyper-cube.
Definition HyperCube.hpp:58
static std::vector< comb< dim > > getCombinations_R(size_t d)
size_t getProcessUnitID()
Get the process unit id.
size_t getProcessingUnits()
Get the total number of processors.
Implementation of VCluster class.
Definition VCluster.hpp:59
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.
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.
const grid_sm< dim, void > & gs
grid info
void operator()(T &t) const
It call the function for each property we want to copy.
grid_key_dx< dim > & gk
grid_key_dx Reference containing the actual position
This class work as a functor.
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.
const dT(& szd)[dim]
Reference to an array containing the spacing.
G_v & g_v
Vertex object to fill.
void operator()(T &t) const
It call the function for each property we want to copy.
grid_key_dx< dim > & gk
grid_key_dx Reference containing the actual position
const grid_sm< dim, void > & gs
grid info
const grid_key_dx< dim > & get() const
Get the actual key.
bool isNext()
Check if there is the next element.
grid_key_dx is the key to access any element in the grid
Definition grid_key.hpp:19
__device__ __host__ index_type get(index_type i) const
Get the i index.
Definition grid_key.hpp:503
Declaration grid_sm.
Definition grid_sm.hpp:167
mem_id LinId(const grid_key_dx< N, ids_type > &gk, const signed char sum_id[N]) const
Linearization of the grid_key_dx with a specified shift.
Definition grid_sm.hpp:454
__device__ __host__ size_t size() const
Return the size of the grid.
Definition grid_sm.hpp:657
Implementation of 1-D std::vector like structure.
Operator for vector and scalar property.
boost::mpl::vector< boost::mpl::int_< id >... > type
construct an mpl vector from the variadic