Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cutile-rs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/).

### Fixed

- Generated constants without captured source spans use their containing
function definition, retaining exact user-expression locations and nested
cross-file inline caller chains.

- Const-generic array bindings retain their function or method signature as
their source origin, and generated reduction bodies retain the reduction
call's location and inline chain.
Expand Down
9 changes: 9 additions & 0 deletions cutile-rs/cutile-book/guide/debugging-and-profiling.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,15 @@ when inlined, including across modules. Core operations are attributed to
the user's call site. Multiple generated instructions can still map to one
Rust line; this is not a one-to-one mapping, especially with optimization.

Known toolkit limitation: tileiras **13.4.59** (in the CUDA 13.4.1 CI image) and
**13.4.92** can replace Rust helper locations
with generated Tile IR locations and omit inline frames, even when the frontend
bytecode contains the correct source information. This affects source correlation
and helper backtraces. The same bytecode retains those locations with tileiras
13.3.36. CI reports this exact backend limitation while continuing to
check frontend origins and surviving kernel locations; it does not waive checks
for other releases, including 13.5. See [#1385](https://github.com/NVIDIA/cuda-rust/pull/1385).

Generated const-generic array bindings use the containing function or method's
signature as their source origin. Generated reduction bodies use the reduction
call's location, including its inline caller chain.
Expand Down
25 changes: 23 additions & 2 deletions cutile-rs/cutile-compiler/src/compiler/_function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -784,9 +784,25 @@ impl<'m> CUDATileFunctionCompiler<'m> {
/// stack.
pub(crate) fn ir_location(&self, span: &proc_macro2::Span) -> cutile_ir::ir::Location {
let stack = self.call_site_stack.borrow();
// Runtime parsing gives each captured module its own source span.
// Generated types, arrays, and wrapper calls do not join that span.
let captured_location = || {
self.modules
.name_resolver
.all_modules()
.iter()
.find_map(|(name, module)| {
module.ident.span().join(*span)?;
let base = self.modules.get_span_base(name).filter(|b| b.is_known())?;
Some(base.resolve_span(span))
})
};
let (caller, callee_scope, span_base) = match stack.last() {
None => {
let loc = self.resolve_span(span);
let loc = captured_location().unwrap_or_else(|| {
self.span_base()
.resolve_span(&self._function.sig.ident.span())
});
return if loc.is_known() {
cutile_ir::ir::Location::FileLineCol {
filename: loc.file,
Expand All @@ -809,7 +825,12 @@ impl<'m> CUDATileFunctionCompiler<'m> {
// callee's own module base; scope the op to the CALLEE's subprogram
// (so inline debug frames name the inlined function, not the kernel
// entry) and chain where it was inlined.
let loc = span_base.resolve_span(span);
let loc = captured_location().unwrap_or_else(|| match callee_scope {
Some(scope) if span_base.is_known() => {
SourceLocation::new(span_base.file.clone(), scope.line as usize, 0)
}
_ => SourceLocation::unknown(),
});
if !loc.is_known() {
return cutile_ir::ir::Location::Unknown;
}
Expand Down
Loading
Loading