Skip to content

Commit 893964d

Browse files
committed
feat(plan-selection)!: let the deployment's accuracy model decide outputs without a guarantee
- Move AccuracyEvidenceProvider and NoAccuracyEvidence to asap_plan_selection::accuracy, next to AccuracyModel; OperandDomain and PropagationStats stay in Stage 1. - Rename DefaultAccuracyModel to BuiltinAccuracyModel. AccuracyModel::propagate gets a default body (the built-in rules), so a deployment model implements only satisfies. - Add AccuracyModel::accepts_output_without_guarantee (default false). Stage 3 asks it only when neither Stage 1 nor the evidence supplies a guarantee; an output it accepts is recorded with AcceptedAccuracy::accepted_without_guarantee, and one it does not is rejected with the new RejectionCause::NoAccuracyGuarantee (was AccuracyTargetMissed). - Document accuracy::estimators::local_guarantee and accuracy::composition::propagate, and drop their duplicate re-exports. - stage_pipeline writes accepted_without_guarantee; the dag-viewer accepts the new cause; the example fixture is regenerated. BREAKING CHANGE: AccuracyEvidenceProvider/NoAccuracyEvidence move to asap_plan_selection; DefaultAccuracyModel is now BuiltinAccuracyModel; a candidate whose output has no guarantee is rejected as no_accuracy_guarantee instead of accuracy_target_missed; AcceptedAccuracy gains a field.
1 parent ede4ee2 commit 893964d

18 files changed

Lines changed: 467 additions & 220 deletions

File tree

‎crates/devtools/src/bin/stage_pipeline.rs‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@
3131
// - stage3_plan_selection: the selected candidate, chosen among all candidates;
3232
// the shown candidates' costs and accepted accuracy (per query: the
3333
// target's metric or null when not set, the accepted guarantee's
34-
// metric or null when exact, the sketches read and a one-line
34+
// metric or null when exact or accepted without a guarantee, whether
35+
// the deployment's accuracy model accepted it without a guarantee
36+
// (`accepted_without_guarantee`), the sketches read and a one-line
3537
// summary), and every other shown candidate under `rejected` with
3638
// its `cause`: a failed check (`failure_probability_resize_failed`,
37-
// `accuracy_target_missed`, `raw_data_not_retained`,
39+
// `accuracy_target_missed`, `no_accuracy_guarantee`, `raw_data_not_retained`,
3840
// `latency_bound_exceeded`, `over_cluster_capacity`) or a loss under
3941
// the cost model (`costlier`, `slower`, `more_memory`,
4042
// `not_lowest_latency_on_pareto_front`, `dominated`,
@@ -617,6 +619,7 @@ fn plan_selection_json(
617619
json!({
618620
"target_metric": accepted.target_metric,
619621
"accepted_metric": accepted.accepted_metric,
622+
"accepted_without_guarantee": accepted.accepted_without_guarantee,
620623
"sketches": accepted.sketches,
621624
"summary": accepted.to_string(),
622625
})

‎crates/devtools/tests/stage_pipeline.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ fn example1_document_is_valid_and_committed_fixture_is_current() {
138138
let failed_a_check = [
139139
"failure_probability_resize_failed",
140140
"accuracy_target_missed",
141+
"no_accuracy_guarantee",
141142
"raw_data_not_retained",
142143
"latency_bound_exceeded",
143144
"over_cluster_capacity",

‎crates/frontend-promql/tests/univmon_candidates.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::rc::Rc;
22

3-
use asap_logical_asap_optimization::accuracy::{local_guarantee, satisfies};
3+
use asap_logical_asap_optimization::accuracy::estimators::local_guarantee;
4+
use asap_logical_asap_optimization::accuracy::satisfies;
45
mod support;
56
use asap_types::ir::cse::share_common_sub_dags;
67
use asap_types::ir::properties::AccuracyMetric;

‎crates/integration-tests/tests/promql_to_post_asap.rs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ use std::rc::Rc;
1111
use asap_integration_tests::fixtures::lower_promql;
1212
use asap_integration_tests::planning::logical_candidates;
1313
use asap_integration_tests::post_asap::{at_ingestion, at_ingestion_post_asap_dag, post_asap_dag};
14-
use asap_logical_asap_optimization::accuracy::{AccuracyEvidenceProvider, OperandDomain};
14+
use asap_logical_asap_optimization::accuracy::OperandDomain;
1515
use asap_physical_asap_optimization::PhysicalCandidate;
16+
use asap_plan_selection::AccuracyEvidenceProvider;
1617
use asap_plan_selection::PlanningModels;
1718
use asap_plan_selection::Selection;
1819
use asap_types::ir::operator::operator_properties::Reduction;

‎crates/logical-asap-optimization/src/accuracy/composition.rs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,12 @@ fn composed_provenance(
694694
provenance
695695
}
696696

697+
/// The built-in composition rule: `inputs`' guarantees (in the parent's
698+
/// child order) composed with the parent's own `local` guarantee under `op`,
699+
/// given the statistics in `stats` (all unknown in Stage 1; plan selection
700+
/// binds some). `Err` is the fail-closed answer: no registered rule, or a
701+
/// missing input guarantee. It means "no rule", not "infeasible": Pass 1
702+
/// keeps the candidate with `guarantee = None`.
697703
pub fn propagate(
698704
op: &CompositionOperator,
699705
inputs: &[AccuracyGuarantee],

‎crates/logical-asap-optimization/src/accuracy/estimators/mod.rs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ fn bounded_guarantee(
5454
)
5555
}
5656

57+
/// The built-in guarantee of reading `query` out of a summary of family
58+
/// `family` built over an **exact** input, derived from the family's
59+
/// committed parameters by inverting the same sizing formulas
60+
/// [`crate::realization::default_size_params`] uses. Exact for a plain value
61+
/// or an exact aggregate. `None` when the family has no error model
62+
/// (`Sample`, `Wavelet`, `StatModel`, and sketch evaluations without a
63+
/// certified bound): Pass 1 then leaves the guarantee `None` and keeps the
64+
/// candidate for plan selection to decide.
5765
pub fn local_guarantee(
5866
family: &FieldDataType,
5967
query: &SketchStatistic,

‎crates/logical-asap-optimization/src/accuracy/evidence.rs‎

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
//! Scoped source contracts and evidence required by accuracy rules.
1+
//! Scoped source contracts and statistics the accuracy rules consult.
22
use super::*;
3-
use asap_types::ir::QueryRoot;
43

54
/// An enforced domain for the true values of one operand of an exact
65
/// arithmetic operation, in every evaluation: they are finite and lie in
@@ -59,31 +58,3 @@ pub struct PropagationStats {
5958
/// certificate.
6059
pub topk_interval_failure_probability: Option<f64>,
6160
}
62-
63-
/// Supplies typed planning-time evidence required by propagation rules.
64-
pub trait AccuracyEvidenceProvider {
65-
/// Enforced domain of `operand`'s true values ([`OperandDomain`]), scoped
66-
/// to this complete expression, including its source, filters, grouping
67-
/// and window: a quantile ratio's operands, or the operands of a
68-
/// product or quotient of estimates. `None` means unknown, including
69-
/// emptiness.
70-
fn operand_domain(&self, _operand: &OperatorNode) -> Option<OperandDomain> {
71-
None
72-
}
73-
74-
/// The deployment's empirical accuracy for one candidate's whole query
75-
/// output, as a guarantee. Plan selection (#509 Stage 3) accepts a
76-
/// candidate whose output has no theoretical guarantee that meets the
77-
/// target (e.g. a difference of two quantile estimates) only when this
78-
/// shows the output meets it. Stage 1 composition never reads it: root
79-
/// guarantees there come from the built-in theoretical model. `None`
80-
/// means no evidence.
81-
fn output_guarantee(&self, _output: &QueryRoot) -> Option<AccuracyGuarantee> {
82-
None
83-
}
84-
}
85-
86-
#[derive(Debug, Default, Clone, Copy)]
87-
pub struct NoAccuracyEvidence;
88-
89-
impl AccuracyEvidenceProvider for NoAccuracyEvidence {}

‎crates/logical-asap-optimization/src/accuracy/mod.rs‎

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
//! Planner accuracy interfaces and model dispatch.
1+
//! The planner's built-in analytical accuracy rules: estimators, composition, budget split and target check.
22
//!
33
//! Estimator models derive local guarantees, composition propagates them,
44
//! the budget split sizes each approximate input of a composition for an
5-
//! equal share of its target, and evidence supplies scoped contracts.
6-
//! Unknown evidence may retain a candidate but does not authorize selection.
5+
//! equal share of its target, and `evidence` holds the scoped contracts and
6+
//! statistics the rules consult. The deployment's evidence provider and
7+
//! accuracy model live in plan selection (`asap_plan_selection::accuracy`).
78
//! See `docs/design_docs/concepts/accuracy-models.md` for the design.
89
910
pub mod budget;
@@ -12,18 +13,14 @@ pub mod estimators;
1213
pub mod evidence;
1314

1415
pub use budget::per_input_target;
15-
pub use evidence::{AccuracyEvidenceProvider, NoAccuracyEvidence, OperandDomain, PropagationStats};
16+
pub use evidence::{OperandDomain, PropagationStats};
1617

1718
use asap_types::ir::properties::{
1819
AccuracyError, AccuracyGuarantee, AccuracyMetric, BoundExpr, CompositionOperator,
1920
GuaranteeSource, ProbabilityExpr,
2021
};
2122
use asap_types::ir::properties::{AccuracyScope, AccuracyTarget};
2223
use asap_types::ir::schema::{FieldDataType, SketchAlgorithm, SketchParams, SketchStatistic};
23-
use asap_types::ir::OperatorNode;
24-
25-
pub use composition::propagate;
26-
pub use estimators::local_guarantee;
2724

2825
/// Small relative tolerance for comparing an evaluated bound against a
2926
/// target, so a parameter sized by `⌈·⌉` to *exactly* meet ε is not rejected
@@ -38,7 +35,7 @@ const SATISFACTION_TOLERANCE: f64 = 1e-9;
3835
/// another metric does not satisfy, however small. When it sets none, a
3936
/// bound in any metric does, each compared in its own metric. Unknown
4037
/// required dimensions fail. Plan selection's default accuracy model
41-
/// (`asap_plan_selection::DefaultAccuracyModel`) delegates to it.
38+
/// (`asap_plan_selection::BuiltinAccuracyModel`) delegates to it.
4239
pub fn satisfies(guarantee: &AccuracyGuarantee, target: &AccuracyTarget) -> bool {
4340
let within = |value: Option<f64>, limit: f64| {
4441
value.is_some_and(|v| v <= limit * (1.0 + SATISFACTION_TOLERANCE) + f64::EPSILON)

‎crates/logical-asap-optimization/src/lib.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub mod realization;
5151
#[cfg(any(test, feature = "test-support"))]
5252
pub mod test_support;
5353

54-
pub use accuracy::{AccuracyEvidenceProvider, NoAccuracyEvidence, PropagationStats};
54+
pub use accuracy::PropagationStats;
5555
pub use deployment_capabilities::{
5656
DeploymentCapabilities, DeploymentCapabilitiesError, SupportedSummary,
5757
};

‎crates/logical-asap-optimization/src/per_computation_candidates.rs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,15 @@ use asap_types::ir::{
113113
use asap_types::physical::Materialization;
114114
use thiserror::Error;
115115

116+
use crate::accuracy::composition::propagate;
116117
use crate::accuracy::composition::samples_sign_statistic;
117118
use crate::accuracy::composition::{
118119
additive_as_absolute, StreamNorm, DIVISION_OPERAND_DOMAINS, GROUP_ROW_COUNT,
119120
PRODUCT_OPERAND_DOMAINS, QUOTIENT_OPERAND_DOMAINS,
120121
};
122+
use crate::accuracy::estimators::local_guarantee;
121123
use crate::accuracy::estimators::{hll, univmon};
122-
use crate::accuracy::{local_guarantee, per_input_target, propagate, PropagationStats};
124+
use crate::accuracy::{per_input_target, PropagationStats};
123125
use crate::deployment_capabilities::DeploymentCapabilities;
124126
use crate::function_rules::approximate_input_composition;
125127
use crate::realization::{accuracy_budget, default_size_params, sizing_target, summary_candidates};

0 commit comments

Comments
 (0)