diff --git a/gtsam_unstable/partition/FindSeparator-inl.h b/gtsam_unstable/partition/FindSeparator-inl.h index 73012cceb..8b05984d2 100644 --- a/gtsam_unstable/partition/FindSeparator-inl.h +++ b/gtsam_unstable/partition/FindSeparator-inl.h @@ -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 separatorMetis(int n, const sharedInts& xadj, const sharedInts& adjncy, const sharedInts& adjwgt, bool verbose) { + pair 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 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& adjancyMap1 = adjancyMap[index1]; pair& adjancyMap2 = adjancyMap[index2]; adjancyMap1.first .push_back(index2); @@ -240,11 +245,15 @@ namespace gtsam { namespace partition { /* ************************************************************************* */ template - boost::optional separatorPartitionByMetis(const GenericGraph& graph, const vector& keys, WorkSpace& workspace, bool verbose) { + boost::optional separatorPartitionByMetis(const GenericGraph& graph, + const vector& 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(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(); - // 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& 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 >& int2symbol, const bool reduceGraph, const int minNrConstraintsPerCamera, const int minNrConstraintsPerLandmark) { - boost::optional result = findPartitoning(graph, keys, workspace, verbose, int2symbol, reduceGraph); + boost::optional result = findPartitoning(graph, keys, workspace, + verbose, int2symbol, reduceGraph); // find the island in A and B, and make them separated submaps typedef vector Island; list islands; - list islands_in_A = findIslands(graph, result->A, workspace, minNrConstraintsPerCamera, minNrConstraintsPerLandmark); - list islands_in_B = findIslands(graph, result->B, workspace, minNrConstraintsPerCamera, minNrConstraintsPerLandmark); + + list islands_in_A = findIslands(graph, result->A, workspace, + minNrConstraintsPerCamera, minNrConstraintsPerLandmark); + + list 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); diff --git a/gtsam_unstable/partition/tests/testFindSeparator.cpp b/gtsam_unstable/partition/tests/testFindSeparator.cpp index 8d42aa62a..093f385f3 100644 --- a/gtsam_unstable/partition/tests/testFindSeparator.cpp +++ b/gtsam_unstable/partition/tests/testFindSeparator.cpp @@ -34,7 +34,9 @@ TEST ( Partition, separatorPartitionByMetis ) std::vector keys; keys += 0, 1, 2, 3, 4; WorkSpace workspace(5); - boost::optional actual = separatorPartitionByMetis(graph, keys, workspace, false); + boost::optional actual = separatorPartitionByMetis(graph, keys, + workspace, true); + CHECK(actual.is_initialized()); vector A_expected; A_expected += 0, 3; // frontal vector B_expected; B_expected += 2, 4; // frontal @@ -55,8 +57,11 @@ TEST ( Partition, separatorPartitionByMetis2 ) graph.push_back(boost::make_shared(1, NODE_POSE_2D, 2, NODE_POSE_2D)); graph.push_back(boost::make_shared(2, NODE_POSE_2D, 3, NODE_POSE_2D)); std::vector keys; keys += 1, 2, 3, 5, 6; + WorkSpace workspace(8); - boost::optional actual = separatorPartitionByMetis(graph, keys, workspace, false); + boost::optional actual = separatorPartitionByMetis(graph, keys, + workspace, true); + CHECK(actual.is_initialized()); vector A_expected; A_expected += 1, 5; // frontal vector B_expected; B_expected += 3, 6; // frontal @@ -77,7 +82,8 @@ TEST ( Partition, edgePartitionByMetis ) std::vector keys; keys += 0, 2, 3, 5; WorkSpace workspace(6); - boost::optional actual = edgePartitionByMetis(graph, keys, workspace, false); + boost::optional actual = edgePartitionByMetis(graph, keys, + workspace, false); CHECK(actual.is_initialized()); vector A_expected; A_expected += 0, 2; // frontal vector B_expected; B_expected += 3, 5; // frontal @@ -106,7 +112,8 @@ TEST ( Partition, edgePartitionByMetis2 ) std::vector keys; keys += 0, 2, 3, 5, 6; WorkSpace workspace(6); - boost::optional actual = edgePartitionByMetis(graph, keys, workspace, false); + boost::optional actual = edgePartitionByMetis(graph, keys, + workspace, false); CHECK(actual.is_initialized()); vector A_expected; A_expected += 0, 2; // frontal vector B_expected; B_expected += 3, 5, 6; // frontal