Repository navigation
feat(asap-aware-mapping)!: deployment capabilities (supported summaries, raw-data and query-time retention) - #730
Merged
Merged
Conversation
DeploymentCapabilities states which sketch families and readouts the executor supports, whether raw data is retained and whether a query-time result may be kept across evaluations. It sits in PlanningModels, and stage_pipeline reads it from --deployment <json> and shows it read-only under the document's top-level deployment. - Stage 1: Pass 1 offers no unsupported summary (PruneReason::UnsupportedByDeployment); Pass 2 adds none. - Stage 2: with query_time_retention, a tumbling-pane chain whose readers repeat at its pane width is also offered MatAtQuery (Example 4's B3). - Stage 3: such a chain is priced as kept across evaluations (one pane scanned and built per evaluation, N - 1 panes held); without raw data retained, a query-time scan makes a candidate invalid. - Remove CostModel::summary_support_evidence, replaced by the supported summaries. - Example 4's B3 tests run with query-time retention and are no longer ignored. The default deployment plans exactly as before.
…; surface Pass 1 pruning - Materialization gains MatAtQueryKeptAcrossEvaluations. With query_time_results_retained, Stage 2 offers it beside MatAtQuery (shared within one evaluation) and Stage 3 prices each, so a chain two panels read is no longer always priced as kept. - builds_one_pane_per_evaluation requires equal known evaluation phases. - Stored data with raw_data_retained false is bad input (DeploymentCapabilities::validate); the raw-data rejection lists every query-time scan. - Rename query_time_retention to query_time_results_retained and PlanningModels::deployment to deployment_capabilities (with with_deployment_capabilities, --deployment-capabilities and the document key). - stage_pipeline shows Pass 1 pruned candidates per target (pass1_pruned); FusedComputation records its pruned candidates. - Remove NodeCost.usage, NodeCost.per_second and NodeUsage; price() accumulates the candidate's ResourceUsage directly. The node map and kept chains are built once per candidate. - The kept arm charges N - 1 panes on disk; drop StatisticKind's Hash.
This was referenced Oct 16, 2026
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.
Why
#509 lists three deployment inputs: the cost model, the accuracy model and the executor's capabilities. Only the first two existed (the cost model's unit costs, resource speed and settings landed in #723). So the planner could offer a summary the executor cannot build or answer, it could not tell whether raw data is kept for query-time scans, and it had no way to plan Example 4's B3 (tumbling panes built at query time and kept across evaluations). Old drafts #609, #610 and #625 predate the current stage code. This PR reuses their ideas, not their code.
What
DeploymentCapabilities(new, inasap-aware-mapping, fieldPlanningModels::deployment_capabilities). It holds three inputs, all data:supported_summaries: the sketch families the executor supports, each with the readouts it supports, in the family-capability table's vocabulary (SketchAlgorithm,StatisticKind). "Supports" means the executor can build the family's state and answer that statistic from it.None(the default) supports everything the planner can build. Exact accumulators and plain exact execution are always supported.raw_data_retained(defaulttrue).query_time_results_retained(defaultfalse).PruneReason::UnsupportedByDeployment, and a fused computation moves its unsupported heaps to its own newprunedlist (with none left, it is not offered). Pass 2 then offers none either. Its rules share builds, split them into panes or reuse them, and none of them adds a family or a readout. A test checks this on Pass 2 output.scans 300000 ms of raw a, 60000 ms of raw b at query time, but the deployment does not retain raw data. Only ingestion-time work reads raw rows.AtRestorMixed) withraw_data_retained: falseis a contradiction. Plan selection refuses it as bad input (SelectionError::InvalidDeploymentCapabilities) before measuring any candidate.MaterializationgainsMatAtQueryKeptAcrossEvaluations(Medium). Stage 2 offers it for a tumbling-pane chain that builds exactly one new pane per evaluation (builds_one_pane_per_evaluation): every reader repeats at a fixed interval equal to the pane width, and readers with a known evaluation phase share one phase. Withquery_time_results_retained:MatAtQueryoption (shared within one evaluation) beside it, and Stage 3 prices both, so the cheaper wins.CostModel::summary_support_evidenceis removed, becausesupported_summariesreplaces it. No non-test code overrode it, and the legacy search's summary arm now returns its old default (None). TheCostModeltrait itself stays.NodeCost.usage,NodeCost.per_secondand theNodeUsagetype are deleted: nothing outsideprice()and tests read them, andstage_pipelinenever wrote them.price()adds each node's use straight into the candidate'sResourceUsage. A node's rate is still in itsdetail(x 0.0167/s).stage_pipeline --deployment-capabilities '<json>'reads the inputs (unknown fields are refused) and writes them read-only as the document's top-leveldeployment_capabilities. Stage 1 gainspass1_pruned: per target with any pruned candidate, its index, the query it is listed under, and every pruned candidate of its own (pruned) and of its fused computation (fused_pruned) with the reason. A user can now see why DDSketch disappeared.How
PerComputationCandidates::without_unsupported_summariesfilters the Pass 1 inventory. Each target's readout isstatistic(intent).kind(), the statistic its estimate reads. It runs inrun_stage1_to_stage3_from_pass1and in the devtools pipeline before enumeration, so the Cartesian product shrinks; nothing is enumerated and then discarded.run_stage2_and_stage3does not prune. Its doc now says so: callers must pass an inventory already pruned formodels.deployment_capabilities, withstage1enumerated from it. Pruning there would come too late, because each Stage 1 choice indexes the inventory it was enumerated from.MaterializationCandidate::may_keep_across_evaluationsadds theMatAtQueryKeptAcrossEvaluationsoption after the existing ones, which keeps the ids under default inputs.builds_one_pane_per_evaluationalso compares known phases modulo the interval. Its doc states the co-scheduling assumption: readers with no known phase run at the same instants as the others, as Stage 3's evaluation rate already assumes.node_map) and the kept chains (kept_pane_chains, now just the chains with the new variant) are built once per candidate and passed to bothraw_data_violationandprice. Stage 3 no longer recomputes the readers to decide what is kept.windows_readcounts one pane for those chains, so the scan, its latency and the raw data kept on disk cover one pane.DeploymentCapabilities::validateruns at the top ofselect_plan, beside the settings check.fixed_interval_msmoved fromstage1_to_stage3to Stage 2, so Stage 2 and Stage 3 share it.Decisions:
DeploymentCapabilitiesis a new struct next toPlanSelectionSettings, not a set of extra fields on it, because Stages 1 and 2 read it too andPlanSelectionSettingsis Stage 3's.query_time_results_retaineddefaults tofalse, so that the default inputs keep today's candidates and ids.Materializationvariant (overriding the earlier "no IR field" decision), so the physical DAG says which chains an executor keeps. A separate variant leaves the serializedMatAtQueryand every default document unchanged.ResourceCalibration::cost_per_retained_byteis not deleted. The legacyphysical_plan_cost_modelstill reads it throughResourceEstimate::calibrated_cost, and these inputs do not replace it.value_operation_*hooks stay. They gate exact-operation placement, which these inputs do not cover.Key code interfaces added / modified
crates/asap-aware-mapping/src/deployment_capabilities.rs(new module)crates/types/src/post_asap/execution_data_state.rscrates/asap-aware-mapping/src/pass/mod.rs,crates/asap-aware-mapping/src/pass/stage1_to_stage3.rscrates/asap-aware-mapping/src/per_computation_candidates.rscrates/asap-aware-mapping/src/stage2_physical_asap_optimization.rscrates/asap-aware-mapping/src/stage3_plan_selection.rscrates/types/src/post_asap/family_capability.rscrates/asap-aware-mapping/src/cost_model.rscrates/devtools/src/planning_stages.rs,crates/devtools/src/candidate_labels.rs,crates/devtools/src/bin/stage_pipeline.rsUsage, end to end (Example 3's Pattern B; every number is checked by
deployment_capabilities_flag_sets_the_capabilities_and_shows_them,query_time_results_retained_still_offers_the_chain_shared_within_one_evaluationand the Example 4 tests at this commit):Before this PR
CostModel::summary_support_evidence, which the stage pipeline never read.MatAtQuerywas offered only for a build shared by two or more queries, and it was reused within one evaluation. Example 4's B3 tests were#[ignore]d.After this PR
PlanningModels::with_deployment_capabilities, orstage_pipeline --deployment-capabilities), and the stage document shows them and every Pass 1 pruning with its reason.query_time_results_retained: trueraw_data_retained: falseWith the default deployment, nothing changes:
deployment_capabilitiesand an emptypass1_pruned.pass1_prunedis not empty: it lists the pruning that already happened on main (Cms, CountSketch and UnivMon pruned withRequiresExactfor its Q2 and Q3 targets).Verification
a_family_the_deployment_cannot_build_is_pruned,a_readout_the_deployment_cannot_answer_prunes_its_family,a_fused_computation_loses_its_unsupported_heaps(now also checks the fusedprunedreasons), andrestricting_summaries_removes_exactly_the_candidates_that_use_them(Examples 1, 2 and Pattern B: the restricted Stage 1 candidates equal, in order, the unrestricted ones whose every family and readout is supported).query_time_results_retained_still_offers_the_chain_shared_within_one_evaluation(the Pattern B + p50 workload; it failed before the fix with only the kept option offered).readers_at_different_phases_do_not_build_one_pane_per_evaluation(failed before the fix on phases 0 and 30 s).without_raw_data_every_query_time_scan_is_listed(failed before: only the first scan was listed),stored_data_without_raw_data_retained_is_bad_input(failed before: AtRest was accepted),without_raw_data_only_ingestion_time_scans_are_valid.query_time_results_retained_keeps_a_pane_chain_across_evaluations(now also checks that on disk the kept chain charges N − 1 panes; that check failed before the fix).node_prices_add_up_to_the_candidates_usagereplaces the test that summed node usages;state_on_disk_is_counted_as_disk_not_memoryandpartial_copies_of_the_newest_window_add_to_peak_memorynow check the candidate's usage.deployment_capabilities_flag_sets_the_capabilities_and_shows_them(flag, document key,pass1_pruned, raw-data rejection, unknown field refused).stage2_..._b_tumbling_kll_has_three_materialization_optionsandstage2_..._b_b3_keeps_query_time_windowsrun (no longer ignored).stage3_plan_selection_b_rebuilding_every_window_costs_moststays ignored with the numbers in its reason: the built-in model makes B2 (2.183/s) cheaper than B3 (8,884.5/s) and B1 (13,326.5/s).cargo nextest run -p asap-aware-mapping --libfiltered to Stage 2, Stage 3, deployment and Pass 1 tests: 118 passed;-p asap-aware-mapping --test per_computation_candidates: 29 passed.cargo nextest run -p asap-integration-tests --test deployment_capabilities --test planner_layering_example1 --test planner_layering_example2 --test planner_layering_example3 --test planner_layering_example4 --test reuse_rulesand-p asap-devtools --test stage_pipeline: all passed.cargo fmt --all -- --checkclean;cargo clippy -p asap-aware-mapping -p asap-devtools -p asap-integration-tests -p asap-types --all-targets --all-features --locked -- -D warningsclean.Limitations and follow-ups
The IR now records which pane chains are kept across evaluations (
MatAtQueryKeptAcrossEvaluations), but no executor in this repo keeps panes across evaluations yet. The kept option is planned and priced only.The executor does not declare its own capability set yet. Planning defaults to "everything", so a deployment must pass
--deployment-capabilitiesorwith_deployment_capabilities.B3 is priced in steady state; cold start, before the first N panes exist, is not.
Readers with no known phase are assumed co-scheduled with the others.
The DAG viewer does not render
deployment_capabilitiesorpass1_prunedyet.Raw retention is one global bool, with "not retained" meaning nothing is kept.