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
38 changes: 3 additions & 35 deletions crates/asap-aware-mapping/src/analytical_cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,60 +152,28 @@ pub fn cache_hit_ratios(
/// Memory's coefficient means cost units per retained byte over this model's
/// explicit comparison scope; it is not mixed with a rate implicitly.
///
/// Plan selection prices per second of wall time and also reads
/// `cost_per_retained_byte_second`, the price of state kept across
/// evaluations per byte per second, and `horizon_s`, the seconds over which
/// it spreads one-off, scheduled and unknown queries.
/// The legacy core's prices ([`crate::physical_plan_cost_model`]); plan
/// selection (Stage 3) prices with
/// [`crate::stage3_plan_selection::ResourceUnitCost`] instead.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct ResourceCalibration {
pub cost_per_cpu_op: f64,
pub cost_per_scan_byte: f64,
pub cost_per_retained_byte: f64,
#[serde(default)]
pub cost_per_retained_byte_second: f64,
#[serde(default = "default_horizon_s")]
pub horizon_s: f64,
/// Milliseconds one CPU operation takes on one core: plan selection's
/// latency check reads it (0: work takes no time).
#[serde(default)]
pub ms_per_cpu_op: f64,
/// Milliseconds scanning one byte takes on one core, for the latency
/// check.
#[serde(default)]
pub ms_per_scan_byte: f64,
pub version: String,
}

/// One hour.
pub const DEFAULT_HORIZON_S: f64 = 3_600.0;

fn default_horizon_s() -> f64 {
DEFAULT_HORIZON_S
}

impl ResourceCalibration {
pub fn validate(&self) -> Result<(), AnalyticalCostError> {
for (name, value) in [
("cost_per_cpu_op", self.cost_per_cpu_op),
("cost_per_scan_byte", self.cost_per_scan_byte),
("cost_per_retained_byte", self.cost_per_retained_byte),
(
"cost_per_retained_byte_second",
self.cost_per_retained_byte_second,
),
("ms_per_cpu_op", self.ms_per_cpu_op),
("ms_per_scan_byte", self.ms_per_scan_byte),
] {
if !value.is_finite() || value < 0.0 {
return Err(AnalyticalCostError::InvalidCalibration(name, value));
}
}
if !self.horizon_s.is_finite() || self.horizon_s <= 0.0 {
return Err(AnalyticalCostError::InvalidCalibration(
"horizon_s",
self.horizon_s,
));
}
if self.cost_per_cpu_op == 0.0
&& self.cost_per_scan_byte == 0.0
&& self.cost_per_retained_byte == 0.0
Expand Down
23 changes: 20 additions & 3 deletions crates/asap-aware-mapping/src/pass/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use crate::accuracy::{
};
use crate::cost_model::{CostModel, DefaultCostModel};
use crate::per_computation_candidates::PerComputationCandidateError;
use crate::stage3_plan_selection::{Selection, SelectionError};
use crate::stage3_plan_selection::{PlanSelectionSettings, Selection, SelectionError};

pub use stage1_to_stage3::{
run_stage1_to_stage3, run_stage1_to_stage3_from_pass1, run_stage2_and_stage3,
Expand All @@ -43,20 +43,28 @@ pub use stage1_to_stage3::{
static DEFAULT_COST_MODEL: DefaultCostModel = DefaultCostModel;
static DEFAULT_ACCURACY_MODEL: DefaultAccuracyModel = DefaultAccuracyModel;
static NO_ACCURACY_EVIDENCE: NoAccuracyEvidence = NoAccuracyEvidence;
static DEFAULT_PLAN_SELECTION: std::sync::LazyLock<PlanSelectionSettings> =
std::sync::LazyLock::new(PlanSelectionSettings::default);

// ── Input ────────────────────────────────────────────────────────────────

/// Planning logic, as opposed to the scoped facts it consumes: a model can have
/// a built-in default, evidence about a particular deployment cannot.
///
/// Plan selection reads `accuracy` and `evidence`. It prices candidates with
/// its own analytical model, so [`Stage1ToStage3Pass`] does not read `cost`.
/// Plan selection reads `accuracy`, `evidence` and `plan_selection`. It
/// measures candidates with its own analytical model and compares them
/// under `plan_selection`'s cost model, so [`Stage1ToStage3Pass`] does not
/// read `cost`.
#[derive(Clone, Copy)]
#[non_exhaustive]
pub struct PlanningModels<'a> {
pub cost: &'a dyn CostModel,
pub accuracy: &'a dyn AccuracyModel,
pub evidence: &'a dyn AccuracyEvidenceProvider,
/// The deployment's plan selection settings: the cost model (default
/// cost model 1 with illustrative unit costs), the resource speed and
/// the non-repeating query horizon.
pub plan_selection: &'a PlanSelectionSettings,
}

impl<'a> PlanningModels<'a> {
Expand All @@ -69,6 +77,7 @@ impl<'a> PlanningModels<'a> {
cost,
accuracy,
evidence,
plan_selection: &DEFAULT_PLAN_SELECTION,
}
}

Expand All @@ -78,6 +87,7 @@ impl<'a> PlanningModels<'a> {
cost: &DEFAULT_COST_MODEL,
accuracy: &DEFAULT_ACCURACY_MODEL,
evidence: &NO_ACCURACY_EVIDENCE,
plan_selection: &DEFAULT_PLAN_SELECTION,
}
}

Expand All @@ -95,6 +105,13 @@ impl<'a> PlanningModels<'a> {
self.evidence = evidence;
self
}

/// These models with the deployment's plan selection settings (cost
/// model, resource speed, non-repeating query horizon).
pub fn with_plan_selection(mut self, plan_selection: &'a PlanSelectionSettings) -> Self {
self.plan_selection = plan_selection;
self
}
}

#[derive(Clone, Copy)]
Expand Down
16 changes: 0 additions & 16 deletions crates/asap-aware-mapping/src/physical_plan_cost_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,10 +595,6 @@ mod tests {
cost_per_cpu_op: 1.0,
cost_per_scan_byte: 1.0,
cost_per_retained_byte: 1.0,
cost_per_retained_byte_second: 0.0,
horizon_s: crate::analytical_cost::DEFAULT_HORIZON_S,
ms_per_cpu_op: 0.0,
ms_per_scan_byte: 0.0,
version: "test-v1".into(),
}
}
Expand Down Expand Up @@ -685,10 +681,6 @@ mod tests {
cost_per_cpu_op: 0.0,
cost_per_scan_byte: 0.0,
cost_per_retained_byte: 0.0,
cost_per_retained_byte_second: 0.0,
horizon_s: crate::analytical_cost::DEFAULT_HORIZON_S,
ms_per_cpu_op: 0.0,
ms_per_scan_byte: 0.0,
version: "unused-base-v1".into(),
};
let candidates =
Expand Down Expand Up @@ -816,10 +808,6 @@ mod tests {
cost_per_cpu_op: 0.0,
cost_per_scan_byte: 0.0,
cost_per_retained_byte: 0.0,
cost_per_retained_byte_second: 0.0,
horizon_s: crate::analytical_cost::DEFAULT_HORIZON_S,
ms_per_cpu_op: 0.0,
ms_per_scan_byte: 0.0,
version: "handoff-only-v1".into(),
};
let space = crate::replacement::search_workload_with(
Expand Down Expand Up @@ -942,10 +930,6 @@ mod tests {
cost_per_cpu_op: 0.0,
cost_per_scan_byte: 1.0,
cost_per_retained_byte: 0.0,
cost_per_retained_byte_second: 0.0,
horizon_s: crate::analytical_cost::DEFAULT_HORIZON_S,
ms_per_cpu_op: 0.0,
ms_per_scan_byte: 0.0,
version: "disk-only-v1".into(),
},
)
Expand Down
Loading
Loading