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, Value};
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: &Scope,
13    line: u32,
14    col: u32,
15    call: impl FnOnce(&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.borrow_mut() = source_loc;
24    ret
25}
26
27/// Adds source instruction if debug is enabled
28#[track_caller]
29pub fn debug_source_expand(
30    scope: &Scope,
31    name: &'static str,
32    file: &'static str,
33    source_text: &'static str,
34    line: u32,
35    column: u32,
36) {
37    let file = file.replace("\\", "/");
38    scope.update_source(CubeFnSource {
39        function_name: name.into(),
40        file: file.into(),
41        source_text: source_text.into(),
42        line,
43        column,
44    });
45}
46
47/// Registers name for an expand if possible
48#[track_caller]
49pub fn debug_var_expand<E: CubeDebug>(scope: &Scope, name: &'static str, expand: E) -> E {
50    expand.set_debug_name(scope, name);
51    expand
52}
53
54/// Prints a formatted message using the print debug layer in Vulkan, or `printf` in CUDA.
55pub fn printf_expand(scope: &Scope, format_string: impl Into<String>, args: Vec<Value>) {
56    scope.register(NonSemantic::Print {
57        format_string: format_string.into(),
58        args,
59    });
60}
61
62/// Print a formatted message using the target's debug print facilities. The format string is target
63/// specific, but Vulkan and CUDA both use the C++ conventions. WGSL isn't currently supported.
64#[macro_export]
65macro_rules! debug_print {
66    ($format:literal, $($args:expr),*) => {
67        {
68            let _ = $format;
69            $(let _ = $args;)*
70        }
71    };
72    ($format:literal, $($args:expr,)*) => {
73        $crate::debug_print!($format, $($args),*);
74    };
75}
76
77/// Print a formatted message using the target's debug print facilities. The format string is target
78/// specific, but Vulkan and CUDA both use the C++ conventions. WGSL isn't currently supported.
79#[macro_export]
80macro_rules! __expand_debug_print {
81    ($scope:expr, $format:expr, $($args:expr),*) => {
82        {
83            let args = $crate::__private::vec![$($crate::ir::Value::from($args)),*];
84            $crate::frontend::printf_expand($scope, $format, args);
85        }
86    };
87    ($format:literal, $($args:expr,)*) => {
88        $crate::__expand_debug_print!($format, $($args),*)
89    };
90}
91
92pub mod cube_comment {
93    use alloc::string::ToString;
94
95    use crate::ir::NonSemantic;
96    use cubecl_ir::Scope;
97
98    pub fn expand(scope: &Scope, content: &str) {
99        scope.register(NonSemantic::Comment {
100            content: content.to_string(),
101        });
102    }
103}