## Coverage Report

#### Created: 2026-01-25 15:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /home/noah/src/realizar/src/bench_viz.rs

    Line
    Count
    Source
    1
    //! Benchmark Visualization Module (PAR-040)
    2
    //!
    3
    //! Creates 2×3 grid visualizations for inference benchmark comparisons
    4
    //! and generates profiling logs suitable for chat paste debugging.
    5
    //!
    6
    //! ## Layout
    7
    //!
    8
    //! ```text
    9
    //! ┌─────────────────────────────────────────────────────────────────────┐
    10
    //! │              GGUF Inference Comparison (tok/s GPU)                  │
    11
    //! ├─────────────────────┬─────────────────────┬─────────────────────────┤
    12
    //! │   APR serve GGUF    │      Ollama         │      llama.cpp          │
    13
    //! ├─────────────────────┴─────────────────────┴─────────────────────────┤
    14
    //! │              APR Server Format Comparison (tok/s GPU)               │
    15
    //! ├─────────────────────┬─────────────────────┬─────────────────────────┤
    16
    //! │   APR serve .apr    │  APR serve GGUF     │ Ollama / llama.cpp      │
    17
    //! └─────────────────────┴─────────────────────┴─────────────────────────┘
    18
    //! ```
    19
    20
    use std::fmt::Write as FmtWrite;
    21
    use std::time::{Duration, Instant};
    22
    23
    // ============================================================================
    24
    // Benchmark Result Types
    25
    // ============================================================================
    26
    27
    /// Single benchmark measurement
    28
    #[derive(Debug, Clone)]
    29
    pub struct BenchMeasurement {
    30
        /// Engine name (APR, Ollama, llama.cpp)
    31
        pub engine: String,
    32
        /// Format (GGUF, APR)
    33
        pub format: String,
    34
        /// Throughput in tokens/second
    35
        pub tokens_per_sec: f64,
    36
        /// Time to first token in milliseconds
    37
        pub ttft_ms: f64,
    38
        /// Number of tokens generated
    39
        pub tokens_generated: usize,
    40
        /// Total duration
    41
        pub duration: Duration,
    42
        /// GPU utilization percentage (if available)
    43
        pub gpu_util: Option<f64>,
    44
        /// GPU memory used in MB (if available)
    45
        pub gpu_mem_mb: Option<f64>,
    46
    }
    47
    48
    impl BenchMeasurement {
    49
        /// Create a new benchmark measurement
    50
    18
        pub fn new(engine: &str, format: &str) -> Self {
    51
    18
            Self {
    52
    18
                engine: engine.to_string(),
    53
    18
                format: format.to_string(),
    54
    18
                tokens_per_sec: 0.0,
    55
    18
                ttft_ms: 0.0,
    56
    18
                tokens_generated: 0,
    57
    18
                duration: Duration::ZERO,
    58
    18
                gpu_util: None,
    59
    18
                gpu_mem_mb: None,
    60
    18
            }
    61
    18
        }
    62
    63
        /// Set throughput
    64
        #[must_use]
    65
    13
        pub fn with_throughput(mut self, tps: f64) -> Self {
    66
    13
            self.tokens_per_sec = tps;
    67
    13
            self
    68
    13
        }
    69
    70
        /// Set TTFT
    71
        #[must_use]
    72
    8
        pub fn with_ttft(mut self, ttft_ms: f64) -> Self {
    73
    8
            self.ttft_ms = ttft_ms;
    74
    8
            self
    75
    8
        }
    76
    77
        /// Set tokens generated
    78
        #[must_use]
    79
    2
        pub fn with_tokens(mut self, count: usize, duration: Duration) -> Self {
    80
    2
            self.tokens_generated = count;
    81
    2
            self.duration = duration;
    82
    2
            if duration.as_secs_f64() > 0.0 {
    83
    1
                self.tokens_per_sec = count as f64 / duration.as_secs_f64();
    84
    1
            }
    85
    2
            self
    86
    2
        }
    87
    88
        /// Set GPU metrics
    89
        #[must_use]
    90
    3
        pub fn with_gpu(mut self, util: f64, mem_mb: f64) -> Self {
    91
    3
            self.gpu_util = Some(util);
    92
    3
            self.gpu_mem_mb = Some(mem_mb);
    93
    3
            self
    94
    3
        }
    95
    }
    96
    97
    /// Profiling hotspot for debugging
    98
    #[derive(Debug, Clone)]
    99
    pub struct ProfilingHotspot {
    100
        /// Component name
    101
        pub component: String,
    102
        /// Time spent
    103
        pub time: Duration,
    104
        /// Percentage of total
    105
        pub percentage: f64,
    106
        /// Call count
    107
        pub call_count: u64,
    108
        /// Average time per call
    109
        pub avg_per_call: Duration,
    110
        /// Explanation/recommendation
    111
        pub explanation: String,
    112
        /// Is this expected for inference?
    113
        pub is_expected: bool,
    114
    }
    115
    116
    impl ProfilingHotspot {
    117
        /// Format as single-line report
    118
    1
        pub fn to_line(&self) -> String {
    119
    1
            let marker = if self.is_expected { "✓" } else { "⚠"0 };
    120
    1
            format!(
    121
    1
                "{} {:20} {:>6.1}% {:>8.2}ms ({:>6} calls, {:>6.2}µs/call)",
    122
                marker,
    123
                self.component,
    124
                self.percentage,
    125
    1
                self.time.as_secs_f64() * 1000.0,
    126
                self.call_count,
    127
    1
                self.avg_per_call.as_secs_f64() * 1_000_000.0
    128
            )
    129
    1
        }
    130
    }
    131
    132
    // ============================================================================
    133
    // Benchmark Grid (2×3)
    134
    // ============================================================================
    135
    136
    /// 2×3 Benchmark comparison grid
    137
    #[derive(Debug, Clone, Default)]
    138
    pub struct BenchmarkGrid {
    139
        /// Row 1, Col 1: APR server serving GGUF format
    140
        pub gguf_apr: Option<BenchMeasurement>,
    141
        /// Row 1, Col 2: Ollama serving GGUF format
    142
        pub gguf_ollama: Option<BenchMeasurement>,
    143
        /// Row 1, Col 3: llama.cpp serving GGUF format
    144
        pub gguf_llamacpp: Option<BenchMeasurement>,
    145
    146
        /// Row 2, Col 1: APR server serving native .apr format
    147
        pub apr_native: Option<BenchMeasurement>,
    148
        /// Row 2, Col 2: APR server serving GGUF (for comparison)
    149
        pub apr_gguf: Option<BenchMeasurement>,
    150
        /// Row 2, Col 3: Baseline measurement (Ollama/llama.cpp)
    151
        pub apr_baseline: Option<BenchMeasurement>,
    152
    153
        /// Profiling hotspots
    154
        pub hotspots: Vec<ProfilingHotspot>,
    155
    156
        /// Model name
    157
        pub model_name: String,
    158
        /// Model parameters (e.g., "0.5B")
    159
        pub model_params: String,
    160
        /// Quantization type (e.g., "Q4_K_M")
    161
        pub quantization: String,
    162
    163
        /// GPU name
    164
        pub gpu_name: String,
    165
        /// GPU VRAM in GB
    166
        pub gpu_vram_gb: f64,
    167
    }
    168
    169
    impl BenchmarkGrid {
    170
        /// Create new benchmark grid
    171
    8
        pub fn new() -> Self {
    172
    8
            Self::default()
    173
    8
        }
    174
    175
        /// Set model info
    176
        #[must_use]
    177
    3
        pub fn with_model(mut self, name: &str, params: &str, quant: &str) -> Self {
    178
    3
            self.model_name = name.to_string();
    179
    3
            self.model_params = params.to_string();
    180
    3
            self.quantization = quant.to_string();
    181
    3
            self
    182
    3
        }
    183
    184
        /// Set GPU info
    185
        #[must_use]
    186
    3
        pub fn with_gpu(mut self, name: &str, vram_gb: f64) -> Self {
    187
    3
            self.gpu_name = name.to_string();
    188
    3
            self.gpu_vram_gb = vram_gb;
    189
    3
            self
    190
    3
        }
    191
    192
        /// Add GGUF row measurements
    193
    1
        pub fn set_gguf_row(
    194
    1
            &mut self,
    195
    1
            apr: BenchMeasurement,
    196
    1
            ollama: BenchMeasurement,
    197
    1
            llamacpp: BenchMeasurement,
    198
    1
        ) {
    199
    1
            self.gguf_apr = Some(apr);
    200
    1
            self.gguf_ollama = Some(ollama);
    201
    1
            self.gguf_llamacpp = Some(llamacpp);
    202
    1
        }
    203
    204
        /// Add APR row measurements
    205
    1
        pub fn set_apr_row(
    206
    1
            &mut self,
    207
    1
            native: BenchMeasurement,
    208
    1
            gguf: BenchMeasurement,
    209
    1
            baseline: BenchMeasurement,
    210
    1
        ) {
    211
    1
            self.apr_native = Some(native);
    212
    1
            self.apr_gguf = Some(gguf);
    213
    1
            self.apr_baseline = Some(baseline);
    214
    1
        }
    215
    216
        /// Add profiling hotspot
    217
    5
        pub fn add_hotspot(&mut self, hotspot: ProfilingHotspot) {
    218
    5
            self.hotspots.push(hotspot);
    219
    5
        }
    220
    221
        // ========================================================================
    222
        // Terminal Visualization (ASCII)
    223
        // ========================================================================
    224
    225
        /// Render as ASCII grid for terminal
    226
    1
        pub fn render_ascii(&self) -> String {
    227
    1
            let mut out = String::new();
    228
    229
            // Header
    230
    1
            writeln!(
    231
    1
                out,
    232
    1
                "╔═══════════════════════════════════════════════════════════════════════╗"
    233
            )
    234
    1
            .expect("failed to write benchmark output");
    235
    1
            writeln!(
    236
    1
                out,
    237
    1
                "║           INFERENCE BENCHMARK COMPARISON (tok/s GPU)                  ║"
    238
            )
    239
    1
            .expect("failed to write benchmark output");
    240
    1
            writeln!(
    241
    1
                out,
    242
    1
                "║  Model: {:30} Quant: {:10}         ║",
    243
    1
                truncate(&self.model_name, 30),
    244
    1
                truncate(&self.quantization, 10)
    245
            )
    246
    1
            .expect("failed to write benchmark output");
    247
    1
            writeln!(
    248
    1
                out,
    249
    1
                "║  GPU: {:35} VRAM: {:5.1}GB              ║",
    250
    1
                truncate(&self.gpu_name, 35),
    251
                self.gpu_vram_gb
    252
            )
    253
    1
            .expect("failed to write benchmark output");
    254
    1
            writeln!(
    255
    1
                out,
    256
    1
                "╠═══════════════════════════════════════════════════════════════════════╣"
    257
            )
    258
    1
            .expect("failed to write benchmark output");
    259
    260
            // Row 1: GGUF comparison
    261
    1
            writeln!(
    262
    1
                out,
    263
    1
                "║                    GGUF Format Inference                              ║"
    264
            )
    265
    1
            .expect("failed to write benchmark output");
    266
    1
            writeln!(
    267
    1
                out,
    268
    1
                "╠═══════════════════════╦═══════════════════════╦═══════════════════════╣"
    269
            )
    270
    1
            .expect("failed to write benchmark output");
    271
    1
            writeln!(
    272
    1
                out,
    273
    1
                "║    APR serve GGUF     ║       Ollama          ║      llama.cpp        ║"
    274
            )
    275
    1
            .expect("failed to write benchmark output");
    276
    1
            writeln!(
    277
    1
                out,
    278
    1
                "╠═══════════════════════╬═══════════════════════╬═══════════════════════╣"
    279
            )
    280
    1
            .expect("failed to write benchmark output");
    281
    282
    1
            let gguf_apr_tps = self.gguf_apr.as_ref().map_or(0.0, |m| m.tokens_per_sec);
    283
    1
            let gguf_ollama_tps = self.gguf_ollama.as_ref().map_or(0.0, |m| m.tokens_per_sec);
    284
    1
            let gguf_llamacpp_tps = self
    285
    1
                .gguf_llamacpp
    286
    1
                .as_ref()
    287
    1
                .map_or(0.0, |m| m.tokens_per_sec);
    288
    289
    1
            writeln!(
    290
    1
                out,
    291
    1
                "║  {:>8.1} tok/s      ║  {:>8.1} tok/s      ║  {:>8.1} tok/s      ║",
    292
                gguf_apr_tps, gguf_ollama_tps, gguf_llamacpp_tps
    293
            )
    294
    1
            .expect("failed to write benchmark output");
    295
    296
            // Bar visualization
    297
    1
            let max_tps = [gguf_apr_tps, gguf_ollama_tps, gguf_llamacpp_tps]
    298
    1
                .iter()
    299
    1
                .cloned()
    300
    1
                .fold(1.0, f64::max);
    301
    302
    1
            writeln!(
    303
    1
                out,
    304
    1
                "║  {}  ║  {}  ║  {}  ║",
    305
    1
                render_bar(gguf_apr_tps, max_tps, 17),
    306
    1
                render_bar(gguf_ollama_tps, max_tps, 17),
    307
    1
                render_bar(gguf_llamacpp_tps, max_tps, 17)
    308
            )
    309
    1
            .expect("failed to write benchmark output");
    310
    311
            // TTFT
    312
    1
            let gguf_apr_ttft = self.gguf_apr.as_ref().map_or(0.0, |m| m.ttft_ms);
    313
    1
            let gguf_ollama_ttft = self.gguf_ollama.as_ref().map_or(0.0, |m| m.ttft_ms);
    314
    1
            let gguf_llamacpp_ttft = self.gguf_llamacpp.as_ref().map_or(0.0, |m| m.ttft_ms);
    315
    316
    1
            writeln!(
    317
    1
                out,
    318
    1
                "║  TTFT: {:>6.1}ms      ║  TTFT: {:>6.1}ms      ║  TTFT: {:>6.1}ms      ║",
    319
                gguf_apr_ttft, gguf_ollama_ttft, gguf_llamacpp_ttft
    320
            )
    321
    1
            .expect("failed to write benchmark output");
    322
    323
            // Row 2: APR server comparison
    324
    1
            writeln!(
    325
    1
                out,
    326
    1
                "╠═══════════════════════╩═══════════════════════╩═══════════════════════╣"
    327
            )
    328
    1
            .expect("failed to write benchmark output");
    329
    1
            writeln!(
    330
    1
                out,
    331
    1
                "║                   APR Server Format Comparison                        ║"
    332
            )
    333
    1
            .expect("failed to write benchmark output");
    334
    1
            writeln!(
    335
    1
                out,
    336
    1
                "╠═══════════════════════╦═══════════════════════╦═══════════════════════╣"
    337
            )
    338
    1
            .expect("failed to write benchmark output");
    339
    1
            writeln!(
    340
    1
                out,
    341
    1
                "║   APR serve .apr      ║   APR serve GGUF      ║  Ollama (baseline)    ║"
    342
            )
    343
    1
            .expect("failed to write benchmark output");
    344
    1
            writeln!(
    345
    1
                out,
    346
    1
                "╠═══════════════════════╬═══════════════════════╬═══════════════════════╣"
    347
            )
    348
    1
            .expect("failed to write benchmark output");
    349
    350
    1
            let apr_native_tps = self.apr_native.as_ref().map_or(0.0, |m| m.tokens_per_sec);
    351
    1
            let apr_gguf_tps = self.apr_gguf.as_ref().map_or(0.0, |m| m.tokens_per_sec);
    352
    1
            let apr_baseline_tps = self.apr_baseline.as_ref().map_or(0.0, |m| m.tokens_per_sec);
    353
    354
    1
            writeln!(
    355
    1
                out,
    356
    1
                "║  {:>8.1} tok/s      ║  {:>8.1} tok/s      ║  {:>8.1} tok/s      ║",
    357
                apr_native_tps, apr_gguf_tps, apr_baseline_tps
    358
            )
    359
    1
            .expect("failed to write benchmark output");
    360
    361
    1
            let max_tps2 = [apr_native_tps, apr_gguf_tps, apr_baseline_tps]
    362
    1
                .iter()
    363
    1
                .cloned()
    364
    1
                .fold(1.0, f64::max);
    365
    366
    1
            writeln!(
    367
    1
                out,
    368
    1
                "║  {}  ║  {}  ║  {}  ║",
    369
    1
                render_bar(apr_native_tps, max_tps2, 17),
    370
    1
                render_bar(apr_gguf_tps, max_tps2, 17),
    371
    1
                render_bar(apr_baseline_tps, max_tps2, 17)
    372
            )
    373
    1
            .expect("failed to write benchmark output");
    374
    375
            // Speedup vs baseline
    376
    1
            let speedup_native = if apr_baseline_tps > 0.0 {
    377
    1
                apr_native_tps / apr_baseline_tps
    378
            } else {
    379
    0
                0.0
    380
            };
    381
    1
            let speedup_gguf = if apr_baseline_tps > 0.0 {
    382
    1
                apr_gguf_tps / apr_baseline_tps
    383
            } else {
    384
    0
                0.0
    385
            };
    386
    387
    1
            writeln!(
    388
    1
                out,
    389
    1
                "║  vs Ollama: {:>5.2}x   ║  vs Ollama: {:>5.2}x   ║  (baseline)           ║",
    390
                speedup_native, speedup_gguf
    391
            )
    392
    1
            .expect("failed to write benchmark output");
    393
    394
    1
            writeln!(
    395
    1
                out,
    396
    1
                "╚═══════════════════════╩═══════════════════════╩═══════════════════════╝"
    397
            )
    398
    1
            .expect("failed to write benchmark output");
    399
    400
    1
            out
    401
    1
        }
    402
    403
        // ========================================================================
    404
        // Profiling Log for Chat Paste
    405
        // ========================================================================
    406
    407
        /// Generate profiling log suitable for chat paste
    408
    1
        pub fn render_profiling_log(&self) -> String {
    409
    1
            let mut out = String::new();
    410
    411
    1
            writeln!(out, "```").expect("failed to write benchmark output");
    412
    1
            writeln!(
    413
    1
                out,
    414
    1
                "═══════════════════════════════════════════════════════════════════════"
    415
            )
    416
    1
            .expect("failed to write benchmark output");
    417
    1
            writeln!(out, "INFERENCE PROFILING REPORT").expect("failed to write benchmark output");
    418
    1
            writeln!(
    419
    1
                out,
    420
    1
                "═══════════════════════════════════════════════════════════════════════"
    421
            )
    422
    1
            .expect("failed to write benchmark output");
    423
    1
            writeln!(out).expect("failed to write benchmark output");
    424
    425
            // Model & Hardware
    426
    1
            writeln!(out, "MODEL: {} ({})", self.model_name, self.model_params)
    427
    1
                .expect("failed to write benchmark output");
    428
    1
            writeln!(out, "QUANT: {}", self.quantization).expect("failed to write benchmark output");
    429
    1
            writeln!(
    430
    1
                out,
    431
    1
                "GPU:   {} ({:.1}GB VRAM)",
    432
                self.gpu_name, self.gpu_vram_gb
    433
            )
    434
    1
            .expect("failed to write benchmark output");
    435
    1
            writeln!(out).expect("failed to write benchmark output");
    436
    437
            // Performance Summary
    438
    1
            writeln!(
    439
    1
                out,
    440
    1
                "───────────────────────────────────────────────────────────────────────"
    441
            )
    442
    1
            .expect("failed to write benchmark output");
    443
    1
            writeln!(out, "THROUGHPUT COMPARISON (tok/s)").expect("failed to write benchmark output");
    444
    1
            writeln!(
    445
    1
                out,
    446
    1
                "───────────────────────────────────────────────────────────────────────"
    447
            )
    448
    1
            .expect("failed to write benchmark output");
    449
    450
    1
            if let Some(ref m) = self.gguf_apr {
    451
    1
                writeln!(
    452
    1
                    out,
    453
    1
                    "APR GGUF:      {:>8.1} tok/s  (TTFT: {:>6.1}ms)",
    454
    1
                    m.tokens_per_sec, m.ttft_ms
    455
    1
                )
    456
    1
                .expect("failed to write benchmark output");
    457
    1
            }0
    458
    1
            if let Some(ref m0) = self.apr_native {
    459
    0
                writeln!(
    460
    0
                    out,
    461
    0
                    "APR .apr:      {:>8.1} tok/s  (TTFT: {:>6.1}ms)",
    462
    0
                    m.tokens_per_sec, m.ttft_ms
    463
    0
                )
    464
    0
                .expect("failed to write benchmark output");
    465
    1
            }
    466
    1
            if let Some(ref m0) = self.gguf_ollama {
    467
    0
                writeln!(
    468
    0
                    out,
    469
    0
                    "Ollama:        {:>8.1} tok/s  (TTFT: {:>6.1}ms)",
    470
    0
                    m.tokens_per_sec, m.ttft_ms
    471
    0
                )
    472
    0
                .expect("failed to write benchmark output");
    473
    1
            }
    474
    1
            if let Some(ref m0) = self.gguf_llamacpp {
    475
    0
                writeln!(
    476
    0
                    out,
    477
    0
                    "llama.cpp:     {:>8.1} tok/s  (TTFT: {:>6.1}ms)",
    478
    0
                    m.tokens_per_sec, m.ttft_ms
    479
    0
                )
    480
    0
                .expect("failed to write benchmark output");
    481
    1
            }
    482
    1
            writeln!(out).expect("failed to write benchmark output");
    483
    484
            // Speedup Analysis
    485
    1
            writeln!(
    486
    1
                out,
    487
    1
                "───────────────────────────────────────────────────────────────────────"
    488
            )
    489
    1
            .expect("failed to write benchmark output");
    490
    1
            writeln!(out, "SPEEDUP ANALYSIS").expect("failed to write benchmark output");
    491
    1
            writeln!(
    492
    1
                out,
    493
    1
                "───────────────────────────────────────────────────────────────────────"
    494
            )
    495
    1
            .expect("failed to write benchmark output");
    496
    497
    1
            let ollama_tps = self
    498
    1
                .gguf_ollama
    499
    1
                .as_ref()
    500
    1
                .map_or(318.0, |m| m.tokens_per_sec);
    501
    1
            let llamacpp_tps = self
    502
    1
                .gguf_llamacpp
    503
    1
                .as_ref()
    504
    1
                .map_or(200.0, |m| m.tokens_per_sec);
    505
    506
    1
            if let Some(ref m) = self.gguf_apr {
    507
    1
                let vs_ollama = m.tokens_per_sec / ollama_tps;
    508
    1
                let vs_llamacpp = m.tokens_per_sec / llamacpp_tps;
    509
    1
                writeln!(
    510
    1
                    out,
    511
    1
                    "APR GGUF vs Ollama:     {:>5.2}x  {}",
    512
                    vs_ollama,
    513
    1
                    if vs_ollama >= 1.0 { "✓" } else { "⚠"0 }
    514
                )
    515
    1
                .expect("failed to write benchmark output");
    516
    1
                writeln!(
    517
    1
                    out,
    518
    1
                    "APR GGUF vs llama.cpp:  {:>5.2}x  {}",
    519
                    vs_llamacpp,
    520
    1
                    if vs_llamacpp >= 1.25 {
    521
    1
                        "✓ Point 41 PASS"
    522
                    } else {
    523
    0
                        "⚠ Point 41 FAIL"
    524
                    }
    525
                )
    526
    1
                .expect("failed to write benchmark output");
    527
    0
            }
    528
    529
    1
            if let Some(ref m0) = self.apr_native {
    530
    0
                let vs_ollama = m.tokens_per_sec / ollama_tps;
    531
    0
                writeln!(
    532
    0
                    out,
    533
    0
                    "APR .apr vs Ollama:     {:>5.2}x  {}",
    534
                    vs_ollama,
    535
    0
                    if vs_ollama >= 2.0 {
    536
    0
                        "✓ 2x target"
    537
                    } else {
    538
    0
                        ""
    539
                    }
    540
                )
    541
    0
                .expect("failed to write benchmark output");
    542
    1
            }
    543
    1
            writeln!(out).expect("failed to write benchmark output");
    544
    545
            // Profiling Hotspots
    546
    1
            if !self.hotspots.is_empty() {
    547
    1
                writeln!(
    548
    1
                    out,
    549
    1
                    "───────────────────────────────────────────────────────────────────────"
    550
                )
    551
    1
                .expect("failed to write benchmark output");
    552
    1
                writeln!(out, "PROFILING HOTSPOTS (>5% of execution time)")
    553
    1
                    .expect("failed to write benchmark output");
    554
    1
                writeln!(
    555
    1
                    out,
    556
    1
                    "───────────────────────────────────────────────────────────────────────"
    557
                )
    558
    1
                .expect("failed to write benchmark output");
    559
    560
    2
                for hotspot1 in &self.hotspots {
    561
    1
                    writeln!(out, "{}", hotspot.to_line()).expect("failed to write benchmark output");
    562
    1
                    if !hotspot.explanation.is_empty() {
    563
    1
                        writeln!(out, "   └─ {}", hotspot.explanation)
    564
    1
                            .expect("failed to write benchmark output");
    565
    1
                    }0
    566
                }
    567
    1
                writeln!(out).expect("failed to write benchmark output");
    568
    0
            }
    569
    570
            // GPU Metrics
    571
    1
            writeln!(
    572
    1
                out,
    573
    1
                "───────────────────────────────────────────────────────────────────────"
    574
            )
    575
    1
            .expect("failed to write benchmark output");
    576
    1
            writeln!(out, "GPU METRICS").expect("failed to write benchmark output");
    577
    1
            writeln!(
    578
    1
                out,
    579
    1
                "───────────────────────────────────────────────────────────────────────"
    580
            )
    581
    1
            .expect("failed to write benchmark output");
    582
    583
    1
            if let Some(ref m) = self.gguf_apr {
    584
    1
                if let (Some(util), Some(mem)) = (m.gpu_util, m.gpu_mem_mb) {
    585
    1
                    writeln!(
    586
    1
                        out,
    587
    1
                        "APR GGUF:   GPU Util: {:>5.1}%  VRAM: {:>6.0}MB",
    588
    1
                        util, mem
    589
    1
                    )
    590
    1
                    .expect("failed to write benchmark output");
    591
    1
                }0
    592
    0
            }
    593
    1
            if let Some(ref m0) = self.apr_native {
    594
    0
                if let (Some(util), Some(mem)) = (m.gpu_util, m.gpu_mem_mb) {
    595
    0
                    writeln!(
    596
    0
                        out,
    597
    0
                        "APR .apr:   GPU Util: {:>5.1}%  VRAM: {:>6.0}MB",
    598
    0
                        util, mem
    599
    0
                    )
    600
    0
                    .expect("failed to write benchmark output");
    601
    0
                }
    602
    1
            }
    603
    1
            writeln!(out).expect("failed to write benchmark output");
    604
    605
            // Recommendations
    606
    1
            writeln!(
    607
    1
                out,
    608
    1
                "───────────────────────────────────────────────────────────────────────"
    609
            )
    610
    1
            .expect("failed to write benchmark output");
    611
    1
            writeln!(out, "OPTIMIZATION RECOMMENDATIONS").expect("failed to write benchmark output");
    612
    1
            writeln!(
    613
    1
                out,
    614
    1
                "───────────────────────────────────────────────────────────────────────"
    615
            )
    616
    1
            .expect("failed to write benchmark output");
    617
    618
    1
            let unexpected: Vec<_> = self.hotspots.iter().filter(|h| !h.is_expected).collect();
    619
    1
            if unexpected.is_empty() {
    620
    1
                writeln!(out, "✓ No unexpected hotspots detected")
    621
    1
                    .expect("failed to write benchmark output");
    622
    1
            } else {
    623
    0
                for h in unexpected {
    624
    0
                    writeln!(out, "⚠ {}: {}", h.component, h.explanation)
    625
    0
                        .expect("failed to write benchmark output");
    626
    0
                }
    627
            }
    628
    629
            // Phase 2 status
    630
    1
            let apr_tps = self.gguf_apr.as_ref().map_or(0.0, |m| m.tokens_per_sec);
    631
    1
            if apr_tps < 500.0 {
    632
    0
                writeln!(out).expect("failed to write benchmark output");
    633
    0
                writeln!(out, "Phase 2 Optimizations (projected 3.28x improvement):")
    634
    0
                    .expect("failed to write benchmark output");
    635
    0
                writeln!(out, "  PAR-036: Persistent threads      (1.3x)")
    636
    0
                    .expect("failed to write benchmark output");
    637
    0
                writeln!(out, "  PAR-037: CUDA graph capture      (1.5x)")
    638
    0
                    .expect("failed to write benchmark output");
    639
    0
                writeln!(out, "  PAR-038: Multi-stream pipeline   (1.2x)")
    640
    0
                    .expect("failed to write benchmark output");
    641
    0
                writeln!(out, "  PAR-039: Megakernel fusion       (1.4x)")
    642
    0
                    .expect("failed to write benchmark output");
    643
    0
                writeln!(
    644
    0
                    out,
    645
    0
                    "  Projected: {:.1} × 3.28 = {:.1} tok/s",
    646
    0
                    apr_tps,
    647
    0
                    apr_tps * 3.28
    648
    0
                )
    649
    0
                .expect("failed to write benchmark output");
    650
    1
            }
    651
    652
    1
            writeln!(
    653
    1
                out,
    654
    1
                "═══════════════════════════════════════════════════════════════════════"
    655
            )
    656
    1
            .expect("failed to write benchmark output");
    657
    1
            writeln!(out, "```").expect("failed to write benchmark output");
    658
    659
    1
            out
    660
    1
        }
    661
    662
        /// Generate compact one-liner for quick comparison
    663
    1
        pub fn render_compact(&self) -> String {
    664
    1
            let apr_tps = self.gguf_apr.as_ref().map_or(0.0, |m| m.tokens_per_sec);
    665
    1
            let ollama_tps = self.gguf_ollama.as_ref().map_or(0.0, |m| m.tokens_per_sec);
    666
    1
            let llamacpp_tps = self
    667
    1
                .gguf_llamacpp
    668
    1
                .as_ref()
    669
    1
                .map_or(0.0, |m| m.tokens_per_sec);
    670
    671
    1
            format!(
    672
    1
                "APR:{:.0} Ollama:{:.0} llama.cpp:{:.0} tok/s | APR vs Ollama:{:.2}x vs llama.cpp:{:.2}x",
    673
                apr_tps, ollama_tps, llamacpp_tps,
    674
    1
                apr_tps / ollama_tps.max(1.0),
    675
    1
                apr_tps / llamacpp_tps.max(1.0)
    676
            )
    677
    1
        }
    678
    }
    679
    680
    // ============================================================================
    681
    // Benchmark Runner
    682
    // ============================================================================
    683
    684
    /// Benchmark runner with profiling
    685
    #[derive(Debug)]
    686
    pub struct BenchmarkRunner {
    687
        /// Results grid
    688
        pub grid: BenchmarkGrid,
    689
        /// Profiling start time
    690
        start_time: Option<Instant>,
    691
        /// Component timings
    692
        component_times: Vec<(String, Duration, u64)>,
    693
    }
    694
    695
    impl Default for BenchmarkRunner {
    696
    0
        fn default() -> Self {
    697
    0
            Self::new()
    698
    0
        }
    699
    }
    700
    701
    impl BenchmarkRunner {
    702
        /// Create new benchmark runner
    703
    1
        pub fn new() -> Self {
    704
    1
            Self {
    705
    1
                grid: BenchmarkGrid::new(),
    706
    1
                start_time: None,
    707
    1
                component_times: Vec::new(),
    708
    1
            }
    709
    1
        }
    710
    711
        /// Start profiling
    712
    1
        pub fn start(&mut self) {
    713
    1
            self.start_time = Some(Instant::now());
    714
    1
        }
    715
    716
        /// Record component timing
    717
    3
        pub fn record_component(&mut self, name: &str, duration: Duration, calls: u64) {
    718
    3
            self.component_times
    719
    3
                .push((name.to_string(), duration, calls));
    720
    3
        }
    721
    722
        /// Measure a component
    723
    0
        pub fn measure<F, R>(&mut self, name: &str, f: F) -> R
    724
    0
        where
    725
    0
            F: FnOnce() -> R,
    726
        {
    727
    0
            let start = Instant::now();
    728
    0
            let result = f();
    729
    0
            self.record_component(name, start.elapsed(), 1);
    730
    0
            result
    731
    0
        }
    732
    733
        /// Finalize and compute hotspots
    734
    1
        pub fn finalize(&mut self) {
    735
    1
            let total_time: Duration = self.component_times.iter().map(|(_, d, _)| *d).sum();
    736
    1
            let total_nanos = total_time.as_nanos() as f64;
    737
    738
    1
            if total_nanos == 0.0 {
    739
    0
                return;
    740
    1
            }
    741
    742
    4
            for (name3, duration3, calls3) in &self.component_times {
    743
    3
                let percentage = (duration.as_nanos() as f64 / total_nanos) * 100.0;
    744
    745
    3
                if percentage > 5.0 {
    746
    3
                    let avg_per_call = if *calls > 0 {
    747
    3
                        Duration::from_nanos((duration.as_nanos() / *calls as u128) as u64)
    748
                    } else {
    749
    0
                        Duration::ZERO
    750
                    };
    751
    752
    3
                    let (explanation, is_expected) = explain_inference_hotspot(name, percentage);
    753
    754
    3
                    self.grid.add_hotspot(ProfilingHotspot {
    755
    3
                        component: name.clone(),
    756
    3
                        time: *duration,
    757
    3
                        percentage,
    758
    3
                        call_count: *calls,
    759
    3
                        avg_per_call,
    760
    3
                        explanation,
    761
    3
                        is_expected,
    762
    3
                    });
    763
    0
                }
    764
            }
    765
    766
            // Sort by percentage descending
    767
    2
            self.grid.hotspots1.sort_by1(|a, b| {
    768
    2
                b.percentage
    769
    2
                    .partial_cmp(&a.percentage)
    770
    2
                    .unwrap_or(std::cmp::Ordering::Equal)
    771
    2
            });
    772
    1
        }
    773
    }
    774
    775
    // ============================================================================
    776
    // Helper Functions
    777
    // ============================================================================
    778
    779
    /// Render ASCII bar
    780
    10
    fn render_bar(value: f64, max: f64, width: usize) -> String {
    781
    10
        let ratio = if max > 0.0 { value / max } else { 0.00 };
    782
    10
        let filled = ((ratio * width as f64) as usize).min(width);
    783
    10
        let empty = width - filled;
    784
    785
    10
        format!("{}{}", "█".repeat(filled), "░".repeat(empty))
    786
    10
    }
    787
    788
    /// Truncate string to max length
    789
    6
    fn truncate(s: &str, max_len: usize) -> &str {
    790
    6
        if s.len() <= max_len {
    791
    5
            s
    792
        } else {
    793
    1
            &s[..max_len]
    794
        }
    795
    6
    }
    796
    797
    /// Explain inference hotspot
    798
    7
    fn explain_inference_hotspot(component: &str, percentage: f64) -> (String, bool) {
    799
    7
        match component {
    800
    7
            "Q4K_GEMV" | "MatMul"5 | "GEMM"5 => (
    801
    2
                format!(
    802
    2
                    "Matrix ops dominate ({:.1}%) - expected for transformer inference",
    803
    2
                    percentage
    804
    2
                ),
    805
    2
                true,
    806
    2
            ),
    807
    5
            "Attention" | "FlashAttention"3 => (
    808
    2
                format!(
    809
    2
                    "Attention at {:.1}% - normal for autoregressive decoding",
    810
    2
                    percentage
    811
    2
                ),
    812
    2
                true,
    813
    2
            ),
    814
    3
            "KV_Cache" | "KVCache" => {
    815
    0
                if percentage > 20.0 {
    816
    0
                    (
    817
    0
                        "KV cache overhead high - consider FP16 cache or graph capture".to_string(),
    818
    0
                        false,
    819
    0
                    )
    820
                } else {
    821
    0
                    ("KV cache within normal range".to_string(), true)
    822
                }
    823
            },
    824
    3
            "Softmax" => {
    825
    0
                if percentage > 10.0 {
    826
    0
                    (
    827
    0
                        "Softmax unusually high - check for redundant computations".to_string(),
    828
    0
                        false,
    829
    0
                    )
    830
                } else {
    831
    0
                    ("Softmax within normal range".to_string(), true)
    832
                }
    833
            },
    834
    3
            "RMSNorm" | "LayerNorm" => {
    835
    0
                if percentage > 15.0 {
    836
    0
                    (
    837
    0
                        "Normalization overhead high - consider fused kernels".to_string(),
    838
    0
                        false,
    839
    0
                    )
    840
                } else {
    841
    0
                    ("Normalization within normal range".to_string(), true)
    842
                }
    843
            },
    844
    3
            "MemcpyH2D" | "MemcpyD2H" | "Transfer" => (
    845
    0
                "Memory transfer - consider persistent GPU buffers".to_string(),
    846
    0
                false,
    847
    0
            ),
    848
    3
            "KernelLaunch" => (
    849
    0
                "Kernel launch overhead - consider CUDA graphs or megakernels".to_string(),
    850
    0
                false,
    851
    0
            ),
    852
    3
            "Embedding" => (
    853
    0
                "Embedding lookup - expected at start of inference".to_string(),
    854
    0
                true,
    855
    0
            ),
    856
    3
            "Sampling" | "TopK" | "TopP" => (
    857
    0
                "Sampling overhead - expected for token generation".to_string(),
    858
    0
                true,
    859
    0
            ),
    860
            _ => {
    861
    3
                if percentage > 20.0 {
    862
    1
                    (
    863
    1
                        format!("Unknown component at {:.1}% - investigate", percentage),
    864
    1
                        false,
    865
    1
                    )
    866
                } else {
    867
    2
                    (String::new(), true)
    868
                }
    869
            },
    870
        }
    871
    7
    }
    872
    873
    // ============================================================================
    874
    // Tests
    875
    // ============================================================================
    876
    877
    #[cfg(test)]
    878
    mod tests {
    879
        use super::*;
    880
    881
        #[test]
    882
    1
        fn test_benchmark_grid_ascii() {
    883
    1
            let mut grid = BenchmarkGrid::new()
    884
    1
                .with_model("Qwen2.5-Coder-0.5B", "0.5B", "Q4_K_M")
    885
    1
                .with_gpu("RTX 4090", 24.0);
    886
    887
    1
            grid.set_gguf_row(
    888
    1
                BenchMeasurement::new("APR", "GGUF")
    889
    1
                    .with_throughput(500.0)
    890
    1
                    .with_ttft(7.0),
    891
    1
                BenchMeasurement::new("Ollama", "GGUF")
    892
    1
                    .with_throughput(318.0)
    893
    1
                    .with_ttft(50.0),
    894
    1
                BenchMeasurement::new("llama.cpp", "GGUF")
    895
    1
                    .with_throughput(200.0)
    896
    1
                    .with_ttft(30.0),
    897
            );
    898
    899
    1
            grid.set_apr_row(
    900
    1
                BenchMeasurement::new("APR", ".apr")
    901
    1
                    .with_throughput(600.0)
    902
    1
                    .with_ttft(5.0),
    903
    1
                BenchMeasurement::new("APR", "GGUF")
    904
    1
                    .with_throughput(500.0)
    905
    1
                    .with_ttft(7.0),
    906
    1
                BenchMeasurement::new("Ollama", "GGUF")
    907
    1
                    .with_throughput(318.0)
    908
    1
                    .with_ttft(50.0),
    909
            );
    910
    911
    1
            let ascii = grid.render_ascii();
    912
    1
            assert!(ascii.contains("APR serve GGUF"));
    913
    1
            assert!(ascii.contains("Ollama"));
    914
    1
            assert!(ascii.contains("llama.cpp"));
    915
    1
            assert!(ascii.contains("500.0 tok/s"));
    916
    1
        }
    917
    918
        #[test]
    919
    1
        fn test_profiling_log() {
    920
    1
            let mut grid = BenchmarkGrid::new()
    921
    1
                .with_model("Qwen2.5-Coder-0.5B", "0.5B", "Q4_K_M")
    922
    1
                .with_gpu("RTX 4090", 24.0);
    923
    924
    1
            grid.gguf_apr = Some(
    925
    1
                BenchMeasurement::new("APR", "GGUF")
    926
    1
                    .with_throughput(500.0)
    927
    1
                    .with_ttft(7.0)
    928
    1
                    .with_gpu(95.0, 2048.0),
    929
    1
            );
    930
    931
    1
            grid.add_hotspot(ProfilingHotspot {
    932
    1
                component: "Q4K_GEMV".to_string(),
    933
    1
                time: Duration::from_millis(150),
    934
    1
                percentage: 45.0,
    935
    1
                call_count: 1000,
    936
    1
                avg_per_call: Duration::from_micros(150),
    937
    1
                explanation: "Matrix ops dominate - expected".to_string(),
    938
    1
                is_expected: true,
    939
    1
            });
    940
    941
    1
            let log = grid.render_profiling_log();
    942
    1
            assert!(log.contains("PROFILING REPORT"));
    943
    1
            assert!(log.contains("Q4K_GEMV"));
    944
    1
            assert!(log.contains("45.0%"));
    945
    1
        }
    946
    947
        #[test]
    948
    1
        fn test_compact_output() {
    949
    1
            let mut grid = BenchmarkGrid::new();
    950
    1
            grid.gguf_apr = Some(BenchMeasurement::new("APR", "GGUF").with_throughput(500.0));
    951
    1
            grid.gguf_ollama = Some(BenchMeasurement::new("Ollama", "GGUF").with_throughput(318.0));
    952
    1
            grid.gguf_llamacpp =
    953
    1
                Some(BenchMeasurement::new("llama.cpp", "GGUF").with_throughput(200.0));
    954
    955
    1
            let compact = grid.render_compact();
    956
    1
            assert!(compact.contains("APR:500"));
    957
    1
            assert!(compact.contains("vs llama.cpp:2.50x"));
    958
    1
        }
    959
    960
        #[test]
    961
    1
        fn test_runner_profiling() {
    962
    1
            let mut runner = BenchmarkRunner::new();
    963
    1
            runner.start();
    964
    965
    1
            runner.record_component("Q4K_GEMV", Duration::from_millis(100), 500);
    966
    1
            runner.record_component("Attention", Duration::from_millis(50), 500);
    967
    1
            runner.record_component("Other", Duration::from_millis(10), 100);
    968
    969
    1
            runner.finalize();
    970
    971
    1
            assert!(!runner.grid.hotspots.is_empty());
    972
    1
            assert_eq!(runner.grid.hotspots[0].component, "Q4K_GEMV");
    973
    1
        }
    974
    975
        #[test]
    976
    1
        fn test_render_bar() {
    977
    1
            let bar = render_bar(50.0, 100.0, 10);
    978
    10
            assert_eq!1(bar.chars()1.filter1(|c| *c == '█').count1(), 5);
    979
    10
            assert_eq!1(bar.chars()1.filter1(|c| *c == '░').count1(), 5);
    980
    1
        }
    981
    982
        // =========================================================================
    983
        // Coverage Tests: BenchMeasurement
    984
        // =========================================================================
    985
    986
        #[test]
    987
    1
        fn test_bench_measurement_new() {
    988
    1
            let m = BenchMeasurement::new("TestEngine", "TestFormat");
    989
    1
            assert_eq!(m.engine, "TestEngine");
    990
    1
            assert_eq!(m.format, "TestFormat");
    991
    1
            assert_eq!(m.tokens_per_sec, 0.0);
    992
    1
            assert_eq!(m.ttft_ms, 0.0);
    993
    1
            assert_eq!(m.tokens_generated, 0);
    994
    1
            assert!(m.gpu_util.is_none());
    995
    1
            assert!(m.gpu_mem_mb.is_none());
    996
    1
        }
    997
    998
        #[test]
    999
    1
        fn test_bench_measurement_with_throughput() {
    1000
    1
            let m = BenchMeasurement::new("APR", "GGUF").with_throughput(100.0);
    1001
    1
            assert_eq!(m.tokens_per_sec, 100.0);
    1002
    1
        }
    1003
    1004
        #[test]
    1005
    1
        fn test_bench_measurement_with_ttft() {
    1006
    1
            let m = BenchMeasurement::new("APR", "GGUF").with_ttft(25.5);
    1007
    1
            assert_eq!(m.ttft_ms, 25.5);
    1008
    1
        }
    1009
    1010
        #[test]
    1011
    1
        fn test_bench_measurement_with_tokens() {
    1012
    1
            let duration = Duration::from_secs(2);
    1013
    1
            let m = BenchMeasurement::new("APR", "GGUF").with_tokens(200, duration);
    1014
    1
            assert_eq!(m.tokens_generated, 200);
    1015
    1
            assert_eq!(m.duration, duration);
    1016
    1
            assert!((m.tokens_per_sec - 100.0).abs() < 0.1);
    1017
    1
        }
    1018
    1019
        #[test]
    1020
    1
        fn test_bench_measurement_with_tokens_zero_duration() {
    1021
    1
            let m = BenchMeasurement::new("APR", "GGUF").with_tokens(100, Duration::ZERO);
    1022
    1
            assert_eq!(m.tokens_generated, 100);
    1023
            // Zero duration means no TPS calculation
    1024
    1
        }
    1025
    1026
        #[test]
    1027
    1
        fn test_bench_measurement_with_gpu() {
    1028
    1
            let m = BenchMeasurement::new("APR", "GGUF").with_gpu(95.0, 4096.0);
    1029
    1
            assert_eq!(m.gpu_util, Some(95.0));
    1030
    1
            assert_eq!(m.gpu_mem_mb, Some(4096.0));
    1031
    1
        }
    1032
    1033
        #[test]
    1034
    1
        fn test_bench_measurement_debug() {
    1035
    1
            let m = BenchMeasurement::new("APR", "GGUF").with_throughput(100.0);
    1036
    1
            let debug_str = format!("{:?}", m);
    1037
    1
            assert!(debug_str.contains("BenchMeasurement"));
    1038
    1
            assert!(debug_str.contains("APR"));
    1039
    1
        }
    1040
    1041
        #[test]
    1042
    1
        fn test_bench_measurement_clone() {
    1043
    1
            let m = BenchMeasurement::new("APR", "GGUF")
    1044
    1
                .with_throughput(100.0)
    1045
    1
                .with_gpu(90.0, 1024.0);
    1046
    1
            let cloned = m.clone();
    1047
    1
            assert_eq!(cloned.engine, m.engine);
    1048
    1
            assert_eq!(cloned.tokens_per_sec, m.tokens_per_sec);
    1049
    1
            assert_eq!(cloned.gpu_util, m.gpu_util);
    1050
    1
        }
    1051
    1052
        // =========================================================================
    1053
        // Coverage Tests: ProfilingHotspot
    1054
        // =========================================================================
    1055
    1056
        #[test]
    1057
    1
        fn test_profiling_hotspot_debug() {
    1058
    1
            let hotspot = ProfilingHotspot {
    1059
    1
                component: "Attention".to_string(),
    1060
    1
                time: Duration::from_millis(100),
    1061
    1
                percentage: 50.0,
    1062
    1
                call_count: 1000,
    1063
    1
                avg_per_call: Duration::from_micros(100),
    1064
    1
                explanation: "Expected".to_string(),
    1065
    1
                is_expected: true,
    1066
    1
            };
    1067
    1
            let debug_str = format!("{:?}", hotspot);
    1068
    1
            assert!(debug_str.contains("ProfilingHotspot"));
    1069
    1
            assert!(debug_str.contains("Attention"));
    1070
    1
        }
    1071
    1072
        #[test]
    1073
    1
        fn test_profiling_hotspot_clone() {
    1074
    1
            let hotspot = ProfilingHotspot {
    1075
    1
                component: "GEMM".to_string(),
    1076
    1
                time: Duration::from_millis(200),
    1077
    1
                percentage: 75.0,
    1078
    1
                call_count: 500,
    1079
    1
                avg_per_call: Duration::from_micros(400),
    1080
    1
                explanation: "Matrix multiplication".to_string(),
    1081
    1
                is_expected: true,
    1082
    1
            };
    1083
    1
            let cloned = hotspot.clone();
    1084
    1
            assert_eq!(cloned.component, hotspot.component);
    1085
    1
            assert_eq!(cloned.percentage, hotspot.percentage);
    1086
    1
        }
    1087
    1088
        // =========================================================================
    1089
        // Coverage Tests: BenchmarkGrid
    1090
        // =========================================================================
    1091
    1092
        #[test]
    1093
    1
        fn test_benchmark_grid_new() {
    1094
    1
            let grid = BenchmarkGrid::new();
    1095
    1
            assert!(grid.gguf_apr.is_none());
    1096
    1
            assert!(grid.gguf_ollama.is_none());
    1097
    1
            assert!(grid.gguf_llamacpp.is_none());
    1098
    1
            assert!(grid.hotspots.is_empty());
    1099
    1
        }
    1100
    1101
        #[test]
    1102
    1
        fn test_benchmark_grid_with_model() {
    1103
    1
            let grid = BenchmarkGrid::new().with_model("Llama-7B", "7B", "Q4_K_M");
    1104
    1
            assert_eq!(grid.model_name, "Llama-7B");
    1105
    1
            assert_eq!(grid.model_params, "7B");
    1106
    1
            assert_eq!(grid.quantization, "Q4_K_M");
    1107
    1
        }
    1108
    1109
        #[test]
    1110
    1
        fn test_benchmark_grid_with_gpu() {
    1111
    1
            let grid = BenchmarkGrid::new().with_gpu("RTX 3090", 24.0);
    1112
    1
            assert_eq!(grid.gpu_name, "RTX 3090");
    1113
    1
            assert_eq!(grid.gpu_vram_gb, 24.0);
    1114
    1
        }
    1115
    1116
        #[test]
    1117
    1
        fn test_benchmark_grid_add_hotspot() {
    1118
    1
            let mut grid = BenchmarkGrid::new();
    1119
    1
            grid.add_hotspot(ProfilingHotspot {
    1120
    1
                component: "Test".to_string(),
    1121
    1
                time: Duration::from_millis(50),
    1122
    1
                percentage: 25.0,
    1123
    1
                call_count: 100,
    1124
    1
                avg_per_call: Duration::from_micros(500),
    1125
    1
                explanation: "Test hotspot".to_string(),
    1126
    1
                is_expected: true,
    1127
    1
            });
    1128
    1
            assert_eq!(grid.hotspots.len(), 1);
    1129
    1
            assert_eq!(grid.hotspots[0].component, "Test");
    1130
    1
        }
    1131
    1132
        // =========================================================================
    1133
        // Coverage Tests: render_bar edge cases
    1134
        // =========================================================================
    1135
    1136
        #[test]
    1137
    1
        fn test_render_bar_zero() {
    1138
    1
            let bar = render_bar(0.0, 100.0, 10);
    1139
    10
            assert_eq!1(bar.chars()1.filter1(|c| *c == '█').count1(), 0);
    1140
    10
            assert_eq!1(bar.chars()1.filter1(|c| *c == '░').count1(), 10);
    1141
    1
        }
    1142
    1143
        #[test]
    1144
    1
        fn test_render_bar_full() {
    1145
    1
            let bar = render_bar(100.0, 100.0, 10);
    1146
    10
            assert_eq!1(bar.chars()1.filter1(|c| *c == '█').count1(), 10);
    1147
    10
            assert_eq!1(bar.chars()1.filter1(|c| *c == '░').count1(), 0);
    1148
    1
        }
    1149
    1150
        #[test]
    1151
    1
        fn test_render_bar_over_max() {
    1152
    1
            let bar = render_bar(150.0, 100.0, 10);
    1153
            // Should clamp to max
    1154
    10
            assert_eq!1(bar.chars()1.filter1(|c| *c == '█').count1(), 10);
    1155
    1
        }
    1156
    1157
        // =========================================================================
    1158
        // Coverage Tests: truncate
    1159
        // =========================================================================
    1160
    1161
        #[test]
    1162
    1
        fn test_truncate_short_string() {
    1163
    1
            let result = truncate("short", 10);
    1164
    1
            assert_eq!(result, "short");
    1165
    1
        }
    1166
    1167
        #[test]
    1168
    1
        fn test_truncate_exact_length() {
    1169
    1
            let result = truncate("exactly10c", 10);
    1170
    1
            assert_eq!(result, "exactly10c");
    1171
    1
        }
    1172
    1173
        #[test]
    1174
    1
        fn test_truncate_long_string() {
    1175
    1
            let result = truncate("this is a very long string", 10);
    1176
    1
            assert_eq!(result.len(), 10);
    1177
    1
        }
    1178
    1179
        // =========================================================================
    1180
        // Coverage Tests: explain_inference_hotspot
    1181
        // =========================================================================
    1182
    1183
        #[test]
    1184
    1
        fn test_explain_inference_hotspot_gemv() {
    1185
    1
            let (explanation, is_expected) = explain_inference_hotspot("Q4K_GEMV", 50.0);
    1186
    1
            assert!(is_expected);
    1187
    1
            assert!(!explanation.is_empty());
    1188
    1
        }
    1189
    1190
        #[test]
    1191
    1
        fn test_explain_inference_hotspot_attention() {
    1192
    1
            let (explanation, is_expected) = explain_inference_hotspot("Attention", 30.0);
    1193
    1
            assert!(is_expected);
    1194
    1
            assert!(!explanation.is_empty());
    1195
    1
        }
    1196
    1197
        #[test]
    1198
    1
        fn test_explain_inference_hotspot_unknown() {
    1199
    1
            let (explanation, is_expected) = explain_inference_hotspot("UnknownComponent", 60.0);
    1200
            // High percentage for unknown component is unexpected
    1201
    1
            assert!(!is_expected);
    1202
    1
            assert!(!explanation.is_empty());
    1203
    1
        }
    1204
    1205
        #[test]
    1206
    1
        fn test_explain_inference_hotspot_low_percentage() {
    1207
    1
            let (explanation, is_expected) = explain_inference_hotspot("SomeComponent", 5.0);
    1208
            // Low percentage unknown component returns empty string and is expected
    1209
    1
            assert!(is_expected);
    1210
            // Note: The function returns empty string for low percentage unknown components
    1211
            // which means "nothing to report" - this is valid behavior
    1212
    1
            let _ = explanation;
    1213
    1
        }
    1214
    }