Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/asap-aware-mapping/src/grouping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ impl<'a> HydraGroupingStrategy<'a> {
accuracy: accuracy_model,
allocator,
evidence,
allow_uncertified_ddsketch_ratios: false,
},
}
}
Expand Down
64 changes: 48 additions & 16 deletions crates/asap-aware-mapping/src/replacement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,9 @@ pub(crate) struct Models<'a> {
pub accuracy: &'a dyn AccuracyModel,
pub allocator: &'a dyn AccuracyBudgetAllocator,
pub evidence: &'a dyn AccuracyEvidenceProvider,
/// Demo-only escape hatch for exposing a DDSketch quantile-ratio
/// candidate without claiming that its end-to-end error is certified.
pub allow_uncertified_ddsketch_ratios: bool,
}

impl<'a> Models<'a> {
Expand All @@ -1275,6 +1278,7 @@ impl<'a> Models<'a> {
accuracy: &DEFAULT_ACCURACY_MODEL,
allocator: &DEFAULT_ALLOCATOR,
evidence: &NO_ACCURACY_EVIDENCE,
allow_uncertified_ddsketch_ratios: false,
}
}
}
Expand Down Expand Up @@ -1338,6 +1342,7 @@ impl<'a> SketchAlgorithmStrategy<'a> {
accuracy: accuracy_model,
allocator,
evidence: &NO_ACCURACY_EVIDENCE,
allow_uncertified_ddsketch_ratios: false,
},
}
}
Expand All @@ -1356,10 +1361,23 @@ impl<'a> SketchAlgorithmStrategy<'a> {
accuracy: accuracy_model,
allocator,
evidence,
allow_uncertified_ddsketch_ratios: false,
},
}
}

/// Opts a demo or diagnostic caller into DDSketch quantile-ratio
/// candidates when no input-domain evidence is available.
///
/// Such a candidate carries no [`ResultGuarantee`]. Production planning
/// should use [`Self::with_models_and_evidence`] so the ratio is admitted
/// only when its input domains support a certified error bound.
pub fn with_uncertified_ddsketch_ratios_for_demo(cost_model: &'a dyn CostModel) -> Self {
let mut models = Models::with_default_accuracy(cost_model);
models.allow_uncertified_ddsketch_ratios = true;
Self { models }
}

pub(crate) fn from_models(models: Models<'a>) -> Self {
Self { models }
}
Expand Down Expand Up @@ -1390,11 +1408,18 @@ impl<'a> SketchAlgorithmStrategy<'a> {
}
if intent_override.is_none() && is_supported_exact_binary(root) {
if let Ok(Some(node)) = realize_binary(root, self.models, None) {
let rationale = if node.guarantee.is_none()
&& self.models.allow_uncertified_ddsketch_ratios
{
"demo-only DDSketch quantile ratio; no certified end-to-end accuracy guarantee"
} else {
"preserve exact PromQL arithmetic over independently realized summary operands"
};
proposals.candidates.push(ReplacementSubDAG {
replacement: Replacement::Summary(node),
strategy: "SketchAlgorithmStrategy",
provenance: ReplacementProvenance::SummaryImplementation,
rationale: "preserve exact PromQL arithmetic over independently realized summary operands".into(),
rationale: rationale.into(),
});
}
return proposals;
Expand Down Expand Up @@ -1841,6 +1866,8 @@ fn realize_binary(

let direct_ddsketch_ratio = matches!(op, BinaryOpKind::Arithmetic(ArithmeticOpKind::Div))
&& shared_quantile_target(lhs, rhs).is_some();
let allow_uncertified_ddsketch_ratio =
direct_ddsketch_ratio && models.allow_uncertified_ddsketch_ratios;
let ratio_target = end_to_end_target
.cloned()
.or_else(|| shared_quantile_target(lhs, rhs));
Expand All @@ -1851,31 +1878,34 @@ fn realize_binary(
.as_ref()
.and_then(ddsketch_ratio_operand_target)
{
let Some(domains) = models
let domains = models
.evidence
.quantile_input_domain(lhs)
.zip(models.evidence.quantile_input_domain(rhs))
.map(|(lhs, rhs)| [lhs, rhs])
else {
.map(|(lhs, rhs)| [lhs, rhs]);
if domains.is_none() && !allow_uncertified_ddsketch_ratio {
return Ok(None);
};
}
let (alpha, _) = accuracy_budget(&target);
if domains
.iter()
.any(|domain| !domain.supports_ddsketch(alpha))
{
if domains.as_ref().is_some_and(|domains| {
domains
.iter()
.any(|domain| !domain.supports_ddsketch(alpha))
}) {
return Ok(None);
}
lhs_node = realize_ddsketch_quantile_operand(lhs, models, &target)?;
rhs_node = realize_ddsketch_quantile_operand(rhs, models, &target)?;
for (domain, node) in domains.iter().zip([&lhs_node, &rhs_node]) {
if !ddsketch_quantile_alpha(node)
.is_some_and(|alpha| domain.supports_ddsketch(alpha))
{
return Ok(None);
if let Some(domains) = domains.as_ref() {
for (domain, node) in domains.iter().zip([&lhs_node, &rhs_node]) {
if !ddsketch_quantile_alpha(node)
.is_some_and(|alpha| domain.supports_ddsketch(alpha))
{
return Ok(None);
}
}
}
ratio_domains = Some(domains);
ratio_domains = domains;
}
} else if let Some(target) = end_to_end_target {
let operand_guarantees = [lhs_node.guarantee.as_ref(), rhs_node.guarantee.as_ref()];
Expand Down Expand Up @@ -1925,6 +1955,7 @@ fn realize_binary(
// Only the domain-proven ratio path may consume approximate operands.
// Runtime finite/nonzero checks alone do not establish quantile error bounds.
if ratio_domains.is_none()
&& !allow_uncertified_ddsketch_ratio
&& matches!(op, BinaryOpKind::Arithmetic(ArithmeticOpKind::Div))
&& [&lhs_node, &rhs_node].iter().any(|node| {
!node
Expand All @@ -1947,6 +1978,7 @@ fn realize_binary(

let guarantee = if matches!(op, BinaryOpKind::Arithmetic(ArithmeticOpKind::Div))
&& direct_ddsketch_ratio
&& ratio_domains.is_some()
&& ddsketch_quantile_alpha(&lhs_node).is_some()
&& ddsketch_quantile_alpha(&rhs_node).is_some()
{
Expand Down Expand Up @@ -1974,7 +2006,7 @@ fn realize_binary(
.then(|| ResultGuarantee::exact("BinaryOp over exact operands"))
};

if direct_ddsketch_ratio && guarantee.is_none() {
if direct_ddsketch_ratio && guarantee.is_none() && !allow_uncertified_ddsketch_ratio {
return Ok(None);
}

Expand Down
64 changes: 53 additions & 11 deletions crates/devtools/src/bin/show_post_asap_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,19 @@ const ACCURACY: AccuracyTarget = AccuracyTarget::Epsilon(0.01);
fn bind_all(expr: &QueryExpr) -> Result<Vec<Rc<asap_types::post_asap::SummaryNode>>, String> {
let root = Rc::new(expr.clone());
let target = TargetSubDAG::new(&root);
let candidates = SketchAlgorithmStrategy::default_cost_model()
.replacements(&target)
.into_iter()
.filter_map(|candidate| match candidate {
ReplacementSubDAG {
replacement: Replacement::Summary(node),
..
} => Some(node),
_ => None,
})
.collect::<Vec<_>>();
let candidates = SketchAlgorithmStrategy::with_uncertified_ddsketch_ratios_for_demo(
&asap_aware_mapping::cost_model::DefaultCostModel,
)
.replacements(&target)
.into_iter()
.filter_map(|candidate| match candidate {
ReplacementSubDAG {
replacement: Replacement::Summary(node),
..
} => Some(node),
_ => None,
})
.collect::<Vec<_>>();

if candidates.is_empty() {
Ok(vec![keep_pre_asap(&root).map_err(|e| e.to_string())?])
Expand Down Expand Up @@ -157,4 +159,44 @@ mod tests {
assert!(expected > 1, "fixture exposes alternative bindings");
assert_eq!(bind_all(&expr).expect("binding succeeds").len(), expected);
}

#[test]
fn bind_all_exposes_an_uncertified_ddsketch_ratio_for_the_demo() {
let expr = lower_promql_with_data_ingestion_interval(
"quantile_over_time(0.9,data[5m])/quantile_over_time(0.5,data[5m])",
ACCURACY.clone(),
1_000,
)
.expect("query lowers to pre-ASAP IR");

let candidates = bind_all(&expr).expect("binding succeeds");
assert_eq!(candidates.len(), 1);
assert!(matches!(
candidates[0].expr,
asap_types::post_asap::SummaryExpr::BinaryOp { .. }
));
assert!(
candidates[0].guarantee.is_none(),
"the demo escape hatch must not claim a certified ratio bound"
);
asap_types::post_asap::compile_executable_dag(&candidates[0])
.expect("the demo candidate remains executable");
}

#[test]
fn demo_escape_hatch_does_not_relax_other_approximate_divisions() {
let expr = lower_promql_with_data_ingestion_interval(
"avg_over_time(data[5m])/quantile_over_time(0.5,data[5m])",
ACCURACY.clone(),
1_000,
)
.expect("query lowers to pre-ASAP IR");

let candidates = bind_all(&expr).expect("binding succeeds");
assert_eq!(candidates.len(), 1);
assert!(matches!(
candidates[0].expr,
asap_types::post_asap::SummaryExpr::KeepPreAsap(_)
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,16 @@ Certification requires each domain to lie wholly within the pinned mapping's pos
The denominator range must exclude zero. True and perturbed quotient ranges must stay finite and outside Float64's subnormal range, with an exact zero numerator allowed. Invalid quantile parameters and missing/invalid proofs do not receive a ratio certificate. Without a certificate the approximate ratio candidate is declined and exact execution remains available. These checks are conservative: an actual window may be safe even when its declared bounds cannot prove it.

The final guarantee records both input ranges and their contract identifiers. The integration layer must only provide contracts it enforces for the plan's lifetime. This change adds no runtime guard, fallback executor, or automatic proof inference, and does not change standalone DDSketch readout certification outside this ratio rule.

## V1 demonstration policy

`SketchAlgorithmStrategy::with_uncertified_ddsketch_ratios_for_demo` is an
explicit escape hatch for demos and diagnostics that need to inspect the
DDSketch ratio DAG before an evidence provider is integrated. It permits the
candidate when domain evidence is absent, but leaves the root guarantee unset.
It does not turn missing evidence into evidence, and accuracy-enforcing callers
must not treat this candidate as certified.

The default constructors remain fail-closed. Production callers should use
`with_models_and_evidence`. Runtime or statically enforced domain contracts
remain future work driven by observed v1 correctness needs.
10 changes: 8 additions & 2 deletions docs/user_guide_docs/run-a-query.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,16 @@ your database schema. Use the
[library workflow](../develop_docs/library-api.md) to retain workload alternatives
and provide your own models.

For the v1 demo, this command also opts into DDSketch quantile-ratio candidates
when no input-domain evidence is available. Those candidates have
`guarantee: None`: they demonstrate the intended post-ASAP shape but do not
claim a certified end-to-end accuracy bound. The normal sketch strategy still
declines such ratios unless the caller supplies sufficient domain evidence.

Each input line is followed by its debug IR or an `ERR:` message. Post-ASAP
output may contain summary state, readouts or exact `KeepPreAsap` work. An
approximate target permits approximation; it does not guarantee a legal sketch.
The tool prints plans, not query results.
approximate target permits approximation; it does not guarantee a legal or
certified sketch. The tool prints plans, not query results.

## More inspection commands

Expand Down
Loading