Skip to content
Merged
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
33 changes: 0 additions & 33 deletions crates/asap-aware-mapping/src/accuracy/composition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -697,16 +697,6 @@ fn composed_provenance(
provenance
}

pub(super) fn exact_operation_rule(operation: &ExactOperation) -> Option<CompositionOperator> {
let ExactOperation::Aggregate { measures, .. } = operation;
match measures.as_slice() {
[intent] => crate::function_rules::function_rules(intent).map(|rules| rules.accuracy),
// The remaining functions are exact over exact samples, but have
// no definition-backed rule over approximate values yet.
_ => None,
}
}

pub(super) fn propagate(
op: &CompositionOperator,
inputs: &[AccuracyGuarantee],
Expand Down Expand Up @@ -1002,7 +992,6 @@ mod tests {
assert_eq!(parse_source_norm_statistic(other), None, "{other}");
}
}
use asap_types::pre_asap::AggIntent;
fn abs(bound: f64, delta: f64) -> AccuracyGuarantee {
AccuracyGuarantee::new(
AccuracyMetric::ABSOLUTE,
Expand Down Expand Up @@ -1411,28 +1400,6 @@ mod tests {
assert_eq!(out.spec.failure_probability.evaluate(), Some(0.04));
}
#[test]
fn counter_functions_have_distinct_definition_rules() {
let operation = |intent| ExactOperation::Aggregate {
reduction: asap_types::pre_asap::Reduction::PerEntity,
measures: vec![intent],
output_names: vec![],
filters: vec![],
having: None,
};
assert_eq!(
DefaultAccuracyModel.exact_operation_rule(&operation(AggIntent::Rate)),
Some(CompositionOperator::CounterRate)
);
assert_eq!(
DefaultAccuracyModel.exact_operation_rule(&operation(AggIntent::IRate)),
Some(CompositionOperator::InstantCounterRate)
);
assert_eq!(
DefaultAccuracyModel.exact_operation_rule(&operation(AggIntent::Increase)),
Some(CompositionOperator::CounterIncrease)
);
}
#[test]
fn topk_selection_requires_a_separated_margin_certificate() {
let unknown = DefaultAccuracyModel
.propagate(
Expand Down
53 changes: 53 additions & 0 deletions crates/asap-aware-mapping/src/accuracy/estimators/cms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,57 @@ mod tests {
AccuracyMetric::ABSOLUTE_STREAM_L1
);
}

/// CMS width is `⌈e/ε⌉` and depth `⌈ln(1/δ)⌉`, with an ε-only target
/// taking `DEFAULT_DELTA` (depth 5).
#[test]
fn epsilon_delta_sizes_cms_depth() {
use crate::realization::{accuracy_budget, default_size_params, DEFAULT_DELTA};
let intent = AggIntent::Count {
accuracy: AccuracyTarget::max_error(0.001).failure_probability(0.001),
};
assert_eq!(
default_size_params(SketchAlgorithm::Cms, &intent, 0.001, 0.001),
SketchParams::Cms {
width: 2719,
depth: 7
} // ⌈e/0.001⌉, ⌈ln 1000⌉
);
let target = AccuracyTarget::max_error(0.001);
let (eps, delta) = accuracy_budget(&target);
assert_eq!((eps, delta), (0.001, DEFAULT_DELTA));
let intent = AggIntent::Count { accuracy: target };
assert_eq!(
default_size_params(SketchAlgorithm::Cms, &intent, eps, delta),
SketchParams::Cms {
width: 2719,
depth: 5
}
);
assert_eq!(
default_size_params(SketchAlgorithm::Cms, &intent, 0.01, 0.01),
SketchParams::Cms {
width: 272,
depth: 5
}
);
}

/// 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;
let intent = AggIntent::TopK {
k: 25,
accuracy: AccuracyTarget::max_error(0.01),
};
assert_eq!(
default_size_params(SketchAlgorithm::CmsWithHeap, &intent, 0.01, 0.01),
SketchParams::CmsWithHeap {
width: 272, // ⌈e/0.01⌉
depth: 5,
heap_size: 100,
}
);
}
}
36 changes: 36 additions & 0 deletions crates/asap-aware-mapping/src/accuracy/estimators/kll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,4 +348,40 @@ 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 asap_types::pre_asap::agg_intent::default_quantile;
let q = default_quantile(0.99);
assert_eq!(
default_size_params(SketchAlgorithm::Kll, &q, 0.01, 0.01),
SketchParams::Kll {
k: 269,
failure_probability: None
}
);
assert_eq!(
default_size_params(SketchAlgorithm::Kll, &q, 0.05, 0.01),
SketchParams::Kll {
k: 52,
failure_probability: None
}
);
}

/// 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 asap_types::pre_asap::agg_intent::default_quantile;
assert_eq!(
default_size_params(SketchAlgorithm::Kll, &default_quantile(0.99), 0.0, 0.01),
SketchParams::Kll {
k: 26_602,
failure_probability: None
}
);
}
}
43 changes: 0 additions & 43 deletions crates/asap-aware-mapping/src/accuracy/evidence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,6 @@ pub struct OperandDomain {
pub contract: String,
}

impl OperandDomain {
pub(crate) fn supports_ddsketch(&self, alpha: f64) -> bool {
if !alpha.is_finite()
|| alpha <= 0.0
|| alpha >= 1.0
|| !self.lower.is_finite()
|| !self.upper.is_finite()
|| self.lower > self.upper
|| self.max_samples == 0
|| self.max_samples > (1u64 << 53)
|| self.contract.trim().is_empty()
{
return false;
}
let (min, max) = asap_sketchlib::sketches::ddsketch::ddsketch_indexable_bounds(alpha);
// Same-sign interpolation preserves relative error. Zero alone is
// exact; an interval touching zero also admits tiny zero-mapped values.
(self.lower >= min && self.upper <= max)
|| (self.upper <= -min && self.lower >= -max)
|| (self.lower == 0.0 && self.upper == 0.0)
}
}

/// Statistics a propagation rule may consult. Every field is optional and
/// defaults to "unknown": a rule that needs a missing statistic emits a
/// [`BoundExpr::Unknown`] leaf (or rejects) rather than guessing.
Expand Down Expand Up @@ -81,21 +58,10 @@ pub struct PropagationStats {
/// Union-bound failure probability of all intervals used by the margin
/// certificate.
pub topk_interval_failure_probability: Option<f64>,
/// Hydra shared-grid collision error in the inner guarantee's metric.
pub hydra_shared_grid_collision_bound: Option<f64>,
/// Failure probability assigned to the Hydra shared-grid term.
pub hydra_shared_grid_failure_probability: Option<f64>,
}

/// Supplies typed planning-time evidence required by propagation rules.
pub trait AccuracyEvidenceProvider {
/// Enforced upper bound on distinct (partition, item) identities across a
/// complete TopK evaluation. Used to union-bound score errors for adaptively
/// selected candidates. Observed cardinality is not sufficient evidence.
fn topk_max_distinct_items(&self, _expression: &OperatorNode) -> Option<u64> {
None
}

/// Enforced domain of `operand`'s true values ([`OperandDomain`]), scoped
/// to this complete expression, including its source, filters, grouping
/// and window: a quantile ratio's operands, or the operands of a
Expand All @@ -115,15 +81,6 @@ pub trait AccuracyEvidenceProvider {
fn output_guarantee(&self, _output: &QueryRoot) -> Option<AccuracyGuarantee> {
None
}

fn propagation_stats(
&self,
_op: &CompositionOperator,
_family: &FieldDataType,
_query: Option<&SketchStatistic>,
) -> PropagationStats {
PropagationStats::default()
}
}

#[derive(Debug, Default, Clone, Copy)]
Expand Down
19 changes: 2 additions & 17 deletions crates/asap-aware-mapping/src/accuracy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ pub mod budget;
pub mod composition;
pub mod estimators;
pub mod evidence;
pub mod reconciliation;

pub use budget::per_input_target;
pub use evidence::{AccuracyEvidenceProvider, NoAccuracyEvidence, OperandDomain, PropagationStats};
Expand All @@ -23,21 +22,12 @@ use asap_types::post_asap::{
};
use asap_types::types::{AccuracyScope, AccuracyTarget};

use crate::exact_composition::ExactOperation;

/// The deployment-extensible accuracy algebra. `asap-aware-mapping` ships
/// [`DefaultAccuracyModel`]; a deployment with a proof for a composition the
/// default rejects (a registered cross-metric conversion, say) implements
/// this trait and passes it to
/// [`crate::replacement::ASAPStrategies::new_with_planning_inputs`].
/// this trait and passes it to plan selection in
/// [`crate::PlanningModels::accuracy`].
pub trait AccuracyModel {
/// The definition-registered rule for applying `operation` to an
/// approximate input. `None` means the function is exact only over exact
/// inputs; callers must fail closed for approximate input.
fn exact_operation_rule(&self, _operation: &ExactOperation) -> Option<CompositionOperator> {
None
}

/// The 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
Expand Down Expand Up @@ -93,9 +83,6 @@ impl DefaultAccuracyModel {
}

impl AccuracyModel for DefaultAccuracyModel {
fn exact_operation_rule(&self, operation: &ExactOperation) -> Option<CompositionOperator> {
composition::exact_operation_rule(operation)
}
fn local_guarantee(
&self,
family: &FieldDataType,
Expand Down Expand Up @@ -171,8 +158,6 @@ pub fn native_target(target: &AccuracyTarget, guarantee: &AccuracyGuarantee) ->
.accuracy_scope(AccuracyScope::PerValue)
}

pub(crate) use estimators::topk_capacity;

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Loading
Loading