diff --git a/crates/devtools/src/bin/sketch_coverage.rs b/crates/devtools/src/bin/sketch_coverage.rs index e0e7c7b53..3c171c11d 100644 --- a/crates/devtools/src/bin/sketch_coverage.rs +++ b/crates/devtools/src/bin/sketch_coverage.rs @@ -15,7 +15,7 @@ use asap_devtools::lower_promql_with_sample_interval; use asap_frontend_sql::{lower_sql_dialect, SqlCatalog}; -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ generate_per_computation_candidates, ComputationCandidate, }; use asap_types::ir::properties::AccuracyTarget; diff --git a/crates/devtools/src/bin/stage_pipeline.rs b/crates/devtools/src/bin/stage_pipeline.rs index 25d50e113..17adc2779 100644 --- a/crates/devtools/src/bin/stage_pipeline.rs +++ b/crates/devtools/src/bin/stage_pipeline.rs @@ -270,12 +270,12 @@ use asap_devtools::planning_stages::{ }; use asap_devtools::SqlCatalog; use asap_frontend_promql::{counter_function_over_gauge_warnings, promql_metric_names}; -use asap_logical_asap_optimization::memo::candidates::{CandidateMemo, CandidateOrigin}; -use asap_logical_asap_optimization::memo::enumeration::{compose, enumerate, MemoChoice}; -use asap_logical_asap_optimization::memo::MemoGroupId; -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ ComputationCandidate, PerComputationCandidates, PruneReason, }; +use asap_logical_asap_optimization::pass2::memo::candidates::{CandidateMemo, CandidateOrigin}; +use asap_logical_asap_optimization::pass2::memo::enumeration::{compose, enumerate, MemoChoice}; +use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_logical_asap_optimization::DeploymentCapabilities; use asap_plan_selection::{ large_peak_memory_warning, ClusterLimits, ClusterObjective, CostModel, MeasuredOperationCosts, diff --git a/crates/devtools/src/candidate_labels.rs b/crates/devtools/src/candidate_labels.rs index bb4d84421..cd844ca2f 100644 --- a/crates/devtools/src/candidate_labels.rs +++ b/crates/devtools/src/candidate_labels.rs @@ -6,11 +6,11 @@ use std::collections::BTreeMap; use std::rc::Rc; -use asap_logical_asap_optimization::asap_aware_cse::PaneCandidate; -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ ComputationCandidate, PerComputationCandidates, }; -use asap_logical_asap_optimization::workload_candidates::Pass2Candidate; +use asap_logical_asap_optimization::pass2::asap_aware_cse::PaneCandidate; +use asap_logical_asap_optimization::pass2::workload_candidates::Pass2Candidate; use asap_physical_asap_optimization::PhysicalWorkloadPlan; use asap_types::ir::physical_export::{PhysicalASAPDAG, PhysicalASAPNodeId}; use asap_types::ir::schema::{FieldDataType, SketchAlgorithm}; @@ -661,7 +661,7 @@ mod tests { use super::*; use crate::planner_layering_examples::example1; use crate::planning_stages::lower_promql_roots; - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, }; @@ -712,10 +712,10 @@ mod tests { /// have the same family and pane count (6 × 10s for Q1, 6 × 30s for Q2). #[test] fn physical_labels_name_the_pane_chain_maintained_at_ingestion() { - use asap_logical_asap_optimization::asap_aware_cse::{ + use asap_logical_asap_optimization::deployment_capabilities::DeploymentCapabilities; + use asap_logical_asap_optimization::pass2::asap_aware_cse::{ pane_candidates, window_composition_pass2_candidates, }; - use asap_logical_asap_optimization::deployment_capabilities::DeploymentCapabilities; use asap_physical_asap_optimization::optimize_physical_asap; use asap_types::workload::PlanningWorkload; diff --git a/crates/devtools/src/memo_pricing.rs b/crates/devtools/src/memo_pricing.rs index aa1e9e27d..b53998bfb 100644 --- a/crates/devtools/src/memo_pricing.rs +++ b/crates/devtools/src/memo_pricing.rs @@ -7,9 +7,9 @@ use std::collections::HashMap; use std::rc::Rc; -use asap_logical_asap_optimization::memo::candidates::CandidateMemo; -use asap_logical_asap_optimization::memo::enumeration::{compose, MemoChoice}; -use asap_logical_asap_optimization::memo::MemoGroupId; +use asap_logical_asap_optimization::pass2::memo::candidates::CandidateMemo; +use asap_logical_asap_optimization::pass2::memo::enumeration::{compose, MemoChoice}; +use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_physical_asap_optimization::optimize_physical_asap; use asap_plan_selection::{select_plan, PlanningModels, Selection, SelectionError}; use asap_types::ir::{OperatorNode, QueryRoot}; diff --git a/crates/devtools/src/planner_fuzz/mod.rs b/crates/devtools/src/planner_fuzz/mod.rs index 8d434f396..97a0d0a15 100644 --- a/crates/devtools/src/planner_fuzz/mod.rs +++ b/crates/devtools/src/planner_fuzz/mod.rs @@ -508,7 +508,7 @@ impl Planner { .map_err(|e| format!("witness validation: {e}"))?; } let mut roots = - asap_logical_asap_optimization::per_computation_candidates::recompose_guarantees(roots) + asap_logical_asap_optimization::pass1::per_computation_candidates::recompose_guarantees(roots) .map_err(|e| format!("witness guarantees: {e}"))?; if let (true, Some(last)) = (last_root_is_key_filter, roots.last_mut()) { let filter = last.as_operator().ok_or("a scalar root")?; diff --git a/crates/devtools/src/planning_stages.rs b/crates/devtools/src/planning_stages.rs index 366b7c013..db528d32d 100644 --- a/crates/devtools/src/planning_stages.rs +++ b/crates/devtools/src/planning_stages.rs @@ -3,8 +3,8 @@ //! tests, so both see the same candidates, ids and selection. use asap_frontend_sql::SqlCatalog; -use asap_logical_asap_optimization::per_computation_candidates::PerComputationCandidates; -pub use asap_logical_asap_optimization::workload_candidates::Pass2Candidate; +use asap_logical_asap_optimization::pass1::per_computation_candidates::PerComputationCandidates; +pub use asap_logical_asap_optimization::pass2::workload_candidates::Pass2Candidate; use asap_physical_asap_optimization::PhysicalWorkloadPlan; use asap_plan_selection::pass::{run_stage1_to_stage3_with, Stage1ToStage3Search}; pub use asap_plan_selection::pass::{LogicalCandidate, MemoSteps, PrunedCandidate}; diff --git a/crates/devtools/tests/memo_pricing.rs b/crates/devtools/tests/memo_pricing.rs index 784d45eec..a59c6f421 100644 --- a/crates/devtools/tests/memo_pricing.rs +++ b/crates/devtools/tests/memo_pricing.rs @@ -5,10 +5,10 @@ use asap_devtools::memo_pricing::{price_choices, PricedChoice, SelectedBaseline} use asap_devtools::planner_layering_examples::example1; use asap_devtools::planning_stages::{lower_promql_roots, run_default_search_over}; use asap_logical_asap_optimization::deployment_capabilities::DeploymentCapabilities; -use asap_logical_asap_optimization::memo::candidates::{try_populate_pass1, CandidateMemo}; -use asap_logical_asap_optimization::memo::enumeration::enumerate; -use asap_logical_asap_optimization::memo::LogicalMemo; -use asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates; +use asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates; +use asap_logical_asap_optimization::pass2::memo::candidates::{try_populate_pass1, CandidateMemo}; +use asap_logical_asap_optimization::pass2::memo::enumeration::enumerate; +use asap_logical_asap_optimization::pass2::memo::LogicalMemo; use asap_plan_selection::{PlanSelectionSettings, PlanningModels}; use asap_planner::PlannerExecutorCompileCheck; use asap_types::ir::properties::AccuracyTarget; diff --git a/crates/devtools/tests/stage_pipeline.rs b/crates/devtools/tests/stage_pipeline.rs index 5f3ea2589..05f9f8476 100644 --- a/crates/devtools/tests/stage_pipeline.rs +++ b/crates/devtools/tests/stage_pipeline.rs @@ -1735,7 +1735,7 @@ fn scans_projecting_different_labels_are_shared() { let entries: Vec<_> = workload.query_workload.entries().collect(); let data = workload.data_workload.as_ref().unwrap(); let roots = lower_promql_roots(&workload).unwrap(); - use asap_logical_asap_optimization::asap_aware_cse::with_union_scan_labels; + use asap_logical_asap_optimization::pass2::asap_aware_cse::with_union_scan_labels; let widened = with_union_scan_labels(&roots).unwrap().unwrap(); // Identical sub-DAGs made one node, as the memo's groups are: the // widened scan, and the two instant selectors' identical range. @@ -2337,8 +2337,8 @@ fn memo_section_lists_each_step_the_selected_choice_and_the_enumeration() { #[test] fn composed_selected_choice_is_the_selected_stage1_dag() { use asap_devtools::planning_stages::run_default_search_over; - use asap_logical_asap_optimization::memo::enumeration::compose; - use asap_logical_asap_optimization::per_computation_candidates::recompose_guarantees; + use asap_logical_asap_optimization::pass1::per_computation_candidates::recompose_guarantees; + use asap_logical_asap_optimization::pass2::memo::enumeration::compose; use asap_types::ir::flat::flatten; let ratio: PlanningWorkload = serde_json::from_str(&std::fs::read_to_string(MEMO_RATIO_OF_QUANTILES).unwrap()).unwrap(); diff --git a/crates/executor/tests/common/mod.rs b/crates/executor/tests/common/mod.rs index da5ab3c97..0138c5a8f 100644 --- a/crates/executor/tests/common/mod.rs +++ b/crates/executor/tests/common/mod.rs @@ -37,7 +37,7 @@ pub fn selected_dag( /// computations at their default choice. A bounded solver archive need not /// contain every algorithm that executor binding tests need to exercise. pub fn computation_candidates(root: Rc) -> Vec> { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, }; let inventory = generate_per_computation_candidates(vec![(0, QueryRoot::Operator(root))]) diff --git a/crates/frontend-promql/tests/count_planning.rs b/crates/frontend-promql/tests/count_planning.rs index 491cadff5..5ac20e6cb 100644 --- a/crates/frontend-promql/tests/count_planning.rs +++ b/crates/frontend-promql/tests/count_planning.rs @@ -280,7 +280,7 @@ fn cms_count_updates_total_ten_for_zero_positive_and_negative_samples() { #[test] #[should_panic(expected = "does not compose")] fn logical_candidates_fails_on_a_candidate_that_does_not_compose() { - use asap_logical_asap_optimization::per_computation_candidates::PerComputationCandidateError; + use asap_logical_asap_optimization::pass1::per_computation_candidates::PerComputationCandidateError; support::require_composed_operator_candidates(vec![ asap_plan_selection::search::LogicalCandidate { id: "invalid-composition".into(), diff --git a/crates/frontend-promql/tests/support.rs b/crates/frontend-promql/tests/support.rs index a96d596d0..2716d4d6c 100644 --- a/crates/frontend-promql/tests/support.rs +++ b/crates/frontend-promql/tests/support.rs @@ -183,7 +183,7 @@ pub fn logical_candidates(root: Rc) -> Vec> { } fn local_computation_candidates(root: Rc) -> Result>, String> { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, }; use asap_types::ir::QueryRoot; diff --git a/crates/frontend-sql/tests/frequency_l2.rs b/crates/frontend-sql/tests/frequency_l2.rs index 5254e3318..db14d0bf7 100644 --- a/crates/frontend-sql/tests/frequency_l2.rs +++ b/crates/frontend-sql/tests/frequency_l2.rs @@ -149,7 +149,7 @@ async fn batch_lowering_recognizes_frequency_l2() { /// recognized L2 intent. #[tokio::test] async fn stage1_offers_exact_and_summary_l2_candidates() { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ generate_per_computation_candidates, ComputationCandidate, }; use asap_types::ir::QueryRoot; diff --git a/crates/integration-tests/src/lib.rs b/crates/integration-tests/src/lib.rs index 17789eec6..7e796ca24 100644 --- a/crates/integration-tests/src/lib.rs +++ b/crates/integration-tests/src/lib.rs @@ -218,7 +218,7 @@ pub mod planning { /// Exact computation and each explicit single-target rule application. /// This fixture catalog is independent of the bounded MILP's visited plans. pub fn explicit_local_candidates(root: Rc) -> Vec> { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, }; let local = @@ -252,7 +252,7 @@ pub mod planning { root: Rc, family: asap_types::ir::schema::SketchAlgorithm, ) -> Rc { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; let local = @@ -305,13 +305,13 @@ pub mod planning { pub fn expanded_memo( roots: Vec<(usize, QueryRoot)>, entries: &[asap_types::workload::QueryWorkloadEntry], - ) -> asap_logical_asap_optimization::memo::candidates::CandidateMemo { - use asap_logical_asap_optimization::memo::{ - candidates::try_populate_pass1, state_configurations::PaneWidthDomain, + ) -> asap_logical_asap_optimization::pass2::memo::candidates::CandidateMemo { + use asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass2::memo::{ + candidates::try_populate_pass1, shared_configurations::PaneWidthDomain, state_groups::expand_concrete_summary_state_groups_in_domain, window_candidates::add_local_window_composition, LogicalMemo, }; - use asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates; let initial = LogicalMemo::from_roots(&roots); let inventory = generate_per_computation_candidates(roots).unwrap(); let mut memo = try_populate_pass1(initial, &inventory).unwrap(); @@ -325,11 +325,11 @@ pub mod planning { /// each query's first root group's DAG, every group `choice` does not /// name implemented by its first candidate. pub fn compose_memo_plan( - memo: &asap_logical_asap_optimization::memo::candidates::CandidateMemo, + memo: &asap_logical_asap_optimization::pass2::memo::candidates::CandidateMemo, queries: usize, choice: &std::collections::BTreeMap, ) -> Vec> { - use asap_logical_asap_optimization::memo::{enumeration::compose, MemoGroupId}; + use asap_logical_asap_optimization::pass2::memo::{enumeration::compose, MemoGroupId}; let choice = choice .iter() .map(|(&group, &index)| (MemoGroupId(group as u32), index)) @@ -363,7 +363,7 @@ pub mod planning { // Composed nodes lose their guarantees; recompose them as // `run_explicit_candidates` does. let roots = - asap_logical_asap_optimization::per_computation_candidates::recompose_guarantees( + asap_logical_asap_optimization::pass1::per_computation_candidates::recompose_guarantees( roots, ) .unwrap_or_else(|error| panic!("{name} composes guarantees: {error}")); @@ -399,10 +399,10 @@ pub mod planning { /// alone) candidates `keep` accepts; those of the topmost group (the /// fewest child edges below `q`'s root) first. pub fn own_choices( - memo: &asap_logical_asap_optimization::memo::candidates::CandidateMemo, + memo: &asap_logical_asap_optimization::pass2::memo::candidates::CandidateMemo, q: usize, keep: impl Fn( - &asap_logical_asap_optimization::memo::candidates::ImplementationCandidate, + &asap_logical_asap_optimization::pass2::memo::candidates::ImplementationCandidate, ) -> bool, ) -> Vec<(usize, usize)> { let mut found: Vec<_> = memo @@ -453,7 +453,7 @@ pub mod planning { /// - `shared{g}`: every query reads the summary state group `g`, its own /// estimate or a regrouping merge of it, when every query can. pub fn select_rollup( - memo: &asap_logical_asap_optimization::memo::candidates::CandidateMemo, + memo: &asap_logical_asap_optimization::pass2::memo::candidates::CandidateMemo, queries: usize, entries: &[asap_types::workload::QueryWorkloadEntry], data: &DataWorkload, @@ -463,7 +463,7 @@ pub mod planning { .map(|q| { let found = own_choices(memo, q, |c| { c.origin - == asap_logical_asap_optimization::memo::candidates::CandidateOrigin::Pass1 + == asap_logical_asap_optimization::pass2::memo::candidates::CandidateOrigin::Pass1 && builds(&c.node) }); let top = found @@ -579,13 +579,13 @@ pub mod planning { /// Apply sharing rules and Stage 2 to a small explicitly supplied fixture set, /// then price it with the production evaluator. No workload product search. pub fn explicit_assignment_plans( - inventory: asap_logical_asap_optimization::per_computation_candidates::PerComputationCandidates, + inventory: asap_logical_asap_optimization::pass1::per_computation_candidates::PerComputationCandidates, assignments: Vec>, entries: &[asap_types::workload::QueryWorkloadEntry], data: &asap_types::workload::DataWorkload, ) -> asap_plan_selection::Stage1ToStage3Run { - use asap_logical_asap_optimization::per_computation_candidates::recompose_guarantees; - use asap_logical_asap_optimization::workload_candidates::stage1_candidates_of_choice; + use asap_logical_asap_optimization::pass1::per_computation_candidates::recompose_guarantees; + use asap_logical_asap_optimization::pass2::workload_candidates::stage1_candidates_of_choice; use asap_plan_selection::{search::LogicalCandidate, PlanningModels, Stage1ToStage3Run}; let mut logical = Vec::new(); let mut physical = Vec::new(); diff --git a/crates/integration-tests/tests/deployment_capabilities.rs b/crates/integration-tests/tests/deployment_capabilities.rs index 8063c00e0..7cfa65e52 100644 --- a/crates/integration-tests/tests/deployment_capabilities.rs +++ b/crates/integration-tests/tests/deployment_capabilities.rs @@ -71,12 +71,12 @@ fn assert_removes_exactly( roots: Vec, deployment: &DeploymentCapabilities, ) { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, }; let local = generate_per_computation_candidates(roots.into_iter().enumerate().collect()).unwrap(); - let enumerate_local = |inventory: &asap_logical_asap_optimization::per_computation_candidates::PerComputationCandidates| { + let enumerate_local = |inventory: &asap_logical_asap_optimization::pass1::per_computation_candidates::PerComputationCandidates| { let mut result = Vec::new(); for (target, options) in inventory.targets.iter().enumerate() { for choice in 0..options.choice_count() { @@ -126,12 +126,12 @@ fn pattern_b_with_p50() -> asap_types::workload::PlanningWorkload { /// One explicitly shared KLL pane chain, passed through normal physical rules. fn shared_pane_configurations(deployment: &DeploymentCapabilities) -> Run { - use asap_logical_asap_optimization::asap_aware_cse::{ - pane_candidates, window_composition_pass2_candidates, - }; - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; + use asap_logical_asap_optimization::pass2::asap_aware_cse::{ + pane_candidates, window_composition_pass2_candidates, + }; use asap_types::ir::QueryRoot; let workload = pattern_b_with_p50(); let original = lower_promql(&workload); diff --git a/crates/integration-tests/tests/finer_aggregate_reuse.rs b/crates/integration-tests/tests/finer_aggregate_reuse.rs index a9489e22a..912856a3d 100644 --- a/crates/integration-tests/tests/finer_aggregate_reuse.rs +++ b/crates/integration-tests/tests/finer_aggregate_reuse.rs @@ -4,13 +4,13 @@ use asap_devtools::planner_fuzz::{read_seed_file, FuzzSettings, FuzzWorkload, Pl use asap_devtools::planning_stages::run_search_over; use asap_executor::values::Value; use asap_logical_asap_optimization::{ - memo::{ + pass1::per_computation_candidates::generate_per_computation_candidates, + pass2::memo::{ candidates::{try_populate_pass1, CandidateMemo, CandidateOrigin, ImplementationCandidate}, - state_configurations::PaneWidthDomain, + shared_configurations::PaneWidthDomain, state_groups::expand_concrete_summary_state_groups_in_domain, LogicalMemo, }, - per_computation_candidates::generate_per_computation_candidates, }; use asap_types::ir::{ASAPOp, NonASAPOp, OperatorNode}; use serde_json::json; diff --git a/crates/integration-tests/tests/memo_covers_whole_workload_pass2.rs b/crates/integration-tests/tests/memo_covers_whole_workload_pass2.rs index 5a7f4a75a..46d953c24 100644 --- a/crates/integration-tests/tests/memo_covers_whole_workload_pass2.rs +++ b/crates/integration-tests/tests/memo_covers_whole_workload_pass2.rs @@ -13,7 +13,7 @@ use asap_devtools::planner_layering_examples::{ use asap_executor::physical_planner::promql_rows; use asap_integration_tests::fixtures::lower_promql; use asap_integration_tests::planning::explicit_assignment_plans; -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ generate_per_computation_candidates, PerComputationCandidates, }; use asap_plan_selection::{ diff --git a/crates/integration-tests/tests/memo_enumeration.rs b/crates/integration-tests/tests/memo_enumeration.rs index 3934dc299..2fe586207 100644 --- a/crates/integration-tests/tests/memo_enumeration.rs +++ b/crates/integration-tests/tests/memo_enumeration.rs @@ -37,14 +37,14 @@ use std::rc::Rc; use asap_devtools::planning_stages::lower_promql_roots; use asap_integration_tests::planning::expanded_memo; -use asap_logical_asap_optimization::memo::candidates::{ - CandidateMemo, CandidateOrigin, ImplementationCandidate, -}; -use asap_logical_asap_optimization::memo::enumeration::{compose, enumerate, MemoChoice}; -use asap_logical_asap_optimization::memo::MemoGroupId; -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, PerComputationCandidates, }; +use asap_logical_asap_optimization::pass2::memo::candidates::{ + CandidateMemo, CandidateOrigin, ImplementationCandidate, +}; +use asap_logical_asap_optimization::pass2::memo::enumeration::{compose, enumerate, MemoChoice}; +use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_plan_selection::{ run_stage1_to_stage3_with, MemoSteps, PlanningModels, Stage1ToStage3Run, Stage1ToStage3Search, }; @@ -298,7 +298,7 @@ fn ratio_of_quantiles_production_memo() { } // The state-configuration rule rewrites a candidate's KLL to the size // the readers of a state share; the rewrite is a copy of the candidate - // (`derive` in `memo/rules/state_configurations.rs`), so it keeps its + // (`derive` in `pass2/memo/rules/shared_configuration_readers.rs`), so it keeps its // `budget_share`. In each quantile group the `budget_share` 1 KLL `k` 567 // (sized for the whole result) gets copies at `k` 567, 1156 and 1184, // all with `budget_share` 1; the `budget_share` 2 KLL `k` 1184 keeps 2. @@ -406,7 +406,7 @@ fn choices_whose_candidates_read_each_other_are_left_out() { .expect("a pair of groups whose candidates read each other"); assert!(matches!( compose(memo, &mutual.into()), - Err(asap_logical_asap_optimization::memo::enumeration::ComposeError::Cycle { .. }) + Err(asap_logical_asap_optimization::pass2::memo::enumeration::ComposeError::Cycle { .. }) )); let enumeration = enumerate(memo, 2_000); assert!(!enumeration.choices.is_empty()); diff --git a/crates/integration-tests/tests/per_computation_candidates_sql.rs b/crates/integration-tests/tests/per_computation_candidates_sql.rs index 51fdf357f..50cae4d0d 100644 --- a/crates/integration-tests/tests/per_computation_candidates_sql.rs +++ b/crates/integration-tests/tests/per_computation_candidates_sql.rs @@ -3,7 +3,7 @@ //! ranks. use asap_frontend_sql::{lower_sql, SqlCatalog}; -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, ComputationTarget, HavingPlacement, }; diff --git a/crates/integration-tests/tests/planner_layering_common/mod.rs b/crates/integration-tests/tests/planner_layering_common/mod.rs index 745b3fcea..2e4b10e5d 100644 --- a/crates/integration-tests/tests/planner_layering_common/mod.rs +++ b/crates/integration-tests/tests/planner_layering_common/mod.rs @@ -324,7 +324,7 @@ pub fn run_explicit_candidates( .enumerate() .map(|(index, roots)| { logical(format!("P{}", index + 1), - asap_logical_asap_optimization::per_computation_candidates::recompose_guarantees(&roots) + asap_logical_asap_optimization::pass1::per_computation_candidates::recompose_guarantees(&roots) .expect("explicit fixture contracts compose")) }) .collect(); @@ -384,12 +384,12 @@ pub fn run_pattern_b_fixture( /// Three fixed Pattern-B computations used by cost/retention fixtures: /// exact, whole-window KLL, and a KLL chain of sixty-second panes. pub fn pattern_b_computations(workload: &PlanningWorkload) -> Vec> { - use asap_logical_asap_optimization::asap_aware_cse::{ - pane_candidates, window_composition_pass2_candidates, - }; - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; + use asap_logical_asap_optimization::pass2::asap_aware_cse::{ + pane_candidates, window_composition_pass2_candidates, + }; let roots = lower_promql(workload); let local = generate_per_computation_candidates(roots.iter().cloned().enumerate().collect()).unwrap(); diff --git a/crates/integration-tests/tests/planner_layering_example1.rs b/crates/integration-tests/tests/planner_layering_example1.rs index e5ccc8d9d..1a2c95518 100644 --- a/crates/integration-tests/tests/planner_layering_example1.rs +++ b/crates/integration-tests/tests/planner_layering_example1.rs @@ -28,12 +28,12 @@ fn pipeline() -> Run { // stays exact, and exercise source sharing and ten-second panes. This is not // a production workload search or an exhaustive memo archive. fn rule_fixture(workload: &asap_types::workload::PlanningWorkload) -> Run { - use asap_logical_asap_optimization::asap_aware_cse::{ - pane_candidates, window_composition_pass2_candidates, - }; - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; + use asap_logical_asap_optimization::pass2::asap_aware_cse::{ + pane_candidates, window_composition_pass2_candidates, + }; let roots = lower_promql(workload); let local = generate_per_computation_candidates(roots.iter().cloned().enumerate().collect()).unwrap(); @@ -818,7 +818,7 @@ fn materialized_case() -> Run { let mut workload = example1(); let repeating = workload.query_workload.repeating_queries.as_mut().unwrap(); repeating.truncate(1); - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, }; let roots = lower_promql(&workload); diff --git a/crates/integration-tests/tests/planner_layering_example2.rs b/crates/integration-tests/tests/planner_layering_example2.rs index 1305ddc5a..a06812cfd 100644 --- a/crates/integration-tests/tests/planner_layering_example2.rs +++ b/crates/integration-tests/tests/planner_layering_example2.rs @@ -162,13 +162,13 @@ async fn lower_sql(workload: &PlanningWorkload) -> Vec { // all/pairwise UnivMon consumers needed by compatibility and cost assertions. // Production optimization is tested separately; this is not a Cartesian search. fn rule_fixture(workload: &PlanningWorkload, roots: Vec) -> Run { - use asap_logical_asap_optimization::asap_aware_cse::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ + compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, + }; + use asap_logical_asap_optimization::pass2::asap_aware_cse::{ capability_sharing_candidates, pane_candidates, summary_capability_pass2_candidates, window_composition_pass2_candidates, }; - use asap_logical_asap_optimization::per_computation_candidates::{ - compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, - }; let local = generate_per_computation_candidates(roots.iter().cloned().enumerate().collect()).unwrap(); let exact = vec![0; local.targets.len()]; @@ -287,7 +287,7 @@ fn pipeline_with_distinct_bound(bound: Option) -> Run { /// queries, those queries reading it. fn memo_pipeline() -> Run { use asap_integration_tests::planning::{compose_memo_plan, expanded_memo, own_choices}; - use asap_logical_asap_optimization::memo::candidates::{ + use asap_logical_asap_optimization::pass2::memo::candidates::{ CandidateOrigin, ImplementationCandidate, }; use asap_types::ir::schema::FieldDataType; diff --git a/crates/integration-tests/tests/planner_layering_example3.rs b/crates/integration-tests/tests/planner_layering_example3.rs index 50646f0f2..2280c3d14 100644 --- a/crates/integration-tests/tests/planner_layering_example3.rs +++ b/crates/integration-tests/tests/planner_layering_example3.rs @@ -19,7 +19,7 @@ use planner_layering_common::*; // Fixed algorithm/window fixtures keep numerical evaluator checks independent // of a time-bounded production search's archived incumbents. fn run_a() -> Run { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; let workload = pattern_a( @@ -68,12 +68,12 @@ fn run_a() -> Run { } fn run_b() -> Run { - use asap_logical_asap_optimization::asap_aware_cse::{ - pane_candidates, window_composition_pass2_candidates, - }; - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; + use asap_logical_asap_optimization::pass2::asap_aware_cse::{ + pane_candidates, window_composition_pass2_candidates, + }; let workload = pattern_b(); let roots = lower_promql(&workload); let local = diff --git a/crates/integration-tests/tests/production_rollup_workloads.rs b/crates/integration-tests/tests/production_rollup_workloads.rs index e22d027fc..8caabc5cf 100644 --- a/crates/integration-tests/tests/production_rollup_workloads.rs +++ b/crates/integration-tests/tests/production_rollup_workloads.rs @@ -248,7 +248,7 @@ fn independent_kll_cost( entries: &[QueryWorkloadEntry], data: &DataWorkload, ) -> f64 { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; let inventory = generate_per_computation_candidates(roots).unwrap(); diff --git a/crates/integration-tests/tests/promql_numeric_regressions.rs b/crates/integration-tests/tests/promql_numeric_regressions.rs index 12d11e741..1070ebbb5 100644 --- a/crates/integration-tests/tests/promql_numeric_regressions.rs +++ b/crates/integration-tests/tests/promql_numeric_regressions.rs @@ -129,7 +129,7 @@ fn checked_ratio_must_not_certify_cross_zero_interpolation() { ); assert!(node.guarantee.is_none(), "{:?}", node.guarantee); use asap_logical_asap_optimization::accuracy::composition::raw_data_samples_sign_statistic; - use asap_logical_asap_optimization::per_computation_candidates::bind_guarantees; + use asap_logical_asap_optimization::pass1::per_computation_candidates::bind_guarantees; let root = asap_types::ir::QueryRoot::Operator(node.clone()); assert!(bind_guarantees(&root, &Clone::clone).is_none()); let proven = bind_guarantees(&root, &|guarantee| { @@ -181,7 +181,7 @@ fn checked_ratio_must_not_certify_cross_zero_interpolation() { #[test] fn ddsketch_interpolation_requires_a_nonnegative_domain() { use asap_logical_asap_optimization::accuracy::composition::raw_data_samples_sign_statistic; - use asap_logical_asap_optimization::per_computation_candidates::bind_guarantees; + use asap_logical_asap_optimization::pass1::per_computation_candidates::bind_guarantees; use asap_types::ir::{schema::SketchAlgorithm, QueryRoot}; for (query, endpoint, raw_samples) in [ ("quantile_over_time(0, data[5m])", true, true), @@ -335,7 +335,7 @@ fn sketch_counts_use_unit_weights_and_signed_sums_keep_value_weights() { #[test] #[should_panic(expected = "does not compose")] fn logical_candidates_fails_on_a_candidate_that_does_not_compose() { - use asap_logical_asap_optimization::per_computation_candidates::PerComputationCandidateError; + use asap_logical_asap_optimization::pass1::per_computation_candidates::PerComputationCandidateError; asap_integration_tests::planning::require_composed_operator_candidates(vec![ asap_plan_selection::search::LogicalCandidate { id: "invalid-composition".into(), diff --git a/crates/integration-tests/tests/promql_to_post_asap.rs b/crates/integration-tests/tests/promql_to_post_asap.rs index 81d5c665c..f7609592c 100644 --- a/crates/integration-tests/tests/promql_to_post_asap.rs +++ b/crates/integration-tests/tests/promql_to_post_asap.rs @@ -701,7 +701,7 @@ fn ddsketch_ratio_selection( for facts in data.sources.values_mut() { facts.values_non_negative = non_negative; } - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ generate_per_computation_candidates, ComputationCandidate, }; let inventory = @@ -733,7 +733,7 @@ fn ddsketch_ratio_selection( }]; // Pass 1 choices composed and implemented by Stage 2; one query, so no // sharing rule applies. - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, recompose_guarantees, }; let models = asap_plan_selection::PlanningModels::builtin(); diff --git a/crates/integration-tests/tests/range_evaluation.rs b/crates/integration-tests/tests/range_evaluation.rs index 1a68bcc5d..7c3062cde 100644 --- a/crates/integration-tests/tests/range_evaluation.rs +++ b/crates/integration-tests/tests/range_evaluation.rs @@ -30,12 +30,12 @@ const LAST_HOUR_BY_MINUTE: RangeEvaluation = RangeEvaluation { /// This fixture controls its pane width; a timed MILP archive is not a catalog /// of every legal materialization or a stable source of P1/P2 identifiers. fn run_explicit_for(workload: &PlanningWorkload, deployment: &DeploymentCapabilities) -> Run { - use asap_logical_asap_optimization::asap_aware_cse::{ - pane_candidates, window_composition_pass2_candidates, - }; - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; + use asap_logical_asap_optimization::pass2::asap_aware_cse::{ + pane_candidates, window_composition_pass2_candidates, + }; use asap_types::ir::schema::SketchAlgorithm; let roots = lower_promql(workload); let inventory = diff --git a/crates/integration-tests/tests/reuse_rules.rs b/crates/integration-tests/tests/reuse_rules.rs index ee055c346..4db2a1626 100644 --- a/crates/integration-tests/tests/reuse_rules.rs +++ b/crates/integration-tests/tests/reuse_rules.rs @@ -17,7 +17,7 @@ use asap_integration_tests::fixtures::lower_promql; use asap_integration_tests::planning::{ cheapest_of, compose_memo_plan, expanded_memo, select_among, }; -use asap_logical_asap_optimization::memo::candidates::{CandidateMemo, CandidateOrigin}; +use asap_logical_asap_optimization::pass2::memo::candidates::{CandidateMemo, CandidateOrigin}; use asap_plan_selection::PlanningModels; use asap_types::ir::physical_export::compile_physical_asap_dag; use asap_types::ir::properties::AccuracyTarget; diff --git a/crates/integration-tests/tests/rollup_controlled.rs b/crates/integration-tests/tests/rollup_controlled.rs index 7b5f4f2ed..b6d3ff4dd 100644 --- a/crates/integration-tests/tests/rollup_controlled.rs +++ b/crates/integration-tests/tests/rollup_controlled.rs @@ -1,10 +1,10 @@ //! Controlled plans for the viewer's actual distinct-count rollup workload. use asap_integration_tests::planning::{builds_and_rollups, expanded_memo, select_rollup}; use asap_logical_asap_optimization::{ - asap_aware_cse::{rollup_candidates, rollup_pass2_candidates}, - per_computation_candidates::{ + pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }, + pass2::asap_aware_cse::{rollup_candidates, rollup_pass2_candidates}, }; use asap_plan_selection::{CostModel, PlanSelectionSettings, PlanningModels, ResourceUnitCost}; use asap_types::{ diff --git a/crates/integration-tests/tests/sharing_issue_regressions.rs b/crates/integration-tests/tests/sharing_issue_regressions.rs index 585448570..eac95a8e7 100644 --- a/crates/integration-tests/tests/sharing_issue_regressions.rs +++ b/crates/integration-tests/tests/sharing_issue_regressions.rs @@ -118,7 +118,7 @@ fn grouped_filtered_quantile_plans() { /// #886: SQL count-ranked TopK offers a heap over raw rows, absorbing the count. #[test] fn sql_count_topk_has_a_fused_raw_row_heap() { - use asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates; let roots = Planner::new(FuzzSettings::default()) .lower(&workload(886)) .unwrap(); @@ -134,7 +134,7 @@ fn sql_count_topk_has_a_fused_raw_row_heap() { let mut selected = vec![0; inventory.targets.len()]; selected[index] = choice; let composed = - asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate( + asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate( &inventory, &selected, ) .unwrap(); @@ -199,13 +199,13 @@ fn sql_count_topk_has_a_fused_raw_row_heap() { #[test] fn exact_rollup_catalog_crosses_identical_per_series_average() { use asap_logical_asap_optimization::{ - memo::{ + pass1::per_computation_candidates::generate_per_computation_candidates, + pass2::memo::{ candidates::{try_populate_pass1, CandidateOrigin}, - state_configurations::PaneWidthDomain, + shared_configurations::PaneWidthDomain, state_groups::expand_concrete_summary_state_groups_in_domain, LogicalMemo, }, - per_computation_candidates::generate_per_computation_candidates, }; let roots: Vec<_> = Planner::new(FuzzSettings::default()) .lower(&workload(923)) @@ -240,13 +240,13 @@ mod physical_common; fn filtered_group_preserves_sql_empty_and_null_semantics() { use asap_executor::values::Value; use asap_logical_asap_optimization::{ - memo::{ + pass1::per_computation_candidates::generate_per_computation_candidates, + pass2::memo::{ candidates::{try_populate_pass1, CandidateOrigin}, - state_configurations::PaneWidthDomain, + shared_configurations::PaneWidthDomain, state_groups::expand_concrete_summary_state_groups_in_domain, LogicalMemo, }, - per_computation_candidates::generate_per_computation_candidates, }; use asap_types::ir::{operator::AggIntent, NonASAPOp}; let roots: Vec<_> = Planner::new(FuzzSettings::default()) @@ -266,7 +266,7 @@ fn filtered_group_preserves_sql_empty_and_null_semantics() { .expect("filtered group read candidate"); // The same readout keeps a KLL's rank bound: it selects a whole group, // never predicates on an approximate value or combines populations. - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, recompose_guarantees, ComputationCandidate, }; use asap_types::ir::{schema::SketchAlgorithm, QueryRoot}; @@ -393,13 +393,13 @@ fn filtered_group_preserves_sql_empty_and_null_semantics() { fn sql_count_rollup_executes_with_integer_results() { use asap_executor::values::Value; use asap_logical_asap_optimization::{ - memo::{ + pass1::per_computation_candidates::generate_per_computation_candidates, + pass2::memo::{ candidates::{try_populate_pass1, CandidateOrigin}, - state_configurations::PaneWidthDomain, + shared_configurations::PaneWidthDomain, state_groups::expand_concrete_summary_state_groups_in_domain, LogicalMemo, }, - per_computation_candidates::generate_per_computation_candidates, }; use asap_types::ir::ASAPOp; let mut w = workload(902); @@ -521,13 +521,13 @@ fn sql_sum_shares_nested_windows_and_slower_readers() { #[test] fn sketch_rollup_crosses_inner_range_function() { use asap_logical_asap_optimization::{ - memo::{ + pass1::per_computation_candidates::generate_per_computation_candidates, + pass2::memo::{ candidates::{try_populate_pass1, CandidateOrigin}, - state_configurations::PaneWidthDomain, + shared_configurations::PaneWidthDomain, state_groups::expand_concrete_summary_state_groups_in_domain, LogicalMemo, }, - per_computation_candidates::generate_per_computation_candidates, }; let mut w = workload(923); for (query, keys) in w.queries.iter_mut().zip(["job, region", "job"]) { @@ -561,7 +561,7 @@ fn sketch_rollup_crosses_inner_range_function() { /// the exact counter and separately typed raw-row TopK fusion remain available. #[test] fn sql_grouped_count_sketches_are_not_offered() { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ generate_per_computation_candidates, ComputationCandidate, PruneReason, }; use asap_types::ir::{operator::AggIntent, NonASAPOp}; diff --git a/crates/integration-tests/tests/sql_group_bound.rs b/crates/integration-tests/tests/sql_group_bound.rs index a193d9126..817183545 100644 --- a/crates/integration-tests/tests/sql_group_bound.rs +++ b/crates/integration-tests/tests/sql_group_bound.rs @@ -66,7 +66,7 @@ fn every_column() -> serde_json::Value { /// Evaluate the exact computation and each supported local summary choice. /// These tests exercise group/error models, not a timed search's visited archive. fn run_group_choices(workload: &PlanningWorkload) -> Run { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, }; let roots = lower_sql_roots(workload, &http_catalog()).expect("lowers"); diff --git a/crates/integration-tests/tests/sql_trailing_window.rs b/crates/integration-tests/tests/sql_trailing_window.rs index 6f41f6b5f..767afaec1 100644 --- a/crates/integration-tests/tests/sql_trailing_window.rs +++ b/crates/integration-tests/tests/sql_trailing_window.rs @@ -101,12 +101,12 @@ async fn roots(workload: &PlanningWorkload) -> Vec { async fn run(deployment: &DeploymentCapabilities) -> Run { let workload = workload(); let roots = roots(&workload).await; - use asap_logical_asap_optimization::asap_aware_cse::{ - pane_candidates, window_composition_pass2_candidates, - }; - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; + use asap_logical_asap_optimization::pass2::asap_aware_cse::{ + pane_candidates, window_composition_pass2_candidates, + }; let local = generate_per_computation_candidates(roots.iter().cloned().enumerate().collect()).unwrap(); let compose = |choices: &[usize]| { diff --git a/crates/integration-tests/tests/sql_two_percentiles.rs b/crates/integration-tests/tests/sql_two_percentiles.rs index 76e0b2d00..757412bf4 100644 --- a/crates/integration-tests/tests/sql_two_percentiles.rs +++ b/crates/integration-tests/tests/sql_two_percentiles.rs @@ -303,12 +303,12 @@ async fn q1_with_one_exact_and_one_sketched_percentile_compiles_and_matches() { /// The id and query roots of every Stage 1 candidate of `queries`. async fn stage1(queries: &[&str]) -> Vec<(String, Vec)> { - use asap_logical_asap_optimization::asap_aware_cse::{ - pane_candidates, window_composition_pass2_candidates, - }; - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; + use asap_logical_asap_optimization::pass2::asap_aware_cse::{ + pane_candidates, window_composition_pass2_candidates, + }; let workload = workload(queries); let entries: Vec<_> = workload.query_workload.entries().collect(); let mut roots = Vec::new(); diff --git a/crates/integration-tests/tests/stage1_logical_asap_optimization.rs b/crates/integration-tests/tests/stage1_logical_asap_optimization.rs index c89aaf9c4..9f653f0d2 100644 --- a/crates/integration-tests/tests/stage1_logical_asap_optimization.rs +++ b/crates/integration-tests/tests/stage1_logical_asap_optimization.rs @@ -12,7 +12,7 @@ use asap_executor::{ values::{Batch, Value}, }; use asap_frontend_sql::{lower_sql, SqlCatalog}; -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; use asap_types::ir::physical_export::PhysicalASAPOperatorPayload; @@ -564,9 +564,9 @@ async fn every_candidate( ComputationCandidate, Result< Vec<(i32, QueryRoot)>, - asap_logical_asap_optimization::per_computation_candidates::PerComputationCandidateError, + asap_logical_asap_optimization::pass1::per_computation_candidates::PerComputationCandidateError, >, -)> { +)>{ let root = lower_sql(query, catalog, accuracy()).await.unwrap(); let inventory = generate_per_computation_candidates(vec![(0, QueryRoot::Operator(root))]).unwrap(); @@ -727,7 +727,7 @@ async fn sql_count_star_without_a_non_null_column_is_unsupported() { every_candidate(&catalog, "SELECT k, count(*) FROM t GROUP BY k").await { match composed { - Err(asap_logical_asap_optimization::per_computation_candidates::PerComputationCandidateError::Unsupported(_)) => {} + Err(asap_logical_asap_optimization::pass1::per_computation_candidates::PerComputationCandidateError::Unsupported(_)) => {} other => panic!("{columns:?} {candidate:?}: {other:?}"), } } diff --git a/crates/integration-tests/tests/stage2_physical_asap_optimization_sql.rs b/crates/integration-tests/tests/stage2_physical_asap_optimization_sql.rs index 9ce69efcf..1ffd20314 100644 --- a/crates/integration-tests/tests/stage2_physical_asap_optimization_sql.rs +++ b/crates/integration-tests/tests/stage2_physical_asap_optimization_sql.rs @@ -5,7 +5,7 @@ //! then the group keys naming each ranked item. use asap_frontend_sql::{lower_sql, SqlCatalog}; -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; use asap_physical_asap_optimization::optimize_physical_asap; diff --git a/crates/integration-tests/tests/tumbling_pane_merge.rs b/crates/integration-tests/tests/tumbling_pane_merge.rs index afbb3a653..5c3aff2ca 100644 --- a/crates/integration-tests/tests/tumbling_pane_merge.rs +++ b/crates/integration-tests/tests/tumbling_pane_merge.rs @@ -15,7 +15,7 @@ use asap_executor::sources::InMemoryDataStore; use asap_executor::values::{Batch, Value}; use asap_integration_tests::fixtures::lower_promql; use asap_integration_tests::planning::{explicit_local_candidates, explicit_summary_candidate}; -use asap_logical_asap_optimization::asap_aware_cse::{ +use asap_logical_asap_optimization::pass2::asap_aware_cse::{ pane_candidates, window_composition_pass2_candidates, window_composition_shared_chain_candidates, }; diff --git a/crates/logical-asap-optimization/src/accuracy/estimators/cms.rs b/crates/logical-asap-optimization/src/accuracy/estimators/cms.rs index df5dcb3d8..487a80484 100644 --- a/crates/logical-asap-optimization/src/accuracy/estimators/cms.rs +++ b/crates/logical-asap-optimization/src/accuracy/estimators/cms.rs @@ -41,7 +41,7 @@ mod tests { #[test] fn local_guarantee_inverts_frequency_sizing() { - use crate::realization::default_size_params; + use crate::pass1::realization::default_size_params; use asap_types::ir::schema::{GroupingStrategy, SketchKind}; let c = asap_types::ir::operator::agg_intent::default_cardinality(); let params = default_size_params(SketchAlgorithm::Cms, &c, 0.01, 0.001); @@ -92,7 +92,7 @@ mod tests { /// taking `DEFAULT_DELTA` (depth 5). #[test] fn epsilon_delta_sizes_cms_depth() { - use crate::realization::{accuracy_budget, default_size_params, DEFAULT_DELTA}; + use crate::pass1::realization::{accuracy_budget, default_size_params, DEFAULT_DELTA}; let intent = AggIntent::Count { accuracy: AccuracyTarget::max_error(0.001).failure_probability(0.001), }; @@ -126,7 +126,7 @@ mod tests { /// A top-k heap holds `max(k, ⌈1/ε⌉)` entries over a CMS sized as for counts. #[test] fn topk_heap_capacity_respects_accuracy_and_output_count() { - use crate::realization::default_size_params; + use crate::pass1::realization::default_size_params; let intent = AggIntent::TopK { k: 25, accuracy: AccuracyTarget::max_error(0.01), diff --git a/crates/logical-asap-optimization/src/accuracy/estimators/count_sketch.rs b/crates/logical-asap-optimization/src/accuracy/estimators/count_sketch.rs index 4dffa5d43..5f49bed5a 100644 --- a/crates/logical-asap-optimization/src/accuracy/estimators/count_sketch.rs +++ b/crates/logical-asap-optimization/src/accuracy/estimators/count_sketch.rs @@ -155,7 +155,7 @@ mod tests { #[test] fn count_sketch_uses_an_l2_guarantee() { - use crate::realization::default_size_params; + use crate::pass1::realization::default_size_params; use asap_types::ir::operator::agg_intent::default_cardinality; use asap_types::ir::schema::{GroupingStrategy, SketchKind}; let intent = default_cardinality(); diff --git a/crates/logical-asap-optimization/src/accuracy/estimators/hll.rs b/crates/logical-asap-optimization/src/accuracy/estimators/hll.rs index 65ba001da..907559c97 100644 --- a/crates/logical-asap-optimization/src/accuracy/estimators/hll.rs +++ b/crates/logical-asap-optimization/src/accuracy/estimators/hll.rs @@ -458,7 +458,7 @@ mod tests { /// bound. #[test] fn precision_is_sized_from_epsilon_and_delta() { - use crate::realization::default_size_params; + use crate::pass1::realization::default_size_params; use asap_types::ir::operator::agg_intent::default_cardinality; for (eps, delta, precision) in [(0.05, 0.01, 15), (0.02, 0.01, 17)] { let params = @@ -476,7 +476,7 @@ mod tests { #[test] fn generic_rse_sizing_does_not_certify_confidence() { - use crate::realization::default_size_params; + use crate::pass1::realization::default_size_params; use asap_types::ir::operator::agg_intent::default_cardinality; use asap_types::ir::schema::{GroupingStrategy, SketchKind}; let c = default_cardinality(); diff --git a/crates/logical-asap-optimization/src/accuracy/estimators/kll.rs b/crates/logical-asap-optimization/src/accuracy/estimators/kll.rs index 616ba9e81..b3b170e51 100644 --- a/crates/logical-asap-optimization/src/accuracy/estimators/kll.rs +++ b/crates/logical-asap-optimization/src/accuracy/estimators/kll.rs @@ -214,7 +214,7 @@ mod tests { #[test] fn local_guarantee_inverts_rank_sizing() { - use crate::realization::default_size_params; + use crate::pass1::realization::default_size_params; use asap_types::ir::operator::agg_intent::default_quantile; use asap_types::ir::schema::{GroupingStrategy, SketchKind}; let q = default_quantile(0.99); @@ -252,7 +252,7 @@ mod tests { /// larger than at δ = 0.01, and the guarantee meets ε = 0.01, δ = 0.001. #[test] fn sizing_meets_a_failure_probability_below_one_percent() { - use crate::realization::default_size_params; + use crate::pass1::realization::default_size_params; use asap_types::ir::operator::agg_intent::default_quantile; let q = default_quantile(0.99); let k = |delta| match default_size_params(SketchAlgorithm::Kll, &q, 0.01, delta) { @@ -379,7 +379,7 @@ mod tests { /// KLL `k` inverts the rank-error fit: ε = 0.01 → 269, ε = 0.05 → 52. #[test] fn accuracy_target_drives_kll_k() { - use crate::realization::default_size_params; + use crate::pass1::realization::default_size_params; use asap_types::ir::operator::agg_intent::default_quantile; let q = default_quantile(0.99); assert_eq!( @@ -401,7 +401,7 @@ mod tests { /// A zero ε saturates KLL `k` to the tightest buildable value. #[test] fn degenerate_epsilon_saturates_to_tightest_kll_params() { - use crate::realization::default_size_params; + use crate::pass1::realization::default_size_params; use asap_types::ir::operator::agg_intent::default_quantile; assert_eq!( default_size_params(SketchAlgorithm::Kll, &default_quantile(0.99), 0.0, 0.01), diff --git a/crates/logical-asap-optimization/src/accuracy/estimators/mod.rs b/crates/logical-asap-optimization/src/accuracy/estimators/mod.rs index e9b44e084..0b5ab4fcf 100644 --- a/crates/logical-asap-optimization/src/accuracy/estimators/mod.rs +++ b/crates/logical-asap-optimization/src/accuracy/estimators/mod.rs @@ -56,7 +56,7 @@ fn bounded_guarantee( /// The built-in guarantee of reading `query` out of a summary of family /// `family` built over an **exact** input, derived from the family's /// committed parameters by inverting the same sizing formulas -/// [`crate::realization::default_size_params`] uses. Exact for a plain value +/// [`crate::pass1::realization::default_size_params`] uses. Exact for a plain value /// or an exact aggregate. `None` when a sketch does not answer `query` (its /// family-capability table row), and when the family has no error model /// (`SummarySample`, `Wavelet`, `StatModel`, and sketch evaluations without a diff --git a/crates/logical-asap-optimization/src/function_rules.rs b/crates/logical-asap-optimization/src/accuracy/function_rules.rs similarity index 100% rename from crates/logical-asap-optimization/src/function_rules.rs rename to crates/logical-asap-optimization/src/accuracy/function_rules.rs diff --git a/crates/logical-asap-optimization/src/accuracy/mod.rs b/crates/logical-asap-optimization/src/accuracy/mod.rs index 431f4a17e..ca865b73b 100644 --- a/crates/logical-asap-optimization/src/accuracy/mod.rs +++ b/crates/logical-asap-optimization/src/accuracy/mod.rs @@ -11,6 +11,7 @@ pub mod budget; pub mod composition; pub mod estimators; pub mod evidence; +pub(crate) mod function_rules; pub use budget::per_input_target; pub use evidence::{OperandDomain, PropagationStats}; diff --git a/crates/logical-asap-optimization/src/lib.rs b/crates/logical-asap-optimization/src/lib.rs index 27fadb0d9..e14a53988 100644 --- a/crates/logical-asap-optimization/src/lib.rs +++ b/crates/logical-asap-optimization/src/lib.rs @@ -4,7 +4,7 @@ //! //! Identical-sub-DAG sharing over the logical DAG (`asap_types::ir::cse`) //! runs before the stages; Stage 1 adds the ASAP-aware sharing that is -//! invisible at the logical level ([`asap_aware_cse`], Pass 2), e.g. +//! invisible at the logical level ([`asap_aware_cse`](pass2::asap_aware_cse), Pass 2), e.g. //! `Quantile(x, 0.99)` and `Quantile(x, 0.95)` reading one built sketch. //! //! It depends only on `asap-types`, never on a later stage: Stage 2 @@ -22,12 +22,12 @@ //! //! ## Components //! -//! - [`per_computation_candidates`] — Pass 1: per-computation candidate +//! - [`per_computation_candidates`](pass1::per_computation_candidates) — Pass 1: per-computation candidate //! generation and composition. -//! - [`asap_aware_cse`] — Pass 2: ASAP-aware common-subexpression elimination. -//! - [`workload_candidates`] — the whole-workload Stage 1 candidates: each +//! - [`asap_aware_cse`](pass2::asap_aware_cse) — Pass 2: ASAP-aware common-subexpression elimination. +//! - [`workload_candidates`](pass2::workload_candidates) — the whole-workload Stage 1 candidates: each //! composed Pass 1 candidate followed by its Pass 2 candidates. -//! - [`realization`] — the summary families that can serve an aggregate +//! - [`realization`](pass1::realization) — the summary families that can serve an aggregate //! intent, the intent's accuracy target and `(ε, δ)` budget, and default //! sketch sizing, shared by Pass 1 and Pass 2. //! - [`accuracy`] — the built-in analytical accuracy rules: per-family @@ -46,8 +46,6 @@ pub mod accuracy; /// The deployment's capabilities: supported summaries and what it retains. pub mod deployment_capabilities; -mod function_rules; -pub mod realization; /// Test helpers shared by the stage crates' tests (feature `test-support`). #[cfg(any(test, feature = "test-support"))] pub mod test_support; @@ -55,18 +53,7 @@ pub mod test_support; pub use deployment_capabilities::{ DeploymentCapabilities, DeploymentCapabilitiesError, SupportedSummary, }; -pub use realization::summary_candidates; +pub use pass1::realization::summary_candidates; -/// Stage 1, Pass 1: per-computation candidate generation. No execution timing is -/// assigned: that is a Stage 2 materialization decision. -pub mod per_computation_candidates; - -/// Stage 1, Pass 2: ASAP-aware common-subexpression elimination (the -/// identical-expression rule). -pub mod asap_aware_cse; -mod finer_aggregate; - -pub mod workload_candidates; - -/// Logical group identity available before Pass 1 candidate generation. -pub mod memo; +pub mod pass1; +pub mod pass2; diff --git a/crates/logical-asap-optimization/src/pass1.rs b/crates/logical-asap-optimization/src/pass1.rs new file mode 100644 index 000000000..d6973709d --- /dev/null +++ b/crates/logical-asap-optimization/src/pass1.rs @@ -0,0 +1,7 @@ +//! Stage 1, Pass 1: per-computation candidate generation and composition, +//! and the summary realizations it offers. + +/// Stage 1, Pass 1: per-computation candidate generation. No execution timing is +/// assigned: that is a Stage 2 materialization decision. +pub mod per_computation_candidates; +pub mod realization; diff --git a/crates/logical-asap-optimization/src/per_computation_candidates.rs b/crates/logical-asap-optimization/src/pass1/per_computation_candidates.rs similarity index 99% rename from crates/logical-asap-optimization/src/per_computation_candidates.rs rename to crates/logical-asap-optimization/src/pass1/per_computation_candidates.rs index 2fee0167d..a2a2883ea 100644 --- a/crates/logical-asap-optimization/src/per_computation_candidates.rs +++ b/crates/logical-asap-optimization/src/pass1/per_computation_candidates.rs @@ -124,10 +124,10 @@ use crate::accuracy::composition::{ }; use crate::accuracy::estimators::local_guarantee; use crate::accuracy::estimators::{hll, univmon}; +use crate::accuracy::function_rules::approximate_input_composition; use crate::accuracy::{per_input_target, PropagationStats}; use crate::deployment_capabilities::DeploymentCapabilities; -use crate::function_rules::approximate_input_composition; -use crate::realization::{ +use crate::pass1::realization::{ accuracy_budget, default_size_params, sizing_target, sketch_statistic, summary_candidates, }; @@ -610,7 +610,7 @@ pub fn generate_per_computation_candidates( /// occurrence-specific. Cached choices are cloned before any contextual pruning. pub fn generate_per_computation_candidates_with_memo( roots: Vec<(Id, QueryRoot)>, - memo: &crate::memo::LogicalMemo, + memo: &crate::pass2::memo::LogicalMemo, ) -> Result, PerComputationCandidateError> { if !memo.matches_root_dependencies(&roots) { return Err(PerComputationCandidateError::MemoRootsChanged); @@ -618,11 +618,11 @@ pub fn generate_per_computation_candidates_with_memo( generate_with_local_candidate_cache(roots, Some(memo), &mut HashMap::new()) } -type LocalCandidateCache = HashMap<(crate::memo::MemoGroupId, usize), ComputationChoices>; +type LocalCandidateCache = HashMap<(crate::pass2::memo::MemoGroupId, usize), ComputationChoices>; fn generate_with_local_candidate_cache( roots: Vec<(Id, QueryRoot)>, - memo: Option<&crate::memo::LogicalMemo>, + memo: Option<&crate::pass2::memo::LogicalMemo>, local_candidates: &mut LocalCandidateCache, ) -> Result, PerComputationCandidateError> { let mut seen = HashSet::new(); @@ -1044,7 +1044,7 @@ fn reads_only_time_series(node: &OperatorNode) -> bool { fn whole_expression_input( target: &OperatorNode, ) -> Option<(Rc, SummaryUpdate, Reduction)> { - use crate::realization::realize_keyed_additive_summary_input; + use crate::pass1::realization::realize_keyed_additive_summary_input; let Some(NonASAPOp::Aggregate { child, reduction, @@ -1119,8 +1119,9 @@ pub(crate) fn partitions_over( if keys.is_without() { return None; } - let column = - |schema: &Schema, index: usize| crate::realization::column_ref(&schema.fields[index]); + let column = |schema: &Schema, index: usize| { + crate::pass1::realization::column_ref(&schema.fields[index]) + }; let keys = keys .keys() .iter() @@ -1655,7 +1656,7 @@ fn with_guarantees( /// an aggregate whose measures are all `MIN`/`MAX` over a (possibly /// filtered) grouped estimate, where every column of a unique key of the /// estimate is a group key or pinned to one value by the filter -/// ([`crate::finer_aggregate`]'s same-level read). Unlike a general +/// ([`crate::pass2::finer_aggregate`]'s same-level read). Unlike a general /// aggregate over rank estimates, this does not change the population to /// which the input's error bound refers. fn selected_group_guarantee(node: &OperatorNode) -> Option { @@ -1686,7 +1687,7 @@ fn selected_group_guarantee(node: &OperatorNode) -> Option { NonASAPOp::Filter { pred, child } => (Some(&pred.0), child), _ => (None, child), }; - let pinned = pred.map_or_else(Vec::new, crate::finer_aggregate::pinned_columns); + let pinned = pred.map_or_else(Vec::new, crate::pass2::finer_aggregate::pinned_columns); // The filter may read only key columns: a predicate on an estimate // would decide by an approximate value which groups are kept. let reads = pred.map_or_else(Vec::new, ScalarExpr::columns_referenced); @@ -3720,13 +3721,13 @@ fn measure_input( } // A top-k ranks its child's aggregate output, not a column of its own. AggIntent::TopK { .. } => SummaryInputExpr::Column( - crate::realization::ranked_value(input) + crate::pass1::realization::ranked_value(input) .map_err(|_| { PerComputationCandidateError::Unsupported("Top-K has no ranked column") })? .1, ), - _ => crate::realization::summarised_input(intent, schema).ok_or( + _ => crate::pass1::realization::summarised_input(intent, schema).ok_or( PerComputationCandidateError::Unsupported("input column outside child schema"), )?, }; @@ -3767,7 +3768,12 @@ fn counted_column( .then_some(id) }) }; - let reference = |id: usize| schema.fields.get(id).map(crate::realization::column_ref); + let reference = |id: usize| { + schema + .fields + .get(id) + .map(crate::pass1::realization::column_ref) + }; filter .map_or_else(Vec::new, |filter| not_null(&filter.0)) .into_iter() @@ -3829,7 +3835,7 @@ fn summary_update( .enumerate() .filter(|(index, _)| *index != value && !groups.contains(index)) .map(|(_, field)| { - SummaryInputExpr::Column(crate::realization::column_ref(field)) + SummaryInputExpr::Column(crate::pass1::realization::column_ref(field)) }) .collect(); if items.is_empty() { @@ -3842,7 +3848,7 @@ fn summary_update( let excluding = groups .iter() .filter_map(|&index| child.fields.get(index)) - .map(crate::realization::column_ref) + .map(crate::pass1::realization::column_ref) .collect(); SummaryInputExpr::EntityIdentity(EntityIdentity::PromqlLabelSet { excluding }) }; @@ -4617,7 +4623,7 @@ mod tests { (id, inventory.roots[0].1.clone()) }) .collect(); - let memo = crate::memo::LogicalMemo::from_roots(&roots); + let memo = crate::pass2::memo::LogicalMemo::from_roots(&roots); let baseline = generate_per_computation_candidates(roots.clone()).unwrap(); let mut cache = LocalCandidateCache::new(); let cached = generate_with_local_candidate_cache(roots, Some(&memo), &mut cache).unwrap(); diff --git a/crates/logical-asap-optimization/src/realization.rs b/crates/logical-asap-optimization/src/pass1/realization.rs similarity index 99% rename from crates/logical-asap-optimization/src/realization.rs rename to crates/logical-asap-optimization/src/pass1/realization.rs index 05f6e0280..78126b58a 100644 --- a/crates/logical-asap-optimization/src/realization.rs +++ b/crates/logical-asap-optimization/src/pass1/realization.rs @@ -284,7 +284,7 @@ pub(crate) fn realize_keyed_additive_summary_input( [AggIntent::Rate | AggIntent::Increase | AggIntent::IRate] ) => { - Some(crate::per_computation_candidates::raw_data_samples_of_metric(samples)) + Some(crate::pass1::per_computation_candidates::raw_data_samples_of_metric(samples)) } _ => None, }; diff --git a/crates/logical-asap-optimization/src/pass2.rs b/crates/logical-asap-optimization/src/pass2.rs new file mode 100644 index 000000000..987d62daf --- /dev/null +++ b/crates/logical-asap-optimization/src/pass2.rs @@ -0,0 +1,10 @@ +//! Stage 1, Pass 2: ASAP-aware sharing over the Pass 1 candidates, through the +//! logical memo and its rules. + +/// Stage 1, Pass 2: ASAP-aware common-subexpression elimination (the +/// identical-expression rule). +pub mod asap_aware_cse; +pub(crate) mod finer_aggregate; +/// Logical group identity available before Pass 1 candidate generation. +pub mod memo; +pub mod workload_candidates; diff --git a/crates/logical-asap-optimization/src/asap_aware_cse.rs b/crates/logical-asap-optimization/src/pass2/asap_aware_cse.rs similarity index 99% rename from crates/logical-asap-optimization/src/asap_aware_cse.rs rename to crates/logical-asap-optimization/src/pass2/asap_aware_cse.rs index bf130f5bc..a99ab37e2 100644 --- a/crates/logical-asap-optimization/src/asap_aware_cse.rs +++ b/crates/logical-asap-optimization/src/pass2/asap_aware_cse.rs @@ -128,7 +128,7 @@ //! read only the finer keys (`… WHERE city IN ('NYC', 'SF')` from a build //! by `city`), is answered by first keeping the finer states that pass //! those conjuncts, a compensating `Filter` over the states -//! ([`filtered_finer`], [`match_finer`](crate::finer_aggregate)), then +//! ([`filtered_finer`], [`match_finer`](crate::pass2::finer_aggregate)), then //! merging them. A SQL aggregate's finer *result* is read the same way by //! the memo rule `memo::rules::finer_aggregate`. //! @@ -168,7 +168,9 @@ use asap_types::ir::{ }; use crate::accuracy::estimators::size_for_all_readers; -use crate::per_computation_candidates::{recompose_guarantees, PerComputationCandidateError}; +use crate::pass1::per_computation_candidates::{ + recompose_guarantees, PerComputationCandidateError, +}; /// A Pass 2 candidate of the identical-expression rule: the candidate's /// roots with each of `sharing_candidates` made one node. @@ -2373,7 +2375,7 @@ fn filtered_finer(coarse: &OperatorNode, fine: &OperatorNode) -> Option<(usize, return None; } let matched = - crate::finer_aggregate::match_finer(child, by.keys(), fine_child, fine_by.keys())?; + crate::pass2::finer_aggregate::match_finer(child, by.keys(), fine_child, fine_by.keys())?; // The filter reads the finer keys as the state's columns of those names. let state_columns = fine_by .keys() @@ -2485,7 +2487,7 @@ fn rolled_up( finer: &Rc, coarse_value: &OperatorNode, ) -> Option> { - use crate::per_computation_candidates::{exact_accumulator, partitions_over}; + use crate::pass1::per_computation_candidates::{exact_accumulator, partitions_over}; let Some(ASAPOp::SummaryAgg { child, family, @@ -2909,7 +2911,7 @@ fn ranking(child: &Rc, by: &Reduction, k: usize) -> Option Vec { - use crate::per_computation_candidates::ComputationCandidate; + use crate::pass1::per_computation_candidates::ComputationCandidate; chose_where(queries, |c| *c == ComputationCandidate::Summary(family)) } @@ -3303,9 +3305,9 @@ mod tests { /// in which every target chose the first candidate `pick` accepts. fn chose_where( queries: &[(&str, f64)], - pick: impl Fn(&crate::per_computation_candidates::ComputationCandidate) -> bool, + pick: impl Fn(&crate::pass1::per_computation_candidates::ComputationCandidate) -> bool, ) -> Vec { - use crate::per_computation_candidates::{ + use crate::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, }; let roots = queries @@ -3676,7 +3678,7 @@ mod tests { /// the last two samples of the window, does not. #[test] fn exact_accumulators_that_merge_get_panes() { - use crate::per_computation_candidates::ComputationCandidate; + use crate::pass1::per_computation_candidates::ComputationCandidate; let accumulator = |c: &ComputationCandidate| matches!(c, ComputationCandidate::ExactAccumulator(_)); for query in [ @@ -4145,7 +4147,7 @@ mod tests { /// The composed candidate of `queries` with every target at its exact /// option (an exact accumulator, or plain exact execution). fn exact(queries: &[&str]) -> Vec { - use crate::per_computation_candidates::ComputationCandidate as C; + use crate::pass1::per_computation_candidates::ComputationCandidate as C; let queries: Vec<(&str, f64)> = queries.iter().map(|q| (*q, 0.01)).collect(); chose_where(&queries, |c| matches!(c, C::Exact | C::ExactAccumulator(_))) } @@ -4602,7 +4604,7 @@ mod tests { "{queries:?}" ); } - use crate::per_computation_candidates::{ + use crate::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate as C, }; diff --git a/crates/logical-asap-optimization/src/finer_aggregate.rs b/crates/logical-asap-optimization/src/pass2/finer_aggregate.rs similarity index 100% rename from crates/logical-asap-optimization/src/finer_aggregate.rs rename to crates/logical-asap-optimization/src/pass2/finer_aggregate.rs diff --git a/crates/logical-asap-optimization/src/memo.rs b/crates/logical-asap-optimization/src/pass2/memo.rs similarity index 99% rename from crates/logical-asap-optimization/src/memo.rs rename to crates/logical-asap-optimization/src/pass2/memo.rs index f87506099..2450614a9 100644 --- a/crates/logical-asap-optimization/src/memo.rs +++ b/crates/logical-asap-optimization/src/pass2/memo.rs @@ -10,10 +10,10 @@ pub mod candidates; pub mod enumeration; mod groups; mod rules; +/// Shared finite state configuration enumeration. +pub mod shared_configurations; #[cfg(test)] mod shared_producer_snapshot; -/// Shared finite state configuration enumeration. -pub mod state_configurations; /// Concrete summary-state groups exposed by sharing rules. pub mod state_groups; /// Local pane candidates with selected-reader grid configurations. diff --git a/crates/logical-asap-optimization/src/memo/candidates.rs b/crates/logical-asap-optimization/src/pass2/memo/candidates.rs similarity index 100% rename from crates/logical-asap-optimization/src/memo/candidates.rs rename to crates/logical-asap-optimization/src/pass2/memo/candidates.rs diff --git a/crates/logical-asap-optimization/src/memo/enumeration.rs b/crates/logical-asap-optimization/src/pass2/memo/enumeration.rs similarity index 98% rename from crates/logical-asap-optimization/src/memo/enumeration.rs rename to crates/logical-asap-optimization/src/pass2/memo/enumeration.rs index 9beb27c3c..6031d3665 100644 --- a/crates/logical-asap-optimization/src/memo/enumeration.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/enumeration.rs @@ -24,7 +24,9 @@ use asap_types::ir::{OperatorNode, QueryRoot}; use super::candidates::CandidateMemo; use super::rules::reuse::replace; use super::MemoGroupId; -use crate::per_computation_candidates::{recompose_guarantees, PerComputationCandidateError}; +use crate::pass1::per_computation_candidates::{ + recompose_guarantees, PerComputationCandidateError, +}; /// One candidate (an index into `CandidateMemo::candidates[group]`) for each /// group it names. [`compose`] gives a group it does not name its first diff --git a/crates/logical-asap-optimization/src/memo/groups.rs b/crates/logical-asap-optimization/src/pass2/memo/groups.rs similarity index 98% rename from crates/logical-asap-optimization/src/memo/groups.rs rename to crates/logical-asap-optimization/src/pass2/memo/groups.rs index a0c19947f..fad287aac 100644 --- a/crates/logical-asap-optimization/src/memo/groups.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/groups.rs @@ -11,7 +11,7 @@ //! //! A Pass 1 target's aggregate group gets one candidate per combination of //! its measures' Pass 1 candidates: the aggregate alone composed by -//! [`crate::per_computation_candidates::compose_logical_candidate`] with that choice, every target beneath it +//! [`crate::pass1::per_computation_candidates::compose_logical_candidate`] with that choice, every target beneath it //! exact. Its local nodes are the composed nodes above the first node //! equal to one of the group's descendant groups, which are its children. //! The local nodes read each child group through its node (the same @@ -32,7 +32,7 @@ use std::collections::{HashMap, HashSet}; use std::rc::Rc; use super::LogicalMemo; -use crate::per_computation_candidates::{ +use crate::pass1::per_computation_candidates::{ compose_logical_candidate_with_budget_share, ComputationCandidate, PerComputationCandidates, }; use asap_types::ir::schema::FieldDataType; @@ -307,8 +307,10 @@ fn compose_alone( targets: &[usize], choice: &[usize], budget_share: usize, -) -> Result, crate::per_computation_candidates::PerComputationCandidateError> -{ +) -> Result< + Vec<(usize, QueryRoot)>, + crate::pass1::per_computation_candidates::PerComputationCandidateError, +> { let mut kept: Vec = targets.to_vec(); for &t in targets { if let Some((_, Some(absorbs))) = per_computation.targets[t].computation_for(choice[t]) { @@ -538,7 +540,7 @@ mod tests { fn memo_of(inventory: &PerComputationCandidates) -> CandidateMemo { populate_pass1(LogicalMemo::from_roots(&inventory.roots), inventory) } - use crate::per_computation_candidates::{ + use crate::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, }; use crate::test_support::lower_promql; @@ -592,7 +594,7 @@ mod tests { let mut invalid_absorption = inventory; let missing = invalid_absorption.targets.len(); invalid_absorption.targets[0].fused = - Some(crate::per_computation_candidates::FusedComputation { + Some(crate::pass1::per_computation_candidates::FusedComputation { absorbs: vec![missing], candidates: Vec::new(), pruned: Vec::new(), @@ -798,7 +800,7 @@ mod tests { } /// The sketch summaries of the first query of `queries` composed with - /// every target at its `algorithm` summary, by [`crate::per_computation_candidates::compose_logical_candidate`]: + /// every target at its `algorithm` summary, by [`crate::pass1::per_computation_candidates::compose_logical_candidate`]: /// as the exhaustive search sizes them. fn composed_sketches( queries: &[&str], diff --git a/crates/logical-asap-optimization/src/memo/rules.rs b/crates/logical-asap-optimization/src/pass2/memo/rules.rs similarity index 89% rename from crates/logical-asap-optimization/src/memo/rules.rs rename to crates/logical-asap-optimization/src/pass2/memo/rules.rs index 6fea876b4..58e053197 100644 --- a/crates/logical-asap-optimization/src/memo/rules.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/rules.rs @@ -4,8 +4,8 @@ pub(super) mod finer_aggregate; pub(super) mod reuse; pub(super) mod rollup; pub(super) mod scan_labels; +pub(super) mod shared_configuration_readers; pub(super) mod shared_producer; -pub(super) mod state_configurations; pub(super) mod summary_inputs; pub(super) mod summary_results; pub(super) mod topk; diff --git a/crates/logical-asap-optimization/src/memo/rules/finer_aggregate.rs b/crates/logical-asap-optimization/src/pass2/memo/rules/finer_aggregate.rs similarity index 94% rename from crates/logical-asap-optimization/src/memo/rules/finer_aggregate.rs rename to crates/logical-asap-optimization/src/pass2/memo/rules/finer_aggregate.rs index a40072426..209c2e6b4 100644 --- a/crates/logical-asap-optimization/src/memo/rules/finer_aggregate.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/rules/finer_aggregate.rs @@ -1,11 +1,11 @@ //! Read a SQL aggregate from a finer aggregate's result -//! ([`match_finer`](crate::finer_aggregate::match_finer)): filter the finer +//! ([`match_finer`](crate::pass2::finer_aggregate::match_finer)): filter the finer //! rows, then merge them into the query's groups with each measure's rollup. use super::reuse::append_reader; -use crate::finer_aggregate::match_finer; -use crate::memo::candidates::{CandidateMemo, CandidateOrigin}; -use crate::memo::check_generation_deadline; -use crate::memo::state_groups::StateGroupExpansionError; +use crate::pass2::finer_aggregate::match_finer; +use crate::pass2::memo::candidates::{CandidateMemo, CandidateOrigin}; +use crate::pass2::memo::check_generation_deadline; +use crate::pass2::memo::state_groups::StateGroupExpansionError; use asap_types::ir::operator::{AggIntent, Reduction}; use asap_types::ir::{NonASAPOp, Operator, OperatorNode, OperatorResultKind}; use std::collections::HashMap; @@ -70,7 +70,7 @@ fn value_rollup(measure: &AggIntent, col: usize, global: bool) -> Option, ) -> Result { diff --git a/crates/logical-asap-optimization/src/memo/rules/reuse.rs b/crates/logical-asap-optimization/src/pass2/memo/rules/reuse.rs similarity index 92% rename from crates/logical-asap-optimization/src/memo/rules/reuse.rs rename to crates/logical-asap-optimization/src/pass2/memo/rules/reuse.rs index 196ec77ad..ea2c2614f 100644 --- a/crates/logical-asap-optimization/src/memo/rules/reuse.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/rules/reuse.rs @@ -1,17 +1,17 @@ //! Shared boundary handling for producer-level reuse rules. Rule outputs retain //! canonical input identities after guarantee recomposition rebuilds their DAGs. -use crate::memo::candidates::{CandidateMemo, CandidateOrigin, ImplementationCandidate}; -use crate::memo::state_groups::{boundary_groups, StateGroupExpansionError}; -use crate::memo::{MemoGroup, MemoGroupId}; +use crate::pass2::memo::candidates::{CandidateMemo, CandidateOrigin, ImplementationCandidate}; +use crate::pass2::memo::state_groups::{boundary_groups, StateGroupExpansionError}; +use crate::pass2::memo::{MemoGroup, MemoGroupId}; use asap_types::ir::OperatorNode; use std::collections::{HashMap, HashSet}; use std::rc::Rc; -pub(in crate::memo) fn eligible(candidate: &ImplementationCandidate) -> bool { +pub(in crate::pass2::memo) fn eligible(candidate: &ImplementationCandidate) -> bool { !candidate.implements.is_empty() && candidate.budget_share > 0 } -pub(in crate::memo) fn restore_inputs( +pub(in crate::pass2::memo) fn restore_inputs( node: &Rc, memo: &CandidateMemo, inputs: &[MemoGroupId], @@ -56,7 +56,7 @@ pub(in crate::memo) fn restore_inputs( visit(node, &canonical, &mut HashMap::new()) } -pub(in crate::memo) fn same_node( +pub(in crate::pass2::memo) fn same_node( left: &OperatorNode, right: &OperatorNode, guarantees: bool, @@ -91,7 +91,7 @@ pub(in crate::memo) fn same_node( && (!guarantees || left.guarantee == right.guarantee) } -pub(in crate::memo) fn append_producer( +pub(in crate::pass2::memo) fn append_producer( memo: &mut CandidateMemo, node: Rc, queries: &[usize], @@ -137,7 +137,7 @@ pub(in crate::memo) fn append_producer( Ok(id) } -pub(in crate::memo) fn append_reader( +pub(in crate::pass2::memo) fn append_reader( memo: &mut CandidateMemo, owner: usize, original: &ImplementationCandidate, @@ -179,7 +179,7 @@ pub(in crate::memo) fn append_reader( Ok(true) } -pub(in crate::memo) fn replace( +pub(in crate::pass2::memo) fn replace( node: &Rc, replacements: &HashMap<*const OperatorNode, Rc>, ) -> Rc { @@ -214,7 +214,7 @@ pub(in crate::memo) fn replace( visit(node, replacements, &mut HashMap::new()) } -pub(in crate::memo) fn combined_inputs( +pub(in crate::pass2::memo) fn combined_inputs( left: &ImplementationCandidate, right: &ImplementationCandidate, ) -> Vec { diff --git a/crates/logical-asap-optimization/src/memo/rules/rollup.rs b/crates/logical-asap-optimization/src/pass2/memo/rules/rollup.rs similarity index 94% rename from crates/logical-asap-optimization/src/memo/rules/rollup.rs rename to crates/logical-asap-optimization/src/pass2/memo/rules/rollup.rs index e82e513ca..e617a27e8 100644 --- a/crates/logical-asap-optimization/src/memo/rules/rollup.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/rules/rollup.rs @@ -2,10 +2,10 @@ use super::reuse::{ append_producer, append_reader, combined_inputs, eligible, replace, restore_inputs, }; -use crate::asap_aware_cse::{rollup_candidate_for, rollup_pass2_candidates}; -use crate::memo::candidates::{CandidateMemo, CandidateOrigin}; -use crate::memo::check_generation_deadline; -use crate::memo::state_groups::{simple_build, StateGroupExpansionError}; +use crate::pass2::asap_aware_cse::{rollup_candidate_for, rollup_pass2_candidates}; +use crate::pass2::memo::candidates::{CandidateMemo, CandidateOrigin}; +use crate::pass2::memo::check_generation_deadline; +use crate::pass2::memo::state_groups::{simple_build, StateGroupExpansionError}; use asap_types::ir::schema::FieldDataType; use asap_types::ir::{ ASAPOp, NonASAPOp, Operator, OperatorNode, ProjectItem, QueryRoot, ScalarExpr, @@ -14,7 +14,7 @@ use std::collections::HashMap; use std::rc::Rc; use std::time::Instant; -pub(in crate::memo) fn add_rollup_candidates( +pub(in crate::pass2::memo) fn add_rollup_candidates( memo: &mut CandidateMemo, deadline: Option, ) -> Result { @@ -224,12 +224,14 @@ pub(in crate::memo) fn add_rollup_candidates( /// Existing pane rollup rules applied to producer pairs on already generated /// legal local grids. No whole-workload choice combinations are constructed. -pub(in crate::memo) fn add_window_rollup_candidates( +pub(in crate::pass2::memo) fn add_window_rollup_candidates( memo: &mut CandidateMemo, deadline: Option, ) -> Result { check_generation_deadline(deadline)?; - use crate::asap_aware_cse::{pane_candidates, window_composition_shared_chain_candidates}; + use crate::pass2::asap_aware_cse::{ + pane_candidates, window_composition_shared_chain_candidates, + }; let mut grids = vec![std::collections::BTreeSet::new(); memo.groups.len()]; for (group, candidates) in memo.candidates.iter().enumerate() { check_generation_deadline(deadline)?; @@ -324,10 +326,10 @@ pub(in crate::memo) fn add_window_rollup_candidates( #[cfg(test)] mod tests { - use crate::memo::candidates::{try_populate_pass1, CandidateOrigin}; - use crate::memo::state_groups::expand_concrete_summary_state_groups; - use crate::memo::LogicalMemo; - use crate::per_computation_candidates::generate_per_computation_candidates; + use crate::pass1::per_computation_candidates::generate_per_computation_candidates; + use crate::pass2::memo::candidates::{try_populate_pass1, CandidateOrigin}; + use crate::pass2::memo::state_groups::expand_concrete_summary_state_groups; + use crate::pass2::memo::LogicalMemo; use crate::test_support::lower_promql; use asap_types::ir::properties::AccuracyTarget; use asap_types::ir::QueryRoot; diff --git a/crates/logical-asap-optimization/src/memo/rules/scan_labels.rs b/crates/logical-asap-optimization/src/pass2/memo/rules/scan_labels.rs similarity index 95% rename from crates/logical-asap-optimization/src/memo/rules/scan_labels.rs rename to crates/logical-asap-optimization/src/pass2/memo/rules/scan_labels.rs index d94768db4..c17939f08 100644 --- a/crates/logical-asap-optimization/src/memo/rules/scan_labels.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/rules/scan_labels.rs @@ -1,6 +1,6 @@ //! Scan-label widening for explicit memo state sharing. Reuses the existing //! Pass 2 widening rule; only its source-chain boundaries are interned here. -use crate::memo::check_generation_deadline; +use crate::pass2::memo::check_generation_deadline; use std::collections::{HashMap, HashSet}; use std::rc::Rc; use std::time::Instant; @@ -8,13 +8,13 @@ use std::time::Instant; use asap_types::ir::operator::Reduction; use asap_types::ir::{ASAPOp, NonASAPOp, OperatorNode, QueryRoot}; -use crate::memo::candidates::{CandidateMemo, CandidateOrigin, ImplementationCandidate}; -use crate::memo::state_groups::{boundary_groups, simple_build, StateGroupExpansionError}; -use crate::memo::{MemoGroup, MemoGroupId}; +use crate::pass2::memo::candidates::{CandidateMemo, CandidateOrigin, ImplementationCandidate}; +use crate::pass2::memo::state_groups::{boundary_groups, simple_build, StateGroupExpansionError}; +use crate::pass2::memo::{MemoGroup, MemoGroupId}; /// Preserve local implementations and append readers over union-label inputs. /// Parent/query reachability is rebuilt by the enclosing state-group expansion. -pub(in crate::memo) fn add_scan_label_candidates( +pub(in crate::pass2::memo) fn add_scan_label_candidates( memo: &mut CandidateMemo, deadline: Option, ) -> Result { @@ -63,7 +63,7 @@ pub(in crate::memo) fn add_scan_label_candidates( roots.push(QueryRoot::Operator(Rc::clone(&candidate.node))); } } - let Some(widened) = crate::asap_aware_cse::with_union_scan_labels(&roots) + let Some(widened) = crate::pass2::asap_aware_cse::with_union_scan_labels(&roots) .map_err(|error| StateGroupExpansionError::ScanLabelWidening(error.to_string()))? else { return Ok(0); diff --git a/crates/logical-asap-optimization/src/memo/rules/state_configurations.rs b/crates/logical-asap-optimization/src/pass2/memo/rules/shared_configuration_readers.rs similarity index 96% rename from crates/logical-asap-optimization/src/memo/rules/state_configurations.rs rename to crates/logical-asap-optimization/src/pass2/memo/rules/shared_configuration_readers.rs index a92644ba2..be3fe7042 100644 --- a/crates/logical-asap-optimization/src/memo/rules/state_configurations.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/rules/shared_configuration_readers.rs @@ -1,6 +1,6 @@ //! Expand compatible readers at finite shared sizes and pane horizons before //! interning concrete states. Local candidates remain available. -use crate::memo::check_generation_deadline; +use crate::pass2::memo::check_generation_deadline; use std::collections::{HashMap, HashSet}; use std::rc::Rc; use std::time::Instant; @@ -12,13 +12,13 @@ use asap_types::ir::{ASAPOp, Operator, OperatorNode, QueryRoot}; use super::shared_producer::{ add_shared_producer_candidates, spans_groups, Reader, SharedProducer, }; -use crate::asap_aware_cse::{with_pane_chain, with_resized_build}; -use crate::memo::candidates::CandidateMemo; -use crate::memo::state_configurations::{ +use crate::pass2::asap_aware_cse::{with_pane_chain, with_resized_build}; +use crate::pass2::memo::candidates::CandidateMemo; +use crate::pass2::memo::shared_configurations::{ pane_configurations_before, shared_size, state_size_configurations, PaneConfiguration, PaneRequirement, PaneWidthDomain, }; -use crate::memo::state_groups::{same_range_input, simple_build, StateGroupExpansionError}; +use crate::pass2::memo::state_groups::{same_range_input, simple_build, StateGroupExpansionError}; /// `resized` (a rewrite of `original` with the same shape) with each node /// that is a child group's node in `original` put back, and the nodes above @@ -95,7 +95,7 @@ struct SummaryStates { requests: HashSet<(usize, usize)>, } -pub(in crate::memo) fn add_state_configuration_candidates_in_domain( +pub(in crate::pass2::memo) fn add_state_configuration_candidates_in_domain( memo: &mut CandidateMemo, domain: PaneWidthDomain, deadline: Option, @@ -478,8 +478,8 @@ fn compatible(left: &StateNeed, right: &StateNeed) -> bool { #[cfg(test)] mod tests { use super::*; - use crate::memo::{candidates::try_populate_pass1, LogicalMemo}; - use crate::per_computation_candidates::generate_per_computation_candidates; + use crate::pass1::per_computation_candidates::generate_per_computation_candidates; + use crate::pass2::memo::{candidates::try_populate_pass1, LogicalMemo}; use crate::test_support::{entry_with, lower_promql}; use asap_types::ir::properties::AccuracyTarget; use asap_types::workload::{QueryRecurrence, RepeatedDemand, RepetitionInterval}; @@ -512,7 +512,7 @@ mod tests { ); 2 ]; - crate::memo::window_candidates::add_local_window_composition(&mut memo, &entries); + crate::pass2::memo::window_candidates::add_local_window_composition(&mut memo, &entries); let mut unoptimized = memo.clone(); let optimized_rewrites = expand_configurations(&mut memo, true, PaneWidthDomain::Complete, None).unwrap(); diff --git a/crates/logical-asap-optimization/src/memo/rules/shared_producer.rs b/crates/logical-asap-optimization/src/pass2/memo/rules/shared_producer.rs similarity index 86% rename from crates/logical-asap-optimization/src/memo/rules/shared_producer.rs rename to crates/logical-asap-optimization/src/pass2/memo/rules/shared_producer.rs index ed1e73f17..fe78e622c 100644 --- a/crates/logical-asap-optimization/src/memo/rules/shared_producer.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/rules/shared_producer.rs @@ -4,19 +4,19 @@ //! from it as one more candidate; its own candidates stay, so plan selection //! decides. Identical expressions are the trivial case, shared by memo group //! identity, and add no candidates here. -use crate::memo::candidates::CandidateMemo; -use crate::memo::check_generation_deadline; -use crate::memo::state_groups::StateGroupExpansionError; +use crate::pass2::memo::candidates::CandidateMemo; +use crate::pass2::memo::check_generation_deadline; +use crate::pass2::memo::state_groups::StateGroupExpansionError; use std::time::Instant; /// One reader of a kind of shared producer: its memo group and its need. -pub(in crate::memo) struct Reader { +pub(in crate::pass2::memo) struct Reader { pub group: usize, pub need: N, } /// A kind of producer several readers can share. -pub(in crate::memo) trait SharedProducer { +pub(in crate::pass2::memo) trait SharedProducer { /// What one reader requires of the producer. type Need; /// A producer's need that serves several readers at once. @@ -46,13 +46,13 @@ pub(in crate::memo) trait SharedProducer { /// Whether `set`'s readers belong to two or more groups; a set inside one /// group shares nothing. -pub(in crate::memo) fn spans_groups(set: &[Reader]) -> bool { +pub(in crate::pass2::memo) fn spans_groups(set: &[Reader]) -> bool { set.iter().any(|reader| reader.group != set[0].group) } /// Gives every reader of a set spanning two or more groups its derivation /// from each of the set's coverings; the number of candidates added. -pub(in crate::memo) fn add_shared_producer_candidates( +pub(in crate::pass2::memo) fn add_shared_producer_candidates( memo: &mut CandidateMemo, producer: &mut P, deadline: Option, diff --git a/crates/logical-asap-optimization/src/memo/rules/summary_inputs.rs b/crates/logical-asap-optimization/src/pass2/memo/rules/summary_inputs.rs similarity index 92% rename from crates/logical-asap-optimization/src/memo/rules/summary_inputs.rs rename to crates/logical-asap-optimization/src/pass2/memo/rules/summary_inputs.rs index 46c20c0b1..2aba23bb3 100644 --- a/crates/logical-asap-optimization/src/memo/rules/summary_inputs.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/rules/summary_inputs.rs @@ -2,15 +2,15 @@ //! This preserves their full expressions and schema, including opaque series //! identity, rather than assuming that a projection is an identity operation. use super::reuse::{append_producer, append_reader, eligible, replace}; -use crate::memo::candidates::{CandidateMemo, CandidateOrigin}; -use crate::memo::check_generation_deadline; -use crate::memo::state_groups::StateGroupExpansionError; +use crate::pass2::memo::candidates::{CandidateMemo, CandidateOrigin}; +use crate::pass2::memo::check_generation_deadline; +use crate::pass2::memo::state_groups::StateGroupExpansionError; use asap_types::ir::{ASAPOp, NonASAPOp, OperatorNode}; use std::collections::{HashMap, HashSet}; use std::rc::Rc; use std::time::Instant; -pub(in crate::memo) fn factor_summary_inputs( +pub(in crate::pass2::memo) fn factor_summary_inputs( memo: &mut CandidateMemo, deadline: Option, ) -> Result<(), StateGroupExpansionError> { @@ -86,7 +86,7 @@ fn canonical_preprocessing( if let Some(group) = memo .groups .iter() - .find(|group| crate::memo::state_groups::same_range_input(&group.node, node)) + .find(|group| crate::pass2::memo::state_groups::same_range_input(&group.node, node)) { replacements.insert(Rc::as_ptr(node), Rc::clone(&group.node)); } diff --git a/crates/logical-asap-optimization/src/memo/rules/summary_results.rs b/crates/logical-asap-optimization/src/pass2/memo/rules/summary_results.rs similarity index 93% rename from crates/logical-asap-optimization/src/memo/rules/summary_results.rs rename to crates/logical-asap-optimization/src/pass2/memo/rules/summary_results.rs index d82eddc59..0fe3120d2 100644 --- a/crates/logical-asap-optimization/src/memo/rules/summary_results.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/rules/summary_results.rs @@ -2,15 +2,15 @@ //! choose a state configuration independently, without enumerating combinations //! of all private states in the enclosing query. use super::reuse::{append_producer, append_reader, eligible, replace}; -use crate::memo::candidates::{CandidateMemo, CandidateOrigin}; -use crate::memo::check_generation_deadline; -use crate::memo::state_groups::{direct_input_builds, StateGroupExpansionError}; +use crate::pass2::memo::candidates::{CandidateMemo, CandidateOrigin}; +use crate::pass2::memo::check_generation_deadline; +use crate::pass2::memo::state_groups::{direct_input_builds, StateGroupExpansionError}; use asap_types::ir::{ASAPOp, OperatorNode}; use std::collections::{HashMap, HashSet}; use std::rc::Rc; use std::time::Instant; -pub(in crate::memo) fn factor_summary_results( +pub(in crate::pass2::memo) fn factor_summary_results( memo: &mut CandidateMemo, deadline: Option, ) -> Result { diff --git a/crates/logical-asap-optimization/src/memo/rules/topk.rs b/crates/logical-asap-optimization/src/pass2/memo/rules/topk.rs similarity index 96% rename from crates/logical-asap-optimization/src/memo/rules/topk.rs rename to crates/logical-asap-optimization/src/pass2/memo/rules/topk.rs index fb3cde63c..77f4c6fe5 100644 --- a/crates/logical-asap-optimization/src/memo/rules/topk.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/rules/topk.rs @@ -2,11 +2,11 @@ //! flags are required: only exact implementations can supply these inputs. use super::reuse::{append_producer, append_reader, eligible, replace}; use super::shared_producer::{add_shared_producer_candidates, Reader, SharedProducer}; -use crate::asap_aware_cse::topk_reuse_candidates; -use crate::memo::candidates::{CandidateMemo, CandidateOrigin}; -use crate::memo::check_generation_deadline; -use crate::memo::state_groups::StateGroupExpansionError; -use crate::memo::MemoGroupId; +use crate::pass2::asap_aware_cse::topk_reuse_candidates; +use crate::pass2::memo::candidates::{CandidateMemo, CandidateOrigin}; +use crate::pass2::memo::check_generation_deadline; +use crate::pass2::memo::state_groups::StateGroupExpansionError; +use crate::pass2::memo::MemoGroupId; use asap_types::ir::operator::{AggIntent, Reduction}; use asap_types::ir::properties::AccuracyGuarantee; use asap_types::ir::schema::FieldDataType; @@ -15,7 +15,7 @@ use std::collections::{HashMap, HashSet}; use std::rc::Rc; use std::time::Instant; -pub(in crate::memo) fn add_topk_candidates( +pub(in crate::pass2::memo) fn add_topk_candidates( memo: &mut CandidateMemo, deadline: Option, ) -> Result { diff --git a/crates/logical-asap-optimization/src/memo/state_configurations.rs b/crates/logical-asap-optimization/src/pass2/memo/shared_configurations.rs similarity index 100% rename from crates/logical-asap-optimization/src/memo/state_configurations.rs rename to crates/logical-asap-optimization/src/pass2/memo/shared_configurations.rs diff --git a/crates/logical-asap-optimization/src/memo/shared_producer_snapshot.rs b/crates/logical-asap-optimization/src/pass2/memo/shared_producer_snapshot.rs similarity index 98% rename from crates/logical-asap-optimization/src/memo/shared_producer_snapshot.rs rename to crates/logical-asap-optimization/src/pass2/memo/shared_producer_snapshot.rs index c633ae133..711c3e134 100644 --- a/crates/logical-asap-optimization/src/memo/shared_producer_snapshot.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/shared_producer_snapshot.rs @@ -5,11 +5,11 @@ //! group: the readers' shared `sum_over_time` is now one group, not one per //! reader. use super::candidates::{try_populate_pass1, CandidateMemo, CandidateOrigin}; -use super::state_configurations::PaneWidthDomain; +use super::shared_configurations::PaneWidthDomain; use super::state_groups::expand_concrete_summary_state_groups_in_domain; use super::window_candidates::add_local_window_composition; use super::LogicalMemo; -use crate::per_computation_candidates::generate_per_computation_candidates; +use crate::pass1::per_computation_candidates::generate_per_computation_candidates; use crate::test_support::{entry_with, lower_promql}; use asap_types::ir::flat::flatten; use asap_types::ir::properties::AccuracyTarget; diff --git a/crates/logical-asap-optimization/src/memo/state_groups.rs b/crates/logical-asap-optimization/src/pass2/memo/state_groups.rs similarity index 97% rename from crates/logical-asap-optimization/src/memo/state_groups.rs rename to crates/logical-asap-optimization/src/pass2/memo/state_groups.rs index 0fd263352..ca13f6dbb 100644 --- a/crates/logical-asap-optimization/src/memo/state_groups.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/state_groups.rs @@ -60,13 +60,13 @@ pub fn expand_concrete_summary_state_groups( ) -> Result { expand_concrete_summary_state_groups_in_domain( memo, - super::state_configurations::PaneWidthDomain::Complete, + super::shared_configurations::PaneWidthDomain::Complete, ) } pub fn expand_concrete_summary_state_groups_in_domain( memo: CandidateMemo, - domain: super::state_configurations::PaneWidthDomain, + domain: super::shared_configurations::PaneWidthDomain, ) -> Result { expand_concrete_summary_state_groups_before(memo, domain, None) } @@ -74,7 +74,7 @@ pub fn expand_concrete_summary_state_groups_in_domain( /// An interrupted catalog is discarded, never returned as a complete search space. pub fn expand_concrete_summary_state_groups_before( memo: CandidateMemo, - domain: super::state_configurations::PaneWidthDomain, + domain: super::shared_configurations::PaneWidthDomain, deadline: Option, ) -> Result { expand_with_state_index(memo, domain, deadline, true) @@ -82,7 +82,7 @@ pub fn expand_concrete_summary_state_groups_before( fn expand_with_state_index( mut memo: CandidateMemo, - domain: super::state_configurations::PaneWidthDomain, + domain: super::shared_configurations::PaneWidthDomain, deadline: Option, indexed: bool, ) -> Result { @@ -106,7 +106,7 @@ fn expand_with_state_index( super::rules::rollup::add_rollup_candidates(&mut memo, deadline)?; super::rules::rollup::add_window_rollup_candidates(&mut memo, deadline)?; super::rules::summary_results::factor_summary_results(&mut memo, deadline)?; - super::rules::state_configurations::add_state_configuration_candidates_in_domain( + super::rules::shared_configuration_readers::add_state_configuration_candidates_in_domain( &mut memo, domain, deadline, )?; let mut builds: Vec = Vec::new(); @@ -480,9 +480,9 @@ fn replace_node( #[cfg(test)] mod tests { use super::*; - use crate::memo::candidates::try_populate_pass1; - use crate::memo::LogicalMemo; - use crate::per_computation_candidates::generate_per_computation_candidates; + use crate::pass1::per_computation_candidates::generate_per_computation_candidates; + use crate::pass2::memo::candidates::try_populate_pass1; + use crate::pass2::memo::LogicalMemo; use asap_types::ir::properties::AccuracyTarget; use asap_types::ir::QueryRoot; @@ -498,7 +498,7 @@ mod tests { ]), &[6, 6, 6], ); - let domain = super::super::state_configurations::PaneWidthDomain::Complete; + let domain = super::super::shared_configurations::PaneWidthDomain::Complete; let indexed = expand_with_state_index(memo.clone(), domain, None, true).unwrap(); let linear = expand_with_state_index(memo, domain, None, false).unwrap(); assert_eq!(indexed.state_groups, linear.state_groups); @@ -539,7 +539,7 @@ mod tests { assert!(matches!( expand_concrete_summary_state_groups_before( memo, - super::super::state_configurations::PaneWidthDomain::Complete, + super::super::shared_configurations::PaneWidthDomain::Complete, Some(Instant::now()) ), Err(StateGroupExpansionError::DeadlineExceeded(_)) @@ -664,7 +664,7 @@ mod tests { } fn with_local_panes(mut memo: CandidateMemo, grids: &[u64]) -> CandidateMemo { - use crate::asap_aware_cse::{pane_candidates, window_composition_pass2_candidates}; + use crate::pass2::asap_aware_cse::{pane_candidates, window_composition_pass2_candidates}; let boundaries: HashMap<_, _> = memo .groups @@ -1294,7 +1294,8 @@ mod tests { }; replacements.insert(Rc::as_ptr(input), project); } - candidate.node = crate::memo::rules::reuse::replace(&candidate.node, &replacements); + candidate.node = + crate::pass2::memo::rules::reuse::replace(&candidate.node, &replacements); assert!(direct_input_builds(&memo, &candidate).is_empty()); memo.candidates[owner].push(candidate); injected += 1; @@ -1329,7 +1330,7 @@ mod tests { .filter(|node| is_univmon(node)) .collect(); assert!(!before.is_empty(), "real generation must offer UnivMon"); - crate::memo::rules::summary_inputs::factor_summary_inputs(&mut memo, None).unwrap(); + crate::pass2::memo::rules::summary_inputs::factor_summary_inputs(&mut memo, None).unwrap(); assert!(memo .candidates .iter() @@ -1403,7 +1404,7 @@ mod tests { ), grouping.clone(), ); - let roots = crate::asap_aware_cse::with_resized_build( + let roots = crate::pass2::asap_aware_cse::with_resized_build( &[QueryRoot::Operator(Rc::clone(&base.node))], &build, family, @@ -1412,7 +1413,8 @@ mod tests { let QueryRoot::Operator(root) = &roots[0] else { unreachable!() }; - let root = crate::memo::rules::reuse::restore_inputs(root, &memo, &base.children); + let root = + crate::pass2::memo::rules::reuse::restore_inputs(root, &memo, &base.children); without_private_guarantees(&root, &boundaries) }; let weak = rewritten(0.001); @@ -1423,7 +1425,7 @@ mod tests { ); base.node = weak; memo.candidates[owner] = vec![base.clone()]; - assert!(crate::memo::rules::reuse::append_reader( + assert!(crate::pass2::memo::rules::reuse::append_reader( &mut memo, owner, &base, diff --git a/crates/logical-asap-optimization/src/memo/window_candidates.rs b/crates/logical-asap-optimization/src/pass2/memo/window_candidates.rs similarity index 97% rename from crates/logical-asap-optimization/src/memo/window_candidates.rs rename to crates/logical-asap-optimization/src/pass2/memo/window_candidates.rs index bc76b5d9f..41b5ca4b2 100644 --- a/crates/logical-asap-optimization/src/memo/window_candidates.rs +++ b/crates/logical-asap-optimization/src/pass2/memo/window_candidates.rs @@ -2,11 +2,11 @@ //! connections, not the union of potential consumers, determine eligibility. use super::candidates::{CandidateMemo as Memo, CandidateOrigin, ImplementationCandidate}; #[cfg(test)] -use super::state_configurations::pane_width_divisors; -use super::state_configurations::{pane_width_domain_before, PaneWidthDomain}; +use super::shared_configurations::pane_width_divisors; +use super::shared_configurations::{pane_width_domain_before, PaneWidthDomain}; use super::{check_generation_deadline, CandidateGenerationTimeout}; use super::{MemoGroup, MemoGroupId as GroupId}; -use crate::asap_aware_cse::{pane_candidates, window_composition_pass2_candidates}; +use crate::pass2::asap_aware_cse::{pane_candidates, window_composition_pass2_candidates}; use asap_types::ir::flat::flatten; use asap_types::ir::{OperatorNode, QueryRoot}; use asap_types::workload::QueryWorkloadEntry; @@ -247,7 +247,7 @@ fn restore_scan_boundaries( // Nongridded potential consumers do not veto a repeated reader's panes. #[cfg(test)] fn compatible_reader_grids(group: &MemoGroup, entries: &[QueryWorkloadEntry]) -> Vec { - super::state_configurations::pane_width_domain( + super::shared_configurations::pane_width_domain( group .queries .iter() @@ -323,8 +323,8 @@ fn candidate_signature(candidate: &ImplementationCandidate) -> Result { #[cfg(test)] mod tests { use super::*; - use crate::per_computation_candidates::generate_per_computation_candidates; + use crate::pass1::per_computation_candidates::generate_per_computation_candidates; use crate::test_support::lower_promql; use asap_types::ir::schema::schema_support::with_promql_series_identity; diff --git a/crates/logical-asap-optimization/src/test_support.rs b/crates/logical-asap-optimization/src/test_support.rs index d6ffa859f..21c49103c 100644 --- a/crates/logical-asap-optimization/src/test_support.rs +++ b/crates/logical-asap-optimization/src/test_support.rs @@ -193,8 +193,8 @@ pub fn at_ingestion(root: &Rc) -> Rc { /// The Count-Min summary of a Stage 1 candidate of `query`. pub fn cms_summary(query: &str) -> OperatorNode { use crate::deployment_capabilities::DeploymentCapabilities; - use crate::per_computation_candidates::compose_logical_candidate; - use crate::per_computation_candidates::generate_per_computation_candidates; + use crate::pass1::per_computation_candidates::compose_logical_candidate; + use crate::pass1::per_computation_candidates::generate_per_computation_candidates; use asap_types::ir::schema::{FieldDataType, SketchAlgorithm}; use asap_types::ir::{ASAPOp, QueryRoot}; let target = AccuracyTarget::max_error(0.01).failure_probability(0.01); diff --git a/crates/logical-asap-optimization/tests/per_computation_candidates.rs b/crates/logical-asap-optimization/tests/per_computation_candidates.rs index 7108b643f..f395cebca 100644 --- a/crates/logical-asap-optimization/tests/per_computation_candidates.rs +++ b/crates/logical-asap-optimization/tests/per_computation_candidates.rs @@ -1,5 +1,5 @@ //! Frontend-to-Pass-1 acceptance: candidate discovery precedes empirical selection. -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ computation_candidates_for_intent, generate_per_computation_candidates, ComputationCandidate, HavingEntry, HavingPlacement, PerComputationCandidateError, PruneReason, }; @@ -448,7 +448,7 @@ fn filtered_measure_keeps_candidates_and_records_its_filter() { } fn assert_sql_count_choices( - choices: &asap_logical_asap_optimization::per_computation_candidates::ComputationChoices, + choices: &asap_logical_asap_optimization::pass1::per_computation_candidates::ComputationChoices, ) { assert_eq!( choices.candidates, @@ -763,7 +763,7 @@ fn example_1_exact_q2_prunes_topk_heaps() { /// The `HAVING` entries of the target whose measure satisfies `is`. fn having_of( - targets: &[asap_logical_asap_optimization::per_computation_candidates::ComputationTarget], + targets: &[asap_logical_asap_optimization::pass1::per_computation_candidates::ComputationTarget], is: impl Fn(&AggIntent) -> bool, ) -> Vec { let target = targets @@ -916,7 +916,7 @@ fn without_and_per_entity_having_stays_above() { /// with an exact guarantee. #[test] fn composed_candidate_replaces_chosen_target_with_summary_evaluation() { - use asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate; + use asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate; let producer = aggregate(AggIntent::Cardinality { cols: vec![0], accuracy: approximate(), @@ -955,7 +955,7 @@ fn composed_candidate_replaces_chosen_target_with_summary_evaluation() { /// The one root of the workload candidate composed from `roots` and `choice`. fn composed(roots: Vec>, choice: &[usize]) -> Vec> { - use asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate; + use asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate; let inventory = generate_per_computation_candidates( roots .into_iter() @@ -1010,7 +1010,7 @@ fn summary_agg(node: &OperatorNode) -> &ASAPOp { /// measure's accuracy requirement. #[test] fn composed_summary_is_sized_for_its_measure() { - use asap_logical_asap_optimization::realization::default_size_params; + use asap_logical_asap_optimization::pass1::realization::default_size_params; let intent = quantile(); let [root] = <[_; 1]>::try_from(composed(vec![aggregate(intent.clone())], &[1])).unwrap(); let ASAPOp::SummaryAgg { @@ -1222,7 +1222,7 @@ fn composed_guarantees() { /// a subquery in it reads the subquery's substitution. #[test] fn own_having_subquery_is_substituted() { - use asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate; + use asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate; let inner = aggregate(quantile()); let outer = grouped_quantile(Some(above_scalar(1, inner.clone()))); let inventory = @@ -1324,10 +1324,10 @@ fn grouped_avg_composition_preserves_the_whole_schema() { // Cached local rules preserve filtered and unfiltered consumers independently. #[test] fn memo_cached_rules_preserve_occurrence_specific_having() { - use asap_logical_asap_optimization::memo::LogicalMemo; - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates_with_memo, }; + use asap_logical_asap_optimization::pass2::memo::LogicalMemo; let shared = grouped_count(None); let other = grouped_count(None); let key = equals(0, ScalarValue::Utf8("a".into())); diff --git a/crates/physical-asap-optimization/src/lib.rs b/crates/physical-asap-optimization/src/lib.rs index 600abefa2..93421e714 100644 --- a/crates/physical-asap-optimization/src/lib.rs +++ b/crates/physical-asap-optimization/src/lib.rs @@ -1186,7 +1186,7 @@ fn implement_topk( return Err(unsupported("HAVING")); } let child = memo[&Rc::as_ptr(child)].clone(); - let value = asap_logical_asap_optimization::realization::ranked_column(&child) + let value = asap_logical_asap_optimization::pass1::realization::ranked_column(&child) .map_err(|e| unsupported(&format!("no ranked column: {e}")))?; let sorted = Rc::new( OperatorNode::new(Operator::NonASAP(NonASAPOp::Sort { @@ -1556,7 +1556,7 @@ mod tests { "topk by (job) (10, sum_over_time(m[1m]))", AccuracyTarget::max_error(0.01).failure_probability(0.001), ); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates( + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates( vec![(0, QueryRoot::Operator(root))], ) .unwrap(); @@ -1567,7 +1567,7 @@ mod tests { .map(|t| t.choice_count() - 1) .collect(); let roots: Vec<_> = - asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate( + asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate( &inventory, &choice, ) .unwrap() @@ -1602,7 +1602,7 @@ mod tests { .failure_probability(0.001) .accuracy_metric(asap_types::ir::properties::AccuracyMetric::Rank), ); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates( + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates( vec![(0, QueryRoot::Operator(root))], ) .unwrap(); @@ -1611,7 +1611,7 @@ mod tests { .iter() .map(|t| t.choice_count() - 1) .collect(); - asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate( + asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate( &inventory, &choice, ) .unwrap() @@ -1622,13 +1622,14 @@ mod tests { /// `root` with its summary build in 1-min tumbling panes. fn in_panes(root: QueryRoot) -> QueryRoot { let roots = [root]; - let rule_candidates = asap_logical_asap_optimization::asap_aware_cse::pane_candidates( - &roots, - &[Some(MINUTE)], - ); + let rule_candidates = + asap_logical_asap_optimization::pass2::asap_aware_cse::pane_candidates( + &roots, + &[Some(MINUTE)], + ); assert_eq!(rule_candidates.len(), 1, "{rule_candidates:?}"); let mut pass2_candidates = - asap_logical_asap_optimization::asap_aware_cse::window_composition_pass2_candidates( + asap_logical_asap_optimization::pass2::asap_aware_cse::window_composition_pass2_candidates( &roots, &rule_candidates, ) diff --git a/crates/plan-selection/src/lib.rs b/crates/plan-selection/src/lib.rs index a22ebf3d0..331e1d27f 100644 --- a/crates/plan-selection/src/lib.rs +++ b/crates/plan-selection/src/lib.rs @@ -279,7 +279,7 @@ use asap_logical_asap_optimization::accuracy::estimators::with_failure_probabili use asap_logical_asap_optimization::accuracy::estimators::{hll, univmon}; use asap_logical_asap_optimization::accuracy::OperandDomain; use asap_logical_asap_optimization::deployment_capabilities::DeploymentCapabilitiesError; -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ approximate_inputs, distinct_bound_source, operand_domain_statistic, operand_guarantee, operand_of, project_column_guarantee, root_guarantee, with_resized_summaries, }; @@ -2707,9 +2707,9 @@ fn bound_root_guarantee( }; match root_guarantee(root) { Some(guarantee) => Some(bind(&guarantee)), - None => { - asap_logical_asap_optimization::per_computation_candidates::bind_guarantees(root, &bind) - } + None => asap_logical_asap_optimization::pass1::per_computation_candidates::bind_guarantees( + root, &bind, + ), } } @@ -5391,7 +5391,7 @@ mod tests { "topk by (job) (10, sum_over_time(m[1m]))", AccuracyTarget::max_error(0.01).failure_probability(0.001), ); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates( + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates( vec![(0, QueryRoot::Operator(root))], ) .unwrap(); @@ -5405,7 +5405,7 @@ mod tests { .map(|index| { let mut choice = vec![0; inventory.targets.len()]; choice[topk] = index; - let roots: Vec<_> = asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate( + let roots: Vec<_> = asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate( &inventory, &choice, ) .unwrap() @@ -6103,7 +6103,7 @@ mod tests { /// candidates `P1`, `P2`, ... fn all_candidates(query: &str, target: &AccuracyTarget) -> Vec { let root = lower_promql(query, target.clone()); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates( + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates( vec![(0, QueryRoot::Operator(root))], ) .unwrap(); @@ -6124,7 +6124,7 @@ mod tests { .iter() .enumerate() .map(|(index, choice)| { - let roots: Vec<_> = asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate( + let roots: Vec<_> = asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate( &inventory, choice, ) .unwrap() @@ -6582,11 +6582,11 @@ mod tests { (index, QueryRoot::Operator(root)) }) .collect(); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates(roots) + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates(roots) .unwrap(); let choice = vec![0; inventory.targets.len()]; let roots: Vec<_> = - asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate( + asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate( &inventory, &choice, ) .unwrap() @@ -8708,7 +8708,7 @@ mod tests { /// symbolic and plan selection treats it as unmet. #[test] fn average_over_relative_estimates_needs_the_sign() { - use asap_logical_asap_optimization::per_computation_candidates as pcc; + use asap_logical_asap_optimization::pass1::per_computation_candidates as pcc; let target = AccuracyTarget::max_error(0.01); let root = lower_promql( "avg by (job) (quantile_over_time(0.99, m[1m]))", @@ -9057,7 +9057,7 @@ mod tests { "quantile_over_time(0.99, m[1m])", AccuracyTarget::max_error(0.01).failure_probability(0.01), ); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates( + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates( vec![(0, QueryRoot::Operator(root))], ) .unwrap(); @@ -9069,7 +9069,7 @@ mod tests { .candidates .iter() .position(|c| { - *c == asap_logical_asap_optimization::per_computation_candidates::ComputationCandidate::Summary( + *c == asap_logical_asap_optimization::pass1::per_computation_candidates::ComputationCandidate::Summary( SketchAlgorithm::Kll, ) }) @@ -9077,7 +9077,7 @@ mod tests { }) .collect(); let roots = - asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate( + asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate( &inventory, &choice, ) .unwrap(); @@ -9104,13 +9104,13 @@ mod tests { /// with nothing materialized. fn first_candidate_dag(query: &str) -> PhysicalASAPDAG { let root = lower_promql(query, AccuracyTarget::exact()); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates( + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates( vec![(0, QueryRoot::Operator(root))], ) .unwrap(); let choice = vec![0; inventory.targets.len()]; let roots: Vec<_> = - asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate( + asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate( &inventory, &choice, ) .unwrap() @@ -9611,7 +9611,7 @@ mod tests { deployment: &DeploymentCapabilities, ) -> Vec { let root = lower_promql("quantile_over_time(0.99, m[5m])", p99_target()); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates( + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates( vec![(0, QueryRoot::Operator(root))], ) .unwrap(); @@ -9622,14 +9622,14 @@ mod tests { .position(|c| { matches!( c, - asap_logical_asap_optimization::per_computation_candidates::ComputationCandidate::Summary( + asap_logical_asap_optimization::pass1::per_computation_candidates::ComputationCandidate::Summary( SketchAlgorithm::Kll ) ) }) .unwrap(); let roots: Vec<_> = - asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate( + asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate( &inventory, &[kll], ) @@ -9637,12 +9637,13 @@ mod tests { .into_iter() .map(|(_, root)| root) .collect(); - let rule_candidates = asap_logical_asap_optimization::asap_aware_cse::pane_candidates( - &roots, - &[Some(u64::from(MINUTE))], - ); + let rule_candidates = + asap_logical_asap_optimization::pass2::asap_aware_cse::pane_candidates( + &roots, + &[Some(u64::from(MINUTE))], + ); let roots = - asap_logical_asap_optimization::asap_aware_cse::window_composition_pass2_candidates( + asap_logical_asap_optimization::pass2::asap_aware_cse::window_composition_pass2_candidates( &roots, &rule_candidates, ) @@ -9825,10 +9826,10 @@ mod tests { .collect(); // The exact candidate of each query. let inventory = - asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates(roots).unwrap(); + asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates(roots).unwrap(); let exact = vec![0; inventory.targets.len()]; let roots: Vec = - asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate( + asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate( &inventory, &exact, ) .unwrap() @@ -10596,7 +10597,7 @@ mod tests { shared: bool, rows_per_s: f64, ) -> PhysicalWorkloadPlan { - use asap_logical_asap_optimization::per_computation_candidates as pcc; + use asap_logical_asap_optimization::pass1::per_computation_candidates as pcc; let inventory = pcc::generate_per_computation_candidates( queries .iter() @@ -10624,12 +10625,13 @@ mod tests { .into_iter() .map(|(_, root)| root) .collect(); - let rule_candidates = asap_logical_asap_optimization::asap_aware_cse::pane_candidates( - &roots, - &queries.map(|(_, interval_ms)| Some(u64::from(interval_ms))), - ); + let rule_candidates = + asap_logical_asap_optimization::pass2::asap_aware_cse::pane_candidates( + &roots, + &queries.map(|(_, interval_ms)| Some(u64::from(interval_ms))), + ); let roots = - asap_logical_asap_optimization::asap_aware_cse::window_composition_pass2_candidates( + asap_logical_asap_optimization::pass2::asap_aware_cse::window_composition_pass2_candidates( &roots, &rule_candidates, ) @@ -11113,13 +11115,13 @@ mod tests { /// with each Stage 2 materialization, ids `P-m`. fn quantile_candidates() -> Vec { let root = lower_promql("quantile_over_time(0.99, m[5m])", p99_target()); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates( + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates( vec![(0, QueryRoot::Operator(root))], ) .unwrap(); let mut out = Vec::new(); for choice in 0..inventory.targets[0].choice_count() { - let roots: Vec<_> = asap_logical_asap_optimization::per_computation_candidates::compose_logical_candidate( + let roots: Vec<_> = asap_logical_asap_optimization::pass1::per_computation_candidates::compose_logical_candidate( &inventory, &[choice], ) diff --git a/crates/plan-selection/src/search/candidates/accuracy_configurations.rs b/crates/plan-selection/src/search/candidates/accuracy_configurations.rs index cb1967bb8..0f877f54c 100644 --- a/crates/plan-selection/src/search/candidates/accuracy_configurations.rs +++ b/crates/plan-selection/src/search/candidates/accuracy_configurations.rs @@ -1,6 +1,6 @@ //! Additional finite capacities for whole-result failure budgets. //! Original capacities remain available; final composed accuracy is still checked. -use asap_logical_asap_optimization::memo::candidates::CandidateMemo; +use asap_logical_asap_optimization::pass2::memo::candidates::CandidateMemo; use asap_types::ir::{properties::AccuracyScope, QueryRoot}; use asap_types::workload::{DataWorkload, QueryWorkloadEntry}; use std::{rc::Rc, time::Instant}; diff --git a/crates/plan-selection/src/search/candidates/configurations.rs b/crates/plan-selection/src/search/candidates/configurations.rs index da83ed313..6072f6e93 100644 --- a/crates/plan-selection/src/search/candidates/configurations.rs +++ b/crates/plan-selection/src/search/candidates/configurations.rs @@ -41,7 +41,9 @@ pub(in crate::search) struct CandidateConfigurationInventory { #[derive(Debug, thiserror::Error)] pub(in crate::search) enum ConfigurationError { #[error(transparent)] - DeadlineExceeded(#[from] asap_logical_asap_optimization::memo::CandidateGenerationTimeout), + DeadlineExceeded( + #[from] asap_logical_asap_optimization::pass2::memo::CandidateGenerationTimeout, + ), #[error("invalid source candidate inventory: {0}")] InvalidInventory(String), #[error("source resource constraints require configuration-specific accounting")] @@ -515,10 +517,10 @@ mod tests { use super::*; use crate::search::candidates::inventory::build_candidate_inventory; use crate::search::milp::model::select_candidates; - use asap_logical_asap_optimization::memo::candidates::try_populate_pass1; - use asap_logical_asap_optimization::memo::state_groups::expand_concrete_summary_state_groups; - use asap_logical_asap_optimization::memo::{LogicalMemo, MemoGroupId}; - use asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass2::memo::candidates::try_populate_pass1; + use asap_logical_asap_optimization::pass2::memo::state_groups::expand_concrete_summary_state_groups; + use asap_logical_asap_optimization::pass2::memo::{LogicalMemo, MemoGroupId}; use asap_logical_asap_optimization::test_support::lower_promql; use asap_types::ir::properties::AccuracyTarget; use asap_types::ir::schema::{FieldDataType, SketchAlgorithm}; diff --git a/crates/plan-selection/src/search/candidates/factoring.rs b/crates/plan-selection/src/search/candidates/factoring.rs index 4ecc28828..6dd18d8ae 100644 --- a/crates/plan-selection/src/search/candidates/factoring.rs +++ b/crates/plan-selection/src/search/candidates/factoring.rs @@ -2,7 +2,7 @@ //! Scope copies preserve independent bindings; internal computations are never merged. use std::collections::HashMap; -use asap_logical_asap_optimization::memo::MemoGroupId; +use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_types::ir::OperatorNode; use super::graph::PhysicalCandidateId; diff --git a/crates/plan-selection/src/search/candidates/graph.rs b/crates/plan-selection/src/search/candidates/graph.rs index 8ddc30553..83574ac82 100644 --- a/crates/plan-selection/src/search/candidates/graph.rs +++ b/crates/plan-selection/src/search/candidates/graph.rs @@ -1,6 +1,6 @@ //! Candidate dependency graph, declared constraints, and structural validation. use super::suppliers::SupplierCandidates; -use asap_logical_asap_optimization::memo::MemoGroupId; +use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use std::collections::HashSet; /// Index into [`CandidateDependencyGraph::candidates`]. diff --git a/crates/plan-selection/src/search/candidates/inventory.rs b/crates/plan-selection/src/search/candidates/inventory.rs index d3947a13f..6ac1bd48f 100644 --- a/crates/plan-selection/src/search/candidates/inventory.rs +++ b/crates/plan-selection/src/search/candidates/inventory.rs @@ -9,8 +9,8 @@ use std::collections::{HashMap, HashSet}; use std::rc::Rc; -use asap_logical_asap_optimization::memo::candidates::CandidateMemo; -use asap_logical_asap_optimization::memo::MemoGroupId; +use asap_logical_asap_optimization::pass2::memo::candidates::CandidateMemo; +use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_types::ir::OperatorNode; use asap_types::physical::Materialization; @@ -32,7 +32,9 @@ pub(in crate::search) struct CandidateInventory { #[derive(Debug, thiserror::Error)] pub(in crate::search) enum CandidateInventoryError { #[error(transparent)] - DeadlineExceeded(#[from] asap_logical_asap_optimization::memo::CandidateGenerationTimeout), + DeadlineExceeded( + #[from] asap_logical_asap_optimization::pass2::memo::CandidateGenerationTimeout, + ), #[error("invalid candidate memo: {0}")] InvalidMemo(String), #[error("unsupported candidate {candidate} in group {group}: {reason}")] @@ -359,10 +361,10 @@ mod tests { use super::*; use crate::search::candidates::reconstruction::reconstruct_candidate_outputs; use crate::search::milp::model::select_candidates; - use asap_logical_asap_optimization::memo::candidates::try_populate_pass1; - use asap_logical_asap_optimization::memo::state_groups::expand_concrete_summary_state_groups; - use asap_logical_asap_optimization::memo::LogicalMemo; - use asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass2::memo::candidates::try_populate_pass1; + use asap_logical_asap_optimization::pass2::memo::state_groups::expand_concrete_summary_state_groups; + use asap_logical_asap_optimization::pass2::memo::LogicalMemo; use asap_logical_asap_optimization::test_support::lower_promql; use asap_types::ir::properties::AccuracyTarget; use asap_types::ir::schema::{FieldDataType, SketchAlgorithm}; @@ -639,7 +641,7 @@ mod tests { entry }) .collect(); - asap_logical_asap_optimization::memo::window_candidates::add_local_window_composition( + asap_logical_asap_optimization::pass2::memo::window_candidates::add_local_window_composition( &mut memo, &entries, ); let memo = expand_concrete_summary_state_groups(memo).unwrap().memo; @@ -860,7 +862,7 @@ mod tests { .unwrap(); if matches!(kind, "ranking" | "sketch") { for (output, group) in inventory.graph.query_roots.iter_mut().zip(&outputs) { - output.compatible_candidates.retain(|id| inventory.group_candidates[group.0 as usize].iter().position(|candidate| candidate == id).is_some_and(|index| memo.candidates[group.0 as usize][index].origin == if kind == "ranking" { asap_logical_asap_optimization::memo::candidates::CandidateOrigin::TopKReuse } else { asap_logical_asap_optimization::memo::candidates::CandidateOrigin::SharedBuild })); + output.compatible_candidates.retain(|id| inventory.group_candidates[group.0 as usize].iter().position(|candidate| candidate == id).is_some_and(|index| memo.candidates[group.0 as usize][index].origin == if kind == "ranking" { asap_logical_asap_optimization::pass2::memo::candidates::CandidateOrigin::TopKReuse } else { asap_logical_asap_optimization::pass2::memo::candidates::CandidateOrigin::SharedBuild })); assert!( !output.compatible_candidates.is_empty(), "{kind} reader generated" @@ -944,7 +946,7 @@ mod tests { // one or both states can serve external queries without a configuration product. #[test] fn factored_summary_results_choose_independent_capacities_and_sharing() { - use asap_logical_asap_optimization::memo::candidates::CandidateOrigin; + use asap_logical_asap_optimization::pass2::memo::candidates::CandidateOrigin; use asap_logical_asap_optimization::test_support::entry_with; use asap_types::ir::schema::sketch::SketchParams; use asap_types::workload::{ diff --git a/crates/plan-selection/src/search/candidates/mod.rs b/crates/plan-selection/src/search/candidates/mod.rs index 0547d8d2b..e89bea93a 100644 --- a/crates/plan-selection/src/search/candidates/mod.rs +++ b/crates/plan-selection/src/search/candidates/mod.rs @@ -12,9 +12,9 @@ pub(crate) mod suppliers; /// Discard partially built catalogs on timeout; they cannot certify coverage. fn check_deadline( deadline: Option, -) -> Result<(), asap_logical_asap_optimization::memo::CandidateGenerationTimeout> { +) -> Result<(), asap_logical_asap_optimization::pass2::memo::CandidateGenerationTimeout> { if deadline.is_some_and(|deadline| std::time::Instant::now() >= deadline) { - Err(asap_logical_asap_optimization::memo::CandidateGenerationTimeout) + Err(asap_logical_asap_optimization::pass2::memo::CandidateGenerationTimeout) } else { Ok(()) } diff --git a/crates/plan-selection/src/search/candidates/physical.rs b/crates/plan-selection/src/search/candidates/physical.rs index 994abfc7d..7732bb734 100644 --- a/crates/plan-selection/src/search/candidates/physical.rs +++ b/crates/plan-selection/src/search/candidates/physical.rs @@ -204,10 +204,10 @@ mod tests { use super::*; use crate::search::candidates::inventory::build_candidate_inventory; use crate::search::milp::model::select_candidates; - use asap_logical_asap_optimization::memo::candidates::try_populate_pass1; - use asap_logical_asap_optimization::memo::state_groups::expand_concrete_summary_state_groups; - use asap_logical_asap_optimization::memo::{LogicalMemo, MemoGroupId}; - use asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass2::memo::candidates::try_populate_pass1; + use asap_logical_asap_optimization::pass2::memo::state_groups::expand_concrete_summary_state_groups; + use asap_logical_asap_optimization::pass2::memo::{LogicalMemo, MemoGroupId}; use asap_logical_asap_optimization::test_support::lower_promql; use asap_types::ir::properties::AccuracyTarget; use asap_types::ir::schema::{FieldDataType, SketchAlgorithm}; diff --git a/crates/plan-selection/src/search/candidates/reconstruction.rs b/crates/plan-selection/src/search/candidates/reconstruction.rs index 81389bc1f..a334af0f0 100644 --- a/crates/plan-selection/src/search/candidates/reconstruction.rs +++ b/crates/plan-selection/src/search/candidates/reconstruction.rs @@ -5,7 +5,7 @@ use std::collections::HashMap; use std::rc::Rc; -use asap_logical_asap_optimization::per_computation_candidates::recompose_guarantees; +use asap_logical_asap_optimization::pass1::per_computation_candidates::recompose_guarantees; use asap_types::ir::{OperatorNode, QueryRoot}; use crate::search::candidates::graph::{ @@ -245,7 +245,7 @@ mod tests { PhysicalCandidate, ProducerRequirement, QueryRootCandidates, }; use crate::search::milp::model::select_candidates; - use asap_logical_asap_optimization::memo::MemoGroupId; + use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_logical_asap_optimization::test_support::lower_promql; // Physical identity is reflexive for NaN, without equating different diff --git a/crates/plan-selection/src/search/candidates/scopes.rs b/crates/plan-selection/src/search/candidates/scopes.rs index 5356c2f66..934ab4879 100644 --- a/crates/plan-selection/src/search/candidates/scopes.rs +++ b/crates/plan-selection/src/search/candidates/scopes.rs @@ -280,7 +280,7 @@ mod tests { use crate::search::candidates::configurations::CandidateConfiguration; use crate::search::candidates::graph::PhysicalCandidate; use crate::search::milp::model::select_candidates; - use asap_logical_asap_optimization::memo::MemoGroupId; + use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_types::ir::properties::ExecutionTiming; use asap_types::physical::Materialization; diff --git a/crates/plan-selection/src/search/candidates/suppliers.rs b/crates/plan-selection/src/search/candidates/suppliers.rs index 322fce580..750d573f1 100644 --- a/crates/plan-selection/src/search/candidates/suppliers.rs +++ b/crates/plan-selection/src/search/candidates/suppliers.rs @@ -119,7 +119,7 @@ mod tests { ProducerConsumerConnection, ProducerRequirement, QueryRootAssignment, QueryRootCandidates, SelectedCandidateGraph, }; - use asap_logical_asap_optimization::memo::MemoGroupId; + use asap_logical_asap_optimization::pass2::memo::MemoGroupId; let mut interner = SupplierSetInterner::default(); let choices = interner.intern(vec![PhysicalCandidateId(0), PhysicalCandidateId(1)]); let graph = CandidateDependencyGraph { diff --git a/crates/plan-selection/src/search/costing/demand.rs b/crates/plan-selection/src/search/costing/demand.rs index 6b1c716aa..21b3aca23 100644 --- a/crates/plan-selection/src/search/costing/demand.rs +++ b/crates/plan-selection/src/search/costing/demand.rs @@ -206,7 +206,7 @@ mod tests { PhysicalCandidate, ProducerRequirement, QueryRootCandidates, }; use crate::search::milp::model::select_candidates; - use asap_logical_asap_optimization::memo::MemoGroupId; + use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_logical_asap_optimization::test_support::entry_with; use asap_types::ir::properties::AccuracyTarget; use asap_types::physical::Medium; diff --git a/crates/plan-selection/src/search/costing/direct_price_options_tests.rs b/crates/plan-selection/src/search/costing/direct_price_options_tests.rs index 3745278eb..16dd392ef 100644 --- a/crates/plan-selection/src/search/costing/direct_price_options_tests.rs +++ b/crates/plan-selection/src/search/costing/direct_price_options_tests.rs @@ -6,7 +6,7 @@ use crate::search::candidates::graph::{ CandidateDependencyGraph, PhysicalCandidate, ProducerRequirement, QueryRootCandidates, }; use crate::search::candidates::inventory::CandidateInventory; -use asap_logical_asap_optimization::memo::MemoGroupId; +use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_logical_asap_optimization::test_support::lower_promql; use asap_types::ir::properties::AccuracyTarget; use asap_types::ir::{Operator, OperatorNode, ProjectItem, ScalarExpr}; @@ -396,7 +396,7 @@ fn downstream_prices_follow_the_selected_supplier_interface() { #[test] fn supplier_worker_buckets_remain_joint_choices_and_match_evaluator() { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; use asap_types::ir::schema::SketchAlgorithm; @@ -469,10 +469,12 @@ fn supplier_worker_buckets_remain_joint_choices_and_match_evaluator() { .into_iter() .map(|(_, root)| root) .collect(); - let pane_rules = - asap_logical_asap_optimization::asap_aware_cse::pane_candidates(&roots, &[Some(60_000)]); + let pane_rules = asap_logical_asap_optimization::pass2::asap_aware_cse::pane_candidates( + &roots, + &[Some(60_000)], + ); let roots = - asap_logical_asap_optimization::asap_aware_cse::window_composition_pass2_candidates( + asap_logical_asap_optimization::pass2::asap_aware_cse::window_composition_pass2_candidates( &roots, &pane_rules, ) diff --git a/crates/plan-selection/src/search/costing/direct_profile.rs b/crates/plan-selection/src/search/costing/direct_profile.rs index 40e2b23b3..1206ed0e6 100644 --- a/crates/plan-selection/src/search/costing/direct_profile.rs +++ b/crates/plan-selection/src/search/costing/direct_profile.rs @@ -21,7 +21,9 @@ use std::collections::HashSet; #[derive(Debug, thiserror::Error)] pub(in crate::search) enum DirectProfileError { #[error(transparent)] - DeadlineExceeded(#[from] asap_logical_asap_optimization::memo::CandidateGenerationTimeout), + DeadlineExceeded( + #[from] asap_logical_asap_optimization::pass2::memo::CandidateGenerationTimeout, + ), #[error("direct cost profile: {0}")] Invalid(String), #[error("direct cost profile unsupported: {0}")] @@ -1001,7 +1003,7 @@ fn state_compaction_seconds( fn check_deadline(deadline: Option) -> Result<(), DirectProfileError> { if deadline.is_some_and(|deadline| std::time::Instant::now() >= deadline) { - Err(asap_logical_asap_optimization::memo::CandidateGenerationTimeout.into()) + Err(asap_logical_asap_optimization::pass2::memo::CandidateGenerationTimeout.into()) } else { Ok(()) } @@ -1074,7 +1076,7 @@ mod tests { CandidateDependencyGraph, PhysicalCandidate, ProducerRequirement, QueryRootCandidates, }; use crate::search::candidates::inventory::CandidateInventory; - use asap_logical_asap_optimization::memo::MemoGroupId; + use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_logical_asap_optimization::test_support::lower_promql; use asap_types::ir::properties::AccuracyTarget; use asap_types::ir::{Operator, OperatorNode, ProjectItem, ScalarExpr}; @@ -1255,7 +1257,7 @@ mod tests { // direct costs include working memory and agree with the complete evaluator. #[test] fn fixed_sketch_profiles_match_the_real_evaluator() { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; use asap_types::ir::schema::SketchAlgorithm; @@ -1480,7 +1482,7 @@ mod tests { mode: Materialization, range_evaluation: Option, ) { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; use asap_types::ir::schema::SketchAlgorithm; @@ -1570,11 +1572,11 @@ mod tests { .map(|(_, root)| root) .collect(); let pane_rules = - asap_logical_asap_optimization::asap_aware_cse::pane_candidates( + asap_logical_asap_optimization::pass2::asap_aware_cse::pane_candidates( &roots, &[Some(width)], ); - let roots = asap_logical_asap_optimization::asap_aware_cse::window_composition_pass2_candidates(&roots, &pane_rules).unwrap().pop().unwrap().roots.unwrap(); + let roots = asap_logical_asap_optimization::pass2::asap_aware_cse::window_composition_pass2_candidates(&roots, &pane_rules).unwrap().pop().unwrap().roots.unwrap(); let data: DataWorkload = serde_json::from_value(serde_json::json!({ "arrival":{"ingesting":{"rows_per_second":rows_per_second}}, "sources":{"latency":{"series_count":series_count,"rows_held":rows_per_second * 300,"values_non_negative":true,"max_distinct_per_evaluation":1000}} @@ -2001,7 +2003,7 @@ mod tests { // including two equal frequencies whose different phases cannot coalesce. #[test] fn heterogeneous_shared_sketch_profiles_match_the_real_evaluator() { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; use asap_types::ir::schema::SketchAlgorithm; diff --git a/crates/plan-selection/src/search/costing/lower_bounds.rs b/crates/plan-selection/src/search/costing/lower_bounds.rs index e28a8e66f..494d4f408 100644 --- a/crates/plan-selection/src/search/costing/lower_bounds.rs +++ b/crates/plan-selection/src/search/costing/lower_bounds.rs @@ -742,12 +742,12 @@ mod tests { use crate::search::candidates::physical::materialize_selected_candidates; use crate::search::milp::model::{solve_candidate_proposal, ObservedAssignment}; use crate::{CalibrationFit, PlanSelector, PlanningModels}; - use asap_logical_asap_optimization::asap_aware_cse::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass2::asap_aware_cse::{ pane_candidates, window_composition_pass2_candidates, }; - use asap_logical_asap_optimization::memo::candidates::try_populate_pass1; - use asap_logical_asap_optimization::memo::{LogicalMemo, MemoGroupId}; - use asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass2::memo::candidates::try_populate_pass1; + use asap_logical_asap_optimization::pass2::memo::{LogicalMemo, MemoGroupId}; use asap_logical_asap_optimization::test_support::{entry_with, lower_promql}; use asap_types::ir::properties::AccuracyTarget; use asap_types::ir::{OperatorNode, QueryRoot}; diff --git a/crates/plan-selection/src/search/costing/multi_input_price_tests.rs b/crates/plan-selection/src/search/costing/multi_input_price_tests.rs index 58d72dd18..3cf9163ad 100644 --- a/crates/plan-selection/src/search/costing/multi_input_price_tests.rs +++ b/crates/plan-selection/src/search/costing/multi_input_price_tests.rs @@ -3,7 +3,7 @@ use super::*; use crate::search::candidates::configurations::CandidateConfiguration; use crate::search::candidates::graph::*; use crate::search::candidates::inventory::CandidateInventory; -use asap_logical_asap_optimization::{memo::MemoGroupId, test_support::lower_promql}; +use asap_logical_asap_optimization::{pass2::memo::MemoGroupId, test_support::lower_promql}; use asap_types::ir::{properties::AccuracyTarget, OperatorNode}; use asap_types::workload::{ DataWorkload, Predictability, Query, QueryRequirements, QueryWorkloadEntry, RepetitionInterval, @@ -168,7 +168,7 @@ fn binary_prices_match_evaluator_with_distinct_and_shared_inputs() { // budgets; pricing may not silently resize either state after selection. #[test] fn two_sketch_binary_prices_match_evaluator_after_budget_sizing() { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; use asap_types::ir::properties::{AccuracyMetric, AccuracyScope}; diff --git a/crates/plan-selection/src/search/costing/proposals.rs b/crates/plan-selection/src/search/costing/proposals.rs index 5544cc7a2..f7e4cfbef 100644 --- a/crates/plan-selection/src/search/costing/proposals.rs +++ b/crates/plan-selection/src/search/costing/proposals.rs @@ -183,9 +183,9 @@ mod tests { use crate::search::candidates::configurations::enumerate_candidate_configurations; use crate::search::candidates::inventory::build_candidate_inventory; use crate::{CalibrationFit, PlanningModels}; - use asap_logical_asap_optimization::memo::candidates::try_populate_pass1; - use asap_logical_asap_optimization::memo::{LogicalMemo, MemoGroupId}; - use asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass2::memo::candidates::try_populate_pass1; + use asap_logical_asap_optimization::pass2::memo::{LogicalMemo, MemoGroupId}; use asap_logical_asap_optimization::test_support::{entry_with, lower_promql}; use asap_types::ir::properties::AccuracyTarget; use asap_types::ir::schema::{FieldDataType, SketchAlgorithm}; diff --git a/crates/plan-selection/src/search/costing/range_price_options_tests.rs b/crates/plan-selection/src/search/costing/range_price_options_tests.rs index 6b17ab00d..1144fc8ba 100644 --- a/crates/plan-selection/src/search/costing/range_price_options_tests.rs +++ b/crates/plan-selection/src/search/costing/range_price_options_tests.rs @@ -5,10 +5,10 @@ use crate::search::candidates::graph::{ CandidateDependencyGraph, PhysicalCandidate, ProducerRequirement, QueryRootCandidates, }; use crate::search::candidates::inventory::CandidateInventory; -use asap_logical_asap_optimization::memo::MemoGroupId; -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; +use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_logical_asap_optimization::test_support::lower_promql; use asap_types::ir::properties::AccuracyTarget; use asap_types::ir::schema::SketchAlgorithm; @@ -93,12 +93,12 @@ fn shared_pane_range_tiers_match_evaluator_for_ingestion_and_kept_refresh() { .into_iter() .map(|(_, root)| root) .collect(); - let rules = asap_logical_asap_optimization::asap_aware_cse::pane_candidates( + let rules = asap_logical_asap_optimization::pass2::asap_aware_cse::pane_candidates( &roots, &[Some(10_000)], ); let roots = - asap_logical_asap_optimization::asap_aware_cse::window_composition_pass2_candidates( + asap_logical_asap_optimization::pass2::asap_aware_cse::window_composition_pass2_candidates( &roots, &rules, ) .unwrap() diff --git a/crates/plan-selection/src/search/milp/direct_cost.rs b/crates/plan-selection/src/search/milp/direct_cost.rs index b9a2fd125..f0260be3c 100644 --- a/crates/plan-selection/src/search/milp/direct_cost.rs +++ b/crates/plan-selection/src/search/milp/direct_cost.rs @@ -752,7 +752,7 @@ mod tests { use crate::search::milp::model::{ solve_direct_cost_proposal_with_metrics, CandidateSolveMetrics, }; - use asap_logical_asap_optimization::memo::MemoGroupId; + use asap_logical_asap_optimization::pass2::memo::MemoGroupId; fn node(input: Option) -> PhysicalCandidate { PhysicalCandidate { diff --git a/crates/plan-selection/src/search/milp/direct_price_options.rs b/crates/plan-selection/src/search/milp/direct_price_options.rs index 8d2a90752..e55a8bb6d 100644 --- a/crates/plan-selection/src/search/milp/direct_price_options.rs +++ b/crates/plan-selection/src/search/milp/direct_price_options.rs @@ -466,7 +466,7 @@ pub(crate) fn solve_joint_price_proposal_with_metrics( #[cfg(test)] mod tests { use super::*; - use asap_logical_asap_optimization::memo::MemoGroupId; + use asap_logical_asap_optimization::pass2::memo::MemoGroupId; fn candidate(inputs: &[usize]) -> PhysicalCandidate { PhysicalCandidate { diff --git a/crates/plan-selection/src/search/milp/general_schedule_tests.rs b/crates/plan-selection/src/search/milp/general_schedule_tests.rs index 0305324ad..2c5da3bb5 100644 --- a/crates/plan-selection/src/search/milp/general_schedule_tests.rs +++ b/crates/plan-selection/src/search/milp/general_schedule_tests.rs @@ -29,7 +29,7 @@ fn fixed(interval: u32, evaluations: u64) -> QueryWorkloadEntry { } fn node(id: usize, input: Option) -> PhysicalCandidate { PhysicalCandidate { - group: asap_logical_asap_optimization::memo::MemoGroupId(id as u32), + group: asap_logical_asap_optimization::pass2::memo::MemoGroupId(id as u32), local_cost: 0.0, producer_requirements: input .into_iter() diff --git a/crates/plan-selection/src/search/milp/model.rs b/crates/plan-selection/src/search/milp/model.rs index ca4aa32a4..a28877f05 100644 --- a/crates/plan-selection/src/search/milp/model.rs +++ b/crates/plan-selection/src/search/milp/model.rs @@ -22,7 +22,7 @@ fn initialized( use crate::search::candidates::graph::*; #[cfg(test)] -use asap_logical_asap_optimization::memo::MemoGroupId; +use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use good_lp::solvers::highs::highs; use good_lp::solvers::{ResolutionError, SolutionStatus}; use good_lp::{ diff --git a/crates/plan-selection/src/search/milp/schedule_selection_tests.rs b/crates/plan-selection/src/search/milp/schedule_selection_tests.rs index 16767b398..c63ab106e 100644 --- a/crates/plan-selection/src/search/milp/schedule_selection_tests.rs +++ b/crates/plan-selection/src/search/milp/schedule_selection_tests.rs @@ -1,6 +1,6 @@ use super::*; use crate::search::milp::model::{solve_direct_cost_proposal_with_metrics, CandidateSolveMetrics}; -use asap_logical_asap_optimization::memo::MemoGroupId; +use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_types::workload::{QueryRecurrence, RepeatedDemand, RepetitionInterval}; fn union(queries: &[QueryRecurrence], mask: usize) -> f64 { diff --git a/crates/plan-selection/src/search/mod.rs b/crates/plan-selection/src/search/mod.rs index 1d7f0ba75..4abe7fe86 100644 --- a/crates/plan-selection/src/search/mod.rs +++ b/crates/plan-selection/src/search/mod.rs @@ -38,7 +38,7 @@ use crate::accuracy::{ }; use crate::{PlanSelectionSettings, Selection, SelectionError}; use asap_logical_asap_optimization::deployment_capabilities::DeploymentCapabilities; -use asap_logical_asap_optimization::per_computation_candidates::PerComputationCandidateError; +use asap_logical_asap_optimization::pass1::per_computation_candidates::PerComputationCandidateError; pub use pipeline::{ run_stage1_to_stage3, run_stage1_to_stage3_from_pass1, run_stage1_to_stage3_with, diff --git a/crates/plan-selection/src/search/pipeline.rs b/crates/plan-selection/src/search/pipeline.rs index 50740665a..231dfe06c 100644 --- a/crates/plan-selection/src/search/pipeline.rs +++ b/crates/plan-selection/src/search/pipeline.rs @@ -6,9 +6,9 @@ use std::rc::Rc; -use asap_logical_asap_optimization::memo::candidates::CandidateMemo; -use asap_logical_asap_optimization::memo::enumeration::MemoChoice; -use asap_logical_asap_optimization::memo::LogicalMemo; +use asap_logical_asap_optimization::pass2::memo::candidates::CandidateMemo; +use asap_logical_asap_optimization::pass2::memo::enumeration::MemoChoice; +use asap_logical_asap_optimization::pass2::memo::LogicalMemo; use asap_types::ir::schema::schema_support::with_promql_series_identity; use asap_types::ir::{OperatorNode, QueryRoot}; @@ -17,11 +17,11 @@ use asap_types::workload::{DataWorkload, QueryLanguage, QueryWorkloadEntry}; use crate::search::{OptimizationInput, OptimizationPass, OptimizeError, PlanOutput, QueryPlan}; use crate::PlanningModels; use crate::{SearchAlgorithm, Selection, SelectionError}; -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ generate_per_computation_candidates_with_memo, PerComputationCandidateError, PerComputationCandidates, }; -use asap_logical_asap_optimization::workload_candidates::Pass2Candidate; +use asap_logical_asap_optimization::pass2::workload_candidates::Pass2Candidate; use asap_physical_asap_optimization::PhysicalWorkloadPlan; /// A selected execution plan and the logical roots from which it was built. diff --git a/crates/plan-selection/src/search/query_pruning.rs b/crates/plan-selection/src/search/query_pruning.rs index 6ab508d60..1c28a68dc 100644 --- a/crates/plan-selection/src/search/query_pruning.rs +++ b/crates/plan-selection/src/search/query_pruning.rs @@ -2,10 +2,10 @@ //! A proof considers every local Pass 2 and Stage 2 choice; unknown/unsupported //! composition and any size-dependent failure remain eligible for joint planning. use crate::{checked_candidate, PlanningModels, RejectionCause}; -use asap_logical_asap_optimization::per_computation_candidates::{ +use asap_logical_asap_optimization::pass1::per_computation_candidates::{ ComputationCandidate, PerComputationCandidates, }; -use asap_logical_asap_optimization::workload_candidates::stage1_candidates_of_choice; +use asap_logical_asap_optimization::pass2::workload_candidates::stage1_candidates_of_choice; use asap_physical_asap_optimization::optimize_physical_asap; use asap_types::ir::{OperatorNode, QueryRoot}; use asap_types::workload::{DataWorkload, QueryWorkloadEntry}; @@ -347,7 +347,7 @@ pub(crate) fn alone_violation( #[cfg(test)] mod tests { use super::*; - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ generate_per_computation_candidates, ComputationCandidate, }; use asap_logical_asap_optimization::test_support::{entry_with, lower_promql}; diff --git a/crates/plan-selection/src/search/refinement/components.rs b/crates/plan-selection/src/search/refinement/components.rs index 341a7130f..dd1cb0de9 100644 --- a/crates/plan-selection/src/search/refinement/components.rs +++ b/crates/plan-selection/src/search/refinement/components.rs @@ -736,7 +736,7 @@ mod tests { }; use crate::search::milp::model::{solve_candidate_proposal, ObservedAssignment}; use crate::{CalibrationFit, PlanSelectionSettings, PlanningModels, ResourceUnitCost}; - use asap_logical_asap_optimization::memo::MemoGroupId; + use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_logical_asap_optimization::test_support::{entry_with, lower_promql}; use asap_types::ir::properties::AccuracyTarget; use asap_types::ir::scalar::{ScalarExpr, ScalarValue}; diff --git a/crates/plan-selection/src/search/refinement/materialization.rs b/crates/plan-selection/src/search/refinement/materialization.rs index ba2a3620f..28e04db32 100644 --- a/crates/plan-selection/src/search/refinement/materialization.rs +++ b/crates/plan-selection/src/search/refinement/materialization.rs @@ -114,7 +114,7 @@ mod tests { search_candidates_with_restricted_feedback, CandidateEvaluation, CandidateSearchLimits, CandidateSearchStatus, }; - use asap_logical_asap_optimization::memo::MemoGroupId; + use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use std::time::Duration; fn graph(readers: usize) -> CandidateDependencyGraph { diff --git a/crates/plan-selection/src/search/refinement/objectives.rs b/crates/plan-selection/src/search/refinement/objectives.rs index 0d070656e..2e51acfb1 100644 --- a/crates/plan-selection/src/search/refinement/objectives.rs +++ b/crates/plan-selection/src/search/refinement/objectives.rs @@ -399,9 +399,9 @@ mod tests { use crate::{ ClusterLimits, ClusterObjective, CostModel, PlanSelectionSettings, PlanningModels, }; - use asap_logical_asap_optimization::memo::candidates::try_populate_pass1; - use asap_logical_asap_optimization::memo::{LogicalMemo, MemoGroupId}; - use asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass2::memo::candidates::try_populate_pass1; + use asap_logical_asap_optimization::pass2::memo::{LogicalMemo, MemoGroupId}; use asap_logical_asap_optimization::test_support::{entry_with, lower_promql}; use asap_types::ir::{properties::AccuracyTarget, QueryRoot}; use asap_types::workload::{ diff --git a/crates/plan-selection/src/search/refinement/planner.rs b/crates/plan-selection/src/search/refinement/planner.rs index 111d82b7d..458632fce 100644 --- a/crates/plan-selection/src/search/refinement/planner.rs +++ b/crates/plan-selection/src/search/refinement/planner.rs @@ -753,7 +753,7 @@ fn accuracy_baseline( .as_ref() .is_some_and(|node| raw_scan_with_shifts(node)) }) - .then_some(asap_logical_asap_optimization::memo::MemoGroupId( + .then_some(asap_logical_asap_optimization::pass2::memo::MemoGroupId( group as u32, )) }) @@ -1197,10 +1197,12 @@ mod tests { use crate::search::candidates::configurations::enumerate_candidate_configurations; use crate::search::candidates::inventory::build_candidate_inventory; use crate::search::refinement::search::CandidateSearchStatus; - use asap_logical_asap_optimization::memo::candidates::{try_populate_pass1, CandidateOrigin}; - use asap_logical_asap_optimization::memo::state_groups::expand_concrete_summary_state_groups; - use asap_logical_asap_optimization::memo::{LogicalMemo, MemoGroupId}; - use asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass2::memo::candidates::{ + try_populate_pass1, CandidateOrigin, + }; + use asap_logical_asap_optimization::pass2::memo::state_groups::expand_concrete_summary_state_groups; + use asap_logical_asap_optimization::pass2::memo::{LogicalMemo, MemoGroupId}; use asap_logical_asap_optimization::test_support::{entry_with, lower_promql}; use asap_types::ir::properties::AccuracyTarget; use asap_types::ir::schema::{FieldDataType, SketchAlgorithm}; @@ -1442,10 +1444,10 @@ mod tests { entries[1].recurrence = QueryRecurrence::Unknown; entries[1].predictability = Predictability::Unknown; // This test isolates selected-consumer eligibility, not width search. - asap_logical_asap_optimization::memo::window_candidates::add_local_window_composition_in_domain( + asap_logical_asap_optimization::pass2::memo::window_candidates::add_local_window_composition_in_domain( &mut memo, &entries, - asap_logical_asap_optimization::memo::state_configurations::PaneWidthDomain::SeedGrids, + asap_logical_asap_optimization::pass2::memo::shared_configurations::PaneWidthDomain::SeedGrids, ); let source = build_candidate_inventory(&memo, &[output, output], |_| Ok(0.0)).unwrap(); let models = PlanningModels::builtin(); @@ -1659,7 +1661,7 @@ mod tests { entry }) .collect(); - asap_logical_asap_optimization::memo::window_candidates::add_local_window_composition( + asap_logical_asap_optimization::pass2::memo::window_candidates::add_local_window_composition( &mut memo, &entries, ); let memo = expand_concrete_summary_state_groups(memo).unwrap().memo; diff --git a/crates/plan-selection/src/search/refinement/pruning.rs b/crates/plan-selection/src/search/refinement/pruning.rs index 8ea2df048..ca75fc897 100644 --- a/crates/plan-selection/src/search/refinement/pruning.rs +++ b/crates/plan-selection/src/search/refinement/pruning.rs @@ -219,7 +219,7 @@ mod tests { }; use crate::search::candidates::inventory::CandidateInventory; use crate::search::milp::model::select_candidates; - use asap_logical_asap_optimization::memo::MemoGroupId; + use asap_logical_asap_optimization::pass2::memo::MemoGroupId; use asap_types::ir::properties::ExecutionTiming; use asap_types::physical::Materialization; diff --git a/crates/plan-selection/src/search/refinement/search.rs b/crates/plan-selection/src/search/refinement/search.rs index 0e914755c..8b5145533 100644 --- a/crates/plan-selection/src/search/refinement/search.rs +++ b/crates/plan-selection/src/search/refinement/search.rs @@ -759,7 +759,7 @@ mod tests { use crate::search::candidates::graph::{ PhysicalCandidate, PhysicalCandidateId, ProducerRequirement, QueryRootCandidates, }; - use asap_logical_asap_optimization::memo::MemoGroupId; + use asap_logical_asap_optimization::pass2::memo::MemoGroupId; fn choices(costs: &[f64]) -> CandidateDependencyGraph { CandidateDependencyGraph { diff --git a/crates/plan-selection/src/search/route.rs b/crates/plan-selection/src/search/route.rs index 8847645c2..755500c49 100644 --- a/crates/plan-selection/src/search/route.rs +++ b/crates/plan-selection/src/search/route.rs @@ -1,9 +1,9 @@ //! Driver integration for the explicit, bounded candidate-connection search. use crate::{CostModel, PlanningModels, SelectionError, Stage1ToStage3Search}; -use asap_logical_asap_optimization::memo::candidates::CandidateMemo; -use asap_logical_asap_optimization::memo::enumeration::MemoChoice; -use asap_logical_asap_optimization::memo::{LogicalMemo, MemoGroupId}; -use asap_logical_asap_optimization::per_computation_candidates::PerComputationCandidates; +use asap_logical_asap_optimization::pass1::per_computation_candidates::PerComputationCandidates; +use asap_logical_asap_optimization::pass2::memo::candidates::CandidateMemo; +use asap_logical_asap_optimization::pass2::memo::enumeration::MemoChoice; +use asap_logical_asap_optimization::pass2::memo::{LogicalMemo, MemoGroupId}; use asap_types::ir::{OperatorNode, QueryRoot}; use asap_types::workload::{DataWorkload, QueryWorkloadEntry}; use std::rc::Rc; @@ -55,16 +55,16 @@ struct DomainProgress { catalog_completed: bool, refinements: usize, report: Option, - local_memo: Option, + local_memo: Option, /// The memo after Stage 0 and after Pass 1, kept with `local_memo`. pass1_steps: Option<( - asap_logical_asap_optimization::memo::candidates::CandidateMemo, - asap_logical_asap_optimization::memo::candidates::CandidateMemo, + asap_logical_asap_optimization::pass2::memo::candidates::CandidateMemo, + asap_logical_asap_optimization::pass2::memo::candidates::CandidateMemo, )>, /// This round's memo steps, with its selected plan's ID when it has one. memo_steps: Option<(Option, crate::search::pipeline::MemoSteps)>, previous_domain: - Option, + Option, } /// Obtain an incumbent on seed grids, then progressively expose finer widths. @@ -79,7 +79,7 @@ pub(crate) fn candidate_connection_search( ) -> crate::search::pipeline::PlanSearchResult { let models = context.models; use crate::search::costing::calibration::CandidateCalibration; - use asap_logical_asap_optimization::memo::state_configurations::PaneWidthDomain; + use asap_logical_asap_optimization::pass2::memo::shared_configurations::PaneWidthDomain; use std::time::Instant; let started = Instant::now(); @@ -177,7 +177,7 @@ pub(crate) fn candidate_connection_search( .filter_map(|entry| entry.evaluation_grid_ms()) .filter(|_| !initial.groups.is_empty()); let mut frontier = - asap_logical_asap_optimization::memo::state_configurations::PaneWidthFrontier::new( + asap_logical_asap_optimization::pass2::memo::shared_configurations::PaneWidthFrontier::new( grids, global_deadline, ); @@ -703,7 +703,7 @@ fn search_domain( search: Stage1ToStage3Search, local_candidate_generation_ms: Option, archive: &mut CandidateArchive, - domain: asap_logical_asap_optimization::memo::state_configurations::PaneWidthDomain, + domain: asap_logical_asap_optimization::pass2::memo::shared_configurations::PaneWidthDomain, progress: &mut DomainProgress, ) -> crate::search::pipeline::PlanSearchResult { let inventory = context.inventory; @@ -719,8 +719,8 @@ fn search_domain( use crate::search::costing::calibration::CandidateCalibration; use crate::search::refinement::planner::CandidatePlanningContext; use crate::search::refinement::search::{CandidateSearchLimits, CandidateSearchStatus}; - use asap_logical_asap_optimization::memo::candidates::try_populate_pass1; - use asap_logical_asap_optimization::memo::state_groups::{ + use asap_logical_asap_optimization::pass2::memo::candidates::try_populate_pass1; + use asap_logical_asap_optimization::pass2::memo::state_groups::{ expand_concrete_summary_state_groups_before, StateGroupExpansionError, }; use std::time::{Duration, Instant}; @@ -750,13 +750,13 @@ fn search_domain( // counts unset rather than inventing completed model statistics. let report = crate::CandidateConnectionReport { pane_width_rounds: vec![format!("{domain:?}")], - pane_widths_pending: domain != asap_logical_asap_optimization::memo::state_configurations::PaneWidthDomain::Complete, + pane_widths_pending: domain != asap_logical_asap_optimization::pass2::memo::shared_configurations::PaneWidthDomain::Complete, status: "time_limit".into(), catalog_scope: format!( "planning stopped after {phase}, before solving; model statistics unavailable" ), full_catalog_completed: progress.catalog_completed - && domain == asap_logical_asap_optimization::memo::state_configurations::PaneWidthDomain::Complete, + && domain == asap_logical_asap_optimization::pass2::memo::shared_configurations::PaneWidthDomain::Complete, max_refinements: search.max_evaluations.unwrap_or(128), time_limit_ms: search.milp_time_limit_ms.unwrap_or(30_000), local_candidate_generation_ms, @@ -886,7 +886,7 @@ fn search_domain( } }; let deadline = Instant::now().checked_add(remaining()); - asap_logical_asap_optimization::memo::window_candidates::extend_local_window_composition( + asap_logical_asap_optimization::pass2::memo::window_candidates::extend_local_window_composition( &mut memo, entries, progress.previous_domain, @@ -954,7 +954,7 @@ fn search_domain( check_budget("physical candidate generation", progress)?; let context = CandidatePlanningContext { deadline, - refine_materialization: domain == asap_logical_asap_optimization::memo::state_configurations::PaneWidthDomain::SeedGrids, + refine_materialization: domain == asap_logical_asap_optimization::pass2::memo::shared_configurations::PaneWidthDomain::SeedGrids, seed_separate_plans: first_round, original_roots: &roots, entries, @@ -1111,12 +1111,12 @@ fn search_domain( supplier_sets: supplier_storage.unique_supplier_sets, stored_supplier_ids: supplier_storage.stored_supplier_ids, pane_width_rounds: vec![format!("{domain:?}")], - pane_widths_pending: domain != asap_logical_asap_optimization::memo::state_configurations::PaneWidthDomain::Complete, + pane_widths_pending: domain != asap_logical_asap_optimization::pass2::memo::shared_configurations::PaneWidthDomain::Complete, rounded_down_cost_bounds: bound_metrics.rounded_down_candidates, seed_planning_ms: 0.0, full_planning_ms: planning_started.elapsed().as_secs_f64() * 1_000.0, seed_selected: false, - full_catalog_completed: domain == asap_logical_asap_optimization::memo::state_configurations::PaneWidthDomain::Complete, + full_catalog_completed: domain == asap_logical_asap_optimization::pass2::memo::shared_configurations::PaneWidthDomain::Complete, seed_fallback_reason: None, independent_components: result.independent_components, catalog_exhausted: result.catalog_exhausted, @@ -1314,7 +1314,7 @@ mod tests { fn generation_time_is_charged_before_search_starts() { let (roots, entries, data) = workload(); let initial = LogicalMemo::from_roots(&roots); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates(roots).unwrap(); + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates(roots).unwrap(); let error = candidate_connection_search( initial, &CandidateSearchContext { @@ -1371,7 +1371,7 @@ mod tests { // Only an explicitly identified budget stop can use an already validated plan. #[test] fn validated_seed_survives_budget_stop_but_not_internal_failure() { - use asap_logical_asap_optimization::memo::state_configurations::PaneWidthDomain; + use asap_logical_asap_optimization::pass2::memo::shared_configurations::PaneWidthDomain; let (_, entries, data) = workload(); let roots = vec![( 0, @@ -1380,7 +1380,7 @@ mod tests { )), )]; let initial = LogicalMemo::from_roots(&roots); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates(roots).unwrap(); + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates(roots).unwrap(); let seed = search_domain( initial.clone(), &CandidateSearchContext { @@ -1450,7 +1450,7 @@ mod tests { fn invalid_generation_durations_are_rejected_before_seed_search() { let (roots, entries, data) = workload(); let initial = LogicalMemo::from_roots(&roots); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates(roots).unwrap(); + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates(roots).unwrap(); for invalid in [-1.0, f64::INFINITY, f64::NAN] { let error = candidate_connection_search( initial.clone(), @@ -1807,7 +1807,7 @@ mod tests { QueryRoot::Operator(lower_promql("latency[5m]", AccuracyTarget::exact())), )]; let initial = LogicalMemo::from_roots(&roots); - let inventory = asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates(roots).unwrap(); + let inventory = asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates(roots).unwrap(); let error = candidate_connection_search( initial, &CandidateSearchContext { @@ -1944,9 +1944,9 @@ mod tests { // Pane rewriting must preserve canonical inputs so equal chains can share state. #[test] fn local_pane_rules_expose_identical_chains_to_state_groups() { - use asap_logical_asap_optimization::memo::candidates::try_populate_pass1; - use asap_logical_asap_optimization::memo::state_groups::expand_concrete_summary_state_groups; - use asap_logical_asap_optimization::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass1::per_computation_candidates::generate_per_computation_candidates; + use asap_logical_asap_optimization::pass2::memo::candidates::try_populate_pass1; + use asap_logical_asap_optimization::pass2::memo::state_groups::expand_concrete_summary_state_groups; let (roots, mut entries, _) = workload(); for entry in &mut entries { entry.recurrence = @@ -1955,7 +1955,7 @@ mod tests { let initial = LogicalMemo::from_roots(&roots); let generated = generate_per_computation_candidates(roots).unwrap(); let mut memo = try_populate_pass1(initial, &generated).unwrap(); - asap_logical_asap_optimization::memo::window_candidates::add_local_window_composition( + asap_logical_asap_optimization::pass2::memo::window_candidates::add_local_window_composition( &mut memo, &entries, ); let expanded = expand_concrete_summary_state_groups(memo).unwrap(); diff --git a/crates/planner/tests/deployment_accuracy_model.rs b/crates/planner/tests/deployment_accuracy_model.rs index eed1c996b..9783c4d53 100644 --- a/crates/planner/tests/deployment_accuracy_model.rs +++ b/crates/planner/tests/deployment_accuracy_model.rs @@ -75,7 +75,7 @@ fn physical_candidates( workload: &PlanningWorkload, ) -> Vec { use asap_logical_asap_optimization::deployment_capabilities::DeploymentCapabilities; - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, }; use asap_physical_asap_optimization::optimize_physical_asap_chosen; diff --git a/crates/planner/tests/summary_sharing.rs b/crates/planner/tests/summary_sharing.rs index 7ff8e8edb..bc95be0a0 100644 --- a/crates/planner/tests/summary_sharing.rs +++ b/crates/planner/tests/summary_sharing.rs @@ -10,7 +10,7 @@ use std::rc::Rc; use asap_frontend_promql::{lower_promql_query_workload, promql_metric_names}; #[cfg(feature = "sql")] use asap_frontend_sql::SqlCatalog; -use asap_logical_asap_optimization::realization::{default_size_params, DEFAULT_DELTA}; +use asap_logical_asap_optimization::pass1::realization::{default_size_params, DEFAULT_DELTA}; use asap_plan_selection::pass::{PlanOutput, PlanningModels, QueryPlan}; use asap_plan_selection::RejectionCause; use asap_planner::{e2e_plan, FrontendInput, UserInput}; @@ -101,7 +101,7 @@ fn composed_summary_candidates( Vec, asap_plan_selection::Selection, ) { - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, ComputationCandidate, }; let workload = promql_workload(queries); @@ -166,7 +166,7 @@ fn shared_kll_candidate( workload: &PlanningWorkload, ) -> asap_physical_asap_optimization::PhysicalWorkloadPlan { use asap_logical_asap_optimization::deployment_capabilities::DeploymentCapabilities; - use asap_logical_asap_optimization::per_computation_candidates::{ + use asap_logical_asap_optimization::pass1::per_computation_candidates::{ compose_logical_candidate, generate_per_computation_candidates, }; use asap_types::physical::Materialization; diff --git a/docs/design_docs/proposals/asap-primitive-schema.md b/docs/design_docs/proposals/asap-primitive-schema.md index c58989aa6..36bdb4fb4 100644 --- a/docs/design_docs/proposals/asap-primitive-schema.md +++ b/docs/design_docs/proposals/asap-primitive-schema.md @@ -92,7 +92,7 @@ Based on our requirement, each field should contain the following information. | `FrequencyL2`, `FrequencyEntropy` | `Sketch`: `UnivMon` | `SummaryEstimate(FrequencyL2 \| FrequencyEntropy)` | | `Sum`, `Count`, `Min`, `Max`, `Rate`, `IRate`, `Increase` (exact) | `ExactAggregate(ExactKind, …)` | `FinalizeExactAccumulator` | - The sketch candidates are `summary_candidates(intent)` in `crates/logical-asap-optimization/src/realization.rs`; exact accumulators come from Pass 1's `ExactAccumulator` candidates in `per_computation_candidates.rs`; the evaluations are `SketchStatistic` ([§6.5](#65-update-input-and-evaluations-irschemasketchrs-iroperatormaintained_populationrs)). + The sketch candidates are `summary_candidates(intent)` in `crates/logical-asap-optimization/src/pass1/realization.rs`; exact accumulators come from Pass 1's `ExactAccumulator` candidates in `pass1/per_computation_candidates.rs`; the evaluations are `SketchStatistic` ([§6.5](#65-update-input-and-evaluations-irschemasketchrs-iroperatormaintained_populationrs)). - **Time window aggregation intents**: whether states built over smaller windows can answer a larger one. This depends on how the family combines states: - **Merge** (`SummaryMerge`, §5.6): states over disjoint panes combine into the state of their union, e.g. two 1-minute KLL states answer a 2-minute quantile. Requires a mergeable family. diff --git a/docs/design_docs/proposals/joint-planning-implementation-plan.md b/docs/design_docs/proposals/joint-planning-implementation-plan.md index 5df78a63c..b9d3d9cae 100644 --- a/docs/design_docs/proposals/joint-planning-implementation-plan.md +++ b/docs/design_docs/proposals/joint-planning-implementation-plan.md @@ -12,8 +12,8 @@ Preserve supported accuracy semantics, physical eligibility, cost objectives, sc | Scope | Current implementation | Responsibility | | --- | --- | --- | -| Logical identity | `logical-asap-optimization/src/memo.rs` | `LogicalMemo`, `MemoGroup`, stable initial query/group references. | -| Computation and sharing rules | `logical-asap-optimization/src/memo/{candidates,rules,state_groups,state_configurations,window_candidates}` | Populate groups, retain local candidates, expose shared states and compatible rewrites. | +| Logical identity | `logical-asap-optimization/src/pass2/memo.rs` | `LogicalMemo`, `MemoGroup`, stable initial query/group references. | +| Computation and sharing rules | `logical-asap-optimization/src/pass2/memo/{candidates,rules,state_groups,shared_configurations,window_candidates}` | Populate groups, retain local candidates, expose shared states and compatible rewrites. | | Physical legality | `physical-asap-optimization` | Executable operators, timing, materialization eligibility, and `PhysicalWorkloadPlan`. | | Candidate dependency inventory | `plan-selection/src/search/candidates` | Local `PhysicalCandidate`, `ProducerRequirement`, compatible suppliers, execution scopes, selected connections, and reconstruction. | | Solver | `plan-selection/src/search/milp` | Activation, producer/root assignment, reachability, acyclicity, resource constraints, and solver warm starts. | diff --git a/docs/design_docs/proposals/planner-layering.md b/docs/design_docs/proposals/planner-layering.md index fd5acbe63..44914bad4 100644 --- a/docs/design_docs/proposals/planner-layering.md +++ b/docs/design_docs/proposals/planner-layering.md @@ -311,16 +311,16 @@ rule's origin, and gives each reader a candidate that reads that group. | `CandidateOrigin` | Added by | Candidates | |---|---|---| -| `Pass1` | `try_populate_pass1` (`memo/groups.rs`) | Every Pass 1 choice of the group's measures: exact, exact accumulator, each summary family and size, and fused computations. Each summary choice comes at every `budget_share` from 1 to the most approximate inputs a query reaching the group has. A fused candidate implements the groups it absorbs only when no other reader needs them; otherwise they stay groups of their own. | -| `Panes` | Window composition: `add_local_window_composition` and `extend_local_window_composition` (`memo/window_candidates.rs`) | A window summary computed from tumbling panes, at each pane width the reader's evaluation grid allows. The pane chain stays private to the candidate. | -| `WidenedScans` | Scan widening: `add_scan_label_candidates` (`memo/rules/scan_labels.rs`) | A reader of a metric's scans widened to a shared label set, read through a `Project`. | -| `SummaryInput` | `factor_summary_inputs` (`memo/rules/summary_inputs.rs`) | Canonical value preprocessing feeding a summary build. | -| `TopKReuse` | Exact top-k reuse: `add_topk_candidates` (`memo/rules/topk.rs`) | One ranking (`Limit(k_max)` over `Sort`), and each top-k reading its first `k` rows from it. | -| `Rollup` | Rollup: `add_finer_aggregate_candidates` (`memo/rules/finer_aggregate.rs`), `add_rollup_candidates` and `add_window_rollup_candidates` (`memo/rules/rollup.rs`) | A coarse group computed from a finer group's values or states. | -| `SummaryResult` | `factor_summary_results` (`memo/rules/summary_results.rs`) | A summary readout factored out of a composite implementation, so that other readers can read it. | -| `SharedBuild` | Summary capability: `expand_concrete_summary_state_groups_before` (`memo/state_groups.rs`) | For each build made two or more times (by different candidates, or twice within one), one concrete summary-state group with one `SharedBuild` candidate; and for each candidate making such builds, one `SharedBuild` copy that reads the groups instead of building its own states. | - -The state-configuration rule (`memo/rules/state_configurations.rs`) runs just +| `Pass1` | `try_populate_pass1` (`pass2/memo/groups.rs`) | Every Pass 1 choice of the group's measures: exact, exact accumulator, each summary family and size, and fused computations. Each summary choice comes at every `budget_share` from 1 to the most approximate inputs a query reaching the group has. A fused candidate implements the groups it absorbs only when no other reader needs them; otherwise they stay groups of their own. | +| `Panes` | Window composition: `add_local_window_composition` and `extend_local_window_composition` (`pass2/memo/window_candidates.rs`) | A window summary computed from tumbling panes, at each pane width the reader's evaluation grid allows. The pane chain stays private to the candidate. | +| `WidenedScans` | Scan widening: `add_scan_label_candidates` (`pass2/memo/rules/scan_labels.rs`) | A reader of a metric's scans widened to a shared label set, read through a `Project`. | +| `SummaryInput` | `factor_summary_inputs` (`pass2/memo/rules/summary_inputs.rs`) | Canonical value preprocessing feeding a summary build. | +| `TopKReuse` | Exact top-k reuse: `add_topk_candidates` (`pass2/memo/rules/topk.rs`) | One ranking (`Limit(k_max)` over `Sort`), and each top-k reading its first `k` rows from it. | +| `Rollup` | Rollup: `add_finer_aggregate_candidates` (`pass2/memo/rules/finer_aggregate.rs`), `add_rollup_candidates` and `add_window_rollup_candidates` (`pass2/memo/rules/rollup.rs`) | A coarse group computed from a finer group's values or states. | +| `SummaryResult` | `factor_summary_results` (`pass2/memo/rules/summary_results.rs`) | A summary readout factored out of a composite implementation, so that other readers can read it. | +| `SharedBuild` | Summary capability: `expand_concrete_summary_state_groups_before` (`pass2/memo/state_groups.rs`) | For each build made two or more times (by different candidates, or twice within one), one concrete summary-state group with one `SharedBuild` candidate; and for each candidate making such builds, one `SharedBuild` copy that reads the groups instead of building its own states. | + +The state-configuration rule (`pass2/memo/rules/shared_configuration_readers.rs`) runs just before the shared builds are found. It rewrites readers to each shared size and to the newest panes of each pane chain layout they may read, so that equal builds appear, and a rewrite keeps the origin of the candidate it @@ -435,7 +435,7 @@ The production search never lists the candidate DAGs (see [How the search uses the memo](#how-the-search-uses-the-memo)). Tests, the DAG viewer and cross-checks of the search need them: the memo must stand for the same candidate DAGs as the vector of whole-workload candidates the stage -table describes. `memo::enumeration` converts a memo after any step into +table describes. `pass2::memo::enumeration` converts a memo after any step into that vector. - **`MemoChoice`** maps each needed group to one candidate index in @@ -523,12 +523,12 @@ The memo types and rules are in `crates/logical-asap-optimization/src/` | Step | Entry point | Path | |---|---|---| -| Stage 0 | `LogicalMemo::from_roots`, `MemoGroup`, `MemoGroupId` | `memo.rs`; hash-consing is `share_common_sub_dags` in `crates/types/src/ir/cse.rs` | -| Pass 1 | `generate_per_computation_candidates_with_memo`; `try_populate_pass1` (exported from `memo::candidates`) | `per_computation_candidates.rs`; `memo/groups.rs` | -| Memo types | `CandidateMemo`, `ImplementationCandidate`, `CandidateOrigin` | `memo/candidates.rs` | -| Pass 2 window composition | `add_local_window_composition`, `extend_local_window_composition` | `memo/window_candidates.rs` | -| Pass 2 rules and concrete summary-state groups | `expand_concrete_summary_state_groups_before`, which runs the rules in `memo/rules/` in this order: scan widening, summary inputs, top-k reuse, finer aggregate, rollup, window rollup, summary results, state configurations; then the shared builds | `memo/state_groups.rs`, `memo/rules/`, `memo/state_configurations.rs` | -| Memo to candidate DAGs | `enumerate`, `compose`, `MemoChoice`, `MemoEnumeration`, `ComposeError` | `memo/enumeration.rs` (module `memo::enumeration`) | +| Stage 0 | `LogicalMemo::from_roots`, `MemoGroup`, `MemoGroupId` | `pass2/memo.rs`; hash-consing is `share_common_sub_dags` in `crates/types/src/ir/cse.rs` | +| Pass 1 | `generate_per_computation_candidates_with_memo`; `try_populate_pass1` (exported from `pass2::memo::candidates`) | `pass1/per_computation_candidates.rs`; `pass2/memo/groups.rs` | +| Memo types | `CandidateMemo`, `ImplementationCandidate`, `CandidateOrigin` | `pass2/memo/candidates.rs` | +| Pass 2 window composition | `add_local_window_composition`, `extend_local_window_composition` | `pass2/memo/window_candidates.rs` | +| Pass 2 rules and concrete summary-state groups | `expand_concrete_summary_state_groups_before`, which runs the rules in `pass2/memo/rules/` in this order: scan widening, summary inputs, top-k reuse, finer aggregate, rollup, window rollup, summary results, state configurations; then the shared builds | `pass2/memo/state_groups.rs`, `pass2/memo/rules/`, `pass2/memo/shared_configurations.rs` | +| Memo to candidate DAGs | `enumerate`, `compose`, `MemoChoice`, `MemoEnumeration`, `ComposeError` | `pass2/memo/enumeration.rs` (module `pass2::memo::enumeration`) | | Production memo build and search | `run_stage1_to_stage3_with` and `run_stage1_to_stage3_from_pass1` build the logical memo (`pipeline.rs`); `candidate_connection_search` (`route.rs`) builds the candidate memo for each pane-width round: query pruning (first round), `try_populate_pass1`, the accuracy-scoped candidates, `extend_local_window_composition`, `expand_concrete_summary_state_groups_before`; then `candidates/`, `milp/` and `refinement/` | `crates/plan-selection/src/search/` | ## ASAPPlanner Detailed Design: Planning Stages and their decisions/Strategies @@ -571,7 +571,7 @@ the memo path's entry points. |---|---|---|---| | 0. Frontends | Query text, language → one logical root per query, carrying its accuracy target | Same: a `QueryRoot` per query | `lower_promql_workload`, `lower_sql_dialect` (`asap-frontend-*`); `plan_installable` (`asap_planner`) runs the frontends and Stages 1–3 on the user input | | 1, Pass 1 | Logical roots; the deployment's supported summaries → the Pass 1 inventory, every computation's candidates (`PerComputationCandidates`) | Logical roots → `LogicalMemo` (hash-consed `MemoGroup`s); with the Pass 1 inventory, less the summaries the deployment does not support → `CandidateMemo`: each group's `ImplementationCandidate`s | `LogicalMemo::from_roots`, `generate_per_computation_candidates_with_memo`, `try_populate_pass1` | -| 1, Pass 2 | One Pass 1 choice per computation → that choice rewritten by each sharing rule, every subset of sharing choices (`Pass2Candidate`, `stage1_candidates_of_choice`) | `CandidateMemo`; the entries' recurrence and range steps → the same memo with each rule's candidates added to the groups they implement | the memo rules (`memo/rules/`), `memo::window_candidates` | +| 1, Pass 2 | One Pass 1 choice per computation → that choice rewritten by each sharing rule, every subset of sharing choices (`Pass2Candidate`, `stage1_candidates_of_choice`) | `CandidateMemo`; the entries' recurrence and range steps → the same memo with each rule's candidates added to the groups they implement | the memo rules (`pass2/memo/rules/`), `pass2::memo::window_candidates` | | 1, concrete summary-state groups | (part of Pass 2) | `CandidateMemo` → the memo with concrete summary-state groups: one group per shared size or pane layout that readers can read | `expand_concrete_summary_state_groups_before` | | 2 | One whole-workload logical candidate; entries (recurrence, predictability), `DataWorkload`, query-time retention → its physical candidates, one per materialization assignment | Each implementation candidate, on demand → its physical operators and its allowed materializations | `implement_candidate_operators`, `summary_materialization_eligibility` (called from Stage 3) | | 3 | Every physical candidate; accuracy targets, accuracy model and evidence, cost model, raw-data retention, executor compile check → one plan | The expanded memo's candidates and their configurations; the same inputs → one candidate per needed group, connected into one plan | `run_stage1_to_stage3_with`, `candidate_connection_search`; output `Stage1ToStage3Run`, which holds the selected `PhysicalWorkloadPlan` and the selection | diff --git a/docs/develop_docs/asap-aware-mapping-architecture.md b/docs/develop_docs/asap-aware-mapping-architecture.md index 247500c4c..4095e5b59 100644 --- a/docs/develop_docs/asap-aware-mapping-architecture.md +++ b/docs/develop_docs/asap-aware-mapping-architecture.md @@ -57,10 +57,10 @@ same pipeline behind the `OptimizationPass` trait that `asap-planner` calls. | Concern | Where it lives | | --- | --- | -| Pass 1: which computations a query has (`ComputationTarget`), how each can be computed (`ComputationCandidate`: `Exact`, `ExactAccumulator`, `Summary`), fused computations (`FusedComputation`), pruning (`PruneReason`) and composing one choice into a logical DAG (`compose_logical_candidate`) | `asap-logical-asap-optimization`, `per_computation_candidates.rs` | -| Which summary families serve an intent (`summary_candidates`), the intent's accuracy target and (ε, δ) budget, default sizing | `asap-logical-asap-optimization`, `realization.rs` | -| Pass 2 rules: identical-expression, summary-capability, window-composition (tumbling panes), rollup and exact top-k reuse; each produces `*Candidate` parts and `*Pass2Candidate` whole-workload plans | `asap-logical-asap-optimization`, `asap_aware_cse.rs` | -| Enumeration of Stage 1 candidates (the Cartesian product of Pass 1 choices, each followed by its Pass 2 candidates) | `asap-logical-asap-optimization`, `workload_candidates.rs` | +| Pass 1: which computations a query has (`ComputationTarget`), how each can be computed (`ComputationCandidate`: `Exact`, `ExactAccumulator`, `Summary`), fused computations (`FusedComputation`), pruning (`PruneReason`) and composing one choice into a logical DAG (`compose_logical_candidate`) | `asap-logical-asap-optimization`, `pass1/per_computation_candidates.rs` | +| Which summary families serve an intent (`summary_candidates`), the intent's accuracy target and (ε, δ) budget, default sizing | `asap-logical-asap-optimization`, `pass1/realization.rs` | +| Pass 2 rules: identical-expression, summary-capability, window-composition (tumbling panes), rollup and exact top-k reuse; each produces `*Candidate` parts and `*Pass2Candidate` whole-workload plans | `asap-logical-asap-optimization`, `pass2/asap_aware_cse.rs` | +| Enumeration of Stage 1 candidates (the Cartesian product of Pass 1 choices, each followed by its Pass 2 candidates) | `asap-logical-asap-optimization`, `pass2/workload_candidates.rs` | | What each summary family can merge and answer (`FamilyCapability::of`: `merge_inputs`, `readouts`) | `asap-types`, `ir/schema/family_capability.rs` | | Stage 2: materialization options per summary build (`NotMaterialized`, `MatAtIngestion`, `MatAtQuery`, `MatAtQueryKeptAcrossEvaluations`), ingestion-time eligibility, physical operator implementation | `asap-physical-asap-optimization` | | Timing and data-state edge rules applied from a `MaterializationAssignment` | `asap-types`, `ir/properties/timing.rs` and `ir/properties/execution_data_state.rs`; `Materialization` in `physical/materialization.rs` | diff --git a/docs/develop_docs/extend-asap-aware-mapping.md b/docs/develop_docs/extend-asap-aware-mapping.md index 3bda592b1..dea8a8470 100644 --- a/docs/develop_docs/extend-asap-aware-mapping.md +++ b/docs/develop_docs/extend-asap-aware-mapping.md @@ -54,12 +54,12 @@ estimator; an execution test in `crates/integration-tests/tests/` such as A new way for computations of one Pass 1 candidate to share, split or reuse work. -1. In `crates/logical-asap-optimization/src/asap_aware_cse.rs`, add the part it can choose as a `*Candidate` type +1. In `crates/logical-asap-optimization/src/pass2/asap_aware_cse.rs`, add the part it can choose as a `*Candidate` type with a finder (for example `rollup_candidates(roots)`), and the function that applies a set of them and returns `*Pass2Candidate`s (for example `rollup_pass2_candidates`). Read summary families only through `FamilyCapability`. -2. In `crates/logical-asap-optimization/src/workload_candidates.rs`, call it +2. In `crates/logical-asap-optimization/src/pass2/workload_candidates.rs`, call it from Stage 1 enumeration after the existing rules and record what it applied in a new `Pass2Candidate` field. 3. Rebuild its label from that field in `asap_devtools::candidate_labels`. @@ -69,7 +69,7 @@ work. A rule must keep every Pass 1 candidate, must not add a family or a readout, and must keep the composed DAG's meaning. Stage 3 decides whether it pays off. -Tests: unit tests beside the rule in `asap_aware_cse.rs` for when it applies +Tests: unit tests beside the rule in `pass2/asap_aware_cse.rs` for when it applies and when it must not; an end-to-end test like `crates/integration-tests/tests/reuse_rules.rs` that the planned workload contains the candidate and that Stage 3 prices it.