[snapshot-regression-fix] lp: remove dio_calls_period linear recovery that defeats dio backoff#9976
Draft
levnach wants to merge 1 commit into
Draft
[snapshot-regression-fix] lp: remove dio_calls_period linear recovery that defeats dio backoff#9976levnach wants to merge 1 commit into
levnach wants to merge 1 commit into
Conversation
The Diophantine-handler scheduler in int_solver applies an exponential backoff: solve_dioph_eq() doubles dio_calls_period on every unproductive (undef) dio call to "throttle dio scheduling on failure", letting the solver escalate to Gomory cuts / branching once dio is persistently unproductive. should_solve_dioph_eq() additionally decreased dio_calls_period by a fixed amount (dio_calls_period_decrease, default 2) on every final_check where dio did not fire. Because non-firing calls vastly outnumber firing calls once the period grows, this linear per-call decrease overwhelms the geometric backoff and pins the period near its initial small value, so an unproductive dio keeps firing and the handoff to Gomory/branching never durably engages. On the nonlinear mixed Int/Real benchmark iss-8418/3.smt2 this causes a 20s timeout where the instance was previously solved as sat. Removing the linear recovery (and the now-unused dio_calls_period_decrease parameter) restores the intended backoff; the benchmark is solved sat in ~0.03s. The dio-before-Gomory ordering and the dio_gomory_enable_period gating are left unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes a snapshot-regression divergence reported in Z3Prover/bench discussion #2709 (
snapshot-regression: iss-8418/3.smt2 diverged).iss-8418/3.smt2(a quantifier-free nonlinear mixed Int/Real instance; corpus pathinputs/issues/iss-8418/inZ3Prover/bench)z3-4.17.0-x64-glibc-2.39(Nightly)sat, current z3 HEAD times out at the 20s per-file budget.Root cause
Bisected to commit
57fb71900"lp: gate Gomory-with-dio on genuine dio failures; separate config from runtime state (#9958)" — reverting that commit restoressat.The proximate cause is a linear "recovery" of
dio_calls_periodthat fights the Diophantine handler's exponential backoff:int_solver::solve_dioph_eq()doublesdio_calls_periodon every unproductive (undef) dio call — explicitly "throttle dio scheduling on failure". This geometric backoff is what lets the solver escalate to Gomory cuts / branching once dio is persistently unproductive (and, afterdio_gomory_enable_periodundefs, start running Gomory alongside dio).int_solver::should_solve_dioph_eq()additionally decreaseddio_calls_periodby a fixed amount (dio_calls_period_decrease, default2) on everyfinal_check()where dio did not fire.Once the period grows, non-firing calls vastly outnumber firing calls, so the linear per-call decrease overwhelms the geometric backoff and pins the period near its initial small value. The result is that a persistently-unproductive dio keeps firing and the intended hand-off to Gomory/branching never durably engages. On
iss-8418/3.smt2, where dio is unproductive on this nonlinear instance, the solver spins until the 20s timeout instead of returningsat.Fix
Remove the linear-recovery block in
should_solve_dioph_eq()and the now-unuseddio_calls_period_decreaseparameter (plus its setting field/accessors/wiring). This restores the intended exponential backoff so dio frequency decays on persistent failure.The two other heuristics introduced by
57fb71900are intentionally left unchanged:check(), anddio_gomory_enable_periodgating that starts Gomory after persistent dio failure.Net change: 4 files, 10 deletions, no additions.
Validation (rebuilt z3 + re-ran the benchmark — step 5)
Built the
./z3checkout at HEAD6a62a531(./configure && make -C build) and ran the failing benchmark with the same options the snapshot capture uses (emptyz3_opts,-T:20):timeoutat 20.00s (reproduced the divergence).satin ~0.03s — matches the recorded3.expected.outoracle, well within the 20s budget.Notes / uncertainty (please review)
dio_calls_periodrecovery heuristic that57fb71900introduced; that commit reported it contributed some additional QF_LIA solves in aggregate. Validation here is on the single regressing benchmark, not the full QF_LIA suite, so a maintainer should confirm there is no material aggregate regression.sat, in ~0.22s). Removing the throttle-defeating recovery was chosen instead because it preserves the author's intended ordering/gating and addresses the actual mechanism (a heuristic working against the documented backoff). Opened as a draft for human review.Originating discussion: https://github.com/Z3Prover/bench/discussions/2709