Skip to main content

trueno/tuner/brick_tuner/
render.rs

1//! TUI rendering methods for BrickTuner recommendations.
2//!
3//! Provides console and TUI panel output for tuner recommendations,
4//! including full panels, compact status bars, and prediction comparisons.
5
6use super::super::helpers::pad_right;
7use super::BrickTuner;
8use super::TunerRecommendation;
9
10impl BrickTuner {
11    /// Print recommendations to console (TUI-friendly)
12    pub fn print_recommendation(&self, rec: &TunerRecommendation) {
13        println!("╭─────────────────────────────────────────────────────────────╮");
14        println!("│           BrickTuner Recommendations v{}                 │", self.version);
15        println!("├─────────────────────────────────────────────────────────────┤");
16        println!(
17            "│ Predicted throughput: {:>7.1} tok/s ({:>4.0}% confidence)     │",
18            rec.throughput.predicted_tps,
19            rec.throughput.confidence * 100.0
20        );
21        println!(
22            "│ Recommended kernel:   {:>15?} ({:>4.0}% conf)       │",
23            rec.kernel.top_kernel,
24            rec.kernel.confidence * 100.0
25        );
26        println!(
27            "│ Bottleneck class:     {:>15} ({:>4.0}% conf)       │",
28            rec.bottleneck.class,
29            rec.bottleneck.confidence * 100.0
30        );
31        println!("├─────────────────────────────────────────────────────────────┤");
32        println!("│ Explanation: {}│", pad_right(&rec.bottleneck.explanation, 47));
33        println!("├─────────────────────────────────────────────────────────────┤");
34        println!("│ Suggested experiments:                                      │");
35        for (i, exp) in rec.suggested_experiments.iter().take(3).enumerate() {
36            println!("│  {}. {}│", i + 1, pad_right(&exp.to_string(), 56));
37        }
38        println!("╰─────────────────────────────────────────────────────────────╯");
39    }
40
41    // ========================================================================
42    // T-TUNER-006: cbtop TUI Integration (GitHub #83)
43    // ========================================================================
44
45    /// Render recommendation as TUI panel lines (for cbtop integration)
46    ///
47    /// Returns a vector of strings that can be rendered in a TUI widget.
48    /// Each line is formatted for fixed-width display (width=61 chars).
49    pub fn render_panel(&self, rec: &TunerRecommendation) -> Vec<String> {
50        let mut lines = Vec::with_capacity(12);
51
52        lines.push(format!(
53            "│           BrickTuner Recommendations v{}                 │",
54            self.version
55        ));
56        lines.push("├─────────────────────────────────────────────────────────────┤".to_string());
57        lines.push(format!(
58            "│ Predicted throughput: {:>7.1} tok/s ({:>4.0}% confidence)     │",
59            rec.throughput.predicted_tps,
60            rec.throughput.confidence * 100.0
61        ));
62        lines.push(format!(
63            "│ Recommended kernel:   {:>15?} ({:>4.0}% conf)       │",
64            rec.kernel.top_kernel,
65            rec.kernel.confidence * 100.0
66        ));
67        lines.push(format!(
68            "│ Bottleneck class:     {:>15} ({:>4.0}% conf)       │",
69            rec.bottleneck.class,
70            rec.bottleneck.confidence * 100.0
71        ));
72        lines.push("├─────────────────────────────────────────────────────────────┤".to_string());
73        lines.push(format!("│ Explanation: {}│", pad_right(&rec.bottleneck.explanation, 47)));
74        lines.push("├─────────────────────────────────────────────────────────────┤".to_string());
75        lines.push("│ Suggested experiments:                                      │".to_string());
76
77        for (i, exp) in rec.suggested_experiments.iter().take(3).enumerate() {
78            lines.push(format!("│  {}. {}│", i + 1, pad_right(&exp.to_string(), 56)));
79        }
80
81        // Pad if fewer than 3 suggestions
82        for _ in rec.suggested_experiments.len()..3 {
83            lines.push(
84                "│                                                             │".to_string(),
85            );
86        }
87
88        lines.push("├─────────────────────────────────────────────────────────────┤".to_string());
89        lines.push("│ [Press 'a' to apply] [Press 't' to toggle] [Press 'r' to run]│".to_string());
90
91        lines
92    }
93
94    /// Render compact recommendation (single line for status bar)
95    pub fn render_compact(&self, rec: &TunerRecommendation) -> String {
96        format!(
97            "Tuner: {:.0} tok/s | {:?} | {} ({:.0}%)",
98            rec.throughput.predicted_tps,
99            rec.kernel.top_kernel,
100            rec.bottleneck.class,
101            rec.confidence_overall * 100.0
102        )
103    }
104
105    /// Render prediction vs actual comparison
106    pub fn render_comparison(&self, rec: &TunerRecommendation, actual_tps: f32) -> Vec<String> {
107        let error_pct = if actual_tps > 0.0 {
108            ((rec.throughput.predicted_tps - actual_tps) / actual_tps * 100.0).abs()
109        } else {
110            0.0
111        };
112
113        let accuracy_indicator = if error_pct < 5.0 {
114            "🎯 Excellent"
115        } else if error_pct < 10.0 {
116            "✓ Good"
117        } else if error_pct < 20.0 {
118            "△ Fair"
119        } else {
120            "✗ Poor"
121        };
122
123        vec![
124            format!(
125                "│ Predicted: {:>7.1} tok/s  Actual: {:>7.1} tok/s           │",
126                rec.throughput.predicted_tps, actual_tps
127            ),
128            format!(
129                "│ Error: {:>5.1}%  Accuracy: {:>12}                       │",
130                error_pct, accuracy_indicator
131            ),
132        ]
133    }
134}