Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve sparseJacobianEigen() #682

Merged
merged 16 commits into from
Jan 28, 2021
Merged

Improve sparseJacobianEigen() #682

merged 16 commits into from
Jan 28, 2021

Conversation

gchenfc
Copy link
Member

@gchenfc gchenfc commented Jan 20, 2021

#677 contained copy/pasted code from GaussianFactorGraph::sparseJacobian in sparseJacobianEigen. This PR makes the more generic, GaussianFactorGraph::sparseJacobianInPlace<T>(T& entries, ...) and uses it instead in sparseJacobianEigen.

It also adds an optional Ordering argument to better match the other jacobian functions, and optional nrows/ncols parameters since these are necessary to keep track of for sparse matrices.

Finally, efficiency is slightly improved by inserting directly as described here, benchmarked by running sparseJacobianEigen on a linearized BALfinal-394-100368-pre:

Description Time
T as vector<Eigen::Triple> and using setFromTriplets (original) 0.67s
T as vector<boost::tuple> and using SparseEigen::insert 0.72s
T as vector<Eigen::Triple> and using SparseEigen::insert (new) 0.63s

Notes about the diff:

  • GaussianFactorGraph.cpp <-> GaussianFactorGraph-impl.h, the function implementation moved from sparseJacobian to sparseJacobianInPlace with the following modifications:
    • (in-place) entries is no longer constructed
    • col/row variables were renamed to nrows and ncols to match parameter names
    • entries in the b vector are only added if they are non-zero
  • in testGaussianFactorGraph one entry A(5, 7) = 0 was removed since it has value 0 (see previous bullet point)

@gchenfc gchenfc requested a review from dellaert January 20, 2021 02:19
Copy link
Member

@dellaert dellaert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two comments before doing a full review.

gtsam/base/Matrix.h Outdated Show resolved Hide resolved
gtsam/linear/GaussianFactorGraph-impl.h Outdated Show resolved Hide resolved
Templating still used in cpp file for generic-ness, but not exposed
anymore

std::tuple has the same performance as Eigen::Triplet, but boost::tuple
is slower.  Sparse matrix indices are int instead of size_t for
efficiency (e.g. A(i, j) = s  ->  i/j are int's instead of size_t's)
Copy link
Member

@dellaert dellaert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gerry, I appreciated the enthusiasm, but it seems you created a (confusing) zoo of options for some hypothetical user in the future. Let's not: we need an opinionated API that provides just what is needed. Try to remember why this PR exists, and satisfy that use case. Leave everything else untouched. I think we can change to your "fast type" without changing the API (substantially).

SparseMatrixBoostTriplets;
/// Sparse matrix representation as vector of slightly more efficient
/// tuples.
typedef std::vector<std::tuple<int, int, double>> SparseMatrixGtsamTriplets;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reasoning here? I'd prefer to keep only one of these.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Originally the code used SparseMatrixBoostTriplets. I added SparseMatrixGtsamTriplets because it's about 14% faster and 33% less memory intensive (16 bytes instead of 24 bytes per nnz entry) in my tests. Reason: 1) size_t is 8 bytes, and even if we use int instead, boost::tuple aligns to 8 bytes. We don't have to typedef these?

Old version kept for backwards compatibility.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the typedefs but both are still used (the std::tuple version is used in the "fast" version).

gtsam/linear/GaussianFactorGraph.h Outdated Show resolved Hide resolved
gtsam/linear/GaussianFactorGraph.h Outdated Show resolved Hide resolved
Copy link
Member

@dellaert dellaert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still confused, see comments. Just switch to int already unless there is a great reason NOT to.

gtsam/linear/GaussianFactorGraph.cpp Outdated Show resolved Hide resolved
gtsam/linear/SparseEigen.h Show resolved Hide resolved
gtsam/linear/GaussianFactorGraph.h Outdated Show resolved Hide resolved
@gchenfc gchenfc requested a review from dellaert January 27, 2021 20:27
Copy link
Member

@dellaert dellaert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay!!!
Just two nits... I'll leave you to merge after that and after CI succeeds. Email me if you can't for some reason.

gtsam/linear/GaussianFactorGraph.cpp Outdated Show resolved Hide resolved
gtsam/linear/GaussianFactorGraph.cpp Outdated Show resolved Hide resolved
@gchenfc gchenfc merged commit 97723d1 into develop Jan 28, 2021
@dellaert
Copy link
Member

Nice!

@dellaert dellaert deleted the feature/sparseJacobian3 branch December 29, 2021 00:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants