trueno/brick/profiler/tiling.rs
1//! Tile-level profiling methods for BrickProfiler.
2//!
3//! TILING-SPEC-001: Tile-Level Profiling Support (Phase 15).
4//! Extracted from mod.rs to keep file sizes manageable.
5
6use super::BrickProfiler;
7use crate::brick::profiler::tile_stats::{TileLevel, TileStats, TileTimer};
8use std::time::Instant;
9
10impl BrickProfiler {
11 // ========================================================================
12 // TILING-SPEC-001: Tile-Level Profiling (Phase 15)
13 // ========================================================================
14
15 /// Enable tile-level profiling.
16 ///
17 /// When enabled, `start_tile()`/`stop_tile()` record per-tile statistics
18 /// for Macro/Midi/Micro tile hierarchy.
19 pub fn enable_tile_profiling(&mut self) {
20 self.tile_profiling_enabled = true;
21 }
22
23 /// Disable tile-level profiling.
24 pub fn disable_tile_profiling(&mut self) {
25 self.tile_profiling_enabled = false;
26 }
27
28 /// Check if tile profiling is enabled.
29 #[must_use]
30 pub fn is_tile_profiling_enabled(&self) -> bool {
31 self.tile_profiling_enabled
32 }
33
34 /// Start timing a tile execution.
35 ///
36 /// Returns a `TileTimer` that should be passed to `stop_tile()` after
37 /// the tile computation completes.
38 ///
39 /// # Arguments
40 /// - `level`: Tile hierarchy level (Macro/Midi/Micro)
41 /// - `row`: Row index within parent tile
42 /// - `col`: Column index within parent tile
43 ///
44 /// # Example
45 /// ```rust,ignore
46 /// let timer = profiler.start_tile(TileLevel::Macro, 0, 0);
47 /// // ... execute tile computation ...
48 /// profiler.stop_tile(timer, 256 * 256, 2 * 256 * 256 * 256);
49 /// ```
50 #[must_use]
51 pub fn start_tile(&self, level: TileLevel, row: u32, col: u32) -> TileTimer {
52 TileTimer { level, _row: row, _col: col, start: Instant::now() }
53 }
54
55 /// Stop timing and record tile statistics.
56 ///
57 /// # Arguments
58 /// - `timer`: Timer handle from `start_tile()`
59 /// - `elements`: Number of elements processed by this tile
60 /// - `flops`: Number of floating-point operations performed
61 pub fn stop_tile(&mut self, timer: TileTimer, elements: u64, flops: u64) {
62 if !self.tile_profiling_enabled {
63 return;
64 }
65
66 let elapsed_ns = timer.start.elapsed().as_nanos() as u64;
67 let idx = timer.level as usize;
68 self.tile_stats[idx].add_sample(elapsed_ns, elements, flops);
69 }
70
71 /// Get tile statistics for a given level.
72 #[must_use]
73 pub fn tile_stats(&self, level: TileLevel) -> &TileStats {
74 &self.tile_stats[level as usize]
75 }
76
77 /// Get mutable tile statistics for a given level.
78 pub fn tile_stats_mut(&mut self, level: TileLevel) -> &mut TileStats {
79 &mut self.tile_stats[level as usize]
80 }
81
82 /// Get all tile statistics as a slice.
83 #[must_use]
84 pub fn all_tile_stats(&self) -> &[TileStats; 3] {
85 &self.tile_stats
86 }
87
88 /// Reset tile statistics for all levels.
89 pub fn reset_tile_stats(&mut self) {
90 self.tile_stats = [
91 TileStats::new(TileLevel::Macro),
92 TileStats::new(TileLevel::Midi),
93 TileStats::new(TileLevel::Micro),
94 ];
95 }
96}