impl ConversionReport {
#[must_use]
pub fn is_lossless(&self) -> bool {
self.dropped_tensors.is_empty()
}
#[must_use]
pub fn tensor_counts_match(&self) -> bool {
self.source_inspection.tensors.len() == self.target_inspection.tensors.len()
}
}
#[derive(Debug, Clone)]
pub struct VerificationReport {
pub is_equivalent: bool,
pub max_diff: f32,
pub mean_diff: f32,
pub tensor_diffs: BTreeMap<String, f32>,
pub changed_metadata: Vec<String>,
pub failed_tensors: Vec<String>,
}
impl VerificationReport {
#[must_use]
pub fn passing() -> Self {
Self {
is_equivalent: true,
max_diff: 0.0,
mean_diff: 0.0,
tensor_diffs: BTreeMap::new(),
changed_metadata: Vec::new(),
failed_tensors: Vec::new(),
}
}
#[must_use]
pub fn passes_with_tolerance(&self, epsilon: f32) -> bool {
self.max_diff <= epsilon && self.failed_tensors.is_empty()
}
}
#[derive(Debug, Clone)]
pub struct TensorValidation {
pub name: String,
pub is_valid: bool,
pub nan_count: usize,
pub inf_count: usize,
pub zero_count: usize,
pub element_count: usize,
pub min: f32,
pub max: f32,
pub mean: f32,
pub std: f32,
pub failures: Vec<String>,
}
impl TensorValidation {
#[must_use]
pub fn has_nan(&self) -> bool {
self.nan_count > 0
}
#[must_use]
pub fn has_inf(&self) -> bool {
self.inf_count > 0
}
#[must_use]
pub fn is_all_zeros(&self) -> bool {
self.zero_count == self.element_count
}
}
#[derive(Debug, Clone)]
pub struct ValidationReport {
pub format: FormatType,
pub file_path: String,
pub is_valid: bool,
pub tensor_count: usize,
pub failed_tensor_count: usize,
pub total_nan_count: usize,
pub total_inf_count: usize,
pub all_zero_tensors: Vec<String>,
pub tensors: Vec<TensorValidation>,
pub duration_ms: u64,
}
impl ValidationReport {
#[must_use]
pub fn passed(&self) -> bool {
self.is_valid
}
#[must_use]
pub fn summary(&self) -> String {
if self.is_valid {
format!(
"VALID: {} tensors checked, 0 contract violations (PMAT-235)",
self.tensor_count
)
} else {
let contract_failures: usize = self.tensors.iter().map(|t| t.failures.len()).sum();
format!(
"INVALID: {} tensors, {} contract violations, {} NaN, {} Inf, {} all-zeros",
self.tensor_count,
contract_failures,
self.total_nan_count,
self.total_inf_count,
self.all_zero_tensors.len()
)
}
}
}
impl fmt::Display for ValidationReport {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "=== Model Validation Report (APR-SPEC 10.9) ===")?;
writeln!(f, "Format: {}", self.format)?;
writeln!(f, "File: {}", self.file_path)?;
writeln!(
f,
"Status: {}",
if self.is_valid { "VALID" } else { "INVALID" }
)?;
writeln!(f, "Tensors: {}", self.tensor_count)?;
writeln!(f, "Total NaN: {}", self.total_nan_count)?;
writeln!(f, "Total Inf: {}", self.total_inf_count)?;
writeln!(f, "All-Zero Tensors: {}", self.all_zero_tensors.len())?;
writeln!(f, "Duration: {} ms", self.duration_ms)?;
if !self.is_valid {
writeln!(f, "\n--- Failed Tensors ---")?;
for tv in &self.tensors {
if !tv.is_valid {
writeln!(
f,
" {}: {} NaN, {} Inf, {} zeros / {}",
tv.name, tv.nan_count, tv.inf_count, tv.zero_count, tv.element_count
)?;
for failure in &tv.failures {
writeln!(f, " - {failure}")?;
}
}
}
}
Ok(())
}
}
#[allow(clippy::struct_excessive_bools)] #[derive(Debug, Clone)]
pub struct ConversionOptions {
pub quantization: Option<String>,
pub verify: bool,
pub compute_stats: bool,
pub tolerance: f32,
pub preserve_metadata: bool,
pub add_provenance: bool,
pub tokenizer_path: Option<PathBuf>,
}
impl Default for ConversionOptions {
fn default() -> Self {
Self {
quantization: None,
verify: true,
compute_stats: false,
tolerance: 1e-6,
preserve_metadata: true,
add_provenance: true,
tokenizer_path: None,
}
}
}
#[derive(Debug)]
pub struct RosettaStone {
options: ConversionOptions,
}