π Minor Release β 49 commits since v0.2.1
CUTracer v0.3.0 (2026-04-23 β 2026-06-09) is a substantial minor release that focuses on three big themes: (1) a new high-performance RapidJSON trace serializer that becomes the default and removes ~16% of host-CPU overhead, (2) the completed NVBit 1.8 first-class TMA capture pipeline, which records fully-structured tensor metadata instead of opaque parameter handles, and (3) warpgroup-targeted random-delay injection that can stall an entire warp or warpgroup as a single scheduling unit to reproduce cross-warpgroup scheduler races. The release also expands the trace schemas to cover every record type the writer emits (with a CI drift guard), and migrates the repository from facebookresearch to facebookexperimental with the wiki now living under docs/.
β¨ Highlights
- RapidJSON trace serializer (default) β Removes ~16% host CPU and ~8% malloc churn from the per-record write path; byte-identical output to the legacy
nlohmannpath for reg/mem/opcode/mem_value records. - Warpgroup-targeted random delay β
--delay-warpgroup-id/--delay-warp-mask/--delay-enable-probflags letrandom_delaystall an entire warp or warpgroup as a single scheduling unit, enabling reproduction of cross-warpgroup scheduler races that per-thread delays could not. - NVBit 1.8 TMA capture pipeline β Migration to first-class
nvbit_parse_tma_transfer_info(); the trace now carries structured tensor metadata (dim, dtype, strides, swizzle, SMEM dst/src/mbar addresses) instead of opaque parameter handles. - Complete trace-record schemas + drift guard β New JSON Schemas for
tma_trace,mem_value_trace, andmem_addr_trace, plus a CI guard that catches writer/schema divergence. - Repository migrated to
facebookexperimentalβ Wiki content moved intodocs/with an auto-sync workflow; CI gains a self-hosted H100 lane and retires the legacy T4 GitHub-hosted workflow.
ποΈ Capture-Side Serializer Overhaul (RapidJSON)
A capture CPU profile attributed ~16% of host CPU to per-record nlohmann::json DOM serialization plus ~8% malloc churn from per-record std::stringstream hex formatting. This release ports the entire hot path to a streaming rapidjson::Writer and makes it the default.
- Opt-in RapidJSON path β Adds a streaming
Writerinto a reusedthread_local StringBufferforreg_trace/mem_addr_trace/mem_value_trace/opcode_only; during the migration window this was gated behindCUTRACER_JSON_ENGINE={nlohmann,rapidjson,ab}with anaboracle that semantically compared both engines per record and reported per-type match/mismatch counters at writer teardown. - Unit-test the RapidJSON serializer β Extracted to its own translation unit with cxx goldens, exercising all four record types.
- Port
tma_traceβ Removes the lastnlohmannfallback in the per-record path; semantically identical on 2,304 TMA descriptors. - RapidJSON becomes the default β Removes the
CUTRACER_JSON_ENGINEswitch, the A/B comparison machinery,build_nlohmann_line, and the entire per-recordnlohmannserializer family (~390 lines net).nlohmannis retained only for the one-timekernel_metadataheader. - Heap-corruption fix in TraceWriter (#225) β Serialize public mutators with
std::mutexto prevent libstdc++_M_mutateheap double-free that surfaced as "JSON decode error - unexpected character" at ~7% per kernel-run on aarch64. Replaces a misleading "CRITICAL FIX"std::movedance that did not actually fix the race. - OSS install fix (#224) β
install_third_party.shnow downloadsrapidjsonheaders so the OSS CI build succeeds.
π― Warpgroup-Targeted Random Delay
Per-thread random delay washes out at the warp boundary (warps are lock-step, so the effective stall is max(thread_delays)), and existing CTA-local modes operate on clusters, not warp ranges within a single CTA. This release teaches random_delay to stall an entire warp or warpgroup as a single scheduling unit β the exact timing distribution needed to reproduce cross-warpgroup scheduler races such as SM100 flash-attention TMEM dealloc.
- Device function + host wrapper β New
instrument_delay_warpgroup(pred, delay_ns, warp_mask)ininject_funcs.cuandinstrument_warpgroup_delay_injectionhost wrapper. Computes CTA-local warp id fromthreadIdx/blockDim, tests thewarp_maskbit, and__nanosleeps the entire warp uniformly via the same 1ms chunked loop asinstrument_delay_random_cluster. - CLI flags + env vars β
--delay-warp-mask(CUTRACER_DELAY_WARP_MASK; hex or decimal CTA-local warp bitmask) and--delay-warpgroup-id(CUTRACER_DELAY_WARPGROUP_ID; integer warpgroup index that resolves to0xF << (id * 4)on the host and wins over--delay-warp-maskwhen both are set). - Dispatcher routing +
--delay-enable-probβ Routes warp targeting through the existing delay dispatcher incutracer.cuand adds a probability gate (default 0.5 preserves the historical 50/50 PC gate; set to 1.0 for deterministic injection β strongly recommended with warp targeting). - Persist warp targeting in delay config JSON β Replay mode (
--delay-load-path) now round-trips warp/warpgroup targeting for deterministic reproduction.
π‘ TMA Pipeline (NVBit 1.8 Migration)
Migrates TMA tracing off non-public ISA semantics (URa/URa+1 layout, MULTICAST register-shift workarounds) and onto NVBit 1.8's first-class TMA APIs.
- GPU-side capture β Asks NVBit for the TMA parameter handle directly via the new public API.
- Host-side parsing β Calls
nvbit_parse_tma_transfer_info()from the receive thread to decode the runtime handle into a structuredTMATransferInfo_t; the trace now carries fully-structured tensor metadata (dim, mode, coords, dtype, rank, global address/dim/strides, box dim, swizzle). - SMEM dst/src addresses β Serializes
dst.data_address,dst.mbar_address(andsrc.*forUTMASTG) from NVBit 1.8'sTMAAddress_tunion. These are the official NVBit API equivalent of the URb/URb+1 register values, so capture no longer relies on implicit register snapshotting inreg_trace.
π§ͺ Schema & Validation
- Trace schemas for every record type + drift guard β Adds JSON Schemas for
tma_trace,mem_value_trace, andmem_addr_trace. PreviouslySCHEMAS_BY_TYPEonly coveredreg_trace/mem_trace/opcode_only/kernel_metadata, sovalidate/comparesilently skipped every current trace's data records. A new CI drift guard catches writer/schema divergence. - SM100 uniform-register indices β
reg_traceschema'suregs_indicesmaximum raised from 62 to 255 (matchesregs_indices) to avoid chasing per-arch maximums; both areuint8_tregister indices where high values encode special registers.
π₯οΈ CLI Changes
# New short alias for --output-dir (matches gcc/ffmpeg/curl/tar convention)
cutracer trace -o ./logs -- python my_kernel.py
# Warpgroup-targeted delay (stall warpgroup 1)
cutracer trace -i random_delay --delay-ns 100000 \
--delay-warpgroup-id 1 \
--delay-enable-prob 1.0 \
-- python my_kernel.py
# Or an explicit CTA-local warp bitmask (warps 4-7)
cutracer trace -i random_delay --delay-ns 100000 \
--delay-warp-mask 0xF0 \
-- python my_kernel.py- Friendlier
traceerrors β Three UX fixes for the intentionally permissivetracesubcommand (ignore_unknown_options=True,nargs=-1,type=click.UNPROCESSED): clearer messages when wrapped command tokens leak into CUTracer's own option parser, a warning when running underbuck2 test, and absolute-path resolution for the wrapped command. -oshort alias β Closes the foot-gun where a stray-o ./logswas silently appended to the wrapped command (yielding/bin/sh: - : invalid option) because the trace subcommand passes unknown options through to the target binary.
π Configuration Changes
Removed Environment Variables
| Variable | Notes |
|---|---|
CUTRACER_JSON_ENGINE |
The opt-in switch from the RapidJSON migration window. No longer required β RapidJSON is now the default and only per-record path; the nlohmann per-record code was removed. |
New Environment Variables
| Variable | Description | Default |
|---|---|---|
CUTRACER_DELAY_WARP_MASK |
CTA-local warp bitmask for random_delay. Accepts hex (0xF) or decimal (15). 0 = disabled. |
0 |
CUTRACER_DELAY_WARPGROUP_ID |
Warpgroup index; >= 0 selects warps [4N..4N+3] and wins over CUTRACER_DELAY_WARP_MASK. -1 = disabled. |
-1 |
CUTRACER_DELAY_ENABLE_PROB |
Probability per PC of enabling delay during recording (random mode). Set to 1.0 for deterministic injection. |
0.5 |
π Dependency Updates
- NVBit: 1.7 β 1.8 (first-class TMA APIs:
nvbit_parse_tma_transfer_info,TMATransferInfo_t,TMAAddress_t) - RapidJSON: now a vendored header dependency installed by
install_third_party.sh(used as the default trace serializer)
ποΈ Infrastructure
- Repository migration β
facebookresearch/CUTracerβfacebookexperimental/CUTracer. PR references in commit messages reflect the new org from #213 onward. - Wiki β
docs/β The GitHub Wiki content now lives in-repo underdocs/with an auto-sync workflow. - CONTRIBUTING.md β Reset to the standard GitHub contributing template.
- Monthly stale-PR cleanup workflow β Adds a scheduled job to prune stale PR branches.
- Per-test/per-run subdir layout β
tests/py_addreorganized withTEST_KEEP_OUTPUTsupport for debugging.
CI
- H100 CI lane (#219, #217) β A new self-hosted H100 workflow running the upstream Triton test suite, alongside the existing T4
test.yml(later retired below). - Triton-Nightly matrix leg (#218) β Replaces
install-triton.shwith a matrixed nightly install; nightly pinned to the latest upstream commit (workaround for in-flight breakage). - Inductor inline-compile (#223) β
test_add.pyforces inductor inline compile to dodge an upstream Triton subprocess-pool driver crash. - Retired legacy cu128 T4 workflow (#226) β
test.ymlremoved in favor of the new H100 lane. - OSS unit-test fix (#222) β Separates the Meta-internal unit tests so the OSS unit-test suite builds cleanly.
- PyPI publish hardening β
pypa/gh-action-pypi-publishpinned to a commit SHA innightly-pypi.yml.
π Notable Bug Fixes
- NDJSON heap double-free (#225) β Concurrent
std::string::appendon the sharedjson_buffer_triggered libstdc++_M_mutatedouble-free under ASan; surfaced in OSS CI as random "unexpected character" JSON decode errors at ~7% per kernel-run on aarch64. Fixed by serializingwrite_tracewithstd::mutex. uregs_indicesschema bound β Raised from 62 to 255 so new Blackwell architectures don't breakvalidate.
β οΈ Breaking Changes
CUTRACER_JSON_ENGINEenv var removed β The opt-in switch from the migration window is gone now that RapidJSON is the default and thenlohmannper-record path has been deleted. Output is byte-identical for reg/mem/opcode/mem_value records and semantically identical fortma_trace. No user action required unless you were settingCUTRACER_JSON_ENGINE=abfor serializer parity testing.- GitHub organization moved β Repository now lives at
facebookexperimental/CUTracer. Update any pinned remotes / submodule URLs / CI references. - Legacy T4 CI workflow retired β Anything that referenced the
test.ymlworkflow name in T4-targeted automation should switch to the new H100 workflow.
Everything else is additive (new flags, new schemas).
π Acknowledgments
CUTracer is built on NVBit by NVIDIA Research. We thank the NVBit team for their excellent binary instrumentation framework β and in particular for the NVBit 1.8 TMA APIs that let this release retire CUTracer's non-public-ISA TMA workarounds.
Contributors to this release: Chen Li, Lei Wang, Xu Zhao, Yueming Hao (alphabetical).
π License
- MIT License β Meta Platforms, Inc. contributions
- BSD-3-Clause License β NVIDIA NVBit components
See LICENSE and LICENSE-BSD for details.
π Documentation
Full documentation is now in-repo under docs/ (auto-synced to the Wiki).