TL Agent Deterministic Fallback - #970
Open
tsrikris wants to merge 6 commits into
Open
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
….com/AMD-AGI/TraceLens into feat/tl_agent_deterministic_fallback ""
gabeweisz
reviewed
Aug 27, 2026
| # --------------------------------------------------------------------------- | ||
| # Fixture helpers | ||
| # --------------------------------------------------------------------------- | ||
| def _make_perf_csv(tmp_path, rows): |
Collaborator
There was a problem hiding this comment.
I feel like this function should not be necessary. But I guess this is a test so maybe not a big deal
| writer.writerow(["name", _WEIGHT_COLUMN, _PERCENT_COLUMN]) | ||
| for row in rows: | ||
| name, weight = row[0], row[1] | ||
| percent = row[2] if len(row) > 2 else 0.0 |
Collaborator
There was a problem hiding this comment.
It looks like the code that generates the rows has to generate 3 inputs - so isn't missing the third columns an error?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deterministic (no-LLM) fallback for graph-collapsed traces
Some inference traces are graph-under-recorded: a GPU graph replay or a
compiled region collapses the whole workload behind a single launch, so the
profiler records device kernels but not the per-op decomposition (Python / aten
op, shapes, launcher path) the analysis pipeline needs. On these traces per-op
decomposition fails and the LLM analysis path cannot run.
This change adds a deterministic fallback that still emits a parser-compatible
analysis.md. It recovers the only three things a graph-collapsed trace carries(kernel name, time, and %E2E) and marks every other field as unrecoverable
instead of guessing at it.
Architecture
The fallback branch is a drop-in: it emits the same
analysis.mdmarker andtable contract as the full analysis path, so a downstream consumer that parses
analysis.mdneeds no structural change.Design
check_graph_replay_coverage()reads the already-writtenperf_report_csvs/,computes the fraction of device time hidden behind graph-replay / compiled-region
launches, and trips when it exceeds
GRAPH_REPLAY_FRACTION_MAX. Benigneager-launch and memcpy plumbing wrappers (present in healthy traces too) are
excluded, so the signal isolates the pathology.
render_fallback_report()builds P-items from the surviving device-kernel rows, ranks them by %E2E, and
writes the contract the pipeline already emits:
#### P{rank}:headings, onereasoning-candidatemarker and oneimpact-begin kind=p_itemmarker per P-item,and the 9-column
**Data:**table. No LLM, no GPU, fully deterministic.(Operation, Args, Kernel Path, Count, FLOPS/Byte, Efficiency, Bound) render a
literal
—instead of a fabricated or duplicated value. The raw device symbol ispreserved verbatim in the
Kernel Namecell so a downstream consumer can key on it,and the P-item heading shows a display-shortened form of that symbol.
%E2Efloor (MIN_PITEM_PERCENT_E2E) plus a defensivecount cap (
MAX_PITEM_COUNT) collapse noisy traces to the significant few. Thepercentage denominator is built over all surviving rows before filtering, so
dropping the tail never inflates the survivors. Drops are reported in the banner
(never silent) when non-zero.
_normalize_kernel_name()shortens the P-itemheading to a fixed length with a truncation marker. It never demangles and never
strips qualifiers, so the symbol in
Kernel Nameand the impact-grouping key bothstay raw. Two long GEMM variants that differ only past the truncation boundary
collapse to the same heading but remain distinct P-items in the arithmetic.
recoverable (kernel, time, %E2E), and what was never captured (shapes, launcher
path, quant operands, category, efficiency), so the report can never be mistaken for
a full analysis.
very large cells exceeded
csv's default field limit and aborted the gate before itcould pass. A module-level
csv.field_size_limit(...)is now raised once with aplatform-safe clamp (start high, halve on
OverflowError).pipeline by one, so the orchestrator prep, the validation utility, and the
orchestrator skill / reference / template prose were renumbered in lockstep. This is
prose and print-label only, with no logic change.
Validation
tests/test_analysis_agent_deterministic.pycovers the gate(fraction math, plumbing-wrapper exclusion, field-size case), the writer contract
(markers 1:1 with P-items, unrecoverable cells em-dashed, raw kernel name preserved,
normalized heading), the normalizer matrix (identity / truncate / mangled-stays-raw
/ length boundary / never-empty), the floor/cap boundaries and drop reporting, and
the consumer-side substitution of the kernel name when Operation is an em dash. No
GPU, no LLM.
inference traces spanning distinct workload shapes (dense and MoE decode, diffusion
image generation, speculative decode). Each tripped the Step 2 gate and routed to
the fallback, and every report preserved the marker contract
(
reasoning-candidate=impact-begin= data-tables = P-item count) with the floorand cap applied.
exists, the fallback recovers the complete compute-heavy tail (every dominant GEMM,
attention, quantization, sort, and norm kernel), and surfaces additional
kernel-granular items the category-grouped path folds together. The only kernels it
cannot recover are ones that live inside a fused region and are visible only when
capture-enabled decomposition splits them apart. That is a genuine limit of a
graph-collapsed trace, and the
—cells reflect it honestly.fires.
Downstream / contract impact
The change is additive and parser-compatible. The 9-column table header, the
#### P{rank}:/reasoning-candidate/impact-beginmarkers, and their attributenames are all unchanged. The one behavioral note for a downstream consumer is the
—Operationcell: a consumer that today drops rows with an empty Operation shouldsubstitute the
Kernel Namesymbol for those rows (a backward-compatible readerrelaxation) so that fallback reports parse to the intended candidates.
Test plan
pytest tests/test_analysis_agent_deterministic.pyblack --checkon all changed Python (clean)