Skip to main content

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}