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

Add propagate and reweight actions #289

Merged
merged 6 commits into from
Jan 16, 2024
Merged

Add propagate and reweight actions #289

merged 6 commits into from
Jan 16, 2024

Conversation

nahueespinosa
Copy link
Member

Proposed changes

Related to #279.

Type of change

  • 🐛 Bugfix (change which fixes an issue)
  • 🚀 Feature (change which adds functionality)
  • 📚 Documentation (change which fixes or extends documentation)

Checklist

  • Lint and unit tests (if any) pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)
  • All commits have been signed for DCO

@nahueespinosa nahueespinosa added enhancement New feature or request cpp Related to C++ code labels Jan 14, 2024
@nahueespinosa nahueespinosa self-assigned this Jan 14, 2024
Base automatically changed from nahuel/self-assign-action to main January 14, 2024 15:45
Copy link
Collaborator

@hidmic hidmic left a comment

Choose a reason for hiding this comment

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

@nahueespinosa how do you imagine motion and sensor models will look like moving forward? Free functions for the simplest models? Stateful functors for the complex ones? I see pass-by-value semantics followed by move-construction. Are we going to divorce behavior and state, and have the latter be passed by reference explicitly?

beluga/include/beluga/actions/propagate.hpp Outdated Show resolved Hide resolved
beluga/include/beluga/actions/reweight.hpp Outdated Show resolved Hide resolved
@nahueespinosa
Copy link
Member Author

@hidmic In general I wouldn't divorce behavior and state unless we need to. I think we should be able to use stateful functors. But here I had a couple of potential implementation issues and I admittedly went for the lazy route.

The arguments of bind_back are always copied or moved, and must be wrapped in std::ref or std::cref if passing by reference is needed. That means there is no direct way to perfect-forward them using action closures.

In the overloads that create closures, if we're going to take a const Model& for instance, we should also overload Model&& (disabling lvalue reference binding) to make sure we make a copy and don't end up with a dangling reference to a temporary when we create our action closure in one line, and use it in another. Should we also consider mutable references? Constexpr ifs may be a way out of this madness.

That, plus the fact that I had to re-order the arguments to allow for the execution policy to go first, made me think I would need an huge amount of code to do this properly. And I couldn't think of a quick way of reducing duplication.

Before trying to implement this the hard way, I decided to give it a try to what the standard library does. It requires that function objects you pass to its algorithms be copyable. C++11 §25.1/10:

[ Note: Unless otherwise specified, algorithms that take function objects as arguments are permitted to copy those function objects freely. Programmers for whom object identity is important should consider using a wrapper class that points to a noncopied implementation object such as reference_wrapper (20.8.3), or some equivalent solution. —end note ]

That means that if we have a stateful (and expensive to copy) functor, we should use the following expression:

input |= beluga::actions::reweight(std::cref(sensor_model));

I know that the standard decision is from a time where perfect forwarding didn't exist and places the burden on the user, so I'm open to try to do it the hard way if you think it's worth it. Maybe it won't be as difficult as I think it will be.

@nahueespinosa
Copy link
Member Author

I have an idea... Will come back later.

@nahueespinosa
Copy link
Member Author

I was drowning in a glass of water. Stateful functors are now supported. 😅

@nahueespinosa nahueespinosa force-pushed the nahuel/actions branch 4 times, most recently from df9f265 to 965f285 Compare January 15, 2024 22:19
nahueespinosa and others added 6 commits January 16, 2024 00:39
Signed-off-by: Nahuel Espinosa <nespinosa@ekumenlabs.com>
Signed-off-by: Nahuel Espinosa <nespinosa@ekumenlabs.com>
Co-authored-by: Michel Hidalgo <michel@ekumenlabs.com>
Signed-off-by: Nahuel Espinosa <nespinosa@ekumenlabs.com>
Signed-off-by: Nahuel Espinosa <nespinosa@ekumenlabs.com>
Signed-off-by: Nahuel Espinosa <nespinosa@ekumenlabs.com>
Signed-off-by: Nahuel Espinosa <nespinosa@ekumenlabs.com>
Copy link
Collaborator

@hidmic hidmic left a comment

Choose a reason for hiding this comment

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

LGTM

@nahueespinosa nahueespinosa merged commit 80e2fe1 into main Jan 16, 2024
8 checks passed
@nahueespinosa nahueespinosa deleted the nahuel/actions branch January 16, 2024 12:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cpp Related to C++ code enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants