feat: add --per-depth-timeout option for kontrol prove#1141
Open
Stevengre wants to merge 2 commits into
Open
Conversation
1f0cc6a to
36d97eb
Compare
36d97eb to
a20aacb
Compare
4 tasks
a20aacb to
bd56284
Compare
--per-depth-timeout option for progressive depth-halving prove--per-depth-timeout option for kontrol prove (blocked by kevm-pyk #2850)
bd56284 to
a0fce21
Compare
--per-depth-timeout option for kontrol prove (blocked by kevm-pyk #2850)--per-depth-timeout option for kontrol prove
71e977c to
3a1e97d
Compare
Adds progressive depth-halving with a per-attempt **stall window**. When `--per-depth-timeout S` is set, each attempt is given an initial window of `current_depth * S` seconds. The parent polls the proof's on-disk subdir every window: if any file mtime changed (i.e. the prove committed at least one step), the window is reset for another round. If no progress is observed across a full window, the entire subprocess session is reaped with `os.killpg(..., SIGKILL)` (Python + KoreServer + parallel-frontier worker threads), `current_depth` is halved (floor 1), and the next attempt resumes from the disk-persisted KCFG state. Each attempt runs in a forked subprocess that calls `os.setsid()` to become its own session leader, so a single `killpg` reaps the entire subtree. The proof state is persisted by `advance_proof`'s maintenance loop (maintenance_rate=1, default), so on-disk KCFG state is current up to the last committed step at the moment of the kill. Default 0 disables the wrapper: the existing single-attempt `run_prover(...)` path is taken with no subprocess overhead.
3a1e97d to
a2d3a09
Compare
Member
|
This seems like something we can probably build into |
Drops the standalone `_init_and_run_proof_progressive` helper and moves the halving loop directly under the `per_depth_timeout > 0` branch at the top of `init_and_run_proof`. The progressive block is followed by the unchanged single-attempt body, separated by a blank line. Per-attempt session management stays in `_run_attempt_under_timeout` (separate concern, ~70 lines). Addresses review feedback on PR #1141.
Contributor
Author
|
@ehildenb Instead of providing this feature through a long dependency, I'd like to have a pr here to prove the concept and use it earlier.
|
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
Adds
--per-depth-timeout SECONDStokontrol prove. Each prove attempt runs in a forked subprocess withcurrent_depth * per_depth_timeoutseconds as a stall window: as long as the proof keeps writing to disk (any file underproofs_dir/<test.id>gets a new mtime), the window resets. When a full window passes with no writes, the whole session is SIGKILL'd,current_depthis halved (floor 1), and the next attempt resumes from the disk-persisted KCFG. Default0disables the wrapper.Example:
--max-depth 1000 --per-depth-timeout 0.5→ 500s window at depth 1000, halving to 250s @ 500, … 0.5s @ 1.Why this shape
execute_depthis too coarse to break out of a stuck step. As long as new nodes appear, we leave the proof alone.advance_proof's maintenance callback only fires afterstep_proofreturns. A single long step (deep symbolic execution, expensive SMT) is uninterruptible from inside the prover. Killing the session is the only way to enforce wall-clock regardless of what the prover is doing.Implementation
cli.py/options.py: new--per-depth-timeoutflag andProveOptions.per_depth_timeoutfield (default0).prove.py: whenper_depth_timeout > 0,init_and_run_proofdispatches to_init_and_run_proof_progressive, which loops over halving depths via_run_attempt_under_timeout:mp.get_context('fork').Process→ child inherits everything via CoW; childos.setsid()so the parent'skillpgreaps Python + KoreServer + worker threads.proc.join(timeout=budget_s)then compares max mtime underproofs_dir/<test.id>against the previous snapshot. Changed → another window. Unchanged → SIGKILL, halve, retry.Test plan
kontrol prove --helplists--per-depth-timeoutwith documented behavior.kontrol prove --match-test TokenValueLibProofs.init --max-depth 100(no--per-depth-timeout) passed in 28s; process tree showed a single python + one kore-rpc-booster (no fork), confirming therun_proverpath is unchanged.test_amountToValueDown,--per-depth-timeout 0.5 --max-depth 1000): observed 10 halvings 1000→1, KCFG advanced 1437 steps in the first attempt then stayed pinned at the deepest unresolvable node — proof stopped exactly where it should.pgrep kore-rpc-boosterreturned 0 — session-group SIGKILL reaped every kore-rpc subprocess across all kill cycles.Caveats
proof.write_proof_data()is assumed atomic (temp + rename); a SIGKILL mid-write would at worst lose one step.budget_swindow beyond actual stall onset.