OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
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
24template<unsigned int dim, typename T>
25class SpaceDistributionWeight
26{
28 Vcluster & v_cl;
29
32
34 Box<dim, T> domain;
35
38
39
42
43public:
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
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_ */
This class represent an N-dimensional box.
Definition Box.hpp:61
This class construct a cartesian graph.
Structure that store a graph in CSR format or basically in compressed adjacency matrix format.
auto vertex(size_t id) -> decltype(v.get(id))
Function to access the vertex.
size_t getNChilds(size_t c) const
Return the number of childs of a vertex.
void swap(Graph_CSR< V, E > &g)
swap the memory of g with this graph
size_t getNVertex() const
Return the number of the vertex.
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
Class that distribute sub-sub-domains across processors using an hilbert curve to divide the space.
Implementation of VCluster class.
Definition VCluster.hpp:59
grid_key_dx is the key to access any element in the grid
Definition grid_key.hpp:19
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__ const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition grid_sm.hpp:760
__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.
size_t size()
Stub size.
static const unsigned int id
id property id in boost::fusion::vector