Repository navigation
feat(devtools): stage_pipeline --price-enumerated prices each enumerated memo choice and flags any cheaper than the selected plan - #1028
Merged
Conversation
…d plan memo_pricing::price_choices composes each choice (memo::enumeration::compose), implements it with Stage 2 (every materialization assignment) and checks and prices it with Stage 3 under the run's models, recording validity, the rejection cause, cost per second and whether it is cheaper than the selected plan. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…emo choices Co-Authored-By: Claude Opus 5.5 <[email protected]>
…e unpriceable flag combinations Co-Authored-By: Claude Opus 5.5 <[email protected]>
This was referenced Oct 28, 2026
Open
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.
Closes #1004. Part of #1008.
Why
The default search (candidate-connection MILP) prices candidates through its own coefficients. Nothing checked that its selected plan is the cheapest of the candidate DAGs the memo stands for. #1009 lists those DAGs (
memo::enumeration::{enumerate, compose}) and #1024 writes them into thestage_pipelinedocument. This PR prices them.What
stage_pipeline --price-enumerated <n>(off by default) takes the firstnlisted choices ofmemo.enumeration. It runs each choice's composed DAG through Stage 2 and Stage 3, the same way the selected plan is checked and costed. For each choice it writesvalid,rejection,rejection_reason,cost_per_secondandcheaper_than_selected. It also writes the summarypriced: {count, cheaper_than_selected, selected_cost_per_second}. Without the flag,pricedstays null and the choices have no pricing fields (the contract's shape).How
asap_devtools::memo_pricing::price_choicestakes each choice and does four things:composegives the choice's DAG. Each query's operator references are replaced by their root groups' composed DAGs.validate_structurechecks the composed roots.optimize_physical_asap) builds every materialization assignment.select_plan) checks and prices them under the run'sPlanningModels: cost model, accuracy model (ignored or enforced), deployment capabilities and executor compile check. The run's calibration factor is frozen.A choice is valid when one of its physical plans passes. Its cost is the cheapest valid plan's cost. A choice is
cheaper_than_selectedwhen it is valid and costs less than the selected plan by more than Stage 3's tie tolerance (1e-9 relative).Key code interfaces added / modified
crates/devtools/src/memo_pricing.rs(new module)crates/devtools/src/bin/stage_pipeline.rs: new CLI flag--price-enumerated <n>(default 0 = off). It fills the contract's #1004 fields inmemo.enumeration. The flag is refused with--no-memo. It is also refused with--exhaustiveplus measured operation costs and nofrozen_calibration_factor, because the exhaustive search reports no calibration factor to cost each choice on the selection's scale.Usage (run at this head):
Major algorithm changes
None. This is a devtool check. Planning, search and selection are unchanged.
Before this PR
The document listed the memo's candidate DAGs without costs. Nobody could tell whether the MILP's selection was the cheapest of them.
After this PR
On small workloads,
--price-enumeratedprices every listed DAG and flags any valid DAG cheaper than the selection. The viewer (#1006) can mark those red.Evidence
All measured on this head with release builds, on a shared host (load average about 450 on 56 cores).
--max-enumerated 20000 --memo-enumeration-limit 20000)latency_bound_exceeded)no_accuracy_guarantee)executor_cannot_compileorno_accuracy_guarantee)Timing: pricing the 343 choices takes 0.21–0.40 s. Pricing the 169 ratio choices adds no measurable time over the run without pricing. Pricing Example 1's 720 final-memo choices adds about 50 s.
Note on the issue's numbers: the issue's 8 groups / 343 DAGs were measured without each series' identity column.
stage_pipelinelowers PromQL with it, so the twoquantile_over_time(0.5, data[5m])share a group: 7 groups, 49 Pass 1 DAGs (as #1024 also notes). The 343-DAG memo is priced in a library test. Without the identity, the executor compiles none of its per-series summaries, so only the exact DAG is valid. That DAG is not cheaper than the plan selected for the same query with identity. The default search finds no plan for the identity-less lowering, even with a 300 s budget, so that test compares against the selection of the identity lowering.Verification
crates/devtools/tests/memo_pricing.rs(new):example1_no_listed_choice_is_cheaper_than_the_selected_plan:stage_pipeline --price-enumeratedon Example 1. Every listed choice is priced, the enumeration is complete, andpricedmatches the Stage 3 selected cost. No valid choice is cheaper, and the latency rejections are named.ratio_of_quantiles_no_listed_choice_is_cheaper_than_the_selected_plan: the same check on the issue's workload, with guarantees ignored and enforced.ratio_of_quantiles_343_pass1_choices_none_cheaper_than_the_selected_plan: the identity-less Pass 1 memo enumerates completely (343 choices, 27 whole-budget). All are priced, and none is cheaper than the selection.a_worse_selection_is_caught_by_cheaper_than_selected: a baseline one step worse than the cheapest (the next-cheapest cost) flags exactly the cheapest choices.crates/devtools/tests/stage_pipeline.rs:memo_section_lists_each_step_the_selected_choice_and_the_enumerationnow also checks that without the flagpricedis null and no choice has pricing fields.cargo fmt --all --check;cargo clippy -p asap-devtools --all-targets -- -D warnings; the tests above, run in release.Architectural decisions
optimize_physical_asap) and Stage 3 (select_plan) entry points with the run's ownPlanningModels. The alternative, the MILP's internalmaterialize_selected_candidates, needs the search's candidate graph, which an enumerated choice has none of.Limitations and follow-up
concrete_states), only that prefix is priced. A clean result there does not prove the selection is optimal.cost_per_secondis null, socheaper_than_selectedis always false.🤖 Generated with Claude Code