OpenFPM_pdata  4.1.0
Project that contain the implementation of distributed structures
 
Loading...
Searching...
No Matches
DistParMetisDistribution.hpp
1/*
2 * DistParMetisDistribution.hpp
3 *
4 * Created on: Nov 19, 2015
5 * Author: Antonio Leo
6 */
7
8#ifndef SRC_DECOMPOSITION_DISTPARMETISDISTRIBUTION_HPP_
9#define SRC_DECOMPOSITION_DISTPARMETISDISTRIBUTION_HPP_
10
11#include "SubdomainGraphNodes.hpp"
12#include "parmetis_dist_util.hpp"
13#include "Graph/dist_map_graph.hpp"
14#include "Graph/DistGraphFactory.hpp"
15
16template<unsigned int dim, typename T>
18{
21
24
27
30
33
36
39
42
44 size_t g_moved = 0;
45
47 size_t m_moved = 0;
48
50 bool verticesGotWeights = false;
51
61 static void * message_receive(size_t msg_i, size_t total_msg, size_t total_p, size_t i, size_t ri, void * ptr)
62 {
63 openfpm::vector < openfpm::vector < idx_t >> *v = static_cast<openfpm::vector<openfpm::vector<idx_t>> *>(ptr);
64
65 v->get(i).resize(msg_i / sizeof(idx_t));
66
67 return &(v->get(i).get(0));
68 }
69
70public:
71
77 v_cl(v_cl), parmetis_graph(v_cl, v_cl.getProcessingUnits()), vtxdist(v_cl.getProcessingUnits() + 1), partitions(v_cl.getProcessingUnits()), v_per_proc(v_cl.getProcessingUnits())
78
79 {
80 }
81
88 {
90 gr = grid;
91 domain = dom;
92
95 g = dist_g_factory.template construct<NO_EDGE, T, dim - 1, 0>(gr.getSize(), domain);
97
98 if (dim == 2)
99 for (size_t i = 0; i < g.getNVertex(); i++)
100 g.vertex(i).template get<nm_v_x>()[2] = 0;
101
102 }
103
108 {
109 return g;
110 }
111
116 {
119
121 parmetis_graph.template decompose<nm_v_proc_id>(g);
122
124 idx_t *partition = parmetis_graph.getPartition();
125
126 for (size_t i = 0, j = g.firstId(); i < g.getNVertex() && j <= g.lastId(); i++, j++)
127 {
128 if ((size_t)partition[i] != v_cl.getProcessUnitID())
129 g.q_move(g.nodeById(j), partition[i]);
130 }
131 g.redistribute();
132 }
133
140 void refine()
141 {
144
146 parmetis_graph.template refine<nm_v_proc_id>(g);
147
149 idx_t *partition = parmetis_graph.getPartition();
150
151 for (size_t i = 0, j = g.firstId(); i < g.getNVertex() && j <= g.lastId(); i++, j++)
152 {
153 if ((size_t)partition[i] != v_cl.getProcessUnitID())
154 g.q_move(g.nodeById(j), partition[i]);
155 }
156 g.redistribute();
157 }
158
164 {
165 long t_cost = getProcessorLoad();
166
167 long min, max, sum;
168 float unbalance;
169
170 min = t_cost;
171 max = t_cost;
172 sum = t_cost;
173
174 v_cl.min(min);
175 v_cl.max(max);
176 v_cl.sum(sum);
177 v_cl.execute();
178
179 unbalance = ((float) (max - min)) / (float) (sum / v_cl.getProcessingUnits());
180
181 return unbalance * 100;
182 }
183
190 void getSubSubDomainPosition(size_t id, T (&pos)[dim])
191 {
192#ifdef SE_CLASS1
193 if (id >= g.getNVertex())
194 std::cerr << __FILE__ << ":" << __LINE__ << " Position - Such vertex doesn't exist (id = " << id << ", " << "total size = " << g.getNVertex() << ")\n";
195#endif
196
197 pos[0] = g.vertex(id).template get<nm_v_x>()[0];
198 pos[1] = g.vertex(id).template get<nm_v_x>()[1];
199 if (dim == 3)
200 pos[2] = g.vertex(id).template get<nm_v_x>()[2];
201 }
202
209 inline void setComputationCost(size_t id, size_t weight)
210 {
211 verticesGotWeights = true;
212#ifdef SE_CLASS1
213 if (id >= g.getNVertex())
214 std::cerr << __FILE__ << ":" << __LINE__ << "Weight - Such vertex doesn't exist (id = " << id << ", " << "total size = " << g.getNVertex() << ")\n";
215#endif
216
217 // If the vertex is inside this processor update the value
218 g.vertex(id).template get<nm_v_computation>() = weight;
219
220 }
221
227 {
228 return verticesGotWeights;
229 }
230
238 size_t getVertexWeight(size_t id)
239 {
240#ifdef SE_CLASS1
241 if (id >= g.getNVertex())
242 std::cerr << __FILE__ << ":" << __LINE__ << "Such vertex doesn't exist (id = " << id << ", " << "total size = " << g.getTotNVertex() << ")\n";
243#endif
244
245 return g.vertex(id).template get<nm_v_computation>();
246 }
247
253 {
254 size_t load = 0;
255
256 for (size_t i = 0; i < g.getNVertex(); i++)
257 {
258 load += g.vertex(i).template get<nm_v_computation>();
259 }
260 return load;
261 }
262
269 {
270 return g_moved;
271 }
272
279 {
280 return m_moved;
281 }
282
288 void setMigrationCost(size_t id, size_t migration)
289 {
290#ifdef SE_CLASS1
291 if (id >= g.getNVertex())
292 std::cerr << __FILE__ << ":" << __LINE__ << "Migration - Such vertex doesn't exist (id = " << id << ", " << "total size = " << g.getNVertex() << ")\n";
293#endif
294
295 g.vertex(id).template get<nm_v_migration>() = migration;
296 }
297
304 void setCommunicationCost(size_t v_id, size_t e, size_t communication)
305 {
306 g.getChildEdge(v_id, e).template get<nm_e::communication>() = communication;
307 }
308
315 {
316 return g.getNVertex();
317 }
318
327 {
328 if (id >= g.getNVertex())
329 std::cerr << "Neighbors - Such vertex doesn't exist (id = " << id << ", " << "total size = " << g.getNVertex() << ")\n";
330
331 return g.getNChilds(id);
332 }
333
339 void write(const std::string & file)
340 {
341 VTKWriter<DistGraph_CSR<nm_v<dim>, nm_e>, DIST_GRAPH> gv2(g);
342 gv2.write(std::to_string(file + ".vtk"));
343 }
344
353 {
354 gr = dist.gr;
355 domain = dist.domain;
356 g = dist.g;
357 vtxdist = dist.vtxdist;
358 partitions = dist.partitions;
359 v_per_proc = dist.v_per_proc;
360 verticesGotWeights = dist.verticesGotWeights;
361
362 return *this;
363 }
364
373 {
374 gr = dist.gr;
375 domain = dist.domain;
376 g.swap(dist.g);
377 vtxdist.swap(dist.vtxdist);
378 partitions.swap(dist.partitions);
379 v_per_proc.swap(dist.v_per_proc);
380 verticesGotWeights = dist.verticesGotWeights;
381
382 return *this;
383 }
384}
385;
386
387#endif /* SRC_DECOMPOSITION_PARMETISDISTRIBUTION_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.
size_t getNVertex() const
Return the number of the vertices in this subgraph.
void swap(DistGraph_CSR< V, E > &g)
Swap the memory of g with this graph.
size_t getTotNVertex() const
Return the total number of the vertices.
void q_move(size_t i, size_t t)
Prepare to send vertex i from the local processor to the target processor.
size_t nodeById(size_t id) const
operator to access the vertex position index by id property
void redistribute()
Redistribute function that wraps different stages of the redistribution.
void getDecompositionVector(openfpm::vector< idx_t > &v)
Operator to access the decomposition vector.
size_t getNChilds(size_t c) const
Return the number of children of a vertex.
size_t firstId() const
size_t lastId() const
auto vertex(size_t id) -> decltype(v.get(id))
Function to access the vertexes.
auto getChildEdge(size_t v, size_t v_e) -> decltype(e.get(0))
Get the vertex edge.
void getSubSubDomainPosition(size_t id, T(&pos)[dim])
function that return the position of the vertex in the space
size_t getProcessorLoad()
Compute the processor load counting the total weights of its vertices.
static void * message_receive(size_t msg_i, size_t total_msg, size_t total_p, size_t i, size_t ri, void *ptr)
Callback of the sendrecv to set the size of the array received.
Box< dim, T > domain
rectangular domain to decompose
void write(const std::string &file)
Print current graph and save it to file.
void refine()
Refine current decomposition.
size_t getTotalMovedV()
return number of moved vertices in all iterations so far
bool verticesGotWeights
Flag to check if weights are used on vertices.
void decompose()
Create first decomposition, it divides the graph in slices and give each slice to a processor.
const DistParMetisDistribution< dim, T > & operator=(const DistParMetisDistribution< dim, T > &dist)
copy operator
bool weightsAreUsed()
Checks if weights are used on the vertices.
openfpm::vector< openfpm::vector< idx_t > > partitions
partitions
void createCartGraph(grid_sm< dim, void > &grid, Box< dim, T > dom)
Initialize the distribution graph.
float getUnbalance()
Compute the unbalance value.
const DistParMetisDistribution< dim, T > & operator=(DistParMetisDistribution< dim, T > &&dist)
copy operator
DistGraph_CSR< nm_v< dim >, nm_e > g
Processor sub-sub-domain graph.
void setMigrationCost(size_t id, size_t migration)
Set migration cost of the vertex id.
size_t getVertexWeight(size_t id)
function that get the weight of the vertex
void setComputationCost(size_t id, size_t weight)
Function that set the weight of the vertex.
openfpm::vector< idx_t > vtxdist
Init vtxdist needed for Parmetis.
size_t getMaxMovedV()
return number of moved vertices in all iterations so far
openfpm::vector< openfpm::vector< size_t > > v_per_proc
Init data structure to keep trace of new vertices distribution in processors (needed to update main g...
size_t getNSubSubDomainNeighbors(size_t id)
Returns total number of neighbors of the sub-sub-domain id.
size_t g_moved
Number of moved vertices in all iterations.
void setCommunicationCost(size_t v_id, size_t e, size_t communication)
Set communication cost of the edge id.
size_t getNSubSubDomains()
Returns total number of sub-sub-domains in the distribution graph.
grid_sm< dim, void > gr
Structure that store the cartesian grid information.
size_t m_moved
Max number of moved vertices in all iterations.
DistParmetis< DistGraph_CSR< nm_v< dim >, nm_e > > parmetis_graph
Convert the graph to parmetis format.
DistGraph_CSR< nm_v< dim >, nm_e > & getGraph()
Get the current graph (main)
Helper class to define Metis graph.
idx_t * getPartition()
Get graph partition vector.
void initSubGraph(Graph &sub_g)
Set the Sub-graph.
void reset(Graph &sub_g)
Reset graph and reconstruct it.
void execute()
Execute all the requests.
void sum(T &num)
Sum the numbers across all processors and get the result.
size_t getProcessUnitID()
Get the process unit id.
void min(T &num)
Get the minimum number across all processors (or reduction with insinity norm)
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
Declaration grid_sm.
Definition grid_sm.hpp:167
__device__ __host__ const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Definition grid_sm.hpp:760
Implementation of 1-D std::vector like structure.
sub-domain edge graph node
It model an expression expr1 + ... exprn.
Definition sum.hpp:93