Skip to main content

torsh_sparse/performance_tools/
mod.rs

1//! # Unified Performance Tools Interface
2//!
3//! This module provides a comprehensive performance analysis and profiling system for sparse
4//! tensor operations. The system is built on a modular architecture with specialized components
5//! for different aspects of performance analysis.
6//!
7//! ## Architecture Overview
8//!
9//! The performance tools system is organized into 5 specialized modules:
10//!
11//! - **core**: Foundation profiling infrastructure with measurement and benchmarking
12//! - **memory**: Memory analysis, compression tracking, and cache performance
13//! - **reporting**: Statistics aggregation, report generation, and performance analysis
14//! - **optimization**: Auto-tuning, hardware optimization, and intelligent recommendations
15//! - **export**: Data export, visualization, and TensorBoard integration
16//!
17//! ## Quick Start
18//!
19//! ```rust,ignore
20//! use torsh_sparse::performance_tools::{SparseProfiler, BenchmarkConfig};
21//!
22//! // Create a profiler with custom configuration
23//! let config = BenchmarkConfig::thorough();
24//! let mut profiler = SparseProfiler::new(config);
25//!
26//! // Profile sparse format conversion
27//! let measurements = profiler.benchmark_format_conversion(&dense_matrix)?;
28//!
29//! // Generate comprehensive report
30//! let mut report = PerformanceReport::new();
31//! report.add_measurements(&measurements);
32//! println!("{}", report);
33//! ```
34//!
35//! ## Advanced Usage
36//!
37//! ```rust,ignore
38//! use torsh_sparse::performance_tools::{
39//!     SparseProfiler, AutoTuner, TrendAnalyzer, PerformanceExporter,
40//!     OptimizationStrategy, InputCharacteristics, DistributionPattern
41//! };
42//!
43//! // Auto-tune sparse format selection
44//! let mut tuner = AutoTuner::new().with_strategy(OptimizationStrategy::Speed);
45//! let characteristics = InputCharacteristics {
46//!     dimensions: (10000, 10000),
47//!     sparsity: 0.95,
48//!     distribution_pattern: DistributionPattern::Random,
49//!     operation_types: vec![OperationType::MatrixVector],
50//!     memory_budget: Some(1024 * 1024 * 1024), // 1GB
51//! };
52//! let tuning_result = tuner.find_optimal_format(&characteristics)?;
53//!
54//! // Analyze performance trends
55//! let mut trend_analyzer = TrendAnalyzer::new();
56//! let regressions = trend_analyzer.detect_regressions(10.0); // 10% threshold
57//!
58//! // Export to various formats
59//! let csv_data = PerformanceExporter::to_csv(&report)?;
60//! let json_data = PerformanceExporter::to_json(&report)?;
61//! ```
62//!
63//! ## Performance Considerations
64//!
65//! - **Memory-efficient profiling**: Uses lazy evaluation and streaming for large datasets
66//! - **Hardware optimization**: Leverages SIMD, cache optimization, and NUMA awareness
67//! - **Adaptive algorithms**: Auto-tuning based on data characteristics and hardware capabilities
68//! - **Minimal overhead**: Optimized measurement infrastructure with configurable precision
69//! - **Scalable analysis**: Supports both single-threaded and distributed profiling scenarios
70
71// Framework infrastructure - components designed for future use
72#![allow(dead_code)]
73// Re-export all modules for internal organization
74pub mod core;
75pub mod export;
76pub mod memory;
77pub mod optimization;
78pub mod reporting;
79
80// Core profiling infrastructure
81pub use core::{BenchmarkConfig, PerformanceMeasurement, SparseProfiler};
82
83// Memory analysis capabilities
84pub use memory::{
85    analyze_sparse_memory, benchmark_cache_performance, CachePerformanceResult,
86    MemoryAccessPattern, MemoryAnalysis, MemoryBreakdown, MemoryTracker, MemoryUsageResult,
87};
88
89// Reporting and statistics
90pub use reporting::{
91    MemoryStatistics, MetricStatistics, OperationStatistics, PerformanceReport, PerformanceSummary,
92    StatisticsCollector,
93};
94
95// Auto-tuning and optimization
96pub use optimization::{
97    AutoTuner, CacheInfo, CpuInfo, DistributionPattern, HardwareBenchmark, InputCharacteristics,
98    MemoryInfo, OperationType, OptimizationStrategy, SystemCapabilityReport, SystemInfo,
99    TuningResult,
100};
101
102// Export and visualization
103pub use export::{
104    PerformanceExporter, PlotData, TensorBoardExporter, TrendAnalysis, TrendAnalyzer,
105    TrendDirection,
106};
107
108use crate::{SparseTensor, TorshError, TorshResult};
109
110/// Convenience function to create a default profiler with balanced configuration
111///
112/// This is the recommended starting point for most performance analysis tasks.
113/// It uses a balanced configuration that provides good accuracy without excessive overhead.
114///
115/// # Examples
116///
117/// ```rust
118/// use torsh_sparse::performance_tools::default_profiler;
119///
120/// let mut profiler = default_profiler();
121/// // Use profiler for benchmarking...
122/// ```
123pub fn default_profiler() -> SparseProfiler {
124    SparseProfiler::new(BenchmarkConfig::default())
125}
126
127/// Create a fast profiler for quick performance checks
128///
129/// This configuration minimizes overhead and is suitable for quick performance
130/// checks during development or CI/CD pipelines.
131///
132/// # Examples
133///
134/// ```rust
135/// use torsh_sparse::performance_tools::fast_profiler;
136///
137/// let mut profiler = fast_profiler();
138/// // Quick performance check...
139/// ```
140pub fn fast_profiler() -> SparseProfiler {
141    SparseProfiler::new(BenchmarkConfig::fast())
142}
143
144/// Create a thorough profiler for detailed analysis
145///
146/// This configuration provides maximum detail and accuracy for comprehensive
147/// performance analysis and optimization work.
148///
149/// # Examples
150///
151/// ```rust
152/// use torsh_sparse::performance_tools::thorough_profiler;
153///
154/// let mut profiler = thorough_profiler();
155/// // Detailed performance analysis...
156/// ```
157pub fn thorough_profiler() -> SparseProfiler {
158    SparseProfiler::new(BenchmarkConfig::thorough())
159}
160
161/// Create a memory-focused profiler for memory analysis
162///
163/// This configuration emphasizes memory usage tracking and analysis,
164/// suitable for memory optimization tasks.
165///
166/// # Examples
167///
168/// ```rust
169/// use torsh_sparse::performance_tools::memory_profiler;
170///
171/// let mut profiler = memory_profiler();
172/// // Memory-focused analysis...
173/// ```
174pub fn memory_profiler() -> SparseProfiler {
175    SparseProfiler::new(BenchmarkConfig::memory_focused())
176}
177
178/// Comprehensive performance analysis function
179///
180/// This function provides a one-stop solution for complete performance analysis
181/// of sparse tensor operations, combining profiling, auto-tuning, and reporting.
182///
183/// # Arguments
184///
185/// * `sparse_tensors` - Collection of sparse tensors to analyze
186/// * `operations` - Operations to benchmark
187/// * `export_path` - Optional path for exporting results
188///
189/// # Returns
190///
191/// Comprehensive analysis report with recommendations
192///
193/// # Examples
194///
195/// ```rust,ignore
196/// use torsh_sparse::performance_tools::comprehensive_analysis;
197///
198/// let tensors = vec![&coo_tensor, &csr_tensor];
199/// let operations = vec!["matmul", "transpose"];
200/// let analysis = comprehensive_analysis(&tensors, &operations, Some("results/"))?;
201/// ```
202pub fn comprehensive_analysis(
203    sparse_tensors: &[&dyn SparseTensor],
204    operations: &[&str],
205    export_path: Option<&str>,
206) -> TorshResult<ComprehensiveAnalysisReport> {
207    let mut profiler = default_profiler();
208    let mut auto_tuner = AutoTuner::new();
209    let mut hardware_benchmark = HardwareBenchmark::new();
210    let _trend_analyzer = TrendAnalyzer::new();
211    let mut exporter = TensorBoardExporter::new();
212
213    // 1. Hardware capability analysis
214    let system_capabilities = hardware_benchmark.analyze_system_capabilities()?;
215
216    // 2. Memory analysis for each tensor
217    let mut memory_analyses = Vec::new();
218    for tensor in sparse_tensors {
219        let analysis = analyze_sparse_memory(*tensor)?;
220        memory_analyses.push(analysis);
221    }
222
223    // 3. Performance profiling
224    let mut all_measurements = Vec::new();
225    for tensor in sparse_tensors {
226        // Auto-tune format selection
227        let characteristics = infer_characteristics(*tensor);
228        let _tuning_result = auto_tuner.find_optimal_format(&characteristics)?;
229
230        // Profile operations based on auto-tuning results
231        for &operation in operations {
232            let measurements = match operation {
233                "matmul" => {
234                    if sparse_tensors.len() >= 2 {
235                        profiler.benchmark_sparse_matmul(*tensor, sparse_tensors[1])?
236                    } else {
237                        continue;
238                    }
239                }
240                "format_conversion" => {
241                    // Create a dummy dense matrix for conversion benchmarking
242                    let shape = tensor.shape();
243                    let dummy_dense = create_dummy_dense_matrix(shape.dims()[0], shape.dims()[1])?;
244                    profiler.benchmark_format_conversion(&dummy_dense)?
245                }
246                "dense_to_sparse" => {
247                    let shape = tensor.shape();
248                    let dummy_dense = create_dummy_dense_matrix(shape.dims()[0], shape.dims()[1])?;
249                    profiler.benchmark_dense_to_sparse(&dummy_dense, 0.01)?
250                }
251                _ => continue,
252            };
253            all_measurements.extend(measurements);
254        }
255    }
256
257    // 4. Generate comprehensive report
258    let mut report = PerformanceReport::new();
259    report.add_measurements(&profiler.measurements);
260
261    // Add memory analyses to the report
262    for analysis in &memory_analyses {
263        report.add_memory_analysis(analysis.clone());
264    }
265
266    // Add metadata about the analysis
267    report.add_metadata("analysis_type".to_string(), "comprehensive".to_string());
268    report.add_metadata(
269        "tensors_analyzed".to_string(),
270        sparse_tensors.len().to_string(),
271    );
272    report.add_metadata("operations_profiled".to_string(), operations.join(","));
273    report.add_metadata(
274        "memory_analyses_count".to_string(),
275        memory_analyses.len().to_string(),
276    );
277
278    // 5. Export results if path provided
279    if let Some(path) = export_path {
280        // Export comprehensive report to CSV
281        let csv_data = PerformanceExporter::to_csv(&report)?;
282        std::fs::write(format!("{}/performance_report.csv", path), csv_data)
283            .map_err(|e| TorshError::IoError(format!("Failed to write CSV report: {}", e)))?;
284
285        // Export comprehensive report to JSON
286        let json_data = PerformanceExporter::to_json(&report)?;
287        std::fs::write(format!("{}/performance_report.json", path), json_data)
288            .map_err(|e| TorshError::IoError(format!("Failed to write JSON report: {}", e)))?;
289
290        // Export detailed analysis report
291        exporter.export_report(&report, path)?;
292
293        // Export memory analyses separately for detailed analysis
294        for (i, analysis) in memory_analyses.iter().enumerate() {
295            let analysis_path = format!("{}/memory_analysis_{}.txt", path, i);
296            let analysis_text = format!("{:#?}", analysis);
297            std::fs::write(&analysis_path, analysis_text).map_err(|e| {
298                TorshError::IoError(format!("Failed to write memory analysis: {}", e))
299            })?;
300        }
301    }
302
303    // 6. Generate optimization recommendations
304    let auto_tuning_recommendations = auto_tuner.get_recommendations();
305    let hardware_recommendations = system_capabilities.recommendations.clone();
306    let performance_recommendations = report.get_recommendations();
307
308    // Generate enhanced memory-aware recommendations
309    let memory_budget = None; // Could be passed as parameter in future
310    let operations_strings: Vec<String> = operations.iter().map(|s| s.to_string()).collect();
311    let memory_recommendations =
312        crate::performance_tools::memory::generate_memory_optimization_recommendations(
313            &memory_analyses,
314            memory_budget,
315            &operations_strings,
316        );
317
318    // Combine all recommendations into comprehensive analysis
319    let mut all_recommendations = Vec::new();
320    all_recommendations.extend(auto_tuning_recommendations.clone());
321    all_recommendations.extend(hardware_recommendations.clone());
322    all_recommendations.extend(performance_recommendations.clone());
323    all_recommendations.extend(memory_recommendations.clone());
324
325    // Create comprehensive analysis report
326    let comprehensive_report = ComprehensiveAnalysisReport {
327        performance_report: report,
328        memory_analyses,
329        system_capabilities,
330        auto_tuning_recommendations,
331        hardware_recommendations,
332        performance_recommendations,
333        export_path: export_path.map(|p| p.to_string()),
334    };
335
336    Ok(comprehensive_report)
337}
338
339/// Result of comprehensive performance analysis
340#[derive(Debug, Clone)]
341pub struct ComprehensiveAnalysisReport {
342    /// Detailed performance report with operation statistics
343    pub performance_report: PerformanceReport,
344    /// Memory analysis results for each tensor
345    pub memory_analyses: Vec<MemoryAnalysis>,
346    /// System capability analysis
347    pub system_capabilities: SystemCapabilityReport,
348    /// Auto-tuning recommendations
349    pub auto_tuning_recommendations: Vec<String>,
350    /// Hardware-specific recommendations
351    pub hardware_recommendations: Vec<String>,
352    /// Performance optimization recommendations
353    pub performance_recommendations: Vec<String>,
354    /// Export path if results were exported
355    pub export_path: Option<String>,
356}
357
358impl ComprehensiveAnalysisReport {
359    /// Get all recommendations in a single list
360    pub fn all_recommendations(&self) -> Vec<String> {
361        let mut all_recs = Vec::new();
362        all_recs.extend(self.auto_tuning_recommendations.clone());
363        all_recs.extend(self.hardware_recommendations.clone());
364        all_recs.extend(self.performance_recommendations.clone());
365        all_recs
366    }
367
368    /// Get a summary of the analysis
369    pub fn summary(&self) -> String {
370        format!(
371            "Performance Analysis Summary:\n\
372             - Total measurements: {}\n\
373             - Operations analyzed: {}\n\
374             - Memory analyses: {}\n\
375             - Recommendations: {}\n\
376             - Export path: {}",
377            self.performance_report.total_measurements,
378            self.performance_report.operation_count,
379            self.memory_analyses.len(),
380            self.all_recommendations().len(),
381            self.export_path.as_deref().unwrap_or("None")
382        )
383    }
384
385    /// Get the most critical recommendations
386    ///
387    /// Returns up to 5 most important recommendations based on potential impact
388    pub fn top_recommendations(&self) -> Vec<String> {
389        let _all_recs = self.all_recommendations();
390
391        // Prioritize hardware and auto-tuning recommendations as they typically have higher impact
392        let mut prioritized = Vec::new();
393
394        // Add hardware recommendations first (usually most impactful)
395        prioritized.extend(self.hardware_recommendations.iter().take(3).cloned());
396
397        // Add auto-tuning recommendations
398        prioritized.extend(self.auto_tuning_recommendations.iter().take(2).cloned());
399
400        // Fill remaining slots with performance recommendations if space available
401        let remaining_slots = 5usize.saturating_sub(prioritized.len());
402        prioritized.extend(
403            self.performance_recommendations
404                .iter()
405                .take(remaining_slots)
406                .cloned(),
407        );
408
409        prioritized
410    }
411
412    /// Get performance bottlenecks analysis
413    ///
414    /// Analyzes performance data to identify the most significant bottlenecks
415    pub fn bottleneck_analysis(&self) -> Vec<String> {
416        let mut bottlenecks = Vec::new();
417
418        // Analyze operation statistics to find bottlenecks
419        if let Some((slowest_op, _)) = self
420            .performance_report
421            .operation_statistics
422            .iter()
423            .max_by_key(|(_, stats)| stats.max_time)
424        {
425            bottlenecks.push(format!(
426                "Slowest operation: {} (consider optimization)",
427                slowest_op
428            ));
429        }
430
431        // Analyze memory efficiency
432        let avg_compression_ratio: f32 = self
433            .memory_analyses
434            .iter()
435            .map(|analysis| analysis.compression_ratio)
436            .sum::<f32>()
437            / self.memory_analyses.len() as f32;
438
439        if avg_compression_ratio < 2.0 {
440            bottlenecks.push(
441                "Low compression ratio detected (consider different sparse format)".to_string(),
442            );
443        }
444
445        // Check for high memory overhead
446        let high_overhead_count = self
447            .memory_analyses
448            .iter()
449            .filter(|analysis| analysis.overhead_per_nnz > 16.0) // More than 16 bytes per nnz is high
450            .count();
451
452        if high_overhead_count > 0 {
453            bottlenecks.push(format!(
454                "High memory overhead detected in {} tensor(s) (consider format optimization)",
455                high_overhead_count
456            ));
457        }
458
459        bottlenecks
460    }
461
462    /// Generate optimization priority matrix
463    ///
464    /// Returns recommendations sorted by potential impact and implementation difficulty
465    pub fn optimization_priorities(&self) -> Vec<(String, String, String)> {
466        let mut priorities = Vec::new();
467
468        // Hardware recommendations - usually high impact, medium difficulty
469        for rec in &self.hardware_recommendations {
470            priorities.push((rec.clone(), "High".to_string(), "Medium".to_string()));
471        }
472
473        // Auto-tuning recommendations - medium impact, low difficulty
474        for rec in &self.auto_tuning_recommendations {
475            priorities.push((rec.clone(), "Medium".to_string(), "Low".to_string()));
476        }
477
478        // Performance recommendations - varies
479        for rec in &self.performance_recommendations {
480            priorities.push((rec.clone(), "Medium".to_string(), "Medium".to_string()));
481        }
482
483        priorities
484    }
485}
486
487/// Quick performance check for a single sparse tensor
488///
489/// This function provides a simplified interface for quick performance
490/// assessment of a single sparse tensor.
491///
492/// # Arguments
493///
494/// * `sparse_tensor` - Sparse tensor to analyze
495///
496/// # Returns
497///
498/// Quick performance summary
499pub fn quick_performance_check(
500    sparse_tensor: &dyn SparseTensor,
501) -> TorshResult<QuickPerformanceResult> {
502    let mut profiler = fast_profiler();
503
504    // Memory analysis
505    let memory_analysis = analyze_sparse_memory(sparse_tensor)?;
506
507    // Basic profiling
508    let shape = sparse_tensor.shape();
509    let dummy_dense = create_dummy_dense_matrix(shape.dims()[0], shape.dims()[1])?;
510    let format_measurements = profiler.benchmark_format_conversion(&dummy_dense)?;
511
512    // Generate actual performance report from measurements
513    let mut report = PerformanceReport::new();
514    report.add_measurements(&format_measurements);
515    report.add_memory_analysis(memory_analysis.clone());
516    let summary = report.performance_summary();
517
518    // Generate recommendations before moving memory_analysis
519    let recommendations = generate_quick_recommendations(&memory_analysis, &summary);
520
521    Ok(QuickPerformanceResult {
522        memory_analysis,
523        performance_summary: summary,
524        format_conversion_time: format_measurements
525            .iter()
526            .find(|m| {
527                m.operation
528                    .contains(&format!("{:?}", sparse_tensor.format()))
529            })
530            .map(|m| m.duration)
531            .unwrap_or_default(),
532        recommendations,
533    })
534}
535
536/// Result of quick performance check
537#[derive(Debug, Clone)]
538pub struct QuickPerformanceResult {
539    /// Memory analysis of the tensor
540    pub memory_analysis: MemoryAnalysis,
541    /// Performance summary
542    pub performance_summary: PerformanceSummary,
543    /// Format conversion time
544    pub format_conversion_time: std::time::Duration,
545    /// Quick recommendations
546    pub recommendations: Vec<String>,
547}
548
549impl std::fmt::Display for QuickPerformanceResult {
550    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
551        writeln!(f, "=== Quick Performance Check ===")?;
552        writeln!(f, "Format: {:?}", self.memory_analysis.format)?;
553        writeln!(
554            f,
555            "Compression Ratio: {:.1}x",
556            self.memory_analysis.compression_ratio
557        )?;
558        writeln!(
559            f,
560            "Memory Efficiency: {}",
561            self.memory_analysis.memory_efficiency_rating()
562        )?;
563        writeln!(
564            f,
565            "Performance Grade: {}",
566            self.performance_summary.performance_grade()
567        )?;
568        writeln!(
569            f,
570            "Format Conversion: {:.3}ms",
571            self.format_conversion_time.as_secs_f64() * 1000.0
572        )?;
573        writeln!(f)?;
574        writeln!(f, "Recommendations:")?;
575        for rec in &self.recommendations {
576            writeln!(f, "  • {}", rec)?;
577        }
578        Ok(())
579    }
580}
581
582// Helper functions
583
584/// Infer characteristics from a sparse tensor for auto-tuning
585fn infer_characteristics(sparse_tensor: &dyn SparseTensor) -> InputCharacteristics {
586    let shape = sparse_tensor.shape();
587    let nnz = sparse_tensor.nnz();
588    let total_elements = shape.dims()[0] * shape.dims()[1];
589    let sparsity = 1.0 - (nnz as f64 / total_elements as f64);
590
591    // Infer distribution pattern based on sparsity and format
592    let distribution_pattern = match sparse_tensor.format() {
593        crate::SparseFormat::Csr => {
594            if sparsity > 0.95 {
595                DistributionPattern::Random
596            } else {
597                DistributionPattern::RowClustered
598            }
599        }
600        crate::SparseFormat::Csc => DistributionPattern::ColumnClustered,
601        crate::SparseFormat::Coo => DistributionPattern::Random,
602        _ => DistributionPattern::Random, // Default case
603    };
604
605    // Default operation types
606    let operation_types = vec![OperationType::MatrixVector, OperationType::ElementWise];
607
608    InputCharacteristics {
609        dimensions: (shape.dims()[0], shape.dims()[1]),
610        sparsity,
611        distribution_pattern,
612        operation_types,
613        memory_budget: None,
614    }
615}
616
617/// Create a dummy dense matrix for benchmarking
618fn create_dummy_dense_matrix(rows: usize, cols: usize) -> TorshResult<crate::Tensor> {
619    use torsh_core::{DType, Shape};
620
621    // Create a simple dense matrix filled with ones
622    let shape = Shape::new(vec![rows.min(100), cols.min(100)]); // Limit size for performance
623    let device = torsh_core::DeviceType::Cpu;
624    let _dtype = DType::F32;
625
626    // This is a simplified implementation - in practice, you'd use the actual
627    // tensor creation APIs from torsh-tensor
628    crate::Tensor::ones(shape.dims(), device)
629}
630
631/// Generate quick recommendations based on analysis
632fn generate_quick_recommendations(
633    memory_analysis: &MemoryAnalysis,
634    performance_summary: &PerformanceSummary,
635) -> Vec<String> {
636    let mut recommendations = Vec::new();
637
638    // Memory-based recommendations
639    if memory_analysis.compression_ratio < 2.0 {
640        recommendations
641            .push("Consider using a denser format or different sparsity threshold".to_string());
642    } else if memory_analysis.compression_ratio > 10.0 {
643        recommendations
644            .push("Excellent compression achieved - current format is optimal".to_string());
645    }
646
647    // Performance-based recommendations
648    match performance_summary.performance_grade().as_str() {
649        "A" => recommendations.push("Excellent performance - no optimization needed".to_string()),
650        "B" => recommendations.push("Good performance - minor optimizations possible".to_string()),
651        "C" => recommendations.push("Fair performance - consider format optimization".to_string()),
652        "D" | "F" => {
653            recommendations.push("Poor performance - significant optimization needed".to_string())
654        }
655        _ => {}
656    }
657
658    // Consistency recommendations
659    if performance_summary.consistency_score < 0.7 {
660        recommendations
661            .push("Performance inconsistency detected - investigate system load".to_string());
662    }
663
664    if recommendations.is_empty() {
665        recommendations.push("Performance appears optimal".to_string());
666    }
667
668    recommendations
669}
670
671#[cfg(test)]
672mod tests {
673    use super::*;
674    use crate::{CooTensor, SparseFormat};
675    use torsh_core::Shape;
676
677    fn create_test_sparse_tensor() -> CooTensor {
678        let row_indices = vec![0, 1, 2];
679        let col_indices = vec![0, 1, 2];
680        let values = vec![1.0, 2.0, 3.0];
681        let shape = Shape::new(vec![3, 3]);
682        CooTensor::new(row_indices, col_indices, values, shape).expect("Coo Tensor should succeed")
683    }
684
685    #[test]
686    fn test_default_profiler() {
687        let profiler = default_profiler();
688        assert_eq!(profiler.config.warmup_iterations, 3);
689        assert_eq!(profiler.config.measured_iterations, 10);
690    }
691
692    #[test]
693    fn test_fast_profiler() {
694        let profiler = fast_profiler();
695        assert_eq!(profiler.config.warmup_iterations, 1);
696        assert_eq!(profiler.config.measured_iterations, 3);
697        assert!(!profiler.config.collect_memory);
698    }
699
700    #[test]
701    fn test_thorough_profiler() {
702        let profiler = thorough_profiler();
703        assert_eq!(profiler.config.warmup_iterations, 5);
704        assert_eq!(profiler.config.measured_iterations, 20);
705        assert!(profiler.config.collect_memory);
706    }
707
708    #[test]
709    fn test_memory_profiler() {
710        let profiler = memory_profiler();
711        assert!(profiler.config.collect_memory);
712        assert!(profiler.config.gc_between_iterations);
713    }
714
715    #[test]
716    fn test_quick_performance_check() {
717        let tensor = create_test_sparse_tensor();
718        let result = quick_performance_check(&tensor);
719
720        assert!(result.is_ok());
721        let quick_result = result.expect("operation should succeed");
722
723        assert_eq!(quick_result.memory_analysis.format, SparseFormat::Coo);
724        assert_eq!(quick_result.memory_analysis.nnz, 3);
725        assert!(!quick_result.recommendations.is_empty());
726    }
727
728    #[test]
729    fn test_quick_performance_result_display() {
730        let tensor = create_test_sparse_tensor();
731        let result =
732            quick_performance_check(&tensor).expect("quick performance check should succeed");
733
734        let display_string = format!("{}", result);
735        assert!(display_string.contains("Quick Performance Check"));
736        assert!(display_string.contains("Format:"));
737        assert!(display_string.contains("Compression Ratio:"));
738        assert!(display_string.contains("Recommendations:"));
739    }
740
741    #[test]
742    fn test_infer_characteristics() {
743        let tensor = create_test_sparse_tensor();
744        let characteristics = infer_characteristics(&tensor);
745
746        assert_eq!(characteristics.dimensions, (3, 3));
747        assert!(characteristics.sparsity > 0.5); // 3 non-zeros out of 9 = 66.7% sparse
748        assert!(characteristics
749            .operation_types
750            .contains(&OperationType::MatrixVector));
751    }
752
753    #[test]
754    fn test_generate_quick_recommendations() {
755        let memory_analysis = MemoryAnalysis::new(SparseFormat::Coo, 100, (1000, 1000));
756        let performance_summary = PerformanceSummary {
757            total_operations: 10,
758            total_time: std::time::Duration::from_millis(100),
759            avg_throughput: 100.0,
760            avg_memory_efficiency: 0.8,
761            consistency_score: 0.9,
762        };
763
764        let recommendations =
765            generate_quick_recommendations(&memory_analysis, &performance_summary);
766        assert!(!recommendations.is_empty());
767    }
768
769    #[test]
770    fn test_comprehensive_analysis_report() {
771        use std::collections::HashMap;
772
773        let report = ComprehensiveAnalysisReport {
774            performance_report: PerformanceReport::new(),
775            memory_analyses: vec![MemoryAnalysis::new(
776                crate::SparseFormat::Coo,
777                100,
778                (1000, 1000),
779            )],
780            system_capabilities: SystemCapabilityReport {
781                system_info: SystemInfo::detect(),
782                capability_scores: HashMap::new(),
783                recommendations: vec!["Test recommendation".to_string()],
784                benchmark_timestamp: std::time::SystemTime::now(),
785            },
786            auto_tuning_recommendations: vec!["Auto-tune rec".to_string()],
787            hardware_recommendations: vec!["Hardware rec".to_string()],
788            performance_recommendations: vec!["Performance rec".to_string()],
789            export_path: Some(std::env::temp_dir().join("test").display().to_string()),
790        };
791
792        let all_recs = report.all_recommendations();
793        assert_eq!(all_recs.len(), 3);
794
795        let summary = report.summary();
796        assert!(summary.contains("Performance Analysis Summary"));
797        assert!(summary.contains("Total measurements: 0"));
798        assert!(summary.contains("Export path:"));
799    }
800
801    #[test]
802    fn test_module_re_exports() {
803        // Test that all major types are accessible through the unified interface
804        let _config = BenchmarkConfig::default();
805        let _profiler = SparseProfiler::new(_config);
806        let _tuner = AutoTuner::new();
807        let _analyzer = TrendAnalyzer::new();
808        let _exporter = TensorBoardExporter::new();
809
810        // Test enum variants
811        let _strategy = OptimizationStrategy::Speed;
812        let _pattern = DistributionPattern::Random;
813        let _operation = OperationType::MatrixVector;
814        let _trend = TrendDirection::Improving;
815    }
816
817    #[test]
818    fn test_convenience_functions() {
819        // Test all convenience profiler creation functions
820        let _default = default_profiler();
821        let _fast = fast_profiler();
822        let _thorough = thorough_profiler();
823        let _memory = memory_profiler();
824
825        // Verify they have different configurations
826        assert_ne!(
827            _fast.config.measured_iterations,
828            _thorough.config.measured_iterations
829        );
830        assert_ne!(_fast.config.collect_memory, _memory.config.collect_memory);
831    }
832}