[Arith] Add opt-in lazily evaluated bounds for bound variables - #72
Open
LeiWang1999 wants to merge 1 commit into
Open
LeiWang1999 wants to merge 1 commit into
LeiWang1999 wants to merge 1 commit into
Conversation
Analyzer::Bind eagerly snapshots the value's integer bounds at bind time, so a bind replayed before the predicates that constrain its value keeps the wide bound forever: v = tx inside 'if (tx < 64)' stays at [0, 255] when the bind is entered first, even though tx itself tightens on demand. Analyses that replay collected constraint sets in an order unrelated to program order (tile-ai/tilelang#3220) hit exactly this. Add Analyzer::BindLazyBounds: identical to Bind except const_int_bound stores the definition instead of a snapshot. The bound is derived on demand under the constraints active at query time and memoized per constraint epoch (bumped on EnterConstraint entry/exit); definition chains recurse with a cycle guard. Results whose subtree consulted a lazy definition stay out of the caller-provided memo table, whose consistency check assumes constraint-independent entries. Eager Bind is untouched and remains the default everywhere; nothing opts in inside this repository, so behavior is unchanged unless a caller asks for the new mode.
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.
Implements the scoped variant of option 3 from tile-ai/tilelang#3220.
Problem
Analyzer::Bindeagerly snapshots the value's integer bounds at bind time and never re-evaluates them:v ≡ tx, yet their bounds disagree under the same constraint stack. Any consumer that replays collected binds/constraints in an order unrelated to program order (merged constraint sets in tile-ai/tilelang#3220) can therefore lose tightening permanently, and every ordering workaround downstream is a symptom of this premature evaluation.Change
Analyzer::BindLazyBounds(var, expr, allow_override)— identical toBindfor all sub-analyzers exceptconst_int_bound, which stores the definition (ConstIntBoundAnalyzer::UpdateDefinition) instead of a snapshot:EnterConstraintentry and exit), so bounds tighten and relax correctly across nested scopes;w = v * 2withvitself lazily bound) recurse, with a cycle guard degrading toEverything;operator()(expr, bound)), whose consistency ICHECK assumes constraint-independent entries;IsBoundreports definition-backed vars;Clone/CopyFromcarries them.Opt-in only: eager
Bindis untouched and remains the default; nothing inside this repository opts in, so behavior and performance are unchanged unless a caller explicitly asks. Exposed to Python asAnalyzer.bind_lazy_boundsvia the analyzer factory.Validation
tests/python/arith/test_arith_lazy_bind.py(7 tests): documents the eager staleness, then pins lazy behavior — later constraints visible, bind-order insensitivity, definition chains, memo invalidation across nested scopes (tighten → tighter → relax),CanProveintegration, override discipline.thread_sync,verify_parallel_loop,auto_schedule,analysis/,constr_set_merge) — 106 + 12 passed, zero behavior change with nothing opted in.Notes for reviewers
CanProve-routed queries are usually rescued from the stale snapshot by the rewrite path (the bound var is substituted by its definition before bounds are consulted), which is why [Transform][Arith] ConstrSet::Populate ordering is load-bearing in two incompatible directions (eager Analyzer::Bind snapshots) tilelang#3220 found upstream tests indistinguishable under reordering. The staleness bites consumers that queryconst_int_boundon bound vars directly — that is the surface this PR fixes. Switching tilelang'sConstrSet::Populateto the lazy mode is therefore optional and deferred until a workload demonstrates a need.const_int_boundonly;modular_set/int_setkeep their eager snapshots (their staleness has no demonstrated consumer yet and each would need its own epoch memo). Can extend in a follow-up if wanted.