Skip to main content

cubecl_core/frontend/
debug.rs

1use alloc::{string::String, vec::Vec};
2
3use cubecl_ir::CubeFnSource;
4
5use crate::ir::{NonSemantic, Scope, Variable};
6
7use super::CubeDebug;
8
9/// Calls a function and inserts debug symbols if debug is enabled.
10#[track_caller]
11pub fn debug_call_expand<C>(
12    scope: &mut Scope,
13    line: u32,
14    col: u32,
15    call: impl FnOnce(&mut Scope) -> C,
16) -> C {
17    // Save source_loc before the call so it can be restored once the call returns
18    let source_loc = scope.debug.source_loc.take();
19    scope.update_span(line, col);
20    scope.register(NonSemantic::EnterDebugScope);
21    let ret = call(scope);
22    scope.register(NonSemantic::ExitDebugScope);
23    scope.debug.source_loc = source_loc;
24    ret
25}
26
27/// Calls an intrinsic op and inserts debug symbols if debug is enabled.
28#[track_caller]
29pub fn spanned_expand<C>(
30    scope: &mut Scope,
31    line: u32,
32    col: u32,
33    call: impl FnOnce(&mut Scope) -> C,
34) -> C {
35    scope.update_span(line, col);
36    call(scope)
37}
38
39/// Adds source instruction if debug is enabled
40#[track_caller]
41pub fn debug_source_expand(
42    scope: &mut Scope,
43    name: &'static str,
44    file: &'static str,
45    source_text: &'static str,
46    line: u32,
47    column: u32,
48) {
49    let file = file.replace("\\", "/");
50    scope.update_source(CubeFnSource {
51        function_name: name.into(),
52        file: file.into(),
53        source_text: source_text.into(),
54        line,
55        column,
56    });
57}
58
59/// Registers name for an expand if possible
60#[track_caller]
61pub fn debug_var_expand<E: CubeDebug>(scope: &mut Scope, name: &'static str, expand: E) -> E {
62    expand.set_debug_name(scope, name);
63    expand
64}
65
66/// Prints a formatted message using the print debug layer in Vulkan, or `printf` in CUDA.
67pub fn printf_expand(scope: &mut Scope, format_string: impl Into<String>, args: Vec<Variable>) {
68    scope.register(NonSemantic::Print {
69        format_string: format_string.into(),
70        args,
71    });
72}
73
74/// Print a formatted message using the target's debug print facilities. The format string is target
75/// specific, but Vulkan and CUDA both use the C++ conventions. WGSL isn't currently supported.
76#[macro_export]
77macro_rules! debug_print {
78    ($format:literal, $($args:expr),*) => {
79        {
80            let _ = $format;
81            $(let _ = $args;)*
82        }
83    };
84    ($format:literal, $($args:expr,)*) => {
85        $crate::debug_print!($format, $($args),*);
86    };
87}
88
89/// Print a formatted message using the target's debug print facilities. The format string is target
90/// specific, but Vulkan and CUDA both use the C++ conventions. WGSL isn't currently supported.
91#[macro_export]
92macro_rules! debug_print_expand {
93    ($scope:expr, $format:expr, $($args:expr),*) => {
94        {
95            let args = $crate::__private::vec![$(*$crate::ir::ExpandElement::from($args)),*];
96            $crate::frontend::printf_expand($scope, $format, args);
97        }
98    };
99    ($format:literal, $($args:expr,)*) => {
100        $crate::debug_print_expand!($format, $($args),*)
101    };
102}
103
104pub mod cube_comment {
105    use alloc::string::ToString;
106
107    use crate::ir::NonSemantic;
108    use cubecl_ir::Scope;
109
110    pub fn expand(scope: &mut Scope, content: &str) {
111        scope.register(NonSemantic::Comment {
112            content: content.to_string(),
113        });
114    }
115}