Test Separator unit test passes. Partially
parent
1ff9309533
commit
05e42ba452
|
|
@ -36,26 +36,29 @@ namespace gtsam { namespace partition {
|
||||||
* whether node j is in the left part of the graph, the right part, or the
|
* whether node j is in the left part of the graph, the right part, or the
|
||||||
* separator, respectively
|
* 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
|
// control parameters
|
||||||
idx_t vwgt[n]; // the weights of the vertices
|
idx_t vwgt[n]; // the weights of the vertices
|
||||||
int options[8]; options [0] = 0 ; // use defaults
|
//int options[8]; options [0] = 0 ;
|
||||||
int sepsize; // the size of the separator, output
|
idx_t options[METIS_NOPTIONS];
|
||||||
sharedInts part_(new int[n]); // the partition of each vertex, output
|
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
|
// set uniform weights on the vertices
|
||||||
std::fill(vwgt, vwgt+n, 1);
|
std::fill(vwgt, vwgt+n, 1);
|
||||||
|
|
||||||
// TODO: Fix at later time
|
// TODO: Fix at later time
|
||||||
/*boost::timer::cpu_timer TOTALTmr;
|
//boost::timer::cpu_timer TOTALTmr;
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
printf("**********************************************************************\n");
|
printf("**********************************************************************\n");
|
||||||
printf("Graph Information ---------------------------------------------------\n");
|
printf("Graph Information ---------------------------------------------------\n");
|
||||||
printf(" #Vertices: %d, #Edges: %u\n", n, *(xadj.get()+n) / 2);
|
printf(" #Vertices: %d, #Edges: %u\n", n, *(xadj.get()+n) / 2);
|
||||||
printf("\nND Partitioning... -------------------------------------------\n");
|
printf("\nND Partitioning... -------------------------------------------\n");
|
||||||
TOTALTmr.start()
|
//TOTALTmr.start()
|
||||||
}*/
|
}
|
||||||
|
|
||||||
// call metis parition routine OLD!!!!
|
// call metis parition routine OLD!!!!
|
||||||
/*METIS_NodeComputeSeparator(&n, xadj.get(), adjncy.get(), vwgt, adjwgt.get(),
|
/*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(),
|
METIS_ComputeVertexSeparator(&n, xadj.get(), adjncy.get(),
|
||||||
vwgt, options, &sepsize, part_.get());
|
vwgt, options, &sepsize, part_.get());
|
||||||
|
|
||||||
/*if (verbose) {
|
if (verbose) {
|
||||||
boost::cpu_times const elapsed_times(timer.elapsed());
|
//boost::cpu_times const elapsed_times(timer.elapsed());
|
||||||
printf("\nTiming Information --------------------------------------------------\n");
|
//printf("\nTiming Information --------------------------------------------------\n");
|
||||||
printf(" Total: \t\t %7.3f\n", elapsed_times);
|
//printf(" Total: \t\t %7.3f\n", elapsed_times);
|
||||||
printf(" Sep size: \t\t %d\n", sepsize);
|
printf(" Sep size: \t\t %d\n", sepsize);
|
||||||
printf("**********************************************************************\n");
|
printf("**********************************************************************\n");
|
||||||
}*/
|
}
|
||||||
|
|
||||||
return make_pair(sepsize, part_);
|
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
|
vector<NeighborsInfo> adjancyMap; // TODO: set is slow, but have to use it to remove duplicated edges
|
||||||
adjancyMap.resize(numNodes);
|
adjancyMap.resize(numNodes);
|
||||||
int index1, index2;
|
int index1, index2;
|
||||||
|
|
||||||
BOOST_FOREACH(const typename GenericGraph::value_type& factor, graph){
|
BOOST_FOREACH(const typename GenericGraph::value_type& factor, graph){
|
||||||
index1 = dictionary[factor->key1.index];
|
index1 = dictionary[factor->key1.index];
|
||||||
index2 = dictionary[factor->key2.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>& adjancyMap1 = adjancyMap[index1];
|
||||||
pair<Neighbors, Weights>& adjancyMap2 = adjancyMap[index2];
|
pair<Neighbors, Weights>& adjancyMap2 = adjancyMap[index2];
|
||||||
adjancyMap1.first .push_back(index2);
|
adjancyMap1.first .push_back(index2);
|
||||||
|
|
@ -240,11 +245,15 @@ namespace gtsam { namespace partition {
|
||||||
|
|
||||||
/* ************************************************************************* */
|
/* ************************************************************************* */
|
||||||
template<class GenericGraph>
|
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
|
// create a metis graph
|
||||||
size_t numKeys = keys.size();
|
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;
|
sharedInts xadj, adjncy, adjwgt;
|
||||||
|
|
||||||
prepareMetisGraph<GenericGraph>(graph, keys, workspace, &xadj, &adjncy, &adjwgt);
|
prepareMetisGraph<GenericGraph>(graph, keys, workspace, &xadj, &adjncy, &adjwgt);
|
||||||
|
|
||||||
// run ND on the graph
|
// run ND on the graph
|
||||||
|
|
@ -253,7 +262,8 @@ namespace gtsam { namespace partition {
|
||||||
boost::tie(sepsize, part) = separatorMetis(numKeys, xadj, adjncy, adjwgt, verbose);
|
boost::tie(sepsize, part) = separatorMetis(numKeys, xadj, adjncy, adjwgt, verbose);
|
||||||
if (!sepsize) return boost::optional<MetisResult>();
|
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;
|
MetisResult result;
|
||||||
result.C.reserve(sepsize);
|
result.C.reserve(sepsize);
|
||||||
result.A.reserve(numKeys - sepsize);
|
result.A.reserve(numKeys - sepsize);
|
||||||
|
|
@ -272,9 +282,9 @@ namespace gtsam { namespace partition {
|
||||||
|
|
||||||
if (verbose) {
|
if (verbose) {
|
||||||
cout << "total key: " << keys.size()
|
cout << "total key: " << keys.size()
|
||||||
<< " result(A,B,C) = " << result.A.size() << ", " << result.B.size() << ", " << result.C.size()
|
<< " result(A,B,C) = " << result.A.size() << ", " << result.B.size() << ", "
|
||||||
<< "; sepsize from Metis = " << sepsize << endl;
|
<< result.C.size() << "; sepsize from Metis = " << sepsize << endl;
|
||||||
throw runtime_error("separatorPartitionByMetis:stop for debug");
|
//throw runtime_error("separatorPartitionByMetis:stop for debug");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result.C.size() != sepsize) {
|
if(result.C.size() != sepsize) {
|
||||||
|
|
@ -429,7 +439,8 @@ namespace gtsam { namespace partition {
|
||||||
case 0: C.push_back(j); break;
|
case 0: C.push_back(j); break;
|
||||||
case 1: A.push_back(j); break;
|
case 1: A.push_back(j); break;
|
||||||
case 2: B.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);
|
workspace.prepareDictionary(keyToPartition);
|
||||||
const std::vector<int>& dictionary = workspace.dictionary;
|
const std::vector<int>& dictionary = workspace.dictionary;
|
||||||
reduceGenericGraph(graph, cameraKeys, landmarkKeys, dictionary, reducedGraph);
|
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);
|
//result = edgePartitionByMetis(reducedGraph, keyToPartition, workspace, verbose);
|
||||||
} else // call Metis to partition the graph to A, B, C
|
} else // call Metis to partition the graph to A, B, C
|
||||||
result = separatorPartitionByMetis(graph, keys, workspace, verbose);
|
result = separatorPartitionByMetis(graph, keys, workspace, verbose);
|
||||||
|
|
@ -488,13 +500,19 @@ namespace gtsam { namespace partition {
|
||||||
const boost::optional<vector<Symbol> >& int2symbol, const bool reduceGraph,
|
const boost::optional<vector<Symbol> >& int2symbol, const bool reduceGraph,
|
||||||
const int minNrConstraintsPerCamera, const int minNrConstraintsPerLandmark) {
|
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
|
// find the island in A and B, and make them separated submaps
|
||||||
typedef vector<size_t> Island;
|
typedef vector<size_t> Island;
|
||||||
list<Island> islands;
|
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_A.begin(), islands_in_A.end());
|
||||||
islands.insert(islands.end(), islands_in_B.begin(), islands_in_B.end());
|
islands.insert(islands.end(), islands_in_B.begin(), islands_in_B.end());
|
||||||
islands.sort(isLargerIsland);
|
islands.sort(isLargerIsland);
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,9 @@ TEST ( Partition, separatorPartitionByMetis )
|
||||||
std::vector<size_t> keys; keys += 0, 1, 2, 3, 4;
|
std::vector<size_t> keys; keys += 0, 1, 2, 3, 4;
|
||||||
|
|
||||||
WorkSpace workspace(5);
|
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());
|
CHECK(actual.is_initialized());
|
||||||
vector<size_t> A_expected; A_expected += 0, 3; // frontal
|
vector<size_t> A_expected; A_expected += 0, 3; // frontal
|
||||||
vector<size_t> B_expected; B_expected += 2, 4; // 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>(1, NODE_POSE_2D, 2, NODE_POSE_2D));
|
||||||
graph.push_back(boost::make_shared<GenericFactor2D>(2, NODE_POSE_2D, 3, 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;
|
std::vector<size_t> keys; keys += 1, 2, 3, 5, 6;
|
||||||
|
|
||||||
WorkSpace workspace(8);
|
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());
|
CHECK(actual.is_initialized());
|
||||||
vector<size_t> A_expected; A_expected += 1, 5; // frontal
|
vector<size_t> A_expected; A_expected += 1, 5; // frontal
|
||||||
vector<size_t> B_expected; B_expected += 3, 6; // 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;
|
std::vector<size_t> keys; keys += 0, 2, 3, 5;
|
||||||
|
|
||||||
WorkSpace workspace(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());
|
CHECK(actual.is_initialized());
|
||||||
vector<size_t> A_expected; A_expected += 0, 2; // frontal
|
vector<size_t> A_expected; A_expected += 0, 2; // frontal
|
||||||
vector<size_t> B_expected; B_expected += 3, 5; // 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;
|
std::vector<size_t> keys; keys += 0, 2, 3, 5, 6;
|
||||||
|
|
||||||
WorkSpace workspace(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());
|
CHECK(actual.is_initialized());
|
||||||
vector<size_t> A_expected; A_expected += 0, 2; // frontal
|
vector<size_t> A_expected; A_expected += 0, 2; // frontal
|
||||||
vector<size_t> B_expected; B_expected += 3, 5, 6; // frontal
|
vector<size_t> B_expected; B_expected += 3, 5, 6; // frontal
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue