Debugger#
FlagPrism Debugger observes values, memory access, and operation execution inside a Triton kernel. It associates compile-time static metadata with device-runtime records, then exports Triton statement-level reports, IR op-level reports, and level-2 NumPy artifacts. It is used to locate numerical anomalies, abnormal memory access, and in-kernel data-flow issues.
The dynamic collection and hidden-argument launch path is validated on Ascend/CANN9, Tianshu/CoreX 4.4 (LLVM 22), MUSA/mthreads 4.3.5, and NVIDIA CUDA.
Public API#
The only public Python import path is:
import flagtree.debugger as debugger
The legacy triton.debugger namespace is not provided. Collection boundaries inside a Triton JIT kernel are expressed with FlagTree language extensions:
ftl.debug_collect_start(level=1, addr_level=1)
# Triton operations to collect
ftl.debug_collect_end()
flagtree.debugger handles Python configuration, compile mode, and export; ftl.debug_collect_start/end only marks the IR region to collect inside an @triton.jit kernel. Passing level to debug_collect_start overrides the collection level for that region; addr_level=None inherits the level from activate().
Quick start#
from pathlib import Path
import torch
import torch_npu
import triton
import flagtree.debugger as debugger
import flagtree.language as ftl
import triton.language as tl
debugger.configure(
output_dir=Path("/tmp/flagtree_debugger_example"),
record_capacity=4096,
export_raw_records=False,
)
debugger.activate(level=1, addr_level=1)
@triton.jit
def debug_abs_kernel(x_ptr, y_ptr, n: tl.constexpr, BLOCK_SIZE: tl.constexpr):
offsets = tl.program_id(0) * BLOCK_SIZE + tl.arange(0, BLOCK_SIZE)
mask = offsets < n
ftl.debug_collect_start(level=1, addr_level=1)
x = tl.load(x_ptr + offsets, mask=mask, other=0.0)
y = tl.abs(x)
z = y + 1.0
tl.store(y_ptr + offsets, z, mask=mask)
ftl.debug_collect_end()
n = 16
x = torch.linspace(-8, 7, n, dtype=torch.float32, device="npu")
y = torch.empty_like(x)
debug_abs_kernel[(1,)](x, y, n, BLOCK_SIZE=16)
torch_npu.npu.synchronize()
for run in debugger.take_exported_runs():
print("report_path=", run.get("report_path"))
Call debugger.activate() before compiling the kernel you want to debug. It enables a process-level Debugger pipeline but does not record Python, PyTorch, or torch_npu operations; only Triton operations between the collect markers are captured.
Configuration#
debugger.configure() changes the defaults used by subsequent activate() calls; unspecified fields keep their current values.
debugger.configure(
output_dir="/tmp/flagtree_debugger_manual",
record_capacity=4096,
export_mode="POST_KERNEL_EXPORT",
export_on_error=False,
export_raw_records=False,
timeline=False,
)
Option |
Default |
Meaning |
|---|---|---|
|
|
Report output directory; |
|
|
Device record slot capacity; must be a positive integer. |
|
|
Export after the kernel completes; |
|
|
Whether to still attempt export after a kernel error. |
|
|
Whether to additionally write a decoded raw-record sidecar. |
|
|
Insert device timestamp timeline records on supporting backends. |
Inspect and restore the configuration:
print(debugger.get_config())
debugger.reset_config()
Collection levels#
level and addr_level are collection strategies configured through activate():
debugger.activate(level=1, addr_level=1, timeline=True)
level=1: collect numerical summaries.level=2: collect summaries and export the supported full tensor values.addr_level=0: do not insert dynamic address collection.addr_level=1: collect address summaries for load/store.addr_level=2: whenlevel=2and the backend supports the current pointer/mask pattern, additionally export full lane addresses.timeline=True: collect device-wide nanosecond timestamps (PTX%globaltimeron NVIDIA CUDA;SYS_CNTon Ascend). Disabled by default to avoid extra device-side record overhead.
For long-running processes, notebooks, or test suites, the pipeline can be turned off when no more debug kernels will be compiled:
debugger.deactivate()
Availability#
After a successful import, debugger.is_available() reports whether both the compiler and runtime native bindings are present. A core-only wheel (TRITON_BUILD_FLAGPRISM=OFF) does not include flagtree.debugger.