Test Separator unit test passes. Partially

release/4.3a0
Andrew Melim 2014-02-21 11:21:08 -05:00
parent 1ff9309533
commit 05e42ba452
2 changed files with 53 additions and 28 deletions

View File

@ -36,26 +36,29 @@ namespace gtsam { namespace partition {
* whether node j is in the left part of the graph, the right part, or the
* separator, respectively
*/
pair<int, sharedInts> separatorMetis(int n, const sharedInts& xadj, const sharedInts& adjncy, const sharedInts& adjwgt, bool verbose) {
pair<int, sharedInts> separatorMetis(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[8]; options [0] = 0 ; // use defaults
int sepsize; // the size of the separator, output
sharedInts part_(new int[n]); // the partition of each vertex, output
//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
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 at later time
/*boost::timer::cpu_timer TOTALTmr;
//boost::timer::cpu_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");
TOTALTmr.start()
}*/
//TOTALTmr.start()
}
// call metis parition routine OLD!!!!
/*METIS_NodeComputeSeparator(&n, xadj.get(), adjncy.get(), vwgt, adjwgt.get(),
@ -64,13 +67,13 @@ namespace gtsam { namespace partition {
METIS_ComputeVertexSeparator(&n, xadj.get(), adjncy.get(),
vwgt, options, &sepsize, part_.get());
/*if (verbose) {
boost::cpu_times const elapsed_times(timer.elapsed());
printf("\nTiming Information --------------------------------------------------\n");
printf(" Total: \t\t %7.3f\n", elapsed_times);
if (verbose) {
//boost::cpu_times const elapsed_times(timer.elapsed());
//printf("\nTiming Information --------------------------------------------------\n");
//printf(" Total: \t\t %7.3f\n", elapsed_times);
printf(" Sep size: \t\t %d\n", sepsize);
printf("**********************************************************************\n");
}*/
}
return make_pair(sepsize, part_);
}
@ -204,10 +207,12 @@ namespace gtsam { namespace partition {
vector<NeighborsInfo> adjancyMap; // TODO: set is slow, but have to use it to remove duplicated edges
adjancyMap.resize(numNodes);
int index1, index2;
BOOST_FOREACH(const typename GenericGraph::value_type& factor, graph){
index1 = dictionary[factor->key1.index];
index2 = dictionary[factor->key2.index];
if (index1 >= 0 && index2 >= 0) { // if both nodes are in the current graph, i.e. not a joint factor between frontal and separator
// 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];
adjancyMap1.first .push_back(index2);
@ -240,11 +245,15 @@ namespace gtsam { namespace partition {
/* ************************************************************************* */
template<class GenericGraph>
boost::optional<MetisResult> separatorPartitionByMetis(const GenericGraph& graph, const vector<size_t>& keys, WorkSpace& workspace, bool verbose) {
boost::optional<MetisResult> separatorPartitionByMetis(const GenericGraph& graph,
const vector<size_t>& keys, WorkSpace& workspace, bool verbose) {
// create a metis graph
size_t numKeys = keys.size();
if (verbose) cout << graph.size() << " factors,\t" << numKeys << " nodes;\t" << endl;
if (verbose)
cout << graph.size() << " factors,\t" << numKeys << " nodes;\t" << endl;
sharedInts xadj, adjncy, adjwgt;
prepareMetisGraph<GenericGraph>(graph, keys, workspace, &xadj, &adjncy, &adjwgt);
// run ND on the graph
@ -253,7 +262,8 @@ namespace gtsam { namespace partition {
boost::tie(sepsize, part) = separatorMetis(numKeys, xadj, adjncy, adjwgt, verbose);
if (!sepsize) return boost::optional<MetisResult>();
// convert the 0-1-2 from Metis to 1-2-0, so that the separator is 0, as later we will have more submaps
// convert the 0-1-2 from Metis to 1-2-0, so that the separator is 0, as later
// we will have more submaps
MetisResult result;
result.C.reserve(sepsize);
result.A.reserve(numKeys - sepsize);
@ -272,9 +282,9 @@ namespace gtsam { namespace partition {
if (verbose) {
cout << "total key: " << keys.size()
<< " result(A,B,C) = " << result.A.size() << ", " << result.B.size() << ", " << result.C.size()
<< "; sepsize from Metis = " << sepsize << endl;
throw runtime_error("separatorPartitionByMetis:stop for debug");
<< " result(A,B,C) = " << result.A.size() << ", " << result.B.size() << ", "
<< result.C.size() << "; sepsize from Metis = " << sepsize << endl;
//throw runtime_error("separatorPartitionByMetis:stop for debug");
}
if(result.C.size() != sepsize) {
@ -429,7 +439,8 @@ namespace gtsam { namespace partition {
case 0: C.push_back(j); break;
case 1: A.push_back(j); break;
case 2: B.push_back(j); break;
default: cout << j << ": " << dictionary[j] << endl; throw runtime_error("addLandmarkToPartitionResult: wrong status for landmark");
default: cout << j << ": " << dictionary[j] << endl;
throw runtime_error("addLandmarkToPartitionResult: wrong status for landmark");
}
}
}
@ -463,7 +474,8 @@ namespace gtsam { namespace partition {
workspace.prepareDictionary(keyToPartition);
const std::vector<int>& dictionary = workspace.dictionary;
reduceGenericGraph(graph, cameraKeys, landmarkKeys, dictionary, reducedGraph);
cout << "original graph: V" << keys.size() << ", E" << graph.size() << " --> reduced graph: V" << cameraKeys.size() << ", E" << reducedGraph.size() << endl;
cout << "original graph: V" << keys.size() << ", E" << graph.size()
<< " --> reduced graph: V" << cameraKeys.size() << ", E" << reducedGraph.size() << endl;
//result = edgePartitionByMetis(reducedGraph, keyToPartition, workspace, verbose);
} else // call Metis to partition the graph to A, B, C
result = separatorPartitionByMetis(graph, keys, workspace, verbose);
@ -488,13 +500,19 @@ namespace gtsam { namespace partition {
const boost::optional<vector<Symbol> >& int2symbol, const bool reduceGraph,
const int minNrConstraintsPerCamera, const int minNrConstraintsPerLandmark) {
boost::optional<MetisResult> result = findPartitoning(graph, keys, workspace, verbose, int2symbol, reduceGraph);
boost::optional<MetisResult> result = findPartitoning(graph, keys, workspace,
verbose, int2symbol, reduceGraph);
// find the island in A and B, and make them separated submaps
typedef vector<size_t> Island;
list<Island> islands;
list<Island> islands_in_A = findIslands(graph, result->A, workspace, minNrConstraintsPerCamera, minNrConstraintsPerLandmark);
list<Island> islands_in_B = findIslands(graph, result->B, workspace, minNrConstraintsPerCamera, minNrConstraintsPerLandmark);
list<Island> islands_in_A = findIslands(graph, result->A, workspace,
minNrConstraintsPerCamera, minNrConstraintsPerLandmark);
list<Island> islands_in_B = findIslands(graph, result->B, workspace,
minNrConstraintsPerCamera, minNrConstraintsPerLandmark);
islands.insert(islands.end(), islands_in_A.begin(), islands_in_A.end());
islands.insert(islands.end(), islands_in_B.begin(), islands_in_B.end());
islands.sort(isLargerIsland);

View File

@ -34,7 +34,9 @@ TEST ( Partition, separatorPartitionByMetis )
std::vector<size_t> keys; keys += 0, 1, 2, 3, 4;
WorkSpace workspace(5);
boost::optional<MetisResult> actual = separatorPartitionByMetis<GenericGraph2D>(graph, keys, workspace, false);
boost::optional<MetisResult> actual = separatorPartitionByMetis<GenericGraph2D>(graph, keys,
workspace, true);
CHECK(actual.is_initialized());
vector<size_t> A_expected; A_expected += 0, 3; // frontal
vector<size_t> B_expected; B_expected += 2, 4; // frontal
@ -55,8 +57,11 @@ TEST ( Partition, separatorPartitionByMetis2 )
graph.push_back(boost::make_shared<GenericFactor2D>(1, NODE_POSE_2D, 2, NODE_POSE_2D));
graph.push_back(boost::make_shared<GenericFactor2D>(2, NODE_POSE_2D, 3, NODE_POSE_2D));
std::vector<size_t> keys; keys += 1, 2, 3, 5, 6;
WorkSpace workspace(8);
boost::optional<MetisResult> actual = separatorPartitionByMetis<GenericGraph2D>(graph, keys, workspace, false);
boost::optional<MetisResult> actual = separatorPartitionByMetis<GenericGraph2D>(graph, keys,
workspace, true);
CHECK(actual.is_initialized());
vector<size_t> A_expected; A_expected += 1, 5; // frontal
vector<size_t> B_expected; B_expected += 3, 6; // frontal
@ -77,7 +82,8 @@ TEST ( Partition, edgePartitionByMetis )
std::vector<size_t> keys; keys += 0, 2, 3, 5;
WorkSpace workspace(6);
boost::optional<MetisResult> actual = edgePartitionByMetis<GenericGraph3D>(graph, keys, workspace, false);
boost::optional<MetisResult> actual = edgePartitionByMetis<GenericGraph3D>(graph, keys,
workspace, false);
CHECK(actual.is_initialized());
vector<size_t> A_expected; A_expected += 0, 2; // frontal
vector<size_t> B_expected; B_expected += 3, 5; // frontal
@ -106,7 +112,8 @@ TEST ( Partition, edgePartitionByMetis2 )
std::vector<size_t> keys; keys += 0, 2, 3, 5, 6;
WorkSpace workspace(6);
boost::optional<MetisResult> actual = edgePartitionByMetis<GenericGraph3D>(graph, keys, workspace, false);
boost::optional<MetisResult> actual = edgePartitionByMetis<GenericGraph3D>(graph, keys,
workspace, false);
CHECK(actual.is_initialized());
vector<size_t> A_expected; A_expected += 0, 2; // frontal
vector<size_t> B_expected; B_expected += 3, 5, 6; // frontal