improved exception message when there are lots of keys

release/4.3a0
Varun Agrawal 2023-07-17 17:56:19 -04:00
parent 64cd436362
commit 89941683a2
2 changed files with 40 additions and 10 deletions

View File

@ -29,7 +29,7 @@ namespace gtsam {
* full elimination routine was called with an ordering that does not include * full elimination routine was called with an ordering that does not include
* all of the variables. */ * all of the variables. */
class InconsistentEliminationRequested : public std::exception { class InconsistentEliminationRequested : public std::exception {
KeySet keys_; KeyVector keys_;
const KeyFormatter& keyFormatter = DefaultKeyFormatter; const KeyFormatter& keyFormatter = DefaultKeyFormatter;
public: public:
@ -38,21 +38,26 @@ class InconsistentEliminationRequested : public std::exception {
InconsistentEliminationRequested( InconsistentEliminationRequested(
const KeySet& keys, const KeySet& keys,
const KeyFormatter& key_formatter = DefaultKeyFormatter) const KeyFormatter& key_formatter = DefaultKeyFormatter)
: keys_(keys), keyFormatter(key_formatter) {} : keys_(keys.begin(), keys.end()), keyFormatter(key_formatter) {}
~InconsistentEliminationRequested() noexcept override {} ~InconsistentEliminationRequested() noexcept override {}
const char* what() const noexcept override { const char* what() const noexcept override {
// Format keys for printing // Format keys for printing
std::stringstream sstr; std::stringstream sstr;
for (auto key : keys_) { size_t nrKeysToDisplay = std::min(size_t(4), keys_.size());
sstr << keyFormatter(key) << ", "; for (size_t i = 0; i < nrKeysToDisplay; i++) {
sstr << keyFormatter(keys_.at(i));
if (i < nrKeysToDisplay - 1) {
sstr << ", ";
} }
}
if (keys_.size() > nrKeysToDisplay) {
sstr << ", ... (total " << keys_.size() << " keys)";
}
sstr << ".";
std::string keys = sstr.str(); std::string keys = sstr.str();
// remove final comma and space.
keys.pop_back();
keys.pop_back();
static std::string msg = std::string msg =
"An inference algorithm was called with inconsistent " "An inference algorithm was called with inconsistent "
"arguments. " "arguments. "
"The\n" "The\n"
@ -64,7 +69,8 @@ class InconsistentEliminationRequested : public std::exception {
"that\n" "that\n"
"does not include all of the variables.\n"; "does not include all of the variables.\n";
msg += ("Leftover keys after elimination: " + keys); msg += ("Leftover keys after elimination: " + keys);
return msg.c_str(); // `new` to allocate memory on heap instead of stack
return (new std::string(msg))->c_str();
} }
}; };
} // namespace gtsam } // namespace gtsam

View File

@ -465,7 +465,31 @@ TEST(GaussianFactorGraph, InconsistentEliminationMessage) {
"an ordering " "an ordering "
"that\n" "that\n"
"does not include all of the variables.\n" "does not include all of the variables.\n"
"Leftover keys after elimination: 2, x3"; "Leftover keys after elimination: 2, x3.";
EXPECT(expected_exception_message == exc.what());
}
// Test large number of keys
fg = GaussianFactorGraph();
for (size_t i = 0; i < 1000; i++) {
fg.emplace_shared<JacobianFactor>(i, -I_2x2, i + 1, I_2x2,
Vector2(2.0, -1.0), unit2);
}
try {
fg.eliminateSequential(ordering);
} catch (const exception& exc) {
std::string expected_exception_message = "An inference algorithm was called with inconsistent "
"arguments. "
"The\n"
"factor graph, ordering, or variable index were "
"inconsistent with "
"each\n"
"other, or a full elimination routine was called with "
"an ordering "
"that\n"
"does not include all of the variables.\n"
"Leftover keys after elimination: 2, 3, 4, 5, ... (total 999 keys).";
EXPECT(expected_exception_message == exc.what()); EXPECT(expected_exception_message == exc.what());
} }
} }