Commit 23b7888c authored by Pietro Incardona's avatar Pietro Incardona

Adding safety on the ids

parent 1069d063
openfpm_data @ 2100d06c
Subproject commit 85dcf64440298004d2951277b2dbd31592b5d9b0
Subproject commit 2100d06c4f962d3f1c8244bf49a876193fbddff7
......@@ -5,11 +5,15 @@
* Author: Antonio Leo
*/
#ifndef SRC_DECOMPOSITION_PARMETISDISTRIBUTION_HPP_
#define SRC_DECOMPOSITION_PARMETISDISTRIBUTION_HPP_
#include "SubdomainGraphNodes.hpp"
#include "parmetis_util.hpp"
#include "Graph/dist_map_graph.hpp"
#ifndef SRC_DECOMPOSITION_PARMETISDISTRIBUTION_HPP_
#define SRC_DECOMPOSITION_PARMETISDISTRIBUTION_HPP_
#include "Graph/ids.hpp"
#define PARMETIS_DISTRIBUTION_ERROR 100002
......@@ -28,7 +32,6 @@
* \snippet Distribution_unit_tests.hpp refine with parmetis the decomposition
*
*/
template<unsigned int dim, typename T>
class ParMetisDistribution
{
......@@ -62,16 +65,16 @@ class ParMetisDistribution
//
// vtx dist is the unique global-id of the vertices
//
openfpm::vector<idx_t> vtxdist;
openfpm::vector<rid> vtxdist;
//! partitions
openfpm::vector<openfpm::vector<idx_t>> partitions;
//! Init data structure to keep trace of new vertices distribution in processors (needed to update main graph)
openfpm::vector<openfpm::vector<size_t>> v_per_proc;
openfpm::vector<openfpm::vector<gid>> v_per_proc;
//! Hashmap to access to the global position given the re-mapped one (needed for access the map)
std::unordered_map<size_t, size_t> m2g;
std::unordered_map<rid, gid> m2g;
//! Flag to check if weights are used on vertices
bool verticesGotWeights = false;
......@@ -81,31 +84,24 @@ class ParMetisDistribution
*/
void updateGraphs()
{
size_t Np = v_cl.getProcessingUnits();
//stats info
size_t moved = 0;
// Init n_vtxdist to gather informations about the new decomposition
openfpm::vector<idx_t> n_vtxdist(Np + 1);
openfpm::vector<rid> n_vtxdist(Np + 1);
for (size_t i = 0; i <= Np; i++)
n_vtxdist.get(i) = 0;
n_vtxdist.get(i).id = 0;
// Update the main graph with received data from processor i
for (size_t i = 0; i < Np; i++)
{
size_t ndata = partitions.get(i).size();
size_t k = 0;
// Update the main graph with the received informations
for (size_t k = 0, l = (size_t)vtxdist.get(i); k < ndata && l < (size_t)vtxdist.get(i + 1); k++, l++)
for (rid l = vtxdist.get(i); k < ndata && l < vtxdist.get(i + 1); k++, ++l)
{
// Create new n_vtxdist (just count processors vertices)
n_vtxdist.get(partitions.get(i).get(k) + 1)++;
// for statistics
if (vertexByMapId(l).template get<nm_v::proc_id>() != (size_t)partitions.get(i).get(k))
moved++;
++n_vtxdist.get(partitions.get(i).get(k) + 1);
// Update proc id in the vertex (using the old map)
vertexByMapId(l).template get<nm_v::proc_id>() = partitions.get(i).get(k);
......@@ -126,10 +122,11 @@ class ParMetisDistribution
// Renumber the main graph and re-create the map
for (size_t p = 0; p < (size_t)Np; p++)
{
for (size_t j = (size_t)vtxdist.get(p), i = 0; j < (size_t)vtxdist.get(p + 1); j++, i++)
size_t i = 0;
for (rid j = vtxdist.get(p); j < vtxdist.get(p + 1); ++j, i++)
{
setMapId(j, v_per_proc.get(p).get(i));
gp.vertex(v_per_proc.get(p).get(i)).template get<nm_v::id>() = j;
gp.vertex(v_per_proc.get(p).get(i).id).template get<nm_v::id>() = j.id;
}
}
}
......@@ -153,9 +150,9 @@ class ParMetisDistribution
* \param id re-mapped id of the vertex to access
*
*/
inline auto vertexByMapId(size_t id) -> decltype( gp.vertex(m2g.find(id)->second) )
inline auto vertexByMapId(rid id) -> decltype( gp.vertex(m2g.find(id)->second.id) )
{
return gp.vertex(m2g.find(id)->second);
return gp.vertex(m2g.find(id)->second.id);
}
/*! \brief operator to remap vertex to a new position
......@@ -164,7 +161,7 @@ class ParMetisDistribution
* \param g global position
*
*/
inline void setMapId(size_t n, size_t g)
inline void setMapId(rid n, gid g)
{
m2g[n] = g;
}
......@@ -175,7 +172,7 @@ class ParMetisDistribution
* \return global id
*
*/
size_t getVertexGlobalId(size_t n)
gid getVertexGlobalId(rid n)
{
return m2g.find(n)->second;
}
......@@ -187,10 +184,16 @@ class ParMetisDistribution
*/
void initLocalToGlobalMap()
{
gid g;
rid i;
i.id = 0;
m2g.clear();
for (size_t i = 0; i < gp.getNVertex(); i++)
for ( ; (size_t)i.id < gp.getNVertex(); ++i)
{
m2g.insert( { i, i });
g.id = i.id;
m2g.insert( { i, g });
}
}
......@@ -277,9 +280,9 @@ public:
for (size_t i = 0; i <= Np; i++)
{
if (i < mod_v)
vtxdist.get(i) = (div_v + 1) * (i);
vtxdist.get(i).id = (div_v + 1) * i;
else
vtxdist.get(i) = (div_v) * (i) + mod_v;
vtxdist.get(i).id = (div_v) * i + mod_v;
}
// Init to 0.0 axis z (to fix in graphFactory)
......@@ -318,7 +321,7 @@ public:
size_t Np = v_cl.getProcessingUnits();
// Number of local vertex
size_t nl_vertex = vtxdist.get(p_id+1) - vtxdist.get(p_id);
size_t nl_vertex = vtxdist.get(p_id+1).id - vtxdist.get(p_id).id;
parmetis_graph.initSubGraph(gp, vtxdist, m2g, verticesGotWeights);
......@@ -367,7 +370,7 @@ public:
size_t p_id = v_cl.getProcessUnitID();
// Number of local vertex
size_t nl_vertex = vtxdist.get(p_id+1) - vtxdist.get(p_id);
rid nl_vertex = vtxdist.get(p_id+1) - vtxdist.get(p_id);
// Reset parmetis graph and reconstruct it
parmetis_graph.reset(gp, vtxdist, m2g);
......@@ -378,8 +381,8 @@ public:
// Get result partition for this processor
idx_t * partition = parmetis_graph.getPartition();
partitions.get(p_id).resize(nl_vertex);
std::copy(partition, partition + nl_vertex, &partitions.get(p_id).get(0));
partitions.get(p_id).resize(nl_vertex.id);
std::copy(partition, partition + nl_vertex.id, &partitions.get(p_id).get(0));
// Reset data structure to keep trace of new vertices distribution in processors (needed to update main graph)
for (size_t i = 0; i < Np; ++i)
......@@ -397,7 +400,7 @@ public:
{
partitions.get(i).clear();
prc.add(i);
sz.add(nl_vertex * sizeof(idx_t));
sz.add(nl_vertex.id * sizeof(idx_t));
ptr.add(partitions.get(p_id).getPointer());
}
}
......@@ -517,9 +520,9 @@ public:
size_t p_id = v_cl.getProcessUnitID();
for (size_t i = (size_t)vtxdist.get(p_id); i < (size_t)vtxdist.get(p_id+1) ; i++)
for (rid i = vtxdist.get(p_id); i < vtxdist.get(p_id+1) ; ++i)
{
load += gp.vertex(m2g.find(i)->second).template get<nm_v::computation>();
load += gp.vertex(m2g.find(i)->second.id).template get<nm_v::computation>();
}
//std::cout << v_cl.getProcessUnitID() << " weight " << load << " size " << sub_g.getNVertex() << "\n";
return load;
......
......@@ -12,6 +12,7 @@
#include "parmetis.h"
#include "VTKWriter/VTKWriter.hpp"
#include "VCluster.hpp"
#include "Graph/ids.hpp"
/*! \brief Metis graph structure
*
......@@ -115,10 +116,10 @@ class Parmetis
size_t nc = 0;
// first re-mapped id
size_t first;
rid first;
// last re-mapped id
size_t last;
rid last;
// number of vertices that the processor has
size_t nvertex;
......@@ -128,7 +129,7 @@ class Parmetis
* \param g Global graph
*
*/
void constructAdjList(Graph &g, const std::unordered_map<size_t,size_t> & m2g)
void constructAdjList(Graph &g, const std::unordered_map<rid,gid> & m2g)
{
// init basic graph informations and part vector
// Put the total communication size to NULL
......@@ -137,10 +138,11 @@ class Parmetis
Mg.part = new idx_t[nvertex];
size_t nedge = 0;
for (size_t i = 0, j = first; i < nvertex ; i++, j++)
size_t i = 0;
for (rid j = first; i < nvertex ; i++, ++j)
{
Mg.part[i] = p_id;
nedge += g.getNChilds(m2g.find(j)->second);
nedge += g.getNChilds(m2g.find(j)->second.id);
}
// create xadj, adjlist, vwgt, adjwgt and vsize
......@@ -156,30 +158,32 @@ class Parmetis
// actual position
size_t id = 0;
size_t j = 0;
// for each vertex calculate the position of the starting point in the adjacency list
for (size_t i = first , j = 0 ; i <= last; i++, j++)
for (rid i = first ; i <= last; ++i, j++)
{
size_t idx = m2g.find(i)->second;
gid idx = m2g.find(i)->second;
// Add weight to vertex and migration cost
Mg.vwgt[j] = g.vertex(idx).template get<nm_v::computation>();
Mg.vsize[j] = g.vertex(idx).template get<nm_v::migration>();;
Mg.vwgt[j] = g.vertex(idx.id).template get<nm_v::computation>();
Mg.vsize[j] = g.vertex(idx.id).template get<nm_v::migration>();;
// Calculate the starting point in the adjacency list
Mg.xadj[id] = prev;
// Create the adjacency list and the weights for edges
for (size_t s = 0; s < g.getNChilds(idx); s++)
for (size_t s = 0; s < g.getNChilds(idx.id); s++)
{
size_t child = g.getChild(idx, s);
size_t child = g.getChild(idx.id, s);
Mg.adjncy[prev + s] = g.vertex(child).template get<nm_v::id>();
Mg.adjwgt[prev + s] = g.getChildEdge(idx,s).template get<nm_e::communication>();
Mg.adjwgt[prev + s] = g.getChildEdge(idx.id,s).template get<nm_e::communication>();
}
// update the position for the next vertex
prev += g.getNChilds(idx);
prev += g.getNChilds(idx.id);
id++;
}
......@@ -290,17 +294,17 @@ public:
* \param g Global graph to set
* \param w true if vertices have weights
*/
void initSubGraph(Graph & g, const openfpm::vector<idx_t> & vtxdist, const std::unordered_map<size_t,size_t> & m2g, bool w)
void initSubGraph(Graph & g, const openfpm::vector<rid> & vtxdist, const std::unordered_map<rid,gid> & m2g, bool w)
{
p_id = v_cl.getProcessUnitID();
first = vtxdist.get(p_id);
last = vtxdist.get(p_id+1)-1;
nvertex = last - first + 1;
nvertex = last.id - first.id + 1;
// Get the number of vertex
Mg.nvtxs = new idx_t[1];
Mg.nvtxs[0] = last - first + 1;
Mg.nvtxs[0] = nvertex;
// Set the number of constrains
Mg.ncon = new idx_t[1];
......@@ -364,11 +368,9 @@ public:
*
* \tparam i which property store the decomposition
*
*
*
*/
template<unsigned int i>
void decompose(openfpm::vector<idx_t> & vtxdist)
void decompose(const openfpm::vector<rid> & vtxdist)
{
// Decompose
......@@ -384,7 +386,7 @@ public:
*/
template<unsigned int i>
void refine(openfpm::vector<idx_t> & vtxdist)
void refine(openfpm::vector<rid> & vtxdist)
{
// Refine
......@@ -406,11 +408,11 @@ public:
* \param Global graph
*
*/
void reset(Graph & g,const openfpm::vector<idx_t> & vtxdist, const std::unordered_map<size_t,size_t> & m2g)
void reset(Graph & g,const openfpm::vector<rid> & vtxdist, const std::unordered_map<rid,gid> & m2g)
{
first = vtxdist.get(p_id);
last = vtxdist.get(p_id+1)-1;
nvertex = last - first + 1;
nvertex = last.id - first.id + 1;
// Deallocate the graph structures
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment