use super::{config::QuantizationParameters, quality_assessment::QualityMetrics};
use std::time::Duration;
use torsh_tensor::Tensor;
#[derive(Debug, Clone)]
pub struct AdaptiveQuantizationResult {
pub quantized_tensor: Tensor,
pub parameters: QuantizationParameters,
pub quality_metrics: QualityMetrics,
pub pattern_info: Option<String>,
pub adaptation_info: Option<AdaptationInfo>,
pub runtime_stats: RuntimeStatistics,
}
#[derive(Debug, Clone)]
pub struct AdaptationInfo {
pub original_params: QuantizationParameters,
pub adapted_params: QuantizationParameters,
pub quality_improvement: f32,
pub adaptation_time: Duration,
}
#[derive(Debug, Clone)]
pub struct QuantizationResult {
pub quantized_tensor: Tensor,
pub scale: f32,
pub zero_point: i32,
}
#[derive(Debug, Clone)]
pub struct RuntimeStatistics {
pub total_operations: usize,
pub adaptation_events: usize,
pub avg_quality: f32,
pub performance_improvements: Vec<f32>,
pub energy_savings: Vec<f32>,
pub prediction_accuracy: f32,
}
impl Default for RuntimeStatistics {
fn default() -> Self {
Self {
total_operations: 0,
adaptation_events: 0,
avg_quality: 1.0,
performance_improvements: Vec::new(),
energy_savings: Vec::new(),
prediction_accuracy: 0.0,
}
}
}
#[derive(Debug, Clone)]
pub struct OptimizationRecommendation {
pub category: String,
pub suggestion: String,
pub priority: RecommendationPriority,
pub expected_improvement: f32,
}
#[derive(Debug, Clone, PartialEq)]
pub enum RecommendationPriority {
Low,
Medium,
High,
Critical,
}
impl AdaptiveQuantizationResult {
pub fn generate_report(&self) -> String {
format!(
"🤖 Adaptive Quantization Report\n\
================================\n\
\n\
🔧 Quantization Parameters:\n\
• Scale: {:.6}\n\
• Zero Point: {}\n\
• Bit Width: {}\n\
• Scheme: {}\n\
\n\
📊 Quality Metrics:\n\
• SNR: {:.2} dB\n\
• MSE: {:.6}\n\
• PSNR: {:.2} dB\n\
• Perceptual Score: {:.4}\n\
• SSIM: {:.4}\n\
\n\
🎯 Pattern Information:\n\
• Detected Pattern: {}\n\
\n\
âš¡ Adaptation Details:\n\
{}\n\
📈 Runtime Statistics:\n\
• Total Operations: {}\n\
• Adaptation Events: {}\n\
• Average Quality: {:.4}\n\
• Prediction Accuracy: {:.4}\n\
\n\
💡 Performance Insights:\n\
• Adaptation Rate: {:.2}%\n\
• Quality Consistency: {}\n\
• Pattern Recognition: {}\n",
self.parameters.scale,
self.parameters.zero_point,
self.parameters.bit_width,
self.parameters.scheme,
self.quality_metrics.snr,
self.quality_metrics.mse,
self.quality_metrics.psnr,
self.quality_metrics.perceptual_score,
self.quality_metrics.ssim,
self.pattern_info.as_ref().unwrap_or(&"Unknown".to_string()),
self.format_adaptation_info(),
self.runtime_stats.total_operations,
self.runtime_stats.adaptation_events,
self.runtime_stats.avg_quality,
self.runtime_stats.prediction_accuracy,
self.calculate_adaptation_rate(),
self.assess_quality_consistency(),
self.assess_pattern_recognition_effectiveness()
)
}
fn format_adaptation_info(&self) -> String {
match &self.adaptation_info {
Some(info) => {
format!(
"• Adaptation Performed: Yes\n\
• Quality Improvement: {:.4}\n\
• Adaptation Time: {:.2}ms\n\
• Parameter Changes:\n\
- Scale: {:.6} → {:.6}\n\
- Zero Point: {} → {}\n\
- Bit Width: {} → {}",
info.quality_improvement,
info.adaptation_time.as_secs_f32() * 1000.0,
info.original_params.scale,
info.adapted_params.scale,
info.original_params.zero_point,
info.adapted_params.zero_point,
info.original_params.bit_width,
info.adapted_params.bit_width
)
}
None => "• Adaptation Performed: No".to_string(),
}
}
fn calculate_adaptation_rate(&self) -> f32 {
if self.runtime_stats.total_operations == 0 {
0.0
} else {
(self.runtime_stats.adaptation_events as f32
/ self.runtime_stats.total_operations as f32)
* 100.0
}
}
fn assess_quality_consistency(&self) -> String {
match self.runtime_stats.avg_quality {
q if q >= 0.95 => "Excellent".to_string(),
q if q >= 0.85 => "Good".to_string(),
q if q >= 0.70 => "Fair".to_string(),
_ => "Needs Improvement".to_string(),
}
}
fn assess_pattern_recognition_effectiveness(&self) -> String {
match &self.pattern_info {
Some(pattern) if pattern != "unknown" => "Effective".to_string(),
Some(_) => "Limited".to_string(),
None => "Disabled".to_string(),
}
}
pub fn generate_json_report(&self) -> String {
format!(
r#"{{
"adaptive_quantization_report": {{
"parameters": {{
"scale": {:.6},
"zero_point": {},
"bit_width": {},
"scheme": "{}"
}},
"quality_metrics": {{
"snr": {:.2},
"mse": {:.6},
"psnr": {:.2},
"perceptual_score": {:.4},
"ssim": {:.4}
}},
"pattern_info": {{
"detected_pattern": "{}"
}},
"adaptation_info": {},
"runtime_stats": {{
"total_operations": {},
"adaptation_events": {},
"avg_quality": {:.4},
"prediction_accuracy": {:.4}
}},
"performance_metrics": {{
"adaptation_rate_percent": {:.2},
"quality_consistency": "{}",
"pattern_recognition": "{}"
}}
}}
}}"#,
self.parameters.scale,
self.parameters.zero_point,
self.parameters.bit_width,
self.parameters.scheme,
self.quality_metrics.snr,
self.quality_metrics.mse,
self.quality_metrics.psnr,
self.quality_metrics.perceptual_score,
self.quality_metrics.ssim,
self.pattern_info.as_ref().unwrap_or(&"unknown".to_string()),
self.format_adaptation_info_json(),
self.runtime_stats.total_operations,
self.runtime_stats.adaptation_events,
self.runtime_stats.avg_quality,
self.runtime_stats.prediction_accuracy,
self.calculate_adaptation_rate(),
self.assess_quality_consistency(),
self.assess_pattern_recognition_effectiveness()
)
}
fn format_adaptation_info_json(&self) -> String {
match &self.adaptation_info {
Some(info) => {
format!(
r#"{{
"performed": true,
"quality_improvement": {:.4},
"adaptation_time_ms": {:.2},
"original_params": {{
"scale": {:.6},
"zero_point": {},
"bit_width": {}
}},
"adapted_params": {{
"scale": {:.6},
"zero_point": {},
"bit_width": {}
}}
}}"#,
info.quality_improvement,
info.adaptation_time.as_secs_f32() * 1000.0,
info.original_params.scale,
info.original_params.zero_point,
info.original_params.bit_width,
info.adapted_params.scale,
info.adapted_params.zero_point,
info.adapted_params.bit_width
)
}
None => r#"{"performed": false}"#.to_string(),
}
}
pub fn generate_csv_line(&self) -> String {
format!(
"{:.6},{},{},{},{:.2},{:.6},{:.2},{:.4},{:.4},{},{},{},{:.4},{:.4},{:.2}",
self.parameters.scale,
self.parameters.zero_point,
self.parameters.bit_width,
self.parameters.scheme,
self.quality_metrics.snr,
self.quality_metrics.mse,
self.quality_metrics.psnr,
self.quality_metrics.perceptual_score,
self.quality_metrics.ssim,
self.pattern_info.as_ref().unwrap_or(&"unknown".to_string()),
self.adaptation_info.is_some(),
self.runtime_stats.total_operations,
self.runtime_stats.avg_quality,
self.runtime_stats.prediction_accuracy,
self.calculate_adaptation_rate()
)
}
pub fn csv_header() -> String {
"scale,zero_point,bit_width,scheme,snr,mse,psnr,perceptual_score,ssim,pattern,adapted,operations,avg_quality,prediction_accuracy,adaptation_rate".to_string()
}
}
impl RuntimeStatistics {
pub fn update_avg_quality(&mut self, new_quality: f32) {
if self.total_operations == 0 {
self.avg_quality = new_quality;
} else {
self.avg_quality = (self.avg_quality * (self.total_operations - 1) as f32
+ new_quality)
/ self.total_operations as f32;
}
}
pub fn add_performance_improvement(&mut self, improvement: f32) {
self.performance_improvements.push(improvement);
if self.performance_improvements.len() > 100 {
self.performance_improvements.remove(0);
}
}
pub fn add_energy_savings(&mut self, savings: f32) {
self.energy_savings.push(savings);
if self.energy_savings.len() > 100 {
self.energy_savings.remove(0);
}
}
pub fn avg_performance_improvement(&self) -> f32 {
if self.performance_improvements.is_empty() {
0.0
} else {
self.performance_improvements.iter().sum::<f32>()
/ self.performance_improvements.len() as f32
}
}
pub fn avg_energy_savings(&self) -> f32 {
if self.energy_savings.is_empty() {
0.0
} else {
self.energy_savings.iter().sum::<f32>() / self.energy_savings.len() as f32
}
}
}