torsh_nn/diagnostics/
mod.rs1#[cfg(feature = "std")]
8use std::collections::HashMap;
9
10#[cfg(not(feature = "std"))]
11use hashbrown::HashMap;
12
13use crate::ParameterDiagnostics;
14
15#[derive(Debug, Clone)]
17pub struct ModuleInfo {
18 pub name: String,
20 pub training: bool,
22 pub parameter_count: usize,
24 pub trainable_parameter_count: usize,
26 pub memory_usage_bytes: usize,
28 pub has_children: bool,
30 pub children_count: usize,
32}
33
34impl core::fmt::Display for ModuleInfo {
35 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
36 writeln!(f, "Module: {}", self.name)?;
37 writeln!(f, " Training: {}", self.training)?;
38 writeln!(
39 f,
40 " Parameters: {} ({} trainable)",
41 self.parameter_count, self.trainable_parameter_count
42 )?;
43 writeln!(
44 f,
45 " Memory: {:.2} MB",
46 self.memory_usage_bytes as f64 / (1024.0 * 1024.0)
47 )?;
48 writeln!(
49 f,
50 " Children: {} (has_children: {})",
51 self.children_count, self.has_children
52 )?;
53 Ok(())
54 }
55}
56
57#[derive(Debug, Clone)]
59pub struct ModuleDiagnostics {
60 pub module_info: ModuleInfo,
62 pub issues: Vec<String>,
64 pub warnings: Vec<String>,
66 pub parameter_diagnostics: HashMap<String, ParameterDiagnostics>,
68}
69
70impl ModuleDiagnostics {
71 pub fn has_issues(&self) -> bool {
73 !self.issues.is_empty()
74 }
75
76 pub fn has_warnings(&self) -> bool {
78 !self.warnings.is_empty()
79 }
80
81 pub fn is_healthy(&self) -> bool {
83 !self.has_issues() && !self.has_warnings()
84 }
85
86 pub fn health_summary(&self) -> String {
88 if self.is_healthy() {
89 "Healthy".to_string()
90 } else {
91 format!(
92 "{} issues, {} warnings",
93 self.issues.len(),
94 self.warnings.len()
95 )
96 }
97 }
98}
99
100impl core::fmt::Display for ModuleDiagnostics {
101 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
102 writeln!(f, "Module Diagnostics:")?;
103 writeln!(f, "{}", self.module_info)?;
104
105 if !self.issues.is_empty() {
106 writeln!(f, "Issues:")?;
107 for issue in &self.issues {
108 writeln!(f, " ❌ {}", issue)?;
109 }
110 }
111
112 if !self.warnings.is_empty() {
113 writeln!(f, "Warnings:")?;
114 for warning in &self.warnings {
115 writeln!(f, " ⚠️ {}", warning)?;
116 }
117 }
118
119 if self.is_healthy() {
120 writeln!(f, "✅ Module appears healthy")?;
121 }
122
123 writeln!(f, "Parameter Health:")?;
124 for (name, param_diag) in &self.parameter_diagnostics {
125 if param_diag.issues.is_empty() && param_diag.warnings.is_empty() {
126 writeln!(f, " ✅ {}: Healthy", name)?;
127 } else {
128 writeln!(
129 f,
130 " ⚠️ {}: {} issues, {} warnings",
131 name,
132 param_diag.issues.len(),
133 param_diag.warnings.len()
134 )?;
135 }
136 }
137
138 Ok(())
139 }
140}