use std::collections::HashSet;
use std::sync::{Mutex, OnceLock};
use crate::fkc::error::FkcError;
use crate::fkc::schema::PrecisionBlock;
use crate::fused::PrecisionGuarantee;
fn intern(s: &str) -> &'static str {
static POOL: OnceLock<Mutex<HashSet<&'static str>>> = OnceLock::new();
let pool = POOL.get_or_init(|| Mutex::new(HashSet::new()));
let mut guard = pool.lock().expect("precision notes interner poisoned");
if let Some(existing) = guard.get(s) {
return existing;
}
let leaked: &'static str = Box::leak(s.to_string().into_boxed_str());
guard.insert(leaked);
leaked
}
fn read_f64(
v: &Option<serde_yaml_ng::Value>,
section: &str,
field: &str,
) -> Result<Option<f64>, FkcError> {
match v {
None => Ok(None),
Some(serde_yaml_ng::Value::Null) => Ok(None),
Some(serde_yaml_ng::Value::Number(n)) => Ok(n.as_f64()),
Some(other) => Err(FkcError::Yaml(format!(
"section `{section}`: precision field `{field}` must be a number or null, got {other:?}"
))),
}
}
fn read_u32(
v: &Option<serde_yaml_ng::Value>,
section: &str,
field: &str,
) -> Result<Option<u32>, FkcError> {
Ok(read_f64(v, section, field)?.map(|f| f as u32))
}
pub fn lower_precision(
block: Option<&PrecisionBlock>,
section: &str,
) -> Result<PrecisionGuarantee, FkcError> {
let Some(b) = block else {
return Ok(PrecisionGuarantee::UNAUDITED);
};
let max_ulp = read_u32(&b.max_ulp, section, "max_ulp")?;
let max_relative = read_f64(&b.max_relative, section, "max_relative")?;
let max_absolute = read_f64(&b.max_absolute, section, "max_absolute")?;
let has_bound = max_ulp.is_some() || max_relative.is_some() || max_absolute.is_some();
let bit_stable = b.bit_stable_on_same_hardware.unwrap_or(false);
let has_notes = b.notes.as_deref().is_some_and(|n| !n.trim().is_empty());
if b.audited.is_none() && !has_bound && !has_notes && b.bit_stable_on_same_hardware.is_none() {
return Err(FkcError::PlaceholderPrecision {
section: section.to_string(),
});
}
if has_bound {
let notes: &'static str = match b.notes.as_deref() {
Some(n) if !n.trim().is_empty() => intern(n),
_ => "",
};
return Ok(PrecisionGuarantee {
bit_stable_on_same_hardware: bit_stable,
max_ulp,
max_relative,
max_absolute,
notes,
});
}
match b.audited {
Some(false) => Ok(PrecisionGuarantee::UNAUDITED),
Some(true) => {
if bit_stable {
let notes: &'static str = match b.notes.as_deref() {
Some(n) if !n.trim().is_empty() => intern(n),
_ => "",
};
Ok(PrecisionGuarantee {
bit_stable_on_same_hardware: true,
max_ulp: None,
max_relative: None,
max_absolute: None,
notes,
})
} else {
let reason: &'static str = match b.notes.as_deref() {
Some(n) if !n.trim().is_empty() => intern(n),
_ => "audited; no static precision bound applies",
};
Ok(PrecisionGuarantee::none(reason))
}
}
None => {
if bit_stable {
let notes: &'static str = match b.notes.as_deref() {
Some(n) if !n.trim().is_empty() => intern(n),
_ => "",
};
Ok(PrecisionGuarantee {
bit_stable_on_same_hardware: true,
max_ulp: None,
max_relative: None,
max_absolute: None,
notes,
})
} else {
let reason: &'static str = match b.notes.as_deref() {
Some(n) if !n.trim().is_empty() => intern(n),
_ => unreachable!("placeholder branch already returned"),
};
Ok(PrecisionGuarantee::none(reason))
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
fn num(v: f64) -> Option<serde_yaml_ng::Value> {
Some(serde_yaml_ng::Value::Number(v.into()))
}
#[test]
fn audited_false_all_null_is_unaudited() {
let block = PrecisionBlock {
bit_stable_on_same_hardware: None,
max_ulp: None,
max_relative: None,
max_absolute: None,
audited: Some(false),
notes: Some("not yet audited".into()),
};
let p = lower_precision(Some(&block), "k").unwrap();
assert_eq!(p.notes, PrecisionGuarantee::UNAUDITED.notes);
assert!(!p.bit_stable_on_same_hardware);
}
#[test]
fn audited_true_all_null_no_bitstable_is_none_with_reason() {
let block = PrecisionBlock {
bit_stable_on_same_hardware: Some(false),
max_ulp: None,
max_relative: None,
max_absolute: None,
audited: Some(true),
notes: Some("scheduler-dependent FADD order".into()),
};
let p = lower_precision(Some(&block), "k").unwrap();
assert!(!p.bit_stable_on_same_hardware);
assert_eq!(p.notes, "scheduler-dependent FADD order");
assert!(p.max_ulp.is_none());
}
#[test]
fn bounds_present_populates_struct() {
let block = PrecisionBlock {
bit_stable_on_same_hardware: Some(true),
max_ulp: num(0.0),
max_relative: None,
max_absolute: None,
audited: Some(true),
notes: Some("Exact IEEE-754 f32 addition.".into()),
};
let p = lower_precision(Some(&block), "add_f32").unwrap();
assert!(p.bit_stable_on_same_hardware);
assert_eq!(p.max_ulp, Some(0));
assert_eq!(p.notes, "Exact IEEE-754 f32 addition.");
}
#[test]
fn bitstable_true_all_null_is_a_real_claim_not_none() {
let block = PrecisionBlock {
bit_stable_on_same_hardware: Some(true),
max_ulp: None,
max_relative: None,
max_absolute: None,
audited: Some(true),
notes: Some("f32 accumulate; deterministic.".into()),
};
let p = lower_precision(Some(&block), "qmatmul").unwrap();
assert!(p.bit_stable_on_same_hardware);
assert!(p.max_ulp.is_none());
assert_eq!(p.notes, "f32 accumulate; deterministic.");
}
#[test]
fn bare_placeholder_is_error() {
let block = PrecisionBlock {
bit_stable_on_same_hardware: None,
max_ulp: None,
max_relative: None,
max_absolute: None,
audited: None,
notes: None,
};
let err = lower_precision(Some(&block), "k").expect_err("placeholder errors");
assert!(
matches!(err, FkcError::PlaceholderPrecision { .. }),
"got {err:?}"
);
}
#[test]
fn absent_block_is_unaudited() {
let p = lower_precision(None, "k").unwrap();
assert_eq!(p.notes, PrecisionGuarantee::UNAUDITED.notes);
}
}