Repository navigation
refactor(stage3): baseline selection MILP over x, y, z, t with (A)-(I), realizer and plan export with θ and coverage (#1207 PR 6) - #1236
Draft
zzylol wants to merge 8 commits into
Conversation
…coverage; workload chain expansion; view coverage from the node (#1207 PR 6) physical_asap_dag_with_assignments exports roots with an ExportedNodeAssignment per operator node (physical properties, θ, summary coverage); the query-time test exporter calls it. PhysicalASAPDAGNode gains summary_coverage: Option<ViewCoverage>, the memo group's coverage the realizer sets, which materialized_views reads instead of deriving coverage from node trees (operator_nodes and the coverage todo deleted). ViewCoverage::of and of_tumbling_window give a plan node's coverage and each expanded tumbling window's. expand_tumbling_window_chains_in_workload returns again for installation. ScanWindow::union is public for Stage 3's memo-level scan windows. test_support::set_summary_coverage_from_memo sets coverage on hand-built plans through a Memo.
… PR 6) summary_shape takes the build's parameters (PhysicalASAPDAGNode::parameters) and fails with UnsupportedCandidate for a sketch without θ; state_family reads the node's θ. Restores the sizing tests deleted in PR 0.
…ed node (#1207 PR 6) The physical planner passes PhysicalASAPDAGNode::parameters to the summary build operators, which carry it to StateColumnUpdater, create_planner_accumulator and create_hydra_cms. validate_summary_kernel checks θ against the family; a state's consumers check the state's own shape at run time (validate_state, keyed evaluation capacity). A SummaryMerge carries its build's θ for the empty global state. Tests set θ on hand-built plans (test_support::set_test_parameters) and restore the parameter tests deleted in PR 0.
…1207 PR 6) Stage2AssignmentRealizer builds each selected node, producers first, as its candidate's operator over its selected producers; a tumbling-window layout becomes a SummaryTumblingWindowChain read through a merge of the whole chain. Each node is exported with its candidate's timing, lifetime, θ and its group's summary coverage; update weights the data proves non-negative are confirmed. The realizer keeps only entries and data (original_roots and query_time_results_retained deleted).
…s (A)-(I) (#1207 PR 6) select_plan prices every physical candidate once (w_v under cost model 1, candidate_cost.rs: asap-cost's node_usage over one representative producer per input at a fixed computation rate), builds x binary per candidate, y on admissible edges whose producer delivers on its consumer's query evaluations, z per query output group, t on candidates, and constraints (A)-(F) as named functions ((E) only inside strongly connected components), solves to optimality with HiGHS, decodes into DagOfSelectedCandidates and realizes it. Uncostable candidates are pruned (UsageNotCostable). The objective is inexact until execution contexts (#1207 PR 7) and reported as such. Selection drops nodes_with_proven_non_negative_weights (the realizer confirms weights). Tests per constraint and a reference enumeration (concepts doc Appendix A) that agrees with the MILP.
…elpers over the realizer (#1207 PR 6) PlanOutput carries the realized plan (replacing its tumbling-window retention map); plan_installable installs it, expanding its chains with each tumbling window at its chain's properties, θ, own coverage and retention (NoRealizedPlan when a pass realized none). Plan file wire version 14 (summary_coverage). The facade and devtools take the plan to run from the realizer. Integration helpers realize plans from the memo (realize_from_root_candidates); the fuzzer prices a witness through Stages 0-3. Planner test workloads that read chains declare their evaluation phase (delivers_on needs known evaluation times).
Installation keeps the assignment of a realized node under an expanded chain (only the new range and time shift run with the chain); a chain's merge runs at ingestion time only when no query reads it. Stage 3 costs candidates producers first in one worklist pass, picking each input's representative among costed producers, and refuses a window layout the realizer would refuse; SelectionInputs indexes candidates by group, the output groups and the edges once. Deleted, unused after the realizer: RealizedPlan::operator_node_of_selected_node, bounds::with_confirmed_weights and with_confirmed_weights_at. Docs and terminology.
…xport gives each sketch build a listed θ (#1207 PR 6)
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.
Stacked on #1235 (PR 5, Stage 2). Part of #1207 (PR 6 of the order), #1204. Draft; not to be merged on its own (one merge unit, PRs 0–9).
Why
After PR 5, planning stops at
select_plan'stodo!(): Stage 3, the realizer, the plan export and the executor's θ paths were stubs. #1207's order makes PR 6 the first end-to-end PR: the baseline formulation of the concepts doc §3 ("Stage 3: baseline selection and realization") as named code, with the export and the backend (executor) changed together.What
crates/stage3-plan-selection): variablesSelectionVariables) and one function per constraint family (A)–(F); (G)/(H) hold becauseasap-cost. Decoded intoDagOfSelectedCandidates, realized once, priced withplan_cost.Stage2AssignmentRealizer): one operator node per selected node over its selected producers; a tumbling-window layout becomes aSummaryTumblingWindowChainread through a whole-chainSummaryMerge. Each exported node carries its candidate's timing, lifetime, θ (parameters) and its memo group's summary coverage.PhysicalASAPDAGNode::summary_coverage(new);parametersis filled; plan-file wire version 14. Materialized-view coverage is read from the node (derived only in the memo); installation expands chains with each tumbling window's own coverage slice.todo!()s); the cost crate sizes states from the node's θ.todo!("#1207 PR 6 …")of the stack is implemented (Stage 3, realizer, installation, executor, cost, materialized-view coverage, integration helpers, fuzz pricing).Not in this PR (#1207 rows 7–9): execution contexts $x^{\mathrm{mat}}v$, $x{\kappa,v}$,$y_{\kappa,u,c,i}$ , $h_v$ and (R) (PR 7); accuracy (K) with $E_c$ /$D_c$ (PR 8); tools/snapshots (PR 9).
Representation, rules, enumeration (#1207 (a)/(b)/(c))
Notation → code
SelectionVariables::x(binary; fixed 0 for an uncostable candidate)SelectionVariables::y: HashMap<PhysicalEdgeId, Variable>SelectionVariables::z: HashMap<(QueryId, PhysicalCandidateId), Variable>SelectionVariables::tinput_satisfaction_constraintsproducer_selection_constraintsquery_coverage_constraintsacyclicity_constraints(edges inside strongly connected components only)utilization_constraintsselection_variables:satisfies_logical_requirement && satisfies_physical_requirementselection_variables(binaries, $0 \le t_v \lecandidate_cost::candidate_costsmilp::model::decode→DagOfSelectedCandidatesdelivers_on(§2 alignment)SelectionInputs::delivers_to_consumer(baseline: every query evaluation reaching the consumer)How
candidate_costs: candidates costed producers first (Kahn's order over admissible edges). Each candidate is onePhysicalASAPDAGNode(a windowed build as the chain the realizer builds) priced byasap_cost::node_usageover one representative (first costed) producer per input, at a fixed rate: 1/s at ingestion; per request of the queries reaching its group for a query-timeAcrossEvaluationsresult; per evaluation of each schedule of those queries otherwise.PruneReason::UsageNotCostable.solve_selection: builds (A)–(F), solves with HiGHS to proven optimality (gap 0, one thread), decodes.select_plan: validates the DAG, realizes it, prices it withplan_cost, reports the objective as inexact (InexactObjective, term "fixed cost per candidate … (execution contexts: Tracking: implement the optimization formulation (memo candidates, properties, edges y_{u,c,i}, MILP) as named code per stage #1207 PR 7)") when it differs, and the solver bound only when the objective is exact.over_childrenmaps a candidate'sOperator<MemoGroupId>onto its producers' nodes inchildren()order; confirms update weights the data proves non-negative (soSelection::nodes_with_proven_non_negative_weightsand the facade's re-application are deleted); exports withphysical_asap_dag_with_assignments.expand_tumbling_window_chains_in_workloadover the realized roots; each tumbling window takes its chain's assignment withViewCoverage::of_tumbling_window(index, width)and the chain's retention; realized nodes keep theirs; the new range/time shift run with the chain, not materialized.Major algorithm changes
Stage 3 selection
todo!(), so no workload planned.p[ctx,c],x[m], result slots,ebinaries, budget shares. After: steps 1–3 of How.DagOfSelectedCandidates::validatechecks it again. Tests: one per constraint family plusthe_milp_agrees_with_the_reference_enumeration(MILP optimum = cheapest enumerated DAG, 100 cases).Deleted (replaced in this PR)
Selection::nodes_with_proven_non_negative_weights, facade/devtools weight re-applicationbounds::confirmed_weights)bounds::with_confirmed_weights,with_confirmed_weights_atRealizedPlan::operator_node_of_selected_nodeStage2AssignmentRealizer::{original_roots, query_time_results_retained}physical.query_roots; Stage 2 already prunedPlanOutput::tumbling_window_retention_msPlanOutput::realized_planPhysicalASAPDAG::operator_nodes, node-treecoverage_ofPhysicalASAPDAGNode::summary_coveragefrom the memo#[cfg(test-support)]on the chain expansion helpersNew abstractions not in #1207 or the doc (pending approval)
asap_types::ir::physical_export::{ExportedNodeAssignment, physical_asap_dag_with_assignments}— what the realizer assigns each exported node, and the exporter.PhysicalASAPDAGNode::summary_coverage: Option<ViewCoverage>(wire field),ViewCoverage::of,ViewCoverage::of_tumbling_window.expand_tumbling_window_chains_in_workload,TumblingWindowChainExpansion,ExpandedTumblingWindowChain(restored; PR 0 deleted them as unused).PlanOutput::realized_plan,InstallablePlanError::NoRealizedPlan; plan-file wire version 14.ScanWindow::unionmade public.test_support::set_summary_coverage_from_memo; executor test-supportset_test_parameters,set_build_parameters,test_parameters.validate_summary_kernel(.., parameters, ..),create_hydra_cms(family, parameters),StateColumnUpdater::new(family, parameters),Operator::{per_group_summary_build, per_group_keyed_summary_build, all_groups_summary_build}(.., parameters, ..),with_emit_empty_global(parameters);parameterson the summary-build andSummaryMergeoperator kinds.asap_cost::state_bytes::summary_shape(family, parameters, rows) -> Result.SelectionInputs,SolvedSelection,SelectionMilpError,candidate_costmodule,SelectionInputs::delivers_to_consumer(a baseline stand-in for PR 7's per-contextdelivers_on).planning::realize_from_root_candidates.Key code interfaces added / modified
Permalinks at 09d69f1: stage3 select.rs, milp/model.rs, candidate_cost.rs, realize.rs, physical_export.rs, installable.rs
Usage (end to end; the test
runtime_install::the_plan_file_carries_theta_and_coverage_and_reads_back, which runs at 09d69f1):Before this PR
Planning stopped at
select_plan(todo!()); the executor could not build any sketch (θ todo!s);plan_installablewastodo!(). On main, the #1144 engine selected plans.After this PR
Every workload plans end to end through the baseline MILP, is realized, exported with θ and coverage, installed and compiled by the executor. Representative plans (cost model 1 defaults;
fixed_interval_at10 min, phase 0; 1,000 series at 1 s):Plans differ from main (the user checks them with
asap-planner --output text; the Stage 3 text printer is PR 9's). Known differences that show in tests are listed below.Verification
cargo fmt --all;cargo clippy --workspace --all-features --all-targets -D warningsclean;cargo clippy -p asap-types(no features) now warning-free (the PR 4tumbling_window_chain.rs/input.rswarnings are gone: the expansion code is used);crate_graph6/6 (stage 2 →asap-costis a stage → shared-model edge).one_producer_per_input_the_cheapest_and_its_inputs_selected((A)–(D)),an_inadmissible_edge_is_never_selected((G)/(H)),a_cycle_is_never_selected((E)),a_free_candidate_nothing_reads_is_not_selected((F)),an_uncostable_candidate_is_not_selected_and_an_uncostable_root_is_infeasible,a_windowed_state_is_read_only_by_queries_it_delivers_on,strongly_connected_components_group_cycles_only,the_milp_agrees_with_the_reference_enumeration; Stage 2 realizer — three tests (properties/θ/coverage, chain + merge + retention, invalid selection); cost — 5 restored sizing tests + 1; executor — θ tests restored/added (281/0/1); planner — the plan-file round trip.t: Vec), range charged though a chain bypasses it (objective is inexact anyway; PR 7).Test table (
cargo test -p <crate> --all-features --no-fail-fast, at 09d69f1; PR 5: 1190/206/9):Remaining failures, each with the later PR or the reason:
todo!()s (asap_plannerpruned-key/group printers,planning_stages_text); 12planner_fuzzrelations are inconclusive: a witness containing ASAP operators cannot be priced through Stages 0–3 (Pass 1 refuses ASAP input; pricing a fixed witness plan needs PR 9's tool rework), or the related workload is infeasible (below); 2asap_plannerCLI tests read the Stage 2/3 JSON the PR 9 printers write.view_refreshes_compile_only_the_nodes_below_them,ignoring_accuracy_guarantees_plans_the_undeclared_p99_query—avg by (…) (quantile_over_time(…))with no raw data: Pass 2 gives the avg-over-quantile edgessummary_sharing::{identical_ungrouped_queries_share_their_producers, identical_sql_percentiles_share_one_producer}— different plans (baseline costs; accuracy not enforced until (K), PR 8);check_compiles_reports_the_executors_error— the selected top-k plan holds anAggregatethe executor cannot run (Stage 2 executor-support rule gap, PR 5).PerEntityAggregateNotExecutablewith no executable alternative, e.g. the unsupported PromQL arm tests; PR 5/Pass 1); (ii) tests pinning a specific plan shape or sharing ratio (sharing_issue_regressions×5,identical_exact_queries×2,rollup_controlled,production_rollup_workloads,sql_to_post_asap×6,promql_to_post_asap,promql_numeric_regressions,filtered_aggregates,sketch_rollup×2,stage1_logical_asap_optimization×3,exact_composition) — the baseline's fixed costs and the missing (K) select other plans or helper realizations find no plan of the pinned shape (PR 7 contexts, PR 8 accuracy, PR 9 re-baseline); (iii)kll_tumbling_window_execution×3,materialized_views— hand-built/snapshot plans without θ or in the pre-14 wire format (PR 9 snapshots); (iv)joint_search_equivalence×3 — infeasible joint workloads and the accuracy-policy hook (PR 8).todo!().