-
Notifications
You must be signed in to change notification settings - Fork 186
Add a third cycle mode, equivalent to old Salsa cycle behavior #801
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
Conversation
✅ Deploy Preview for salsa-rs canceled.
|
3521963
to
1c36d28
Compare
CodSpeed Performance ReportMerging #801 will degrade performances by 5.79%Comparing Summary
Benchmarks breakdown
|
I just realized there is still some non-determinism: if we enter a cycle and cache the result, then we call a query from the cycle that calls the cached result (that is, A -> B -> A then B -> A), it may be different than if we started if the other query (B -> A -> B). But this was also present in old Salsa and we didn't have problems from it, so 🤷 |
1c36d28
to
5f6e95e
Compare
The failing test was a demonstration of this non-determinism... I deleted it as it is fundamentally not compatible with this model. |
I don't think this is equivalent to the old Salsa cycle handling, and I don't think the old Salsa cycle handling was subject to the same non-determinism that this still is. The old cycle handling used catch-unwind to unwind and collect all queries participating in the cycle, without executing any of them, and then set all of them (not just the cycle head) to the same single fallback result. I think if we are OK with non-determinism when |
I don't see how it is possible to recreate equivalent behavior to the old Salsa cycle handling without reintroducing the use of catch-unwind. Catch-unwind is incompatible with WASM (and we need WASM in red-knot), but I think it should be fine for us as long as it's only opt-in with the use of I think catch-unwind is necessary because otherwise you can't cleanly propagate a form of "cancellation" of all the active queries in the cycle back up through the stack to the cycle head. (At least not without requiring cooperation / a new calling convention for all user-authored query code, which I don't think is an option.) |
Yes as Carl pointed out this is still not equivalent unfortunately, and we can't really bring back the old style fully without bringing back the cycle handling logic that was remoived with the fixpoint PR. |
I believe we can do the same, but what did old Salsa do when there was no fallback for query participating in the cycle? |
To explain: we can't cancel cycle participants, this is true. But we can run them to completion then ignore the result. For rust-analyzer at least this should be enough. |
5f6e95e
to
2f57a5c
Compare
@carljm @Veykril I modified the PR to do exactly what old Salsa did - use fallback for every query in the cycle that has them, and ignore the rest (the difference from old Salsa is that we require the cycle head to have fallback, and that we still execute the queries to completion (but throw the result)), and I believe it is fully deterministic now. I also brought back the test. |
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.
This approach looks reasonable to me.
That is, directly set a value for all queries that have fallbacks, and ignore all other queries in the cycle. Unlike old Salsa, we still need all cycle heads to be marked, and we still execute the queries to completion, but we throw their result.
2f57a5c
to
f61f973
Compare
@carljm Addressed comments. |
The failing benchmark is very noisy currently for some reason. |
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.
Looks good! I'm comfortable with this. Wouldn't mind a review from @Veykril or @MichaReiser as well, but fine with merge and post-land review as well.
Acknowledge the perf regression. The supertype bench has been the noisiest of the bunch. |
Simply dropping the query result after running it to completion can result in ever growing memory usage. The fallback query could have created tracked structs that now no longer have an owning query, and thus, never get removed. |
That is, directly set a value for all queries that have fallbacks, and ignore all other queries in the cycle.
Unlike old Salsa, we still need all cycle heads to be marked, and we still execute the queries to completion, but we throw their result.
This is an alternative to @Veykril's #798 PR, that doesn't suffer from non-determinism.