8#ifndef SRC_DECOMPOSITION_METISDISTRIBUTION_HPP_
9#define SRC_DECOMPOSITION_METISDISTRIBUTION_HPP_
11#include "SubdomainGraphNodes.hpp"
12#include "metis_util.hpp"
14#define METIS_DISTRIBUTION_ERROR_OBJECT std::runtime_error("Metis runtime error");
27 static bool noPointers() {
return true;}
43template<
unsigned int dim,
typename T>
83 std::cerr <<
"Error " << __FILE__
":" << __LINE__ <<
" such sub-sub-domain doesn't exist (id = " <<
id <<
", " <<
"total size = " <<
gp.
getNVertex() <<
")\n";
84 ACTION_ON_ERROR(METIS_DISTRIBUTION_ERROR_OBJECT)
99 std::cerr <<
"Error " << __FILE__
":" << __LINE__ <<
" for the sub-sub-domain " <<
id <<
" such neighborhood doesn't exist (e = " << e <<
", " <<
"total size = " <<
gp.
getNChilds(
id) <<
")\n";
100 ACTION_ON_ERROR(METIS_DISTRIBUTION_ERROR_OBJECT)
107 static constexpr unsigned int computation = nm_v_computation;
118 check_new(
this,8,VECTOR_EVENT,1);
132 check_new(
this,8,VECTOR_EVENT,1);
146 check_new(
this,8,VECTOR_EVENT,1);
177 for (
size_t i = 0 ; i < dim ; i++)
178 bc[i] = NON_PERIODIC;
186 gp = g_factory_part.template construct<NO_EDGE, nm_v_id, T, dim - 1, 0>(
gr.
getSize(),
domain, bc);
193 gp.
vertex(i).template get<nm_v_x>()[2] = 0.0;
198 gp.
vertex(i).template get<nm_v_global_id>() = i;
258 recv_ass.get(i).w =
gp.template vertex_p<nm_v_proc_id>(i);
333 pos[0] =
gp.
vertex(
id).template get<nm_v_x>()[0];
334 pos[1] =
gp.
vertex(
id).template get<nm_v_x>()[1];
336 {pos[2] =
gp.
vertex(
id).template get<nm_v_x>()[2];}
352 return gp.
vertex(
id).template get<nm_v_computation>();
374 std::cerr << __FILE__ <<
":" << __LINE__ <<
" Error you are setting a sub-sub-domain the processor does not own" << std::endl;
378 size_t id = fnd->second;
397 gp.
vertex(
id).template get<nm_v_migration>() = cost;
416 gp.
getChildEdge(
id, e).template get<nm_e::communication>() = cost;
461 float load_avg = load_p;
476 return ((
float)load_p - load_avg) / load_avg;
548 {loads.get(
gp.template vertex_p<nm_v_proc_id>(i)) +=
gp.template vertex_p<nm_v_computation>(i);}
552 v_cl.
send(i,1234,&loads.get(i),
sizeof(
size_t));
555 v_cl.
recv(0,1234,&load,
sizeof(
size_t));
596 this->domain = mt.domain;
597 this->gp.
swap(mt.gp);
598 this->owner_cost_sub.swap(mt.owner_cost_sub);
599 this->owner_scs.swap(mt.owner_scs);
618 ret &= (this->gr == mt.
gr);
619 ret &= (this->domain == mt.
domain);
620 ret &= (this->gp == mt.
gp);
646 std::cerr << __FILE__ <<
":" << __LINE__ <<
"Such vertex doesn't exist (id = " <<
id <<
", " <<
"total size = " <<
gp.
getNVertex() <<
")\n";
652 std::cerr << __FILE__ <<
":" << __LINE__ <<
" Error you are setting a sub-sub-domain that the processor does not own" << std::endl;
656 size_t ids = fnd->second;
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.
auto getChildEdge(size_t v, size_t v_e) -> decltype(e.get(0))
Get the vertex edge.
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 Metis Library.
MetisDistribution & operator=(MetisDistribution &&mt)
operator=
size_t getSubSubDomainComputationCost(size_t id)
function that get the weight of the vertex
void setDistTol(double tol)
Set the tolerance for each partition.
void write(std::string out)
Write the distribution graph into file.
size_t getProcessorLoad()
Compute the processor load.
size_t getOwnerSubSubDomain(size_t id) const
Return the id of the set sub-sub-domain.
Box< dim, T > domain
rectangular domain to decompose
size_t getNSubSubDomains()
Returns total number of sub-sub-domains.
size_t get_ndec()
Get the decomposition counter.
std::unordered_map< size_t, size_t > owner_scs
unordered map that map global sub-sub-domain to owned_cost_sub id
size_t getComputationalCost(size_t id)
function that get the computational cost of the sub-sub-domain
void refine()
Refine current decomposition.
Graph_CSR< nm_v< dim >, nm_e > & getGraph()
Get the current graph (main)
~MetisDistribution()
Destructor.
openfpm::vector< met_sub_w > owner_cost_sub
list owned sub-sub-domains set for computation cost
MetisDistribution & operator=(const MetisDistribution &mt)
operator=
void createCartGraph(grid_sm< dim, void > &grid, Box< dim, T > dom)
create a Cartesian distribution graph
Graph_CSR< nm_v< dim >, nm_e > gp
Global sub-sub-domain graph.
void setMigrationCost(size_t id, size_t cost)
Set migration cost on a sub-sub domain.
openfpm::vector< met_sub_w > recv_ass
received assignment
void setCommunicationCost(size_t id, size_t e, size_t cost)
Set communication cost between neighborhood sub-sub-domains (weight on the edge)
void getSSDomainPos(size_t id, T(&pos)[dim])
Function that return the position (point P1) of the sub-sub domain box in the space.
size_t getNOwnerSubSubDomains() const
Return the total number of sub-sub-domains in the distribution graph.
bool testing
Flag that indicate if we are doing a test (In general it fix the seed)
Metis< Graph_CSR< nm_v< dim >, nm_e > > metis_graph
Metis decomposer utility.
void redecompose()
Redecompose current decomposition.
grid_sm< dim, void > gr
Structure that store the cartesian grid information.
void check_overflow(size_t id)
Check that the sub-sub-domain id exist.
void setComputationCost(size_t id, size_t cost)
Set computation cost on a sub-sub domain.
size_t getNSubSubDomainNeighbors(size_t id)
Returns total number of neighbors of one sub-sub-domain.
bool operator==(const MetisDistribution &mt)
operator==
MetisDistribution(const MetisDistribution &mt)
Copy constructor.
void check_overflowe(size_t id, size_t e)
Check that the sub-sub-domain id exist.
MetisDistribution(Vcluster<> &v_cl)
constructor
void onTest()
It set the Classs on test mode.
void decompose()
Distribute the sub-sub-domains.
MetisDistribution(MetisDistribution &&mt)
Copy constructor.
float getUnbalance()
Compute the unbalance of the processor compared to the optimal balance.
Helper class to define Metis graph.
size_t get_ndec()
Get the decomposition counter.
void onTest(bool testing)
It set Metis on test.
void inc_dec()
Increment the decomposition counter.
void setDistTol(real_t tol)
Distribution tolerance.
void initMetisGraph(int nc, bool useWeights)
Initialize the METIS graph.
void execute()
Execute all the requests.
void sum(T &num)
Sum the numbers across all processors and get the result.
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.
bool recv(size_t proc, size_t tag, void *v, size_t sz)
Recv data from a processor.
bool send(size_t proc, size_t tag, const void *mem, size_t sz)
Send data to a processor.
Implementation of VCluster class.
bool SGather(T &send, S &recv, size_t root)
Semantic Gather, gather the data from all processors into one node.
__device__ __host__ const size_t(& getSize() const)[N]
Return the size of the grid as an array.
Implementation of 1-D std::vector like structure.
sub-domain list and weight
size_t w
sub-domain weight / assignment (it depend in which context is used)
sub-domain edge graph node