9#ifndef SRC_DECOMPOSITION_PARMETISDISTRIBUTION_HPP_
10#define SRC_DECOMPOSITION_PARMETISDISTRIBUTION_HPP_
13#include "SubdomainGraphNodes.hpp"
14#include "parmetis_util.hpp"
15#include "Graph/ids.hpp"
16#include "Graph/CartesianGraphFactory.hpp"
18#define PARMETIS_DISTRIBUTION_ERROR 100002
35template<
unsigned int dim,
typename T>
83 std::unordered_map<rid, gid>
m2g;
99 for (
size_t i = 0; i <= Np; i++)
100 n_vtxdist.get(i).id = 0;
103 for (
size_t i = 0; i < Np; i++)
112 ++n_vtxdist.get(
partitions.get(i).get(k) + 1);
115 auto v_id =
m2g.find(l)->second.id;
118 gp.template vertex_p<nm_v_proc_id>(v_id) =
partitions.get(i).get(k);
129 for (
size_t i = 2; i <= Np; i++)
130 n_vtxdist.get(i) += n_vtxdist.get(i - 1);
133 for (
size_t i = 0; i <= Np; i++)
134 vtxdist.get(i) = n_vtxdist.get(i);
141 size_t pid =
gp.template vertex_p<nm_v_proc_id>(i);
146 gp.template vertex_p<nm_v_id>(i) = j.
id;
184 return m2g.find(n)->second;
203 m2g.insert( { i, g });
216 static void *
message_receive(
size_t msg_i,
size_t total_msg,
size_t total_p,
size_t i,
size_t ri,
size_t tag,
void * ptr)
220 v->get(i).resize(msg_i /
sizeof(idx_t));
222 return &(v->get(i).get(0));
246 {std::copy(partition, partition + nl_vertex, &
partitions.get(p_id).get(0));}
249 for (
size_t i = 0; i < Np; ++i)
260 for (
size_t i = 0; i < Np; i++)
266 sz.add(nl_vertex *
sizeof(idx_t));
323 for (
size_t i = 0 ; i < dim ; i++)
324 bc[i] = NON_PERIODIC;
332 gp = g_factory_part.template construct<NO_EDGE, nm_v_id, T, dim - 1, 0>(
gr.
getSize(),
domain, bc);
341 size_t mod_v =
gr.
size() % Np;
342 size_t div_v =
gr.
size() / Np;
344 for (
size_t i = 0; i <= Np; i++)
347 vtxdist.get(i).id = (div_v + 1) * i;
349 vtxdist.get(i).id = (div_v) * i + mod_v;
357 gp.
vertex(i).template get<nm_v_x>()[2] = 0.0;
362 gp.
vertex(i).template get<nm_v_global_id>() = i;
452 return unbalance * 100;
465 std::cerr << __FILE__ <<
":" << __LINE__ <<
"Such vertex doesn't exist (id = " <<
id <<
", " <<
"total size = " <<
gp.
getNVertex() <<
")\n";
469 pos[0] =
gp.
vertex(
id).template get<nm_v_x>()[0];
470 pos[1] =
gp.
vertex(
id).template get<nm_v_x>()[1];
472 pos[2] =
gp.
vertex(
id).template get<nm_v_x>()[2];
488 {std::cerr << __FILE__ <<
":" << __LINE__ <<
"Such vertex doesn't exist (id = " <<
id <<
", " <<
"total size = " <<
gp.
getNVertex() <<
")\n";}
492 gp.
vertex(
id).template get<nm_v_computation>() = weight;
513 std::cerr << __FILE__ <<
":" << __LINE__ <<
"Such vertex doesn't exist (id = " <<
id <<
", " <<
"total size = " <<
gp.
getNVertex() <<
")\n";
516 return gp.
vertex(
id).template get<nm_v_computation>();
532 load +=
gp.
vertex(
m2g.find(i)->second.id).
template get<nm_v_computation>();
547 std::cerr << __FILE__ <<
":" << __LINE__ <<
"Such vertex doesn't exist (id = " <<
id <<
", " <<
"total size = " <<
gp.
getNVertex() <<
")\n";
550 gp.
vertex(
id).template get<nm_v_migration>() = migration;
563 size_t e_id = v_id + e;
566 std::cerr <<
"Such edge doesn't exist (id = " << e_id <<
", " <<
"total size = " <<
gp.
getNEdge() <<
")\n";
569 gp.
getChildEdge(v_id, e).template get<nm_e::communication>() = communication;
615 std::cerr << __FILE__ <<
":" << __LINE__ <<
"Such vertex doesn't exist (id = " <<
id <<
", " <<
"total size = " <<
gp.
getNVertex() <<
")\n";
642 void write(
const std::string & file)
690 for (
size_t i = 0 ; i < dim ; i++)
This class represent an N-dimensional box.
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 getNEdge() const
Return the number of edges.
auto getChildEdge(size_t v, size_t v_e) -> decltype(e.get(0))
Get the vertex edge.
void destroy()
operator to clear the whole graph
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.
void redecompose()
Redecompose current decomposition.
void refine()
Refine current decomposition.
ParMetisDistribution(ParMetisDistribution< dim, T > &&pm)
gid getVertexGlobalId(rid n)
Get the global id of the vertex given the re-mapped one.
grid_sm< dim, void > gr
Structure that store the cartesian grid information.
openfpm::vector< rid > vtxdist
Init vtxdist needed for Parmetis.
ParMetisDistribution(const ParMetisDistribution< dim, T > &pm)
Graph_CSR< nm_v< dim >, nm_e > & getGraph()
Get the current graph (main)
void postDecomposition()
It update the full decomposition.
Parmetis< Graph_CSR< nm_v< dim >, nm_e > > parmetis_graph
Convert the graph to parmetis format.
size_t getOwnerSubSubDomain(size_t id) const
Return the global id of the owned sub-sub-domain.
void setDistTol(double tol)
Set the tolerance for each partition.
std::unordered_map< rid, gid > m2g
Hashmap to access to the global position given the re-mapped one (needed for access the map)
float getUnbalance()
Compute the unbalance of the processor compared to the optimal balance.
void setMigrationCost(size_t id, size_t migration)
Set migration cost of the vertex id.
openfpm::vector< openfpm::vector< idx_t > > partitions
partitions
void destroy_internal_graph()
In case we do not do Dynamic load balancing this this data-structure it is safe to eliminate the full...
Graph_CSR< nm_v< dim >, nm_e > gp
Global sub-sub-domain graph.
void updateGraphs()
Update main graph ad subgraph with the received data of the partitions from the other processors.
void initLocalToGlobalMap()
operator to init ids vector
static void * message_receive(size_t msg_i, size_t total_msg, size_t total_p, size_t i, size_t ri, size_t tag, void *ptr)
Callback of the sendrecv to set the size of the array received.
Box< dim, T > domain
rectangular domain to decompose
bool is_distributed
Is distributed.
openfpm::vector< openfpm::vector< gid > > v_per_proc
Init data structure to keep trace of new vertices distribution in processors (needed to update main g...
void write(const std::string &file)
Print the current distribution and save it to VTK file.
size_t getProcessorLoad()
Compute the processor load counting the total weights of its vertices.
void decompose()
Create the decomposition.
void setCommunicationCost(size_t v_id, size_t e, size_t communication)
Set communication cost of the edge id.
size_t get_ndec()
Get the decomposition counter.
bool weightsAreUsed()
Checks if weights are used on the vertices.
size_t getNOwnerSubSubDomains() const
Return the total number of sub-sub-domains this processor own.
size_t getNSubSubDomains() const
Returns total number of sub-sub-domains in the distribution graph.
auto vertexByMapId(rid id) -> decltype(gp.vertex(m2g.find(id) ->second.id))
operator to access the vertex by mapped position
void setComputationCost(size_t id, size_t weight)
Function that set the weight of the vertex.
size_t getNSubSubDomainNeighbors(size_t id)
Returns total number of neighbors of the sub-sub-domain id.
void getSubSubDomainPos(size_t j, Point< dim, T > &p)
return the the position of the sub-sub-domain
void setMapId(rid n, gid g)
operator to remap vertex to a new position
ParMetisDistribution(Vcluster<> &v_cl)
void getSubSubDomainPosition(size_t id, T(&pos)[dim])
function that return the position of the vertex in the space
size_t getSubSubDomainComputationCost(size_t id)
function that get the weight of the vertex
openfpm::vector< size_t > sub_sub_owner
Id of the sub-sub-domain where we set the costs.
void createCartGraph(grid_sm< dim, void > &grid, Box< dim, T > &dom)
Create the Cartesian graph.
bool verticesGotWeights
Flag to check if weights are used on vertices.
Helper class to define Metis graph.
size_t get_ndec()
Get the decomposition counter.
void redecompose(openfpm::vector< rid > &vtxdist)
Redecompose the graph.
void reset(Graph &g, const openfpm::vector< rid > &vtxdist, const std::unordered_map< rid, gid > &m2g, bool vgw)
Reset graph and reconstruct it.
idx_t * getPartition()
Get graph partition vector.
void setDistTol(real_t tol)
Distribution tolerance.
void refine(openfpm::vector< rid > &vtxdist)
Refine the graph.
void initSubGraph(Graph &g, const openfpm::vector< rid > &vtxdist, const std::unordered_map< rid, gid > &m2g, bool w)
Set the Sub-graph.
void decompose(const openfpm::vector< rid > &vtxdist)
Decompose the graph.
This class implement the point shape in an N-dimensional space.
__device__ __host__ const T & get(unsigned int i) const
Get coordinate.
void execute()
Execute all the requests.
void sum(T &num)
Sum the numbers across all processors and get the result.
void sendrecvMultipleMessagesNBX(openfpm::vector< size_t > &prc, openfpm::vector< T > &data, openfpm::vector< size_t > &prc_recv, openfpm::vector< size_t > &recv_sz, void *(*msg_alloc)(size_t, size_t, size_t, size_t, size_t, size_t, void *), void *ptr_arg, long int opt=NONE)
Send and receive multiple messages.
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.
__device__ __host__ const size_t(& getSize() const)[N]
Return the size of the grid as an array.
__device__ __host__ size_t size() const
Return the size of the grid.
Implementation of 1-D std::vector like structure.
sub-domain edge graph node
It model an expression expr1 + ... exprn.