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

RPITIT and address a TODO for reveal #965

Merged
merged 5 commits into from
Mar 12, 2024

Conversation

andyleiserson
Copy link
Collaborator

Two changes here (separated into two commits) related only in that they both affect reveal.

The first change eliminates async_trait for the Reveal trait, using the same wrapper function workaround for HRTB issues that I used for BooleanArrayMul.

The second change uses a single generic reveal implementation to support both full and partial reveals, reducing duplication.

I have a different version of the second change that specifies whether a reveal is full or partial (and if partial, which helper is excluded) as a type parameter to the generic implementation. It would offer the following:

  • Avoid the unwrap in the trait-provided implementation of reveal. (The unwrap is perfectly safe as long as the code stays as-is, just unsightly.)
  • Prevent writing code that decides which helper to exclude from a partial reveal at runtime, since such code is likely to break TotalRecords determinism restrictions.

However, it ends up being more than a few lines of type-generic (i.e. hard to read) code, so I think it's probably not worth it. But I can share it if there's interest.

@@ -206,6 +210,20 @@ impl<'a, F: ExtendableField> Reveal<UpgradedMaliciousContext<'a, F>, 1> for Mali
}
}

// Workaround for https://github.com/rust-lang/rust/issues/100013. Calling this wrapper function
// instead of `Reveal::reveal` seems to hide the `impl Future` GAT.
pub fn reveal<'fut, C, S>(
Copy link
Collaborator

Choose a reason for hiding this comment

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

just curious if using pub async fn reveal(...) -> Result<S::Output,..> works too

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It does not... my hypothesis is it's related to this issue noted in my comment on #909:

The compiler is smart enough to see that if you have &local in the async move future, it can make that work by moving local into the future. However, this often results in the HRTB errors when the compiler needs to prove a statement of the form "for any lifetime 'local describing &local in the anonymous future, some other anonymous lifetime like 'ctx must outlive 'local.", which looks like for <'local> 'ctx: 'local, which the compiler can only reduce to 'ctx: 'static.

@akoshelev
Copy link
Collaborator

However, it ends up being more than a few lines of type-generic (i.e. hard to read) code, so I think it's probably not worth it. But I can share it if there's interest.

if that's easy, you could post a link to this PR and we can see if it ends up being not that hard. I agree that it is probably an overkill, but we could leave it here for educational purposes

.then(|| left_sender.send(record_id, right));
let send_right_fut = (Some(ctx.role().peer(Direction::Right)) != left_out)
.then(|| right_sender.send(record_id, left));
ctx.parallel_join(send_left_fut.into_iter().chain(send_right_fut))
Copy link
Member

Choose a reason for hiding this comment

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

A parallel join involves a bunch of machinery. Is there a cheaper way to join two Option<impl Future> ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What I really wanted here is the native try_join_all. To avoid the parallel join overhead without trying to use the disallowed method, I added a MaybeFuture helper so that we can treat each of the left and right actions as futures whether or not they're actually sending.

ctx: UpgradedMaliciousContext<'a, F>,
record_id: RecordId,
left_out: Role,
left_out: Option<Role>,
Copy link
Member

Choose a reason for hiding this comment

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

An observation, unrelated to this change:

"left" out is a poor name in this context because of the use of "left" and "right" as subjective labels for helpers. "skipped" or "excluded" perhaps?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I changed it to excluded.

) -> Result<Option<<V as Vectorizable<N>>::Array>, Error>
where
C: 'fut,
{
let left = self.left_arr();
let right = self.right_arr();

// send except to left_out
if ctx.role().peer(Direction::Right) != left_out {
// send except to excluded helper (if any)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
// send except to excluded helper (if any)
// Send shares, unless the target helper is excluded

@andyleiserson
Copy link
Collaborator Author

However, it ends up being more than a few lines of type-generic (i.e. hard to read) code, so I think it's probably not worth it. But I can share it if there's interest.

if that's easy, you could post a link to this PR and we can see if it ends up being not that hard. I agree that it is probably an overkill, but we could leave it here for educational purposes

Here it is: 56b3de6

Or as a diff vs. the version in this PR: https://github.com/andyleiserson/ipa/compare/e7793d60bd22d6c5298ee54cb020378d06cd84af..reveal-alt?expand=1

@akoshelev
Copy link
Collaborator

Here it is: 56b3de6

I kinda like it - it does look heavy on the trait implementation side, but using it is quite easy. Not insisting on using it though

Copy link

codecov bot commented Mar 11, 2024

Codecov Report

Attention: Patch coverage is 95.91837% with 6 lines in your changes are missing coverage. Please review.

Project coverage is 89.24%. Comparing base (603cebe) to head (096179e).
Report is 2 commits behind head on main.

Files Patch % Lines
ipa-core/src/helpers/futures.rs 64.70% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #965      +/-   ##
==========================================
- Coverage   89.24%   89.24%   -0.01%     
==========================================
  Files         158      159       +1     
  Lines       21718    21735      +17     
==========================================
+ Hits        19383    19398      +15     
- Misses       2335     2337       +2     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@andyleiserson andyleiserson merged commit cc5d71c into private-attribution:main Mar 12, 2024
11 checks passed
@andyleiserson andyleiserson deleted the reveal branch March 12, 2024 18:16
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