8000 Gaussian Factor Graph Marginals by gchenfc · Pull Request #139 · borglab/gtsam · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Gaussian Factor Graph Marginals #139

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

Merged
merged 3 commits into from
Oct 10, 2019

Conversation

gchenfc
Copy link
Member
@gchenfc gchenfc commented Oct 9, 2019

Currently Marginals class only has a constructor from a nonlinear factor graph. Adding a constructor for a linear factor graph is trivial by just skipping the linearization step.

updated c++ unittests and created a python unittest, all pass

My c++ is not strong so let me know if I am doing some silly things.


This change is Reviewable

@gchenfc gchenfc changed the ti 10000 tle Gaussian Factor Graph unittests and linearization Gaussian Factor Graph Marginals Oct 9, 2019
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.

Nice. Approve w comments.


/* ************************************************************************* */
Marginals::Marginals(const GaussianFactorGraph& graph, const VectorValues& solution, Factorization factorization,
EliminateableFactorGraph<GaussianFactorGraph>::OptionalOrdering ordering)
Copy link
Member

Choose a reason for hiding this comment

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

Let's just use boost::optional<Ordering> everywhere? Including in .h file?

Copy link
Member Author

Choose a reason for hiding this comment

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

done

: graph_(graph), factorization_(factorization) {
gttic(MarginalsConstructor);
Values vals;
for (const VectorValues::KeyValuePair& v: solution) {
Copy link
Member

Choose a reason for hiding this comment

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

Let's modernize this to for (const auto& keyValue: solution) here and elsewhere in this file?

Copy link
Member Author

Choose a reason for hiding this comment

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

done

@dellaert
Copy link
Member
dellaert commente 8000 d Oct 9, 2019

@ProfFan what's the deal here. Should it be 'const boost::optional&` or boost::optional<const Ordering&>'. I think we ran into some issues with the latter for some compiler, when the Ordering passed in is a temporary object.

@gchenfc
Copy link
Member Author
gchenfc commented Oct 9, 2019

@dellaert
Copy link
Member
dellaert commented Oct 9, 2019

Yeah, I know... Questioning that "wisdom".

@varunagrawal
Copy link
Collaborator

I know this is a longshot, but as Jose mentioned, moving to C++17 would be a great idea, since it would allow us to use the native std::optional. I've had some pain with boost::optional in the past as well.

Just something to keep in mind. 🙂

@dellaert
Copy link
Member

Not doing that yet.

@ProfFan
Copy link
Collaborator
ProfFan commented Oct 10, 2019

@dellaert Today I encountered one problem debugging for Yetong. In some of the dynamics code we are passing temporary objects to boost::optional<Something &>, which definitely have lifetime issues. Thankfully latest boost will just panic and complain.

EDIT: Previous versions of boost will not complain, but anyway this require the temporary object to be stored in a variable instead, e.g.

ORIG:

someFactor(SomeValue * SomeOther)

NEW

auto actual = SomeValue * SomeOther;
someFactor(actual)

@dellaert
Copy link
Member

Exactly. The issue then is, if we say 'const boost::optional&`, is this efficient? Is a copy being made? And will it behave correctly for temporaries (e.g., and Ordering is constructed as part of the argument list)

@ProfFan
Copy link
Collaborator
ProfFan commented Oct 10, 2019

@dellaert

For size:

#include <iostream>
#include <memory>
#include <string>
#include <boost/optional.hpp>

class BigClass {
    public:
    int bigArray[2333];
    BigClass(int a0){
        bigArray[0] = a0;
    }
};

int main() {
  auto test = "Squat TEST!";
  
  std::unique_ptr<BigClass> ptr(new BigClass(0));
  boost::optional<BigClass> opt_empty;
  boost::optional<BigClass> opt_full(0);
  std::cout << "ptr:       " << sizeof(ptr) << '\n';
  std::cout << "*ptr:      " << sizeof(*ptr) << '\n';
  std::cout << "opt_empty: <
8000
span class="pl-pds">" << sizeof(opt_empty) << '\n';
  std::cout << "opt_full:  " << sizeof(opt_full) << '\n';
  std::cout << "*opt_full: " << sizeof(*opt_full) << '\n';
  return 0;
}
> gcc test.cpp -lstdc++ -o bin && ./bin
ptr:       8
*ptr:      9332
opt_empty: 9336
opt_full:  9336
*opt_full: 9332

@ProfFan
Copy link
Collaborator
ProfFan commented Oct 10, 2019

In terms of efficiency, if we are converting an ordinary object to an optional, there will always be a copy, as the layout of boost::optional is static, as shown above.

@ProfFan
Copy link
Collaborator
ProfFan commented Oct 10, 2019

After all, to me, simple overloading seems to be the best approach to optional parameters. (Remember hearing that in a CppCon presentation): https://foonathan.net/2018/07/optional-reference/

@ProfFan
Copy link
Collaborator
ProfFan commented Oct 10, 2019

Demo: https://godbolt.org/z/xwwkPc

@dellaert
Copy link
Member

Wow. Nice experimenting. I see the problem, but I think in this case overloading won’t work as we’re passing optional down.. Without copies, I think, these are const refs.

Here is what I propose, @gchenfc : please change all to const optional<Ordering>&. Then you could also make a separate PR that changes the typedef and hunts down any optional<Ordering&>

@ProfFan ?

@gchenfc
Copy link
Member Author
gchenfc commented Oct 10, 2019

I suspect this may be difficult to change without changing more code first, I'm getting

error: no viable conversion from 'const optional<gtsam::Ordering>' to 'optional<const gtsam::Ordering &>'

but may just be my lack of proficiency around boost/templating, I'm trying
const boost::optional<Ordering>& ordering = boost::none
and it's complaining in the bayesTree generation:
bayesTree_ = *graph_.eliminateMultifrontal(ordering, EliminatePreferCholesky);

@gchenfc
Copy link
Member Author
gchenfc commented Oct 10, 2019

perhaps changing back to
EliminateableFactorGraph<GaussianFactorGraph>::OptionalOrdering ordering
and then doing a separate PR to change OptionalOrdering typedef?

@dellaert
Copy link
Member
dellaert commented Oct 10, 2019 via email

@gchenfc
Copy link
Member Author
gchenfc commented Oct 10, 2019

changed back, compiled and passed tests on my computer.
will work on typedef PR.

@ProfFan
Copy link
Collaborator
ProfFan commented Oct 10, 2019

@dellaert Judging from the semantics, I think we can have an overload here between boost::optional<T&> and just T&, will also experiment later.

@dellaert dellaert merged commit 38cf6bd into borglab:develop Oct 10, 2019
varunagrawal added a commit that referenced this pull request Dec 17, 2021
2cbaf7a3a Merge pull request #131 from borglab/remove-pickle
0c2a4483c add documentation
2e5af11ad Merge pull request #139 from borglab/fix/matlab-memory-leak
442b7d3b0 update test fixtures
f89d5e4bd delete object after clearing it from object collector
971282703 add the correct variable for RTTI registry creation
9758dec57 update test fixture
87aeb8f8c remove need for declaring pickle function in interface file

git-subtree-dir: wrap
git-subtree-split: 2cbaf7a3a628766ff40657e0150b407ed4af7ccd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
48CE
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0