METIS ordering only works on values that are 0 indexed. Otherwise heap corruption occurs inside metis ordering function. Not sure how to fix/enforce

release/4.3a0
Andrew Melim 2014-10-21 15:56:40 -04:00
parent 49d6b04eb8
commit a281240ff1
8 changed files with 77 additions and 28 deletions

View File

@ -86,7 +86,10 @@ int main(int argc, char** argv) {
initial.print("\nInitial Estimate:\n"); // print initial.print("\nInitial Estimate:\n"); // print
// optimize using Levenberg-Marquardt optimization // optimize using Levenberg-Marquardt optimization
Values result = LevenbergMarquardtOptimizer(graph, initial).optimize(); LevenbergMarquardtParams params;
params.orderingType = Ordering::Type::METIS_;
LevenbergMarquardtOptimizer optimizer(graph, initial, params);
Values result = optimizer.optimize();
result.print("Final Result:\n"); result.print("Final Result:\n");
// Calculate and print marginal covariances for all variables // Calculate and print marginal covariances for all variables

View File

@ -55,9 +55,9 @@ namespace gtsam {
// have a VariableIndex already here because we computed one if needed in the previous 'else' // have a VariableIndex already here because we computed one if needed in the previous 'else'
// block. // block.
if (orderingType == Ordering::Type::METIS_) if (orderingType == Ordering::Type::METIS_)
return eliminateSequential(Ordering::METIS(asDerived()), function, variableIndex, orderingType); return eliminateSequential(Ordering::METIS(asDerived()), function, variableIndex, orderingType);
else else
return eliminateSequential(Ordering::COLAMD(*variableIndex), function, variableIndex, orderingType); return eliminateSequential(Ordering::COLAMD(*variableIndex), function, variableIndex, orderingType);
} }
} }

View File

@ -29,6 +29,7 @@ namespace gtsam {
{ {
std::map<int, FastSet<int> > adjMap; std::map<int, FastSet<int> > adjMap;
std::map<int, FastSet<int> >::iterator adjMapIt; std::map<int, FastSet<int> >::iterator adjMapIt;
std::set<int> values;
/* ********** Convert to CSR format ********** */ /* ********** Convert to CSR format ********** */
// Assuming that vertex numbering starts from 0 (C style), // Assuming that vertex numbering starts from 0 (C style),
@ -37,13 +38,19 @@ namespace gtsam {
// index xadj[i + 1](i.e., adjncy[xadj[i]] through // index xadj[i + 1](i.e., adjncy[xadj[i]] through
// and including adjncy[xadj[i + 1] - 1]). // and including adjncy[xadj[i + 1] - 1]).
for (size_t i = 0; i < factors.size(); i++){ for (size_t i = 0; i < factors.size(); i++){
if (factors[i]) if (factors[i]){
BOOST_FOREACH(const Key& k1, *factors[i]) BOOST_FOREACH(const Key& k1, *factors[i]){
BOOST_FOREACH(const Key& k2, *factors[i]) BOOST_FOREACH(const Key& k2, *factors[i]){
if (k1 != k2) if (k1 != k2)
adjMap[k1].insert(adjMap[k1].end(), k2); // Insert at the end adjMap[k1].insert(adjMap[k1].end(), k2); // Insert at the end
}
values.insert(values.end(), k1); // Keep a track of all unique values
}
}
} }
// Number of values referenced in this factorgraph
nValues_ = values.size();
xadj_.push_back(0);// Always set the first index to zero xadj_.push_back(0);// Always set the first index to zero
for (adjMapIt = adjMap.begin(); adjMapIt != adjMap.end(); ++adjMapIt) { for (adjMapIt = adjMap.begin(); adjMapIt != adjMap.end(); ++adjMapIt) {

View File

@ -71,6 +71,7 @@ public:
std::vector<int> xadj() const { return xadj_; } std::vector<int> xadj() const { return xadj_; }
std::vector<int> adj() const { return adj_; } std::vector<int> adj() const { return adj_; }
size_t nValues() const { return nValues_; }
/// @} /// @}
}; };

View File

@ -202,30 +202,30 @@ namespace gtsam {
/* ************************************************************************* */ /* ************************************************************************* */
Ordering Ordering::METIS(const MetisIndex& met) Ordering Ordering::METIS(const MetisIndex& met)
{ {
gttic(Ordering_METIS); gttic(Ordering_METIS);
vector<int> xadj = met.xadj(); vector<idx_t> xadj = met.xadj();
vector<int> adj = met.adj(); vector<idx_t> adj = met.adj();
vector<int> perm, iperm; vector<idx_t> perm, iperm;
idx_t size = xadj.size() - 1; idx_t size = met.nValues();
for (idx_t i = 0; i < size; i++) for (idx_t i = 0; i < size; i++)
{ {
perm.push_back(0); perm.push_back(0);
iperm.push_back(0); iperm.push_back(0);
} }
int outputError; int outputError;
outputError = METIS_NodeND(&size, &xadj[0], &adj[0], NULL, NULL, &perm[0], &iperm[0]); outputError = METIS_NodeND(&size, &xadj[0], &adj[0], NULL, NULL, &perm[0], &iperm[0]);
Ordering result; Ordering result;
if (outputError != METIS_OK) if (outputError != METIS_OK)
{ {
std::cout << "METIS failed during Nested Dissection ordering!\n"; std::cout << "METIS failed during Nested Dissection ordering!\n";
return result; return result;
} }
result.resize(size); result.resize(size);
for (size_t j = 0; j < size; ++j) for (size_t j = 0; j < size; ++j)

View File

@ -116,17 +116,52 @@ TEST(Ordering, csr_format) {
EXPECT(xadjExpected == mi.xadj()); EXPECT(xadjExpected == mi.xadj());
EXPECT(adjExpected.size() == mi.adj().size()); EXPECT(adjExpected.size() == mi.adj().size());
EXPECT( adjExpected == mi.adj()); EXPECT(adjExpected == mi.adj());
} }
/* ************************************************************************* */
TEST(Ordering, csr_format_2) {
SymbolicFactorGraph sfg;
sfg.push_factor(0);
sfg.push_factor(0, 1);
sfg.push_factor(1, 2);
sfg.push_factor(2, 3);
sfg.push_factor(3, 4);
sfg.push_factor(4, 1);
MetisIndex mi(sfg);
vector<int> xadjExpected { 0, 1, 4, 6, 8, 10 };
vector<int> adjExpected { 1, 0, 2, 4, 1, 3, 2, 4, 1, 3 };
EXPECT(xadjExpected == mi.xadj());
EXPECT(adjExpected.size() == mi.adj().size());
EXPECT(adjExpected == mi.adj());
//Ordering metis = Ordering::METIS(sfg);
}
/* ************************************************************************* */ /* ************************************************************************* */
TEST(Ordering, metis) { TEST(Ordering, metis) {
SymbolicFactorGraph sfg; SymbolicFactorGraph sfg;
sfg.push_factor(0, 1); sfg.push_factor(0);
sfg.push_factor(0, 1);
sfg.push_factor(1, 2); sfg.push_factor(1, 2);
Ordering metis = Ordering::METIS(sfg); MetisIndex mi(sfg);
vector<int> xadjExpected{ 0, 1, 3, 4 };
vector<int> adjExpected { 1, 0, 2, 1 };
EXPECT(xadjExpected == mi.xadj());
EXPECT(adjExpected.size() == mi.adj().size());
EXPECT(adjExpected == mi.adj());
Ordering metis = Ordering::METIS(sfg);
} }
/* ************************************************************************* */ /* ************************************************************************* */
int main() { TestResult tr; return TestRegistry::runAllTests(tr); } int main() { TestResult tr; return TestRegistry::runAllTests(tr); }

View File

@ -341,7 +341,10 @@ void LevenbergMarquardtOptimizer::iterate() {
LevenbergMarquardtParams LevenbergMarquardtOptimizer::ensureHasOrdering( LevenbergMarquardtParams LevenbergMarquardtOptimizer::ensureHasOrdering(
LevenbergMarquardtParams params, const NonlinearFactorGraph& graph) const { LevenbergMarquardtParams params, const NonlinearFactorGraph& graph) const {
if (!params.ordering) if (!params.ordering)
params.ordering = Ordering::COLAMD(graph); if (params.orderingType = Ordering::Type::METIS_)
params.ordering = Ordering::METIS(graph);
else
params.ordering = Ordering::COLAMD(graph);
return params; return params;
} }

View File

@ -154,7 +154,7 @@ public:
void setOrdering(const Ordering& ordering) { void setOrdering(const Ordering& ordering) {
this->ordering = ordering; this->ordering = ordering;
this->orderingType = Ordering::Type::CUSTOM_; this->orderingType = Ordering::Type::CUSTOM_;
} }
std::string getOrderingType() const { std::string getOrderingType() const {