OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
SpaceDistribution.hpp
1/*
2 * SpaceDistribution.hpp
3 *
4 * Created on: Dec 3, 2016
5 * Author: i-bird
6 */
7
8#ifndef SRC_DECOMPOSITION_DISTRIBUTION_SPACEDISTRIBUTION_HPP_
9#define SRC_DECOMPOSITION_DISTRIBUTION_SPACEDISTRIBUTION_HPP_
10
11#include "util/mathutil.hpp"
12#include "NN/CellList/CellDecomposer.hpp"
13#include "Grid/grid_key_dx_iterator_hilbert.hpp"
14
23template<unsigned int dim, typename T>
25{
28
31
34
37
38
39public:
40
46 :v_cl(v_cl)
47 {
48 }
49
56 :v_cl(pm.v_cl)
57 {
58 this->operator=(pm);
59 }
60
67 :v_cl(pm.v_cl)
68 {
69 this->operator=(pm);
70 }
71
78 {
79 size_t bc[dim];
80
81 for (size_t i = 0 ; i < dim ; i++)
82 bc[i] = NON_PERIODIC;
83
84 // Set grid and domain
85 gr = grid;
86 domain = dom;
87
88 // Create a cartesian grid graph
90 gp = g_factory_part.template construct<NO_EDGE, nm_v_id, T, dim - 1, 0>(gr.getSize(), domain, bc);
91
92 // Init to 0.0 axis z (to fix in graphFactory)
93 if (dim < 3)
94 {
95 for (size_t i = 0; i < gp.getNVertex(); i++)
96 gp.vertex(i).template get<nm_v_x>()[2] = 0.0;
97 }
98 for (size_t i = 0; i < gp.getNVertex(); i++)
99 gp.vertex(i).template get<nm_v_global_id>() = i;
100
101 }
102
107 {
108 return gp;
109 }
110
115 {
116 // Get the number of processing units
117 size_t Np = v_cl.getProcessingUnits();
118
119 // Calculate the best number of sub-domains for each
120 // processor
121 size_t N_tot = gr.size();
122 size_t N_best_each = N_tot / Np;
123 size_t N_rest = N_tot % Np;
124
126 accu.get(0) = N_best_each + ((0 < N_rest)?1:0);
127 for (size_t i = 1 ; i < Np ; i++)
128 accu.get(i) = accu.get(i-1) + N_best_each + ((i < N_rest)?1:0);
129
130 // Get the maximum along dimensions and take the smallest n number
131 // such that 2^n < m. n it will be order of the hilbert curve
132
133 size_t max = 0;
134
135 for (size_t i = 0; i < dim ; i++)
136 {
137 if (max < gr.size(i))
138 max = gr.size(i);
139 }
140
141 // Get the order of the hilbert-curve
142 size_t order = openfpm::math::log2_64(max);
143 if (1ul << order < max)
144 order += 1;
145
146 size_t n = 1 << order;
147
148 // Create the CellDecomoser
149
150 CellDecomposer_sm<dim,T> cd_sm;
151 cd_sm.setDimensions(domain, gr.getSize(), 0);
152
153 // create the hilbert curve
154
155 //hilbert curve iterator
157
158 T spacing[dim];
159
160 // Calculate the hilbert curve spacing
161 for (size_t i = 0 ; i < dim ; i++)
162 spacing[i] = (domain.getHigh(i) - domain.getLow(i)) / n;
163
164 // Small grid to detect already assigned sub-sub-domains
166 g.setMemory();
167
168 // Reset the grid to -1
170 while (it.isNext())
171 {
172 auto key = it.get();
173
174 g.template get<0>(key) = -1;
175
176 ++it;
177 }
178
179 // Go along the hilbert-curve and divide the space
180
181 size_t proc_d = 0;
182 size_t ele_d = 0;
183 while (h_it.isNext())
184 {
185 auto key = h_it.get();
186
187 // Point p
188 Point<dim,T> p;
189
190 for (size_t i = 0 ; i < dim ; i++)
191 p.get(i) = key.get(i) * spacing[i] + spacing[i] / 2;
192
193 grid_key_dx<dim> sp = cd_sm.getCellGrid(p);
194
195 if (g.template get<0>(sp) == -1)
196 {
197 g.template get<0>(sp) = proc_d;
198 ele_d++;
199
200 if (ele_d >= accu.get(proc_d))
201 proc_d++;
202 }
203
204 ++h_it;
205 }
206
207 // Fill from the grid to the graph
208
209 // Reset the grid to -1
211 while (it2.isNext())
212 {
213 auto key = it2.get();
214
215 gp.template vertex_p<nm_v_proc_id>(gr.LinId(key)) = g.template get<0>(key);
216
217 ++it2;
218 }
219
220 return;
221 }
222
228 void refine()
229 {
230 std::cout << __FILE__ << ":" << __LINE__ << " You are trying to dynamicaly balance a fixed decomposition, this operation has no effect" << std::endl;
231 }
232
238 {
239 return gr.size() % v_cl.getProcessingUnits();
240 }
241
248 void getSubSubDomainPosition(size_t id, T (&pos)[dim])
249 {
250#ifdef SE_CLASS1
251 if (id >= gp.getNVertex())
252 std::cerr << __FILE__ << ":" << __LINE__ << "Such vertex doesn't exist (id = " << id << ", " << "total size = " << gp.getNVertex() << ")\n";
253#endif
254
255 // Copy the geometrical informations inside the pos vector
256 pos[0] = gp.vertex(id).template get<nm_v_x>()[0];
257 pos[1] = gp.vertex(id).template get<nm_v_x>()[1];
258 if (dim == 3)
259 pos[2] = gp.vertex(id).template get<nm_v_x>()[2];
260 }
261
268 inline void setComputationCost(size_t id, size_t weight)
269 {
270 std::cout << __FILE__ << ":" << __LINE__ << " You are trying to set the computation cost on a fixed decomposition, this operation has no effect" << std::endl;
271 }
272
278 {
279 return false;
280 }
281
290 {
291 return 1.0;
292 }
293
299 {
300 // Get the number of processing units
301 size_t Np = v_cl.getProcessingUnits();
302
303 // Calculate the best number of sub-domains for each
304 // processor
305 size_t N_tot = gr.size();
306 size_t N_best_each = N_tot / Np;
307 size_t N_rest = N_tot % Np;
308
309 if (v_cl.getProcessUnitID() < N_rest)
310 N_best_each += 1;
311
312 return N_best_each;
313 }
314
320 void setMigrationCost(size_t id, size_t migration)
321 {
322 }
323
330 void setCommunicationCost(size_t v_id, size_t e, size_t communication)
331 {
332 }
333
340 {
341 return gp.getNVertex();
342 }
343
349 {
350 return gp.getNChilds(id);
351 }
352
358 void write(const std::string & file)
359 {
360 VTKWriter<Graph_CSR<nm_v<dim>, 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
397#endif /* SRC_DECOMPOSITION_DISTRIBUTION_SPACEDISTRIBUTION_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.
Class that distribute sub-sub-domains across processors using ParMetis Library.
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.
void setComputationCost(size_t id, size_t weight)
Function that set the weight of the vertex.
SpaceDistribution(Vcluster<> &v_cl)
Box< dim, T > domain
rectangular domain to decompose
size_t getProcessorLoad()
Compute the processor load counting the total weights of its vertices.
bool weightsAreUsed()
Checks if weights are used on the vertices.
void decompose()
Create the decomposition.
Graph_CSR< nm_v< dim >, nm_e > & getGraph()
Get the current graph (main)
void write(const std::string &file)
Print the current distribution and save it to VTK file.
void setMigrationCost(size_t id, size_t migration)
Set migration cost of the vertex id.
void refine()
Refine current decomposition.
void createCartGraph(grid_sm< dim, void > &grid, Box< dim, T > dom)
Create the Cartesian graph.
size_t getNSubSubDomainNeighbors(size_t id)
Returns total number of neighbors of the sub-sub-domain id.
Graph_CSR< nm_v< dim >, nm_e > gp
Global sub-sub-domain graph.
size_t getNSubSubDomains()
Returns total number of sub-sub-domains in the distribution graph.
float getUnbalance()
Compute the unbalance of the processor compared to the optimal balance.
Vcluster & v_cl
Vcluster.
grid_sm< dim, void > gr
Structure that store the cartesian grid information.
SpaceDistribution(const ParMetisDistribution< dim, T > &pm)
void getSubSubDomainPosition(size_t id, T(&pos)[dim])
function that return the position of the vertex in the space
SpaceDistribution(SpaceDistribution< dim, T > &&pm)
void setCommunicationCost(size_t v_id, size_t e, size_t communication)
Set communication cost of the edge id.
size_t get_ndec()
It return the decomposition id.
size_t getSubSubDomainComputationCost(size_t id)
function that get the weight of the vertex
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
const grid_key_dx< dim > & get()
Get the actual key.
bool isNext()
Check if there is the next element.
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
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.
sub-domain edge graph node