use std::fmt;
#[derive(Debug, Clone)]
pub struct KernelChecksum {
pub name: String,
pub layer_idx: usize,
pub position: u32,
pub checksum: u64,
}
#[derive(Debug, Clone)]
pub struct DivergenceInfo {
pub kernel_name: String,
pub layer_idx: usize,
pub position: u32,
pub expected_checksum: u64,
pub actual_checksum: u64,
}
impl fmt::Display for DivergenceInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"DIVERGENCE at '{}' (layer {}, pos {}): expected 0x{:016X}, got 0x{:016X}",
self.kernel_name,
self.layer_idx,
self.position,
self.expected_checksum,
self.actual_checksum
)
}
}
#[inline]
pub fn fnv1a_f32_checksum(data: &[f32]) -> u64 {
const FNV_OFFSET: u64 = 0xcbf29ce484222325;
const FNV_PRIME: u64 = 0x100000001b3;
let mut hash = FNV_OFFSET;
let len = data.len().min(64);
for &val in &data[..len] {
let bytes = val.to_le_bytes();
for byte in bytes {
hash ^= u64::from(byte);
hash = hash.wrapping_mul(FNV_PRIME);
}
}
hash
}
#[macro_export]
macro_rules! time_brick {
($profiler:expr, $name:expr, $elements:expr, $body:block) => {{
let timer = $profiler.start($name);
let result = $body;
$profiler.stop(timer, $elements);
result
}};
}