OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
CartDecomposition.hpp
1/*
2 * CartDecomposition.hpp
3 *
4 * Created on: Oct 07, 2015
5 * Author: Pietro Incardona, Antonio Leo
6 */
7
8#ifndef CARTDECOMPOSITION_HPP
9#define CARTDECOMPOSITION_HPP
10
11#include "config.h"
12#include <cmath>
13#include "VCluster/VCluster.hpp"
14#include "Graph/CartesianGraphFactory.hpp"
15#include "Decomposition.hpp"
16#include "Vector/map_vector.hpp"
17#include <vector>
18#include <initializer_list>
19#include "SubdomainGraphNodes.hpp"
20#include "dec_optimizer.hpp"
21#include "Space/Shape/Box.hpp"
22#include "Space/Shape/Point.hpp"
23#include "NN/CellList/CellDecomposer.hpp"
24#include <unordered_map>
25#include "NN/CellList/CellList.hpp"
26#include "Space/Ghost.hpp"
27#include "common.hpp"
28#include "ie_loc_ghost.hpp"
29#include "ie_ghost.hpp"
30#include "nn_processor.hpp"
31#include "GraphMLWriter/GraphMLWriter.hpp"
32#include "Distribution/ParMetisDistribution.hpp"
33#include "Distribution/DistParMetisDistribution.hpp"
34#include "Distribution/MetisDistribution.hpp"
35#include "DLB/DLB.hpp"
36#include "util/se_util.hpp"
37#include "util/mathutil.hpp"
38#include "CartDecomposition_ext.hpp"
39#include "data_type/aggregate.hpp"
40#include "Domain_NN_calculator_cart.hpp"
41#include "cuda/CartDecomposition_gpu.cuh"
42#include "Domain_icells_cart.hpp"
43
44#define CARTDEC_ERROR 2000lu
45
46enum dec_options
47{
48 DEC_NONE = 0,
49 DEC_SKIP_ICELL = 1
50};
51
63template<unsigned int dim> static void nsub_to_div2(size_t (& div)[dim], size_t n_sub, size_t dim_r)
64{
65 for (size_t i = 0; i < dim; i++)
66 {
67 if (i < dim_r)
68 {div[i] = openfpm::math::round_big_2(pow(n_sub, 1.0 / dim_r));}
69 else
70 {div[i] = 1;}
71 }
72}
73
85template<unsigned int dim> static void nsub_to_div(size_t (& div)[dim], size_t n_sub, size_t dim_r)
86{
87 for (size_t i = 0; i < dim; i++)
88 {
89 if (i < dim_r)
90 {div[i] = std::floor(pow(n_sub, 1.0 / dim_r));}
91 else
92 {div[i] = 1;}
93 }
94}
95
96#define COMPUTE_SKIN_SUB 1
97
139template<unsigned int dim, typename T, typename Memory, template <typename> class layout_base, typename Distribution>
140class CartDecomposition: public ie_loc_ghost<dim, T,layout_base, Memory>,
141 public nn_prcs<dim, T,layout_base,Memory>,
142 public ie_ghost<dim,T,Memory,layout_base>,
143 public domain_nn_calculator_cart<dim>,
144 public domain_icell_calculator<dim,T,layout_base,Memory>
145{
146public:
147
149 typedef T domain_type;
150
153
156
159
161
163
165
166protected:
167
169 bool host_dev_transfer = false;
170
172 bool commCostSet = false;
173
176 typedef typename openfpm::vector<SpaceBox<dim, T>,
177 Memory,
181
184
187
190
194
197
200
203 CellDecomposer_sm<dim, T, shift<dim,T>> cd;
204
207
209 T spacing[dim];
210
213 size_t magn[dim];
214
217
219 Distribution dist;
220
223
225 long int ref_cnt;
226
229
231 size_t bc[dim];
232
235
238
251 {
252 // A point with all coordinate to one
253 size_t one[dim];
254 for (size_t i = 0 ; i < dim ; i++) {one[i] = 1;}
255
257 SpaceBox<dim, size_t> sub_dce = sub_dc;
258 sub_dce.expand(one);
259 sub_dce.mul(magn);
260
261 // shrink by one
262 for (size_t i = 0 ; i < dim ; i++)
263 {
264 loc_box.template get<Box::p1>()[i] = sub_dce.getLow(i);
265 loc_box.template get<Box::p2>()[i] = sub_dce.getHigh(i) - 1;
266 }
267
268 SpaceBox<dim, T> sub_d(sub_dce);
269 sub_d.mul(spacing);
270 sub_d += domain.getP1();
271
272 // we add the
273
274 // Fixing sub-domains to cover all the domain
275
276 // Fixing sub_d
277 // if (loc_box) is at the boundary we have to ensure that the box span the full
278 // domain (avoiding rounding off error)
279 for (size_t i = 0; i < dim; i++)
280 {
281 if (sub_dc.getHigh(i) == gr.size(i) - 1)
282 {sub_d.setHigh(i, domain.getHigh(i));}
283
284 if (sub_dc.getLow(i) == 0)
285 {sub_d.setLow(i,domain.getLow(i));}
286 }
287
288 return sub_d;
289 }
290
291 void collect_all_sub_domains(openfpm::vector<Box_map<dim,T>,Memory,layout_base> & sub_domains_global)
292 {
293#ifdef SE_CLASS2
294 check_valid(this,8);
295#endif
296
297 sub_domains_global.clear();
298 openfpm::vector<Box_map<dim,T>,Memory,layout_base> bm;
299
300 for (size_t i = 0 ; i < sub_domains.size() ; i++)
301 {
302 bm.add();
303
304 bm.template get<0>(bm.size()-1) = ::SpaceBox<dim,T>(sub_domains.get(i));
305 bm.template get<1>(bm.size()-1) = v_cl.rank();
306 }
307
308 v_cl.SGather<decltype(bm),decltype(sub_domains_global),layout_base>(bm,sub_domains_global,0);
309
310 size_t size = sub_domains_global.size();
311
312 v_cl.max(size);
313 v_cl.execute();
314
315 sub_domains_global.resize(size);
316
318 v_cl.execute();
319 }
320
321public:
322
323 void initialize_fine_s(const ::Box<dim,T> & domain)
324 {
325 fine_s.clear();
326 size_t div_g[dim];
327
328 // We reduce the size of the cells by a factor 8 in 3d 4 in 2d
329 for (size_t i = 0 ; i < dim ; i++)
330 {div_g[i] = (gr.size(i) == 1)?1:gr.size(i)/2;}
331
332 fine_s.Initialize(domain,div_g);
333 }
334
335 void construct_fine_s()
336 {
337 collect_all_sub_domains(sub_domains_global);
338
339 // now draw all sub-domains in fine-s
340
341 for (size_t i = 0 ; i < sub_domains_global.size() ; i++)
342 {
343
344 // get the cells this box span
345 const grid_key_dx<dim> p1 = fine_s.getCellGrid_me(sub_domains_global.template get<0>(i).getP1());
346 const grid_key_dx<dim> p2 = fine_s.getCellGrid_pe(sub_domains_global.template get<0>(i).getP2());
347
348 // Get the grid and the sub-iterator
349 auto & gi = fine_s.getGrid();
350 grid_key_dx_iterator_sub<dim> g_sub(gi,p1,p2);
351
352 // add the box-id to the cell list
353 while (g_sub.isNext())
354 {
355 auto key = g_sub.get();
356 fine_s.addCell(gi.LinId(key),i);
357
358 ++g_sub;
359 }
360 }
361
362 host_dev_transfer = false;
363 }
364
372 void createSubdomains(Vcluster<> & v_cl, const size_t (& bc)[dim], size_t opt = 0)
373 {
374 int p_id = v_cl.getProcessUnitID();
375
376 // Calculate the total number of box and and the spacing
377 // on each direction
378 // Get the box containing the domain
380
381 for (unsigned int i = 0; i < dim; i++)
382 {
383 // Calculate the spacing
384 spacing[i] = (bs.getHigh(i) - bs.getLow(i)) / gr.size(i);
385 }
386
387 // fill the structure that store the processor id for each sub-domain
388 initialize_fine_s(domain);
389
390 // Optimize the decomposition creating bigger spaces
391 // And reducing Ghost over-stress
393
394 // Ghost
396
397 // Set the ghost
398 for (size_t i = 0 ; i < dim ; i++)
399 {
400 ghe.setLow(i,static_cast<long int>(ghost.getLow(i)/spacing[i]) - 1);
401 ghe.setHigh(i,static_cast<long int>(ghost.getHigh(i)/spacing[i]) + 1);
402 }
403
404 // optimize the decomposition or merge sub-sub-domain
405 d_o.template optimize<nm_v_sub_id, nm_v_proc_id>(dist.getGraph(), p_id, loc_box, box_nn_processor,ghe,bc);
406
407 // Initialize
408 if (loc_box.size() > 0)
409 {
411 proc_box = loc_box.get(0);
412 sub_domains.add(bbox);
413 }
414 else
415 {
416 // invalidate all the boxes
417 for (size_t i = 0 ; i < dim ; i++)
418 {
419 proc_box.setLow(i,0.0);
420 proc_box.setHigh(i,0);
421
422 bbox.setLow(i,0.0);
423 bbox.setHigh(i,0);
424 }
425 }
426
427 // convert into sub-domain
428 for (size_t s = 1; s < loc_box.size(); s++)
429 {
431
432 // add the sub-domain
433 sub_domains.add(sub_d);
434
435 // Calculate the bound box
436 bbox.enclose(sub_d);
437 proc_box.enclose(loc_box.get(s));
438 }
439
442
443 // fill fine_s structure
444 // fine_s structure contain the processor id for each sub-sub-domain
445 // with sub-sub-domain we mean the sub-domain decomposition before
446 // running dec_optimizer (before merging sub-domains)
447
449
450 construct_fine_s();
451
453 }
454
461 {
462 // Get the processor bounding Box
464
465 // Check if the box is valid
466 if (bound.isValidN() == true)
467 {
468 // calculate the sub-divisions
469 size_t div[dim];
470 for (size_t i = 0; i < dim; i++)
471 {div[i] = (size_t) ((bound.getHigh(i) - bound.getLow(i)) / cd.getCellBox().getP2()[i]);}
472
473 // Initialize the geo_cell structure
475
476 // Initialize shift vectors
478 }
479 }
480
486 {
487 float migration = 0;
488
489 SpaceBox<dim, T> cellBox = cd.getCellBox();
490 float b_s = static_cast<float>(cellBox.getHigh(0));
491 float gh_s = static_cast<float>(ghost.getHigh(0));
492
493 // compute the gh_area for 2 dim case
494 float gh_v = (gh_s * b_s);
495
496 // multiply for sub-sub-domain side for each domain
497 for (size_t i = 2; i < dim; i++)
498 {
499 /* coverity[dead_error_line] */
500 gh_v *= b_s;
501 }
502
503 size_t norm = (size_t) (1.0 / gh_v);
504
505 migration = pow(b_s, dim);
506
507 size_t prev = 0;
508
509 for (size_t i = 0; i < dist.getNSubSubDomains(); i++)
510 {
511 dist.setMigrationCost(i, norm * migration /* * dist.getSubSubDomainComputationCost(i)*/ );
512
513 for (size_t s = 0; s < dist.getNSubSubDomainNeighbors(i); s++)
514 {
515 // We have to remove dist.getSubSubDomainComputationCost(i) otherwise the graph is
516 // not directed
517 dist.setCommunicationCost(i, s, 1 * ts);
518 }
519 prev += dist.getNSubSubDomainNeighbors(i);
520 }
521
522 commCostSet = true;
523 }
524
529 {
530 // Create a grid where each point is a space
531 grid_sm<dim, void> g(div);
532
533 // create a grid_key_dx iterator
535
536 // Divide the space into subspaces
537 while (gk_it.isNext())
538 {
540 grid_key_dx<dim> key = gk_it.get();
541
544
546 for (int i = 0; i < dim; i++)
547 {
548 tmp.setHigh(i, (key.get(i) + 1) * spacing[i]);
549 tmp.setLow(i, key.get(i) * spacing[i]);
550 }
551
553 sub_domains.add(tmp);
554
555 // Next sub-domain
556 ++gk_it;
557 }
558 }
559
560
655 {
656 // Intersect all the local sub-domains with the sub-domains of the contiguous processors
657
658 // create the internal structures that store ghost information
661
663
664 // Ghost box information must be re-offloaded
665 host_dev_transfer = false;
667 }
668
669
670public:
671
673 static constexpr int dims = dim;
674
676 typedef T stype;
677
679 void incRef()
680 {ref_cnt++;}
681
683 void decRef()
684 {ref_cnt--;}
685
687 long int ref()
688 {
689 return ref_cnt;
690 }
691
698 :nn_prcs<dim, T, layout_base,Memory>(v_cl), v_cl(v_cl), dist(v_cl),ref_cnt(0)
699 {
700 // Reset the box to zero
701 bbox.zero();
702 }
703
710 :nn_prcs<dim,T,layout_base,Memory>(cart.v_cl),v_cl(cart.v_cl),dist(v_cl),ref_cnt(0)
711 {
712 this->operator=(cart);
713 }
714
721 :nn_prcs<dim,T,layout_base,Memory>(cart.v_cl),v_cl(cart.v_cl),dist(v_cl),ref_cnt(0)
722 {
723 this->operator=(cart);
724 }
725
728 {
729 }
730
734 class box_id
735 {
736 public:
745 inline static size_t id(p_box<dim, T> & p, size_t b_id)
746 {
747 return b_id;
748 }
749 };
750
755 {
756 public:
765 template<typename encap_type> inline static size_t id(const encap_type & p, size_t b_id)
766 {
767 return p.template get<proc_>();
768 }
769 };
770
775 {
776 public:
785 template<typename encap_type> inline static size_t id(const encap_type & p, size_t b_id)
786 {
787 return p.template get<lc_proc_>();
788 }
789 };
790
795 {
796 public:
805 template<typename encap_type> inline static size_t id(const encap_type & p, size_t b_id)
806 {
807 return p.template get<shift_id_>();
808 }
809 };
810
820 void applyPointBC(float (& pt)[dim]) const
821 {
822 for (size_t i = 0 ; i < dim ; i++)
823 {
824 if (bc[i] == PERIODIC)
825 {pt[i] = openfpm::math::periodic_l(pt[i],domain.getHigh(i),domain.getLow(i));}
826 }
827 }
828
838 void applyPointBC(Point<dim,T> & pt) const
839 {
840 for (size_t i = 0 ; i < dim ; i++)
841 {
842 if (bc[i] == PERIODIC)
843 {pt.get(i) = openfpm::math::periodic_l(pt.get(i),domain.getHigh(i),domain.getLow(i));}
844 }
845 }
846
856 template<typename Mem> void applyPointBC(encapc<1,Point<dim,T>,Mem> && pt) const
857 {
858 for (size_t i = 0 ; i < dim ; i++)
859 {
860 if (bc[i] == PERIODIC)
861 {pt.template get<0>()[i] = openfpm::math::periodic_l(pt.template get<0>()[i],domain.getHigh(i),domain.getLow(i));}
862 }
863 }
864
873 {
875
878 cart.fine_s = fine_s;
879
880 cart.gr = gr;
881 cart.cd = cd;
882 cart.domain = domain;
883 for (size_t i = 0 ; i < dim ; i++)
884 {
885 cart.spacing[i] = spacing[i];
886 cart.magn[i] = magn[i];
887 };
888
889 cart.bbox = bbox;
890 cart.ghost = g;
891
892 cart.dist = dist;
893
894 for (size_t i = 0 ; i < dim ; i++)
895 cart.bc[i] = bc[i];
896
897 (static_cast<nn_prcs<dim,T,layout_base,Memory> &>(cart)).create(box_nn_processor, sub_domains);
898 (static_cast<nn_prcs<dim,T,layout_base,Memory> &>(cart)).applyBC(domain,ghost,bc);
899
901 cart.calculateGhostBoxes();
902
903 cart.collect_all_sub_domains(cart.sub_domains_global);
904
905 return cart;
906 }
907
914 {
916
917 (static_cast<ie_loc_ghost<dim,T, layout_base,Memory>*>(&cart))->operator=(static_cast<ie_loc_ghost<dim,T,layout_base,Memory>>(*this));
918 (static_cast<nn_prcs<dim,T,layout_base,Memory>*>(&cart))->operator=(static_cast<nn_prcs<dim,T,layout_base,Memory>>(*this));
919 (static_cast<ie_ghost<dim,T,Memory,layout_base>*>(&cart))->operator=(static_cast<ie_ghost<dim,T,Memory,layout_base>>(*this));
920
923 cart.fine_s = fine_s;
924 cart.gr = gr;
925 cart.gr_dist = gr_dist;
926 cart.dist = dist;
928 cart.cd = cd;
929 cart.domain = domain;
931 for (size_t i = 0 ; i < dim ; i++)
932 {
933 cart.spacing[i] = spacing[i];
934 cart.magn[i] = magn[i];
935 };
936
937 cart.ghost = ghost;
938
939 cart.bbox = bbox;
940
941 for (size_t i = 0 ; i < dim ; i++)
942 {cart.bc[i] = this->bc[i];}
943
944 return cart;
945 }
946
952 template<typename Memory2, template <typename> class layout_base2>
954 {
956
957 (static_cast<ie_loc_ghost<dim,T,layout_base2,Memory2>*>(&cart))->operator=(static_cast<ie_loc_ghost<dim,T,layout_base,Memory>>(*this));
958 (static_cast<nn_prcs<dim,T,layout_base2,Memory2>*>(&cart))->operator=(static_cast<nn_prcs<dim,T,layout_base,Memory>>(*this));
960 (static_cast<ie_ghost<dim,T,Memory2,layout_base2>*>(&cart))->operator=(ptr->template duplicate<Memory2,layout_base2>());
961
964 cart.private_get_fine_s() = fine_s;
965 cart.private_get_gr() = gr;
967 cart.private_get_dist() = dist;
969 cart.private_get_cd() = cd;
970 cart.private_get_domain() = domain;
972 for (size_t i = 0 ; i < dim ; i++)
973 {cart.private_get_spacing(i) = spacing[i];};
974
975 cart.private_get_ghost() = ghost;
976
977 cart.private_get_bbox() = bbox;
978
979 for (size_t i = 0 ; i < dim ; i++)
980 {cart.private_get_bc(i) = this->bc[i];}
981
982 return cart;
983 }
984
993 {
994 static_cast<ie_loc_ghost<dim,T,layout_base,Memory>*>(this)->operator=(static_cast<ie_loc_ghost<dim,T,layout_base,Memory>>(cart));
995 static_cast<nn_prcs<dim,T,layout_base,Memory>*>(this)->operator=(static_cast<nn_prcs<dim,T,layout_base,Memory>>(cart));
996 static_cast<ie_ghost<dim,T,Memory,layout_base>*>(this)->operator=(static_cast<ie_ghost<dim,T,Memory,layout_base>>(cart));
997
1000 fine_s = cart.fine_s;
1001 gr = cart.gr;
1002 gr_dist = cart.gr_dist;
1003 dist = cart.dist;
1004 commCostSet = cart.commCostSet;
1005 cd = cart.cd;
1006 domain = cart.domain;
1008
1009 for (size_t i = 0 ; i < dim ; i++)
1010 {
1011 spacing[i] = cart.spacing[i];
1012 magn[i] = cart.magn[i];
1013 };
1014
1015 ghost = cart.ghost;
1016
1017 bbox = cart.bbox;
1018
1019 for (size_t i = 0 ; i < dim ; i++)
1020 bc[i] = cart.bc[i];
1021
1022 return *this;
1023 }
1024
1032 template<typename CartDecomposition2>
1034 {
1035 static_cast<ie_loc_ghost<dim,T,layout_base,Memory>*>(this)->operator=(static_cast<typename CartDecomposition2::ie_loc_ghost_type>(cart));
1036 static_cast<nn_prcs<dim,T,layout_base,Memory>*>(this)->operator=(static_cast<typename CartDecomposition2::nn_prcs_type>(cart));
1037 static_cast<ie_ghost<dim,T,Memory,layout_base>*>(this)->operator=(static_cast<typename CartDecomposition2::ie_ghost_type>(cart));
1038
1039 sub_domains = cart.private_get_sub_domains();
1040 box_nn_processor = cart.private_get_box_nn_processor();
1041 fine_s = cart.private_get_fine_s();
1042 gr = cart.private_get_gr();
1043 gr_dist = cart.private_get_gr_dist();
1044 dist = cart.private_get_dist();
1045 commCostSet = cart.private_get_commCostSet();
1046 cd = cart.private_get_cd();
1047 domain = cart.private_get_domain();
1048 sub_domains_global = cart.private_get_sub_domains_global();
1049
1050 for (size_t i = 0 ; i < dim ; i++)
1051 {
1052 spacing[i] = cart.private_get_spacing(i);
1053 magn[i] = cart.private_get_magn(i);
1054 };
1055
1056 ghost = cart.private_get_ghost();
1057
1058 bbox = cart.private_get_bbox();
1059
1060 for (size_t i = 0 ; i < dim ; i++)
1061 {bc[i] = cart.private_get_bc(i);}
1062
1063 return *this;
1064 }
1065
1074 {
1075 static_cast<ie_loc_ghost<dim,T,layout_base,Memory>*>(this)->operator=(static_cast<ie_loc_ghost<dim,T,layout_base,Memory>>(cart));
1076 static_cast<nn_prcs<dim,T,layout_base,Memory>*>(this)->operator=(static_cast<nn_prcs<dim,T,layout_base,Memory>>(cart));
1077 static_cast<ie_ghost<dim,T,Memory,layout_base>*>(this)->operator=(static_cast<ie_ghost<dim,T,Memory,layout_base>>(cart));
1078
1079 sub_domains.swap(cart.sub_domains);
1080 box_nn_processor.swap(cart.box_nn_processor);
1081 fine_s.swap(cart.fine_s);
1082 gr = cart.gr;
1083 gr_dist = cart.gr_dist;
1084 dist = cart.dist;
1085 commCostSet = cart.commCostSet;
1086 cd = cart.cd;
1087 gr_dist = cart.gr_dist;
1088 dist = cart.dist;
1089
1090 domain = cart.domain;
1091 sub_domains_global.swap(cart.sub_domains_global);
1092
1093 for (size_t i = 0 ; i < dim ; i++)
1094 {
1095 spacing[i] = cart.spacing[i];
1096 magn[i] = cart.magn[i];
1097 };
1098
1099 ghost = cart.ghost;
1100
1101 bbox = cart.bbox;
1102
1103 for (size_t i = 0 ; i < dim ; i++)
1104 bc[i] = cart.bc[i];
1105
1106 return *this;
1107 }
1108
1120 static size_t getDefaultGrid(size_t n_sub)
1121 {
1122 // Calculate the number of sub-sub-domain on
1123 // each dimension
1124 return openfpm::math::round_big_2(pow(n_sub, 1.0 / dim));
1125 }
1126
1134 template<typename Mem> size_t inline processorID(const encapc<1, Point<dim,T>, Mem> & p) const
1135 {
1136 return processorID_impl(p,fine_s,sub_domains_global,getDomain(),bc);
1137 }
1138
1146 size_t inline processorID(const Point<dim,T> &p) const
1147 {
1148 return processorID_impl(p,fine_s,sub_domains_global,getDomain(),bc);
1149 }
1150
1158 size_t inline processorID(const T (&p)[dim]) const
1159 {
1160 return processorID_impl(p,fine_s,sub_domains_global,getDomain(),bc);
1161 }
1162
1172 template<typename Mem> size_t inline processorIDBC(encapc<1, Point<dim,T>, Mem> p)
1173 {
1174 Point<dim,T> pt = p;
1175 applyPointBC(pt);
1176
1177
1178 return processorID_impl(pt,fine_s,sub_domains_global,getDomain(),bc);
1179 }
1180
1190 size_t inline processorIDBC(const Point<dim,T> &p) const
1191 {
1192 Point<dim,T> pt = p;
1193 applyPointBC(pt);
1194
1195 // Get the number of elements in the cell
1196
1197 return processorID_impl(pt,fine_s,sub_domains_global,getDomain(),bc);
1198 }
1199
1209 size_t inline processorIDBC(const T (&p)[dim]) const
1210 {
1211 Point<dim,T> pt = p;
1212 applyPointBC(pt);
1213
1214 return processorID_impl(pt,fine_s,sub_domains_global,getDomain(),bc);
1215 }
1216
1224 inline size_t periodicity(size_t i) const
1225 {
1226 return bc[i];
1227 }
1228
1235 inline const size_t (& periodicity() const) [dim]
1236 {
1237 return bc;
1238 }
1239
1246 {
1247 if (gm.size() == 0)
1248 {
1249 for (size_t i = 0 ; i < dim ; i++)
1250 magn[i] = 1;
1251 }
1252 else
1253 {
1254 for (size_t i = 0 ; i < dim ; i++)
1255 {
1256 if (gr.size(i) % gm.size(i) != 0)
1257 std::cerr << __FILE__ << ":" << __LINE__ << ".Error the decomposition grid specified as gr.size(" << i << ")=" << gr.size(i) << " is not multiple of the distribution grid gm.size(" << i << ")=" << gm.size(i) << std::endl;
1258
1259 magn[i] = gr.size(i) / gm.size(i);
1260 }
1261 }
1262 }
1263
1279 const size_t (& bc)[dim],
1280 const Ghost<dim,T> & ghost,
1281 size_t dec_gran,
1282 const grid_sm<dim,void> & sec_dist = grid_sm<dim,void>())
1283 {
1284 size_t div[dim];
1285
1286 // Create a valid decomposition of the space
1287 // Get the number of processor and calculate the number of sub-domain
1288 // for decomposition
1289 size_t n_proc = v_cl.getProcessingUnits();
1290 size_t n_sub = n_proc * dec_gran;
1291
1292 // Calculate the maximum number (before merging) of sub-domain on
1293 // each dimension
1294
1295 nsub_to_div2(div,n_sub,dim);
1296
1297/* for (size_t i = 0; i < dim; i++)
1298 {
1299 div[i] = openfpm::math::round_big_2(pow(n_sub, 1.0 / dim));
1300 }*/
1301
1302 if (dim > 3)
1303 {
1304 long int dim_r = dim-1;
1305 do
1306 {
1307 // Check for adjustment
1308 size_t tot_size = 1;
1309 for (size_t i = 0 ; i < dim ; i++)
1310 {tot_size *= div[i];}
1311
1312 // the granularity is too coarse increase the divisions
1313 if (tot_size / n_proc > (unsigned int long)(0.75*dec_gran) )
1314 {break;}
1315
1316 nsub_to_div(div,n_sub,dim_r);
1317
1318 dim_r--;
1319 } while(dim_r > 0);
1320 }
1321
1322 setParameters(div,domain_,bc,ghost,sec_dist);
1323 }
1324
1330 void getParameters(size_t (& div_)[dim])
1331 {
1332 for (size_t i = 0 ; i < dim ; i++)
1333 {div_[i] = this->gr.size(i);}
1334 }
1335
1347 void setParameters(const size_t (& div_)[dim],
1348 ::Box<dim,T> & domain_,
1349 const size_t (& bc)[dim],
1350 const Ghost<dim,T> & ghost,
1351 const grid_sm<dim,void> & sec_dist = grid_sm<dim,void>())
1352 {
1353 // set the boundary conditions
1354 for (size_t i = 0 ; i < dim ; i++)
1355 this->bc[i] = bc[i];
1356
1357 // set the ghost
1358 this->ghost = ghost;
1359
1360 // Set the decomposition parameters
1361 gr.setDimensions(div_);
1362 domain = domain_;
1363 cd.setDimensions(domain, div_, 0);
1364
1365 // We we have a secondary grid costruct a reduced graph
1366 if (sec_dist.size(0) != 0)
1367 {
1368 calculate_magn(sec_dist);
1369 gr_dist.setDimensions(sec_dist.getSize());
1370 }
1371 else
1372 {
1373 calculate_magn(sec_dist);
1374 gr_dist = gr;
1375 }
1376
1377 // init distribution
1378 dist.createCartGraph(gr_dist, domain);
1379
1380 }
1381
1386 void reset()
1387 {
1388 sub_domains.clear();
1389 box_nn_processor.clear();
1390 fine_s.clear();
1391 loc_box.clear();
1395 }
1396
1400 void decompose(dec_options opt = dec_options::DEC_NONE)
1401 {
1402 reset();
1403
1404 if (commCostSet == false)
1406
1407 dist.decompose();
1408
1410
1412
1415
1416 if (opt != dec_options::DEC_SKIP_ICELL)
1417 {
1418
1423 this->getProcessorBounds(),
1424 this->getGhost().getRcut(),
1425 this->getGhost());
1426 }
1427 }
1428
1434 void refine(size_t ts)
1435 {
1436 reset();
1437
1438 if (commCostSet == false)
1440
1441 dist.refine();
1442
1444
1446
1449 }
1450
1456 void redecompose(size_t ts)
1457 {
1458 reset();
1459
1460 if (commCostSet == false)
1462
1463 dist.redecompose();
1464
1466
1468
1471 }
1472
1479 bool refine(DLB & dlb)
1480 {
1481 // if the DLB heuristic to use is the "Unbalance Threshold" get unbalance percentage
1482 if (dlb.getHeurisitc() == DLB::Heuristic::UNBALANCE_THRLD)
1483 {
1484 float unbalance = dist.getUnbalance();
1485 dlb.setUnbalance(unbalance);
1486 if (v_cl.getProcessUnitID() == 0)
1487 {
1488 std::cout << std::setprecision(3) << unbalance << "\n";
1489 }
1490 }
1491
1492 if (dlb.rebalanceNeeded())
1493 {
1495
1496 return true;
1497 }
1498 return false;
1499 }
1500
1501// size_t n_step = 0;
1502
1508 {
1509 return dist.getUnbalance();
1510 }
1511
1517 {
1518 return dist.getProcessorLoad();
1519 }
1520
1527 inline void getSubSubDomainPosition(size_t id, T (&pos)[dim])
1528 {
1529 dist.getSubSubDomainPosition(id, pos);
1530 }
1531
1532 //TODO fix in Parmetis distribution to get only the right amount of vertices
1538 {
1539 return dist.getNSubSubDomains();
1540 }
1541
1548 inline void setSubSubDomainComputationCost(size_t id, size_t weight)
1549 {
1550 dist.setComputationCost(id, weight);
1551 }
1552
1560 inline size_t getSubSubDomainComputationCost(size_t id)
1561 {
1562 return dist.getSubSubDomainComputationCost(id);
1563 }
1564
1569 size_t subSize()
1570 {
1571 return dist.subSize();
1572 }
1573
1580 {
1581 return sub_domains.size();
1582 }
1583
1592 {
1593 // Create a space box
1595
1596 // fill the space box
1597
1598 for (size_t k = 0; k < dim; k++)
1599 {
1600 // create the SpaceBox Low and High
1601 sp.setLow(k, sub_domains.template get<Box::p1>(lc)[k]);
1602 sp.setHigh(k, sub_domains.template get<Box::p2>(lc)[k]);
1603 }
1604
1605 return sp;
1606 }
1607
1616 {
1617 // Create a space box
1618 SpaceBox<dim, T> sp = sub_domains.get(lc);
1619
1620 // enlarge with ghost
1621 sp.enlarge(ghost);
1622
1623 return sp;
1624 }
1625
1631 const ::Box<dim,T> & getDomain() const
1632 {
1633 return domain;
1634 }
1635
1636 const openfpm::vector<SpaceBox<dim, T>,Memory,layout_base> &
1637 getSubDomains() const
1638 {
1639 return sub_domains;
1640 }
1641
1651 template<typename Mem> bool isLocal(const encapc<1, Point<dim, T>, Mem> p) const
1652 {
1653 return processorID<Mem>(p) == v_cl.getProcessUnitID();
1654 }
1655
1665 bool isLocal(const T (&pos)[dim]) const
1666 {
1667 return processorID(pos) == v_cl.getProcessUnitID();
1668 }
1669
1679 bool isLocal(const Point<dim,T> & pos) const
1680 {
1681 return processorID(pos) == v_cl.getProcessUnitID();
1682 }
1683
1696 template<typename Mem> bool isLocalBC(const encapc<1, Point<dim,T>, Mem> p, const size_t (& bc)[dim]) const
1697 {
1698 Point<dim,T> pt = p;
1699
1700 for (size_t i = 0 ; i < dim ; i++)
1701 {
1702 if (bc[i] == PERIODIC)
1703 pt.get(i) = openfpm::math::periodic_l(p.template get<0>()[i],domain.getHigh(i),domain.getLow(i));
1704 }
1705
1706 return processorID<Mem>(pt) == v_cl.getProcessUnitID();
1707 }
1708
1721 bool isLocalBC(const Point<dim,T> & p, const size_t (& bc)[dim]) const
1722 {
1723 Point<dim,T> pt = p;
1724
1725 for (size_t i = 0 ; i < dim ; i++)
1726 {
1727 if (bc[i] == PERIODIC)
1728 pt.get(i) = openfpm::math::periodic_l(p[i],domain.getHigh(i),domain.getLow(i));
1729 }
1730
1731 return processorID(pt) == v_cl.getProcessUnitID();
1732 }
1733
1742 {
1744 }
1745
1769 {
1771 }
1772
1780 {
1782 }
1783
1793 {
1795 }
1796
1808 bool isLocalBC(const T (&p)[dim], const size_t (& bc)[dim]) const
1809 {
1810 Point<dim,T> pt = p;
1811
1812 for (size_t i = 0 ; i < dim ; i++)
1813 {
1814 if (bc[i] == PERIODIC)
1815 pt.get(i) = openfpm::math::periodic_l(p[i],domain.getHigh(i),domain.getLow(i));
1816 }
1817
1818 return processorID(pt) == v_cl.getProcessUnitID();
1819 }
1820
1821
1828 {
1829 return bbox;
1830 }
1831
1832
1839 const Ghost<dim,T> & getGhost() const
1840 {
1841 return ghost;
1842 }
1843
1849 {
1850 return gr;
1851 }
1852
1858 {
1859 return gr_dist;
1860 }
1861
1863
1882 bool write(std::string output) const
1883 {
1885 VTKWriter<openfpm::vector<SpaceBox<dim, T>,Memory,layout_base>, VECTOR_BOX> vtk_box1;
1886 vtk_box1.add(sub_domains);
1887 vtk_box1.write(output + std::string("subdomains_") + std::to_string(v_cl.getProcessUnitID()) + std::string(".vtk"));
1888
1892
1893 return true;
1894 }
1895
1902 {
1903#ifdef SE_CLASS2
1904 check_valid(this,8);
1905#endif
1906 return v_cl;
1907 }
1908
1913 {
1915 }
1916
1921 {
1922 fine_s.clear();
1923 fine_s.destroy();
1924 }
1925
1932 {
1934 return false;
1935
1936 return true;
1937 }
1938
1943 {
1944 std::cout << "Subdomains\n";
1945 for (size_t p = 0; p < sub_domains.size(); p++)
1946 {
1947 std::cout << ::SpaceBox<dim, T>(sub_domains.get(p)).toString() << "\n";
1948 }
1949
1950 std::cout << "Subdomains global\n";
1951 for (size_t p = 0; p < sub_domains_global.size(); p++)
1952 {
1953 std::cout << ::SpaceBox<dim, T>(sub_domains_global.template get<0>(p)).toString() << " proc:" << sub_domains_global.template get<1>(p) << "\n";
1954 }
1955
1956 std::cout << "External ghost box\n";
1957
1958 for (size_t p = 0; p<nn_prcs < dim, T, layout_base, Memory>::getNNProcessors(); p++)
1959 {
1960 for (size_t i = 0; i<ie_ghost <dim,T,Memory,layout_base>::getProcessorNEGhost(p); i++)
1961 {
1962 std::cout << ie_ghost<dim,T,Memory,layout_base>::getProcessorEGhostBox(p, i).toString() << " prc=" << nn_prcs<dim, T, layout_base,Memory>::IDtoProc(p) << " id=" << ie_ghost<dim,T,Memory,layout_base>::getProcessorEGhostId(p, i) << "\n";
1963 }
1964 }
1965
1966 std::cout << "Internal ghost box\n";
1967
1968 for (size_t p = 0; p<nn_prcs < dim, T, layout_base, Memory>::getNNProcessors(); p++)
1969 {
1970 for (size_t i = 0; i<ie_ghost<dim,T,Memory,layout_base>::getProcessorNIGhost(p); i++)
1971 {
1972 std::cout << ie_ghost<dim,T,Memory,layout_base>::getProcessorIGhostBox(p, i).toString() << " prc=" << nn_prcs<dim, T, layout_base, Memory>::IDtoProc(p) << " id=" << ie_ghost<dim,T,Memory,layout_base>::getProcessorIGhostId(p, i) << "\n";
1973 }
1974 }
1975 }
1976
1985 {
1986 if (static_cast<ie_loc_ghost<dim,T,layout_base,Memory>*>(this)->is_equal(static_cast<ie_loc_ghost<dim,T,layout_base,Memory>&>(cart)) == false)
1987 return false;
1988
1989 if (static_cast<nn_prcs<dim,T,layout_base,Memory>*>(this)->is_equal(static_cast<nn_prcs<dim,T, layout_base,Memory>&>(cart)) == false)
1990 return false;
1991
1992 if (static_cast<ie_ghost<dim,T,Memory,layout_base>*>(this)->is_equal(static_cast<ie_ghost<dim,T,Memory,layout_base>&>(cart)) == false)
1993 return false;
1994
1995 if (sub_domains != cart.sub_domains)
1996 return false;
1997
1999 return false;
2000
2001 if (fine_s != cart.fine_s)
2002 return false;
2003
2004 if (gr != cart.gr)
2005 return false;
2006
2007 if (cd != cart.cd)
2008 return false;
2009
2010 if (domain != cart.domain)
2011 return false;
2012
2013 if (meta_compare<T[dim]>::meta_compare_f(cart.spacing,spacing) == false)
2014 return false;
2015
2016 if (ghost != cart.ghost)
2017 return false;
2018
2019 return true;
2020 }
2021
2031 {
2032 if (static_cast<ie_loc_ghost<dim,T,layout_base,Memory>*>(this)->is_equal_ng(static_cast<ie_loc_ghost<dim,T,layout_base,Memory>&>(cart)) == false)
2033 return false;
2034
2035 if (static_cast<nn_prcs<dim,T,layout_base,Memory>*>(this)->is_equal(static_cast<nn_prcs<dim,T,layout_base,Memory>&>(cart)) == false)
2036 return false;
2037
2038 if (static_cast<ie_ghost<dim,T,Memory,layout_base>*>(this)->is_equal_ng(static_cast<ie_ghost<dim,T,Memory,layout_base>&>(cart)) == false)
2039 return false;
2040
2041 if (sub_domains != cart.sub_domains)
2042 return false;
2043
2045 return false;
2046
2047 if (fine_s != cart.fine_s)
2048 return false;
2049
2050 if (gr != cart.gr)
2051 return false;
2052
2053 if (cd != cart.cd)
2054 return false;
2055
2056 if (domain != cart.domain)
2057 return false;
2058
2059 if (meta_compare<T[dim]>::meta_compare_f(cart.spacing,spacing) == false)
2060 return false;
2061
2062 return true;
2063 }
2064
2070 Distribution & getDistribution()
2071 {
2072 return dist;
2073 }
2074
2075
2081 inline void addComputationCost(size_t gid, size_t i)
2082 {
2083 size_t c = dist.getSubSubDomainComputationCost(gid);
2084
2085 dist.setComputationCost(gid, c + i);
2086 }
2087
2093 size_t get_ndec()
2094 {
2095 return dist.get_ndec();
2096 }
2097
2103 const CellDecomposer_sm<dim, T, shift<dim,T>> & getCellDecomposer()
2104 {
2105 return cd;
2106 }
2107
2108
2115 {
2116 if (host_dev_transfer == false)
2117 {
2118 fine_s.hostToDevice();
2119 sub_domains_global.template hostToDevice<0,1>();
2120 host_dev_transfer = true;
2121 }
2122
2123 int bc_[dim];
2124
2125 for (int i = 0 ; i < dim ; i++) {bc_[i] = this->periodicity(i);}
2126
2130 getDomain(),
2131 bc_);
2132
2133 return cdg;
2134 }
2135
2138
2145 {
2146 return sub_domains;
2147 }
2148
2155 {
2156 return sub_domains;
2157 }
2158
2165 {
2166 return box_nn_processor;
2167 }
2168
2175 {
2176 return box_nn_processor;
2177 }
2178
2185 {
2186 return fine_s;
2187 }
2188
2195 {
2196 return fine_s;
2197 }
2198
2205 {
2206 return gr;
2207 }
2208
2215 {
2216 return gr;
2217 }
2218
2225 {
2226 return gr_dist;
2227 }
2228
2235 {
2236 return gr_dist;
2237 }
2238
2244 Distribution & private_get_dist()
2245 {
2246 return dist;
2247 }
2248
2254 const Distribution & private_get_dist() const
2255 {
2256 return dist;
2257 }
2258
2265 {
2266 return commCostSet;
2267 }
2268
2274 const bool & private_get_commCostSet() const
2275 {
2276 return commCostSet;
2277 }
2278
2284 CellDecomposer_sm<dim, T, shift<dim,T>> & private_get_cd()
2285 {
2286 return cd;
2287 }
2288
2294 const CellDecomposer_sm<dim, T, shift<dim,T>> & private_get_cd() const
2295 {
2296 return cd;
2297 }
2298
2305 {
2306 return domain;
2307 }
2308
2314 const ::Box<dim,T> & private_get_domain() const
2315 {
2316 return domain;
2317 }
2318
2325 {
2326 return sub_domains_global;
2327 }
2328
2335 {
2336 return sub_domains_global;
2337 }
2338
2345 {
2346 return spacing[i];
2347 }
2348
2354 const T & private_get_spacing(int i) const
2355 {
2356 return spacing[i];
2357 }
2358
2365 {
2366 return spacing[i];
2367 }
2368
2374 const T & private_get_magn(int i) const
2375 {
2376 return spacing[i];
2377 }
2378
2379
2386 {
2387 return ghost;
2388 }
2389
2396 {
2397 return ghost;
2398 }
2399
2406 {
2407 return bbox;
2408 }
2409
2415 const ::Box<dim,T> & private_get_bbox() const
2416 {
2417 return bbox;
2418 }
2419
2425 size_t & private_get_bc(int i)
2426 {
2427 return bc[i];
2428 }
2429
2435 const size_t & private_get_bc(int i) const
2436 {
2437 return bc[i];
2438 }
2439};
2440
2441
2442#endif
This class represent an N-dimensional box.
Definition Box.hpp:61
void expand(T(&exp)[dim])
expand the box by a vector
Definition Box.hpp:793
__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
void enlarge(const Box< dim, T > &gh)
Enlarge the box with ghost margin.
Definition Box.hpp:823
Box< dim, T > & getBox()
Get the box enclosing this Box.
Definition Box.hpp:623
__device__ __host__ void setHigh(int i, T val)
set the high interval of the box
Definition Box.hpp:544
Point< dim, T > getP1() const
Get the point p1.
Definition Box.hpp:708
void enclose(const Box< dim, T > &en)
Refine the box to enclose the given box and itself.
Definition Box.hpp:935
__device__ __host__ void setLow(int i, T val)
set the low interval of the box
Definition Box.hpp:533
bool isValidN() const
Check if the Box is a valid box P2 > P1.
Definition Box.hpp:1196
class to select the returned id by ghost_processorID
static size_t id(p_box< dim, T > &p, size_t b_id)
Return the box id.
class to select the returned id by ghost_processorID
static size_t id(const encap_type &p, size_t b_id)
Return the near processor id.
class to select the returned id by ghost_processorID
static size_t id(const encap_type &p, size_t b_id)
Return the processor id.
class to select the returned id by ghost_processorID
static size_t id(const encap_type &p, size_t b_id)
Return the shift id.
This class decompose a space into sub-sub-domains and distribute them across processors.
This class decompose a space into sub-sub-domains and distribute them across processors.
size_t processorID(const Point< dim, T > &p) const
Given a point return in which processor the particle should go.
void setGoodParameters(::Box< dim, T > &domain_, const size_t(&bc)[dim], const Ghost< dim, T > &ghost, size_t dec_gran, const grid_sm< dim, void > &sec_dist=grid_sm< dim, void >())
Set the best parameters for the decomposition.
void setNNParameters(grid_key_dx< dim > &shift, grid_sm< dim, void > &gs)
set NN parameters to calculate cell-list neighborhood
const ::Box< dim, T > & private_get_bbox() const
Return the internal data structure bbox.
void calculateGhostBoxes()
It calculate the internal ghost boxes.
grid_sm< dim, void > gr_dist
Structure that store the cartesian grid information.
static size_t getDefaultGrid(size_t n_sub)
The default grid size.
T domain_type
Type of the domain we are going to decompose.
bool check_consistency()
function to check the consistency of the information of the decomposition
const bool & private_get_commCostSet() const
Return the internal data structure commCostSet.
size_t processorID(const T(&p)[dim]) const
Given a point return in which processor the particle should go.
SpaceBox< dim, T > convertDecBoxIntoSubDomain(encapc< 1,::Box< dim, size_t >, Memory_bx > loc_box)
It convert the box from the domain decomposition into sub-domain.
openfpm::vector< SpaceBox< dim, T > > & private_get_sub_domains()
Return the internal data structure sub_domains.
Vcluster & v_cl
Runtime virtual cluster machine.
Ghost< dim, T > ghost
ghost info
bool isLocal(const encapc< 1, Point< dim, T >, Mem > p) const
Check if the particle is local.
::Box< dim, T > & private_get_domain()
Return the internal data structure domain.
Distribution & getDistribution()
Return the distribution object.
openfpm::vector< subsub_lin< dim > > & getCRSAnomDomainCells()
Get the CRS anomalous cells.
void free_geo_cell()
Deallocate structures that identify a point to which internal ghost is located.
void applyPointBC(float(&pt)[dim]) const
Apply boundary condition to the point.
const CellList< dim, T, Mem_fast< Memory, int >, shift< dim, T > > & private_get_fine_s() const
Return the internal data structure fine_s.
const grid_sm< dim, void > getGrid()
Decomposition grid.
CartDecomposition_gpu< dim, T, Memory, layout_base > toKernel()
convert to a structure usable in a device kernel
openfpm::vector< openfpm::vector< long unsigned int > > box_nn_processor
for each sub-domain, contain the list of the neighborhood processors
const grid_sm< dim, void > & private_get_gr_dist() const
Return the internal data structure gr_dist.
CartDecomposition(Vcluster<> &v_cl)
Cartesian decomposition constructor.
openfpm::vector< size_t > & getDomainCells()
Get the domain Cells.
size_t processorIDBC(encapc< 1, Point< dim, T >, Mem > p)
Given a point return in which processor the point/particle should go.
size_t processorID(const encapc< 1, Point< dim, T >, Mem > &p) const
Given a point return in which processor the particle should go.
long int ref_cnt
reference counter of the object in case is shared between object
::Box< dim, T > & getProcessorBounds()
Return the bounding box containing union of all the sub-domains for the local processor.
::Box< dim, T > bbox
Processor bounding box.
size_t getProcessorLoad()
Compute the processor load counting the total weights of its vertices.
const openfpm::vector< openfpm::vector< long unsigned int > > & private_get_box_nn_processor() const
Return the internal data structure box_nn_processor.
CellDecomposer_sm< dim, T, shift< dim, T > > cd
Ghost< dim, T > & private_get_ghost()
Return the internal data structure ghost.
void decompose(dec_options opt=dec_options::DEC_NONE)
Start decomposition.
::Box< dim, size_t > proc_box
Processor domain bounding box.
CartDecomposition< dim, T, Memory, layout_base, Distribution > duplicate(const Ghost< dim, T > &g) const
It create another object that contain the same decomposition information but with different ghost box...
bool is_equal(CartDecomposition< dim, T, Memory > &cart)
Check if the CartDecomposition contain the same information.
grid_sm< dim, void > & private_get_gr_dist()
Return the internal data structure gr_dist.
const T & private_get_spacing(int i) const
Return the internal data structure spacing.
openfpm::vector< size_t > & getCRSDomainCells()
Get the CRS domain Cells with normal neighborhood.
CartDecomposition(CartDecomposition< dim, T, Memory, layout_base, Distribution > &&cart)
Cartesian decomposition copy constructor.
const CellDecomposer_sm< dim, T, shift< dim, T > > & getCellDecomposer()
Get the cell decomposer of the decomposition.
size_t getNSubSubDomains()
Get the number of sub-sub-domains in this sub-graph.
openfpm::vector< SpaceBox< dim, T >, Memory, memory_traits_lin, openfpm::vector_grow_policy_default, openfpm::vect_isel< SpaceBox< dim, T > >::value >::access_key acc_key
const Ghost< dim, T > & private_get_ghost() const
Return the internal data structure ghost.
CartDecomposition< dim, T, Memory, layout_base, Distribution > duplicate() const
It create another object that contain the same information and act in the same way.
void addComputationCost(size_t gid, size_t i)
Add computation cost i to the subsubdomain with global id gid.
size_t & private_get_bc(int i)
Return the internal data structure bc.
const size_t & private_get_bc(int i) const
Return the internal data structure bc.
Vcluster & getVC() const
Get the Virtual Cluster machine.
CartDecomposition< dim, T, Memory, layout_base, Distribution > base_type
This class is base of itself.
void computeCommunicationAndMigrationCosts(size_t ts)
Calculate communication and migration costs.
long int ref()
Return the reference counter.
const Ghost< dim, T > & getGhost() const
Return the ghost.
CartDecomposition< dim, T, Memory, layout_base, Distribution > & operator=(const CartDecomposition2 &cart)
Copy the element.
const ::Box< dim, T > & getDomain() const
Return the box of the physical domain.
bool write(std::string output) const
Write the decomposition as VTK file.
size_t periodicity(size_t i) const
Get the periodicity on i dimension.
void getParameters(size_t(&div_)[dim])
return the parameters of the decomposition
T spacing[dim]
Box Spacing.
const grid_sm< dim, void > getDistGrid()
Distribution grid.
Distribution & private_get_dist()
Return the internal data structure dist.
CartDecomposition(const CartDecomposition< dim, T, Memory, layout_base, Distribution > &cart)
Cartesian decomposition copy constructor.
const grid_sm< dim, void > & private_get_gr() const
Return the internal data structure gr.
CellDecomposer_sm< dim, T, shift< dim, T > > & private_get_cd()
Return the internal data structure cd.
void getSubSubDomainPosition(size_t id, T(&pos)[dim])
function that return the position of the cell in the space
void calculate_magn(const grid_sm< dim, void > &gm)
Calculate magnification.
void setSubSubDomainComputationCost(size_t id, size_t weight)
Function that set the computational cost for a of a sub-sub domain.
grid_sm< dim, void > & private_get_gr()
Return the internal data structure gr.
bool commCostSet
Indicate the communication weight has been set.
bool host_dev_transfer
bool that indicate whenever the buffer has been already transfer to device
size_t getNSubDomain()
Get the number of local sub-domains.
bool refine(DLB &dlb)
Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call.
T & private_get_magn(int i)
Return the internal data structure magn.
openfpm::vector< Box_map< dim, T >, Memory, layout_base > & private_get_sub_domains_global()
Return the internal data structure sub_domains_global.
grid_sm< dim, void > gr
Structure that store the cartesian grid information.
bool isLocalBC(const encapc< 1, Point< dim, T >, Mem > p, const size_t(&bc)[dim]) const
Check if the particle is local considering boundary conditions.
bool isLocal(const T(&pos)[dim]) const
Check if the particle is local.
const ::Box< dim, T > & private_get_domain() const
Return the internal data structure domain.
const size_t(& periodicity() const)[dim]
Get the periodicity.
bool isLocalBC(const Point< dim, T > &p, const size_t(&bc)[dim]) const
Check if the particle is local considering boundary conditions.
SpaceBox< dim, T > getSubDomain(size_t lc)
Get the local sub-domain.
void createSubdomains(Vcluster<> &v_cl, const size_t(&bc)[dim], size_t opt=0)
Constructor, it decompose and distribute the sub-domains across the processors.
bool & private_get_commCostSet()
Return the internal data structure commCostSet.
openfpm::vector< openfpm::vector< long unsigned int > > & private_get_box_nn_processor()
Return the internal data structure box_nn_processor.
friend extended_type
friend classes
::Box< dim, T > & private_get_bbox()
Return the internal data structure bbox.
void incRef()
Increment the reference counter.
CartDecomposition< dim, T, Memory, layout_base, Distribution > & operator=(CartDecomposition &&cart)
Copy the element, move semantic.
Distribution dist
Create distribution.
size_t subSize()
Operator to access the size of the sub-graph.
void free_fines()
Deallocate structures that identify a point to which internal ghost is located.
openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > sub_domains
the set of all local sub-domain as vector
CellList< dim, T, Mem_fast< Memory, int >, shift< dim, T > > & private_get_fine_s()
Return the internal data structure fine_s.
const openfpm::vector< Box_map< dim, T >, Memory, layout_base > & private_get_sub_domains_global() const
Return the internal data structure sub_domains_global.
CartDecomposition_ext< dim, T, Memory, layout_base, Distribution > extended_type
This class admit a class defined on an extended domain.
const CellDecomposer_sm< dim, T, shift< dim, T > > & private_get_cd() const
Return the internal data structure cd.
SpaceBox< dim, T > getSubDomainWithGhost(size_t lc)
Get the local sub-domain enlarged with ghost extension.
size_t bc[dim]
Boundary condition info.
void CreateSubspaces()
Create the sub-domain that decompose your domain.
float getUnbalance()
Get the current un-balance value.
void applyPointBC(Point< dim, T > &pt) const
Apply boundary condition to the point.
size_t processorIDBC(const T(&p)[dim]) const
Given a point return in which processor the particle should go.
void debugPrint()
Print subdomains, external and internal ghost boxes.
bool isLocal(const Point< dim, T > &pos) const
Check if the particle is local.
static constexpr int dims
Space dimensions.
void decRef()
Decrement the reference counter.
CellList< dim, T, Mem_fast< Memory, int >, shift< dim, T > > fine_s
void setParameters(const size_t(&div_)[dim], ::Box< dim, T > &domain_, const size_t(&bc)[dim], const Ghost< dim, T > &ghost, const grid_sm< dim, void > &sec_dist=grid_sm< dim, void >())
Set the parameter of the decomposition.
CartDecomposition< dim, T, Memory, layout_base, Distribution > & operator=(const CartDecomposition &cart)
Copy the element.
void reset()
Delete the decomposition and reset the data-structure.
bool isLocalBC(const T(&p)[dim], const size_t(&bc)[dim]) const
Check if the particle is local considering boundary conditions.
::Box< dim, T > domain
rectangular domain to decompose
CartDecomposition< dim, T, Memory2, layout_base2, Distribution > duplicate_convert() const
It create another object that contain the same information and act in the same way.
size_t processorIDBC(const Point< dim, T > &p) const
Given a point return in which processor the particle should go.
bool is_equal_ng(CartDecomposition< dim, T, Memory > &cart)
Check if the CartDecomposition contain the same information with the exception of the ghost part It i...
~CartDecomposition()
Cartesian decomposition destructor.
size_t getSubSubDomainComputationCost(size_t id)
function that return the computation cost of the sub-sub-domain id
const Distribution & private_get_dist() const
Return the internal data structure dist.
openfpm::vector< Box_map< dim, T >, Memory, layout_base > sub_domains_global
the remote set of all sub-domains as vector of 'sub_domains' vectors
const T & private_get_magn(int i) const
Return the internal data structure magn.
void redecompose(size_t ts)
Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call.
size_t get_ndec()
Get the decomposition counter.
void refine(size_t ts)
Refine the decomposition, available only for ParMetis distribution, for Metis it is a null call.
openfpm::vector<::Box< dim, size_t > > loc_box
set of Boxes produced by the decomposition optimizer
SpaceBox< dim, T > Box
It simplify to access the SpaceBox element.
const openfpm::vector< SpaceBox< dim, T > > & private_get_sub_domains() const
Return the internal data structure sub_domains.
void applyPointBC(encapc< 1, Point< dim, T >, Mem > &&pt) const
Apply boundary condition to the point.
T & private_get_spacing(int i)
Return the internal data structure spacing.
void Initialize_geo_cell_lists()
Initialize geo_cell lists.
Class for FAST cell list implementation.
Definition CellList.hpp:357
const grid_sm< dim, void > & getGrid()
Return the underlying grid information of the cell list.
Definition CellList.hpp:447
void clear()
Clear the cell list.
void destroy()
Litterary destroy the memory of the cell list, including the retained one.
void swap(CellList< dim, T, Mem_type, transform, vector_pos_type > &cl)
Swap the memory.
Definition CellList.hpp:892
void Initialize(CellDecomposer_sm< dim, T, transform > &cd_sm, const Box< dim, T > &dom_box, const size_t pad=1, size_t slot=STARTING_NSLOT)
Definition CellList.hpp:465
void addCell(size_t cell_id, typename Mem_type::local_index_type ele)
Add to the cell.
Definition CellList.hpp:715
Definition DLB.hpp:54
bool rebalanceNeeded()
check if a re-balance is needed using the selected heuristic
Definition DLB.hpp:200
void setUnbalance(float u)
Set un-balance value.
Definition DLB.hpp:318
size_t getNTimeStepSinceDLB()
Get how many time-steps have passed since the last re-balancing.
Definition DLB.hpp:309
Heuristic getHeurisitc()
Get the heuristic.
Definition DLB.hpp:190
This class implement the point shape in an N-dimensional space.
Definition Point.hpp:28
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
Definition Point.hpp:172
This class represent an N-dimensional box.
Definition SpaceBox.hpp:27
void mul(T(&sp)[dim])
multiply the space box with the coefficient defined in sp
Definition SpaceBox.hpp:178
void execute()
Execute all the requests.
size_t rank()
Get the process unit id.
bool Bcast(openfpm::vector< T, Mem, layout_base > &v, size_t root)
Broadcast the data to all processors.
size_t getProcessUnitID()
Get the process unit id.
size_t getProcessingUnits()
Get the total number of processors.
void max(T &num)
Get the maximum number across all processors (or reduction with infinity norm)
Implementation of VCluster class.
Definition VCluster.hpp:59
bool SGather(T &send, S &recv, size_t root)
Semantic Gather, gather the data from all processors into one node.
Definition VCluster.hpp:450
This class take a graph representing the space decomposition and produce a simplified version.
This class calculate processor domains and neighborhood of each processor domain.
openfpm::vector< size_t > & getCRSDomainCells()
Get the domain Cells.
openfpm::vector< subsub_lin< dim > > & getCRSAnomDomainCells()
Get the domain anomalous cells.
openfpm::vector< size_t > & getDomainCells()
Get the domain Cells.
grid_sm< dim, void > gs
Processor cells-grid.
void setParameters(const Box< dim, long int > &proc_box)
Set parameters to calculate the cell neighborhood.
void reset()
In case you have to recompute the indexes.
void setNNParameters(openfpm::vector<::Box< dim, size_t > > &loc_box, const grid_key_dx< dim > &shift, const grid_sm< dim, void > &gs)
Set parameters to calculate the cell neighborhood.
grid_key_dx< dim > one
key with all coordinates set to one
Declaration grid_key_dx_iterator_sub.
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
void setDimensions(const size_t(&dims)[N])
Reset the dimension of the grid.
Definition grid_sm.hpp:326
__device__ __host__ const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition grid_sm.hpp:760
void swap(grid_sm< N, T > &g)
swap the grid_sm informations
Definition grid_sm.hpp:829
__device__ __host__ size_t size() const
Return the size of the grid.
Definition grid_sm.hpp:657
structure that store and compute the internal and external local ghost box
Definition ie_ghost.hpp:48
void create_box_nn_processor_int(Vcluster<> &v_cl, Ghost< dim, T > &ghost, openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > &sub_domains, const openfpm::vector< openfpm::vector< long unsigned int > > &box_nn_processor, const nn_prcs< dim, T, layout_base, Memory > &nn_p)
Create the box_nn_processor_int (nbx part) structure, the geo_cell list and proc_int_box.
Definition ie_ghost.hpp:348
void reset_host_dev_transfer()
Notify that the next toKernel() data-structures must be re-offloaded.
void free_geo_cell()
Deallocate structures that identify a point to which internal ghost is located.
Definition ie_ghost.hpp:226
ie_ghost_gpu< dim, T, Memory, layout_base > toKernel()
toKernel() Convert this data-structure into a kernel usable data-structure
void reset()
Reset the nn_prcs structure.
bool write(std::string output, size_t p_id) const
write the information about the ghost in vtk format
size_t getProcessorEGhostId(size_t id, size_t j) const
Get the j External ghost box id.
Definition ie_ghost.hpp:804
void generateShiftVectors(const Box< dim, T > &domain, size_t(&bc)[dim])
Here we generare the shift vectors.
Definition ie_ghost.hpp:196
void Initialize_geo_cell(const Box< dim, T > &domain, const size_t(&div)[dim])
Initialize the geo cell list structure.
Definition ie_ghost.hpp:217
void create_box_nn_processor_ext(Vcluster<> &v_cl, Ghost< dim, T > &ghost, openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > &sub_domains, const openfpm::vector< openfpm::vector< long unsigned int > > &box_nn_processor, const nn_prcs< dim, T, layout_base, Memory > &nn_p)
Create the box_nn_processor_int (bx part) structure.
Definition ie_ghost.hpp:246
size_t getProcessorIGhostId(size_t id, size_t j) const
Get the j Internal ghost box id.
Definition ie_ghost.hpp:788
structure that store and compute the internal and external local ghost box
void create(openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > &sub_domains, Box< dim, T > &domain, Ghost< dim, T > &ghost, const size_t(&bc)[dim])
Create external and internal local ghosts.
bool write(std::string output, size_t p_id) const
Write the decomposition as VTK file.
void reset()
Reset the ie_loc_ghost.
This class store the adjacent processors and the adjacent sub_domains.
static bool check_valid(comb< dim > cmb, const size_t(&bc)[dim])
void applyBC(const Box< dim, T > &domain, const Ghost< dim, T > &ghost, const size_t(&bc)[dim])
Apply boundary conditions.
void create(const openfpm::vector< openfpm::vector< long unsigned int > > &box_nn_processor, const openfpm::vector< SpaceBox< dim, T >, Memory, layout_base > &sub_domains)
Create the list of adjacent processors and the list of adjacent sub-domains.
bool write(std::string output) const
Write the decomposition as VTK file.
size_t IDtoProc(size_t id) const
Return the processor id of the near processor list at place id.
void reset()
Reset the nn_prcs structure.
Implementation of 1-D std::vector like structure.
size_t size()
Stub size.
grow_policy_double vector_grow_policy_default
default grow policy
aggregate of properties, from a list of object if create a struct that follow the OPENFPM native stru...
Definition ids.hpp:149
Transform the boost::fusion::vector into memory specification (memory_traits)
This class compare general objects.
sub-domain edge graph node
It analyze the type given and it select correctly the implementation for vector.
Definition vect_isel.hpp:37
It store all the boxes of the near processors in a linear array.
Definition common.hpp:300