-
Notifications
You must be signed in to change notification settings - Fork 767
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
Conversation
Also, the unit test changed due to a 0 entry that was previously wrongly included in the b-column of the sparse representation.
About 5% speed improvement.
There was a problem hiding this 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.
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)
There was a problem hiding this 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).
gtsam/linear/GaussianFactorGraph.h
Outdated
SparseMatrixBoostTriplets; | ||
/// Sparse matrix representation as vector of slightly more efficient | ||
/// tuples. | ||
typedef std::vector<std::tuple<int, int, double>> SparseMatrixGtsamTriplets; |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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).
There was a problem hiding this 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.
There was a problem hiding this 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.
Nice! |
#677 contained copy/pasted code from
GaussianFactorGraph::sparseJacobian
insparseJacobianEigen
. This PR makes the more generic,GaussianFactorGraph::sparseJacobianInPlace<T>(T& entries, ...)
and uses it instead insparseJacobianEigen
.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 linearizedBALfinal-394-100368-pre
:T
asvector<Eigen::Triple>
and usingsetFromTriplets
(original)T
asvector<boost::tuple>
and usingSparseEigen::insert
T
asvector<Eigen::Triple>
and usingSparseEigen::insert
(new)Notes about the diff:
sparseJacobian
tosparseJacobianInPlace
with the following modifications:entries
is no longer constructedcol
/row
variables were renamed tonrows
andncols
to match parameter namesb
vector are only added if they are non-zerotestGaussianFactorGraph
one entry A(5, 7) = 0 was removed since it has value 0 (see previous bullet point)