use std::sync::Mutex;
use metrale_telemetry::kernel_audit::AuditRow;
#[derive(Clone, Debug)]
pub struct KernelRow {
pub module: String,
pub ptx_hash: String,
pub resolution: Option<bool>,
}
#[derive(Clone, Debug)]
pub struct MissingKernel {
pub module: String,
pub func: String,
pub site: String,
}
impl MissingKernel {
fn from_row(r: &AuditRow) -> Self {
Self {
module: r.module.clone(),
func: r.func.clone(),
site: format!("{}:{}", r.site.file(), r.site.line()),
}
}
}
#[derive(Default)]
pub struct KernelTableModel {
pub rows: Vec<KernelRow>,
pub missing_required: Vec<MissingKernel>,
pub missing_expected: Vec<MissingKernel>,
}
static LOADED_TARGET: Mutex<Option<(String, String)>> = Mutex::new(None);
pub fn publish_loaded_target(model: &str, quant: &str) {
if let Ok(mut g) = LOADED_TARGET.lock() {
*g = Some((model.to_string(), quant.to_string()));
}
}
fn loaded_target() -> Option<(String, String)> {
let guard = LOADED_TARGET.lock().ok()?;
guard.clone()
}
fn ptx_hash(bytes: &[u8]) -> String {
let mut h: u64 = 0xcbf2_9ce4_8422_2325;
for &b in bytes {
h ^= b as u64;
h = h.wrapping_mul(0x0000_0100_0000_01b3);
}
format!("{:012x}", h & 0xffff_ffff_ffff)
}
pub fn build() -> KernelTableModel {
let audit = metrale_telemetry::kernel_audit::audit_rows();
let Some(ptx) = loaded_target()
.and_then(|(model, quant)| metrale_kernels::ptx_for_exact_target(&model, &quant))
else {
return KernelTableModel::default();
};
let mut rows: Vec<KernelRow> = ptx
.modules
.iter()
.map(|(module, blob)| {
let mut resolution = None;
for r in &audit {
if r.module == *module {
resolution = Some(resolution.unwrap_or(false) || r.loaded);
}
}
KernelRow {
module: (*module).to_string(),
ptx_hash: ptx_hash(blob),
resolution,
}
})
.collect();
rows.sort_by(|a, b| a.module.cmp(&b.module));
let split = metrale_telemetry::kernel_audit::split_failures(&audit, ptx.expected_absent);
KernelTableModel {
rows,
missing_required: split.required.iter().map(MissingKernel::from_row).collect(),
missing_expected: split.expected.iter().map(MissingKernel::from_row).collect(),
}
}