Skip to main content

rlx_runtime/
kernel_trace.rs

1// RLX — versatile ML compiler + runtime.
2// Copyright (C) 2026 Eugene Hauptmann, Nataliya Kosmyna.
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, version 3.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License
14// along with this program. If not, see <https://www.gnu.org/licenses/>.
15
16//! Compile-time gated kernel tracing (plan #7).
17//!
18//! Borrowed from MAX's `Trace, TraceLevel, trace_arg` pattern.
19//! Tracing calls are baked into hot paths but the *macro* expands to
20//! either a stamped `eprintln!` (when the `kernel-trace` feature is
21//! on) or to nothing (default). The compiler eliminates the
22//! disabled branch entirely — production builds pay zero overhead.
23//!
24//! Use it like:
25//! ```ignore
26//! rlx_runtime::ktrace!("matmul", "m={m} k={k} n={n}");
27//! ```
28//!
29//! The macro takes a `kind` (op/section name) and a format string
30//! plus args. Output is namespaced with `[ktrace:<kind>]` and
31//! includes a monotonic timestamp from `rlx_ir::Tick`.
32
33#[cfg(feature = "kernel-trace")]
34#[doc(hidden)]
35pub fn _emit(kind: &str, msg: std::fmt::Arguments<'_>) {
36    use std::sync::OnceLock;
37    static T0: OnceLock<rlx_ir::Tick> = OnceLock::new();
38    let start = *T0.get_or_init(rlx_ir::Tick::now);
39    let now = rlx_ir::Tick::now();
40    eprintln!("[ktrace:{kind}] +{:>10} ns  {msg}", now.elapsed_ns(start));
41}
42
43#[cfg(not(feature = "kernel-trace"))]
44#[doc(hidden)]
45pub fn _emit(_kind: &str, _msg: std::fmt::Arguments<'_>) {}
46
47/// Compile-time gated kernel trace. Expands to a no-op call without
48/// the `kernel-trace` feature; the optimizer removes it entirely.
49#[macro_export]
50macro_rules! ktrace {
51    ($kind:expr, $($arg:tt)+) => {{
52        $crate::kernel_trace::_emit($kind, format_args!($($arg)+));
53    }};
54}
55
56#[cfg(test)]
57mod tests {
58    #[test]
59    fn macro_compiles_and_runs() {
60        // The macro must compile and run regardless of feature state.
61        // With the feature off, this is a no-op call — verify it
62        // doesn't panic and doesn't write anything we can observe in
63        // a unit test.
64        crate::ktrace!("test", "x={} y={}", 1, 2);
65    }
66}