Updating to new metis interface. Need to address prepareMetisGraph since its causing core dump on second edgeseparator test
parent
05e42ba452
commit
0aa32a748f
|
@ -19,6 +19,7 @@
|
|||
|
||||
extern "C" {
|
||||
#include <metis.h>
|
||||
#include "metislib.h"
|
||||
}
|
||||
|
||||
#include "FindSeparator.h"
|
||||
|
@ -41,7 +42,6 @@ namespace gtsam { namespace partition {
|
|||
|
||||
// control parameters
|
||||
idx_t vwgt[n]; // the weights of the vertices
|
||||
//int options[8]; options [0] = 0 ;
|
||||
idx_t options[METIS_NOPTIONS];
|
||||
METIS_SetDefaultOptions(options); // use defaults
|
||||
idx_t sepsize; // the size of the separator, output
|
||||
|
@ -60,10 +60,7 @@ namespace gtsam { namespace partition {
|
|||
//TOTALTmr.start()
|
||||
}
|
||||
|
||||
// call metis parition routine OLD!!!!
|
||||
/*METIS_NodeComputeSeparator(&n, xadj.get(), adjncy.get(), vwgt, adjwgt.get(),
|
||||
options, &sepsize, part_.get());*/
|
||||
// new
|
||||
// call metis parition routine
|
||||
METIS_ComputeVertexSeparator(&n, xadj.get(), adjncy.get(),
|
||||
vwgt, options, &sepsize, part_.get());
|
||||
|
||||
|
@ -78,103 +75,90 @@ namespace gtsam { namespace partition {
|
|||
return make_pair(sepsize, part_);
|
||||
}
|
||||
|
||||
/* ************************************************************************* *
|
||||
void modefied_EdgeComputeSeparator(int *nvtxs, idx_t *xadj, idx_t *adjncy, idx_t *vwgt,
|
||||
idx_t *adjwgt, int *options, int *edgecut, idx_t *part)
|
||||
/* ************************************************************************* */
|
||||
void modefied_EdgeComputeSeparator(idx_t *nvtxs, idx_t *xadj, idx_t *adjncy, idx_t *vwgt,
|
||||
idx_t *adjwgt, idx_t *options, idx_t *edgecut, idx_t *part)
|
||||
{
|
||||
int i, j, tvwgt, tpwgts[2];
|
||||
GraphType graph;
|
||||
CtrlType ctrl;
|
||||
idx_t i, j, ncon;
|
||||
graph_t *graph;
|
||||
real_t *tpwgts2;
|
||||
ctrl_t *ctrl;
|
||||
ctrl = SetupCtrl(METIS_OP_OMETIS, options, 1, 3, NULL, NULL);
|
||||
ctrl->iptype = METIS_IPTYPE_GROW;
|
||||
//if () == NULL)
|
||||
// return METIS_ERROR_INPUT;
|
||||
|
||||
SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, 3);
|
||||
tvwgt = idxsum(*nvtxs, graph.vwgt);
|
||||
InitRandom(ctrl->seed);
|
||||
|
||||
if (options[0] == 0) { // Use the default parameters
|
||||
ctrl.CType = ONMETIS_CTYPE;
|
||||
ctrl.IType = ONMETIS_ITYPE;
|
||||
ctrl.RType = ONMETIS_RTYPE;
|
||||
ctrl.dbglvl = ONMETIS_DBGLVL;
|
||||
}
|
||||
else {
|
||||
ctrl.CType = options[OPTION_CTYPE];
|
||||
ctrl.IType = options[OPTION_ITYPE];
|
||||
ctrl.RType = options[OPTION_RTYPE];
|
||||
ctrl.dbglvl = options[OPTION_DBGLVL];
|
||||
}
|
||||
graph = SetupGraph(ctrl, *nvtxs, 1, xadj, adjncy, vwgt, NULL, NULL);
|
||||
|
||||
ctrl.oflags = 0;
|
||||
ctrl.pfactor = 0;
|
||||
ctrl.nseps = 1;
|
||||
ctrl.optype = OP_OEMETIS;
|
||||
ctrl.CoarsenTo = amin(100, *nvtxs-1);
|
||||
ctrl.maxvwgt = 1.5*tvwgt/ctrl.CoarsenTo;
|
||||
AllocateWorkSpace(ctrl, graph);
|
||||
|
||||
InitRandom(options[7]);
|
||||
ncon = graph->ncon;
|
||||
ctrl->ncuts = 1;
|
||||
|
||||
/* determine the weights of the two partitions as a function of the weight of the
|
||||
target partition weights */
|
||||
|
||||
AllocateWorkSpace(&ctrl, &graph, 2);
|
||||
tpwgts2 = rwspacemalloc(ctrl, 2*ncon);
|
||||
for (i=0; i<ncon; i++) {
|
||||
tpwgts2[i] = rsum((2>>1), ctrl->tpwgts+i, ncon);
|
||||
tpwgts2[ncon+i] = 1.0 - tpwgts2[i];
|
||||
}
|
||||
/* perform the bisection */
|
||||
*edgecut = MultilevelBisect(ctrl, graph, tpwgts2);
|
||||
|
||||
//============================================================
|
||||
// Perform the bisection
|
||||
//============================================================
|
||||
tpwgts[0] = tvwgt/2;
|
||||
tpwgts[1] = tvwgt-tpwgts[0];
|
||||
|
||||
MlevelEdgeBisection(&ctrl, &graph, tpwgts, 1.05);
|
||||
// ConstructMinCoverSeparator(&ctrl, &graph, 1.05);
|
||||
*edgecut = graph.mincut;
|
||||
// ConstructMinCoverSeparator(&ctrl, &graph, 1.05);
|
||||
// *edgecut = graph->mincut;
|
||||
// *sepsize = graph.pwgts[2];
|
||||
idxcopy(*nvtxs, graph.where, part);
|
||||
|
||||
GKfree((void**)&graph.gdata, &graph.rdata, &graph.label, LTERM);
|
||||
|
||||
|
||||
FreeWorkSpace(&ctrl, &graph);
|
||||
icopy(*nvtxs, graph->where, part);
|
||||
cout << "Finished bisection:" << *edgecut << endl;
|
||||
FreeGraph(&graph);
|
||||
|
||||
FreeCtrl(&ctrl);
|
||||
}
|
||||
|
||||
/* ************************************************************************* */
|
||||
/**
|
||||
* Return the number of edge cuts and the partiion indices {part}
|
||||
* Return the number of edge cuts and the partition indices {part}
|
||||
* Part [j] is 0 or 1, depending on
|
||||
* whether node j is in the left part of the graph or the right part respectively
|
||||
*
|
||||
pair<int, sharedInts> edgeMetis(int n, const sharedInts& xadj, const sharedInts& adjncy, const sharedInts& adjwgt, bool verbose) {
|
||||
*/
|
||||
pair<int, sharedInts> edgeMetis(idx_t n, const sharedInts& xadj, const sharedInts& adjncy,
|
||||
const sharedInts& adjwgt, bool verbose) {
|
||||
|
||||
// control parameters
|
||||
idx_t vwgt[n]; // the weights of the vertices
|
||||
int options[10]; options [0] = 1; options [1] = 3; options [2] = 1; options [3] = 1; options [4] = 0; // use defaults
|
||||
int edgecut; // the number of edge cuts, output
|
||||
sharedInts part_(new int[n]); // the partition of each vertex, output
|
||||
idx_t options[METIS_NOPTIONS];
|
||||
METIS_SetDefaultOptions(options); // use defaults
|
||||
idx_t edgecut; // the number of edge cuts, output
|
||||
sharedInts part_(new idx_t[n]); // the partition of each vertex, output
|
||||
|
||||
// set uniform weights on the vertices
|
||||
std::fill(vwgt, vwgt+n, 1);
|
||||
|
||||
TODO: Fix later
|
||||
boost::timer TOTALTmr;
|
||||
//TODO: Fix later
|
||||
//boost::timer TOTALTmr;
|
||||
if (verbose) {
|
||||
printf("**********************************************************************\n");
|
||||
printf("Graph Information ---------------------------------------------------\n");
|
||||
printf(" #Vertices: %d, #Edges: %u\n", n, *(xadj.get()+n) / 2);
|
||||
printf("\nND Partitioning... -------------------------------------------\n");
|
||||
cleartimer(TOTALTmr);
|
||||
starttimer(TOTALTmr);
|
||||
//cleartimer(TOTALTmr);
|
||||
//starttimer(TOTALTmr);
|
||||
}
|
||||
|
||||
// call metis parition routine
|
||||
int wgtflag = 1; // only edge weights
|
||||
int numflag = 0; // c style numbering starting from 0
|
||||
int nparts = 2; // partition the graph to 2 submaps
|
||||
// METIS_PartGraphRecursive(&n, xadj.get(), adjncy.get(), NULL, adjwgt.get(), &wgtflag,
|
||||
// &numflag, &nparts, options, &edgecut, part_.get());
|
||||
|
||||
//int wgtflag = 1; // only edge weights
|
||||
//int numflag = 0; // c style numbering starting from 0
|
||||
//int nparts = 2; // partition the graph to 2 submaps
|
||||
modefied_EdgeComputeSeparator(&n, xadj.get(), adjncy.get(), vwgt, adjwgt.get(),
|
||||
options, &edgecut, part_.get());
|
||||
|
||||
|
||||
if (verbose) {
|
||||
stoptimer(TOTALTmr);
|
||||
//stoptimer(TOTALTmr);
|
||||
printf("\nTiming Information --------------------------------------------------\n");
|
||||
printf(" Total: \t\t %7.3f\n", gettimer(TOTALTmr));
|
||||
//printf(" Total: \t\t %7.3f\n", gettimer(TOTALTmr));
|
||||
printf(" Edge cuts: \t\t %d\n", edgecut);
|
||||
printf("**********************************************************************\n");
|
||||
}
|
||||
|
@ -204,17 +188,21 @@ namespace gtsam { namespace partition {
|
|||
// prepare for {adjancyMap}, a pair of neighbor indices and the correponding edge weights
|
||||
int numNodes = keys.size();
|
||||
int numEdges = 0;
|
||||
vector<NeighborsInfo> adjancyMap; // TODO: set is slow, but have to use it to remove duplicated edges
|
||||
vector<NeighborsInfo> adjancyMap;
|
||||
adjancyMap.resize(numNodes);
|
||||
cout << "Number of nodes: " << adjancyMap.size() << endl;
|
||||
int index1, index2;
|
||||
|
||||
BOOST_FOREACH(const typename GenericGraph::value_type& factor, graph){
|
||||
index1 = dictionary[factor->key1.index];
|
||||
index2 = dictionary[factor->key2.index];
|
||||
cout << "index1: " << index1 << endl;
|
||||
cout << "index2: " << index2 << endl;
|
||||
// if both nodes are in the current graph, i.e. not a joint factor between frontal and separator
|
||||
if (index1 >= 0 && index2 >= 0) {
|
||||
pair<Neighbors, Weights>& adjancyMap1 = adjancyMap[index1];
|
||||
pair<Neighbors, Weights>& adjancyMap2 = adjancyMap[index2];
|
||||
cout << adjancyMap1.first.size() << endl;
|
||||
adjancyMap1.first .push_back(index2);
|
||||
adjancyMap1.second.push_back(factor->weight);
|
||||
adjancyMap2.first .push_back(index1);
|
||||
|
@ -297,9 +285,10 @@ namespace gtsam { namespace partition {
|
|||
return boost::make_optional<MetisResult >(result);
|
||||
}
|
||||
|
||||
/* *************************************************************************
|
||||
/* *************************************************************************/
|
||||
template<class GenericGraph>
|
||||
boost::optional<MetisResult> edgePartitionByMetis(const GenericGraph& graph, const vector<size_t>& keys, WorkSpace& workspace, bool verbose) {
|
||||
boost::optional<MetisResult> edgePartitionByMetis(const GenericGraph& graph,
|
||||
const vector<size_t>& keys, WorkSpace& workspace, bool verbose) {
|
||||
|
||||
// a small hack for handling the camera1-camera2 case used in the unit tests
|
||||
if (graph.size() == 1 && keys.size() == 2) {
|
||||
|
@ -338,7 +327,8 @@ namespace gtsam { namespace partition {
|
|||
}
|
||||
|
||||
if (verbose) {
|
||||
cout << "the size of two submaps in the reduced graph: " << result.A.size() << " " << result.B.size() << endl;
|
||||
cout << "the size of two submaps in the reduced graph: " << result.A.size()
|
||||
<< " " << result.B.size() << endl;
|
||||
int edgeCut = 0;
|
||||
|
||||
BOOST_FOREACH(const typename GenericGraph::value_type& factor, graph){
|
||||
|
|
|
@ -71,7 +71,7 @@ TEST ( Partition, separatorPartitionByMetis2 )
|
|||
CHECK(C_expected == actual->C);
|
||||
}
|
||||
|
||||
/* *************************************************************************
|
||||
/* *************************************************************************/
|
||||
// x0 - x2 - x3 - x5
|
||||
TEST ( Partition, edgePartitionByMetis )
|
||||
{
|
||||
|
@ -83,24 +83,25 @@ TEST ( Partition, edgePartitionByMetis )
|
|||
|
||||
WorkSpace workspace(6);
|
||||
boost::optional<MetisResult> actual = edgePartitionByMetis<GenericGraph3D>(graph, keys,
|
||||
workspace, false);
|
||||
workspace, true);
|
||||
|
||||
CHECK(actual.is_initialized());
|
||||
vector<size_t> A_expected; A_expected += 0, 2; // frontal
|
||||
vector<size_t> B_expected; B_expected += 3, 5; // frontal
|
||||
vector<size_t> C_expected; // separator
|
||||
// BOOST_FOREACH(const size_t a, actual->A)
|
||||
// cout << a << " ";
|
||||
// cout << endl;
|
||||
// BOOST_FOREACH(const size_t b, actual->B)
|
||||
// cout << b << " ";
|
||||
// cout << endl;
|
||||
BOOST_FOREACH(const size_t a, actual->A)
|
||||
cout << a << " ";
|
||||
cout << endl;
|
||||
BOOST_FOREACH(const size_t b, actual->B)
|
||||
cout << b << " ";
|
||||
cout << endl;
|
||||
|
||||
CHECK(A_expected == actual->A || A_expected == actual->B);
|
||||
CHECK(B_expected == actual->B || B_expected == actual->A);
|
||||
CHECK(C_expected == actual->C);
|
||||
}
|
||||
|
||||
|
||||
/* *************************************************************************/
|
||||
// x0 - x2 - x3 - x5 - x6
|
||||
TEST ( Partition, edgePartitionByMetis2 )
|
||||
{
|
||||
|
@ -111,7 +112,7 @@ TEST ( Partition, edgePartitionByMetis2 )
|
|||
graph.push_back(boost::make_shared<GenericFactor3D>(5, 6, 3, NODE_POSE_3D, NODE_POSE_3D, 1));
|
||||
std::vector<size_t> keys; keys += 0, 2, 3, 5, 6;
|
||||
|
||||
WorkSpace workspace(6);
|
||||
WorkSpace workspace(5);
|
||||
boost::optional<MetisResult> actual = edgePartitionByMetis<GenericGraph3D>(graph, keys,
|
||||
workspace, false);
|
||||
CHECK(actual.is_initialized());
|
||||
|
|
Loading…
Reference in New Issue