use super::PlacementTypeError;
use super::capability::{AttrValue, Capability, CapabilityId, Provenance};
use super::requirement::{AttrPredicate, Requirement};
pub const PERF_COG_CYCLE_MS: &str = "perf.cog.cycle_ms";
pub const PERF_INFER_TOK_S: &str = "perf.infer.tok_s";
pub const VALUE_ATTR: &str = "value";
fn measured(
id: &str,
param: &str,
key: &str,
value: AttrValue,
) -> Result<Capability, PlacementTypeError> {
if value.as_f64().is_none_or(|v| !v.is_finite() || v < 0.0) {
return Err(PlacementTypeError::InvalidAttr {
id: id.to_string(),
attr: VALUE_ATTR.to_string(),
reason: "measured value must be finite and non-negative".to_string(),
});
}
if key.is_empty() || key.len() > super::capability::MAX_STR_LEN {
return Err(PlacementTypeError::InvalidAttr {
id: id.to_string(),
attr: param.to_string(),
reason: "parameter must be non-empty and bounded".to_string(),
});
}
let cap = Capability::new(CapabilityId::new(id)?, Provenance::Measured)
.with_attr(param, key)
.with_attr(VALUE_ATTR, value);
cap.validate()?;
Ok(cap)
}
pub fn cog_cycle_ms(cog_id: &str, ms: f64) -> Result<Capability, PlacementTypeError> {
measured(PERF_COG_CYCLE_MS, "cog_id", cog_id, AttrValue::Float(ms))
}
pub fn infer_tok_s(model: &str, tok_s: f64) -> Result<Capability, PlacementTypeError> {
measured(PERF_INFER_TOK_S, "model", model, AttrValue::Float(tok_s))
}
pub fn require_cog_cycle_within(
cog_id: &str,
budget_ms: f64,
) -> Result<Requirement, PlacementTypeError> {
Ok(Requirement::exact(CapabilityId::new(PERF_COG_CYCLE_MS)?)
.try_with_where(AttrPredicate::eq("cog_id", cog_id))?
.try_with_where(AttrPredicate::lte(VALUE_ATTR, budget_ms))?
.with_min_provenance(Provenance::Measured))
}
pub fn require_infer_tok_s_at_least(
model: &str,
min_tok_s: f64,
) -> Result<Requirement, PlacementTypeError> {
Ok(Requirement::exact(CapabilityId::new(PERF_INFER_TOK_S)?)
.try_with_where(AttrPredicate::eq("model", model))?
.try_with_where(AttrPredicate::gte(VALUE_ATTR, min_tok_s))?
.with_min_provenance(Provenance::Measured))
}