-
Notifications
You must be signed in to change notification settings - Fork 192
Fix maybe_changed_after runnaway for fixpoint queries
#961
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
Fix maybe_changed_after runnaway for fixpoint queries
#961
Conversation
✅ Deploy Preview for salsa-rs canceled.
|
CodSpeed Performance ReportMerging #961 will not alter performanceComparing Summary
|
47f0e6a to
0f8dfca
Compare
| db.assert_logs(expect![[r#" | ||
| [ | ||
| "salsa_event(DidValidateMemoizedValue { database_key: min_panic(Id(2)) })", | ||
| "salsa_event(WillExecute { database_key: min_iterate(Id(0)) })", | ||
| "salsa_event(WillExecute { database_key: min_iterate(Id(1)) })", | ||
| "salsa_event(WillExecute { database_key: min_panic(Id(3)) })", | ||
| "salsa_event(WillIterateCycle { database_key: min_iterate(Id(0)), iteration_count: IterationCount(1), fell_back: false })", | ||
| "salsa_event(WillExecute { database_key: min_iterate(Id(1)) })", | ||
| ]"#]]); |
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.
The output before this change was:
[
"salsa_event(WillExecute { database_key: min_iterate(Id(0)) })",
"salsa_event(WillExecute { database_key: min_iterate(Id(1)) })",
"salsa_event(DidValidateMemoizedValue { database_key: min_panic(Id(2)) })",
"salsa_event(WillExecute { database_key: min_panic(Id(3)) })",
"salsa_event(WillIterateCycle { database_key: min_iterate(Id(0)), iteration_count: IterationCount(1), fell_back: false })",
"salsa_event(WillExecute { database_key: min_iterate(Id(1)) })",
]
Note how c (min_panic(Id(2))) doesn't get verified as part of a's deep_verify_memo. Instead, it only gets verified once a re-runs.
davidbarsky
left a comment
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.
a few nits/asks for clarification
73fd32d to
2131fee
Compare
maybe_changed_after runnaway for fixpoint queries
|
The failing test is related to Rust 1.89 |
carljm
left a comment
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, thank you!
2131fee to
3a7e731
Compare
This PR fixes a few bugs related to
maybe_changed_afterand fixpoint iteration.Runnaway
The most important fix is for a runaway issue where
maybe_changed_afterrevalidates the same queries repeatedly, see #960.Given a query:
C doesn't participate in the cycle, but we didn't mark it as verified before this PR because the outer query `a is participating in a not-yet-resolved cycle.
This PR fixes this by tracking the cycles per query (each subtree tracks the cycles independently). I added
cycle_sibling_interferenceas a regression test.validate_same_iterationmaybe_changed_afterinternally callsdeep_verify_memo, which, on master, callsmaybe_validate_provisional, which callsvalidate_same_iteration.validate_same_iterationreturnstruefor a provisional query if the cycle heads between its cycle head entries and the latest available memos for those cycle heads have the same iteration count. This is important infetch, where we want to reuse cached query results during a fixpoint iteration.However, we shouldn't return
Unchangedinmaybe_changed_afterfor a memo that's not finalized butvalidate_same_iterationreturnstruebecause we simply don't know yet if that value has changed or not (we need to wait for its cycle heads to resolve).This PR moves the
validate_same_iterationcheck out ofdeep_verify_memoand instead duplicates it insidefetch_coldandmaybe_changed_after_cold, where onlyfetch_coldreturns early whenvalidate_same_iterationreturnstrue.I tried to write a regression test for this but I failed. However, we have an incremental integration test in ty that starts failing without this change (because a query now returns an outdated result).
Re-execution and provisional memos
If there are no pending cycles in
maybe_changed_afterand there's an old memo, Salsa executes the query again and then compares thelast_changed_atwith therevisionpassed tomaybe_changed_afterto decide if the value has changed.This PR adds an additional check to only return
unchangedif the value isn't provisional.I don't know if this is a 100% necessary and I failed to write an integration test for it (and no test in ty fails). So it might be that some other combination of checks prevent this but I can't say for sure. That's why I added the check.