fix(bypass): honest CUDA-graph handling in the TraceLens-free trace analysis - #1047
Closed
zengleixin-amd wants to merge 8 commits into
Closed
fix(bypass): honest CUDA-graph handling in the TraceLens-free trace analysis#1047zengleixin-amd wants to merge 8 commits into
zengleixin-amd wants to merge 8 commits into
Conversation
…loop The TraceLens-free bypass trace reader ignored cuda_runtime event names, so it never saw CUDA-graph replay launches (cudaGraphLaunch/hipGraphLaunch). Under graph replay the profiler under-records device kernels, so the union of recorded kernel intervals covers only a fraction of the real GPU-busy time and idle_pct reads spuriously high (~99%) even on a near-saturated GPU. The shared high-idle gate then suppressed every hot-kernel candidate and emitted the route-to-params high_gpu_idle_pct warning, steering the run away from kernel optimization on a false "GPU is idle" signal. Stop-the-bleed minimal set (does not fix idle numerics or replay attribution): - A: _bypass_trace_reader counts graph-replay launches by name on cuda_runtime events and exposes attribution.graph_launch_count. The launch-name regex is now the reader's canonical _GRAPH_LAUNCH_RE; _trace_shape_manifest reuses it instead of keeping a duplicate. - B: bypass_trace_analysis high-idle gate carve-out: when graph replays are detected the idle_pct is untrustworthy, so it keeps the candidate lists and emits bypass_cudagraph_unreliable_idle instead of the misleading high_gpu_idle_pct. The shared _idle_gate (also used by the TraceLens route) is untouched. - C: _emit_quality_warnings surfaces bypass_cudagraph_replay whenever replays are detected (attribution/idle unreliable). Adds a reproduction test asserting candidates are retained and the right warnings fire on a cudagraph high-idle trace. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Emit bypass_cudagraph_replay unconditionally (moved out of the kernels-gated _emit_quality_warnings), so a graph-replay trace with zero recorded device kernels — the most severe under-recording case — still surfaces the replay signal. Compute graph_launch_count once and reuse it in the idle-gate carve-out. Adds a zero-kernel regression test. - Reduce _GRAPH_LAUNCH_RE to `graphlaunch|graph_launch` (the hip/cuda alternatives were dead: `graphlaunch` already matches as a substring). - Restore the missing blank line before _trace_shape_manifest.classify_op (PEP8 E302). Not changed (deferred, out of stop-the-bleed scope): the idle-gate carve-out still keys off graph_launch_count>0 within the high-idle branch (a genuinely host-idle cudagraph workload is not routed to params — needs replay-aware busy time, D/E); count_graph_replays still scans device kernels (pre-existing). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When the upstream trace is an incomplete CUDA-graph capture, the GPU-time and
op-attribution data simply are not present. Rather than reconstruct absent data
(impossible) or fabricate fallbacks, the bypass analysis now DETECTS the
incomplete trace and marks the affected metrics unreliable, propagating that so
nothing downstream treats a spurious idle_pct / zero attribution as authoritative.
- Reliability predicates (reuse existing signals, no new thresholds):
* idle_reliable=False when idle_pct>gate AND graph replays present
(a high idle reading under replay is an under-recording artifact).
* attribution_reliable=False when graph replays present AND attributed_pct
below the shared op-attribution floor. The floor is now a single
_bypass_corr_warn_pct() used by both this gate and the
bypass_low_op_correlation warning so they can never disagree.
* data_reliability_reason="cudagraph_incomplete_trace" when either is false.
- Propagate idle_reliable / attribution_reliable / data_reliability_reason into
the result (and result.timeline), summary.json, and trace_input_manifest.json.
- analysis.md: when unreliable, the idle/busy/op-attribution cells render as the
em-dash placeholder (not a bogus number) and a DATA RELIABILITY provenance
note is emitted. This also keeps any workload-summary parser from reading a
spurious idle_pct downstream.
No data reconstruction, no capture-folder wiring, no fallback fabrication. The
idle-gate carve-out is unchanged in behavior (now expressed via idle_reliable).
Adds tests: idle marked unreliable + degraded rendering; attribution unreliable
on a zero-recorded-kernel replay trace; and a regression lock that a normal
(non-cudagraph) trace stays fully reliable with a numeric idle.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…y flags The unconditional bypass_cudagraph_replay message asserted idle_pct/attribution "are unreliable" whenever replays were detected, which contradicts idle_reliable =True computed for a cudagraph trace whose idle is below the gate. Reword it to state only the mechanism (under-recording, no cpu_op link) and defer the trustworthiness verdict to the idle_reliable / attribution_reliable flags, so the general replay signal never contradicts the first-class reliability flags. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adversarial self-review (correct base) surfaced consistency/coverage gaps in the honest-degradation change. Fixes: - Attribution coverage is no longer nulled in the Executive Summary. The low coverage % is accurate and is itself the evidence that op mapping is poor; nulling it hid that and contradicted the Appendix (which still printed the raw figure). Now the number is kept and the attribution_reliable flag + bypass_low_op_correlation warning + a reworded DATA RELIABILITY note carry the "op names/shapes unresolved" signal. Resolves the Exec-vs-Appendix contradiction. - xDiT diffusion sidecar no longer derives gpu_busy_ratio from a spurious busy/idle: when idle is unreliable the timeline handed to build_report_from_bypass has busy_pct/idle_pct nulled (diffusion_roofline treats a missing busy_pct as gpu_busy_ratio=None, not a fabricated value). - attribution_reliable is mirrored into result["attribution"] (symmetric with the idle_reliable mirror into result["timeline"]) so a consumer reading the sub-block directly sees the untrusted marker. - The DATA RELIABILITY provenance note now describes each metric accurately (idle shown as '-'; attribution coverage shown but op mapping unresolved). Tests: attribution-only degradation (idle kept numeric, coverage kept numeric + flagged, mirror asserted); and a healthy low-idle cudagraph trace stays fully reliable — locking the deliberate threshold semantics (CUDA graph alone does not mark idle unreliable; only a high idle does). Not changed (deliberate, per decision): idle_reliable keys off the idle threshold, not off graph presence — under-recording manifests as high idle, so a sub-threshold cudagraph idle is treated as trustworthy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
--capture-folder was a silent no-op for the core analysis: it is only consumed by the opt-in TraceShapeManifest and never feeds idle/attribution/candidates, so an operator could believe passing it fixed the CUDA-graph data gaps when it did not. Rather than wire it up (there is no valid upstream capture data to reconstruct from — the deliberate "no reconstruction" stance), make the no-op explicit: when --capture-folder is provided, emit a bypass_capture_folder_not_used_for_core health warning stating it is not used by the core analysis (only the opt-in manifest) and does not reconstruct idle or op-attribution. A run without the flag emits nothing new. Adds a test for both the flag-present warning and the flag-absent silence. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…line The zero-recorded-kernel case (graph replays present, no device kernels) is the most severe under-recording: total_time_ms computes to 0, so idle_pct fell out as 0.0, which is below the gate threshold — leaving idle_reliable=True and the report showing "GPU Idle % = 0.00%" as trustworthy even though nothing was recorded. Extend idle_reliable to also trip when, under graph replay, the timeline is degenerate (total_time_ms missing or <= 0). A plausible low/moderate idle computed from real recorded kernels stays trustworthy (the deliberate threshold semantics), so this only catches the empty-timeline artifact. Adds the idle_reliable=False assertion to the zero-kernel regression test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Problem
On the bypass (TraceLens-free) trace-analysis route (
HYPERLOOM_TRACE_ANALYSIS_ROUTE=bypass), CUDA-graph replay traces derailed the optimization loop. Root cause: the reader ignoredcuda_runtimeevent names, so it never saw the graph-replay launches. Under graph replay the profiler under-records device kernels, so:busy = union(recorded kernels),total = event span→busy 63ms / total 7242ms → idle 99.1%on a near-saturated GPU.cpu_oplink → ~91% of kernel time unlinked (no op names/shapes/sources).high_gpu_idle_pct— steering the run to "tune params, not kernels."Approach: honest degradation, not reconstruction
The upstream trace genuinely lacks the data (graph replays carry no per-replay device/op info). It cannot be reconstructed downstream, so this change detects the incomplete trace and marks the affected metrics unreliable — it never fabricates values or adds fallbacks.
What changed (5 files,
agents/kernel/tools/)_bypass_trace_reader→attribution.graph_launch_count(canonical_GRAPH_LAUNCH_RE, reused by_trace_shape_manifest).bypass_cudagraph_unreliable_idleinstead of the misleadinghigh_gpu_idle_pct(the shared_idle_gate/ TraceLens route is untouched).idle(high idle, or degenerate empty timeline, under replay) andattribution(coverage below the shared floor under replay):idle_reliable/attribution_reliable/data_reliability_reasonpropagated throughresult(+timeline/attributionsub-blocks),summary.json,trace_input_manifest.json, andanalysis.md(idle/busy rendered—; accurate op-attribution coverage kept + flagged; aDATA RELIABILITYnote). xDiT diffusion sidecar nulls busy/idle when unreliable.--capture-folder: made its no-op explicit — it is not consumed by the core analysis (only the opt-in shape manifest) and does not reconstruct anything →bypass_capture_folder_not_used_for_corewarning when provided.Deliberate:
idle_reliablekeys off the idle threshold (under-recording manifests as high idle), so a plausible low idle from real recorded kernels stays trustworthy.Verification
Before/after on an incident-shaped trace (128 replays, ~4410 kernels, ~91% unlinked, idle 99.1%), run on a real Linux MI300X pod:
graph_launch_counthigh_gpu_idle_pctbypass_cudagraph_unreliable_idle+bypass_cudagraph_replay99.11%(authoritative)—+ DATA RELIABILITY note;idle_reliable=FalseTests: bypass suite green locally and on the Linux pod (185 passed / 21 skipped on pod). Adds regression tests for detection, non-suppression, idle/attribution degradation, degenerate empty timeline, healthy-low-idle-cudagraph, and the capture-folder signal.
Not done (deliberate)
Accurate idle values and recovered op-attribution are not reconstructed — the data is absent upstream; reconstructing it would mean fabricating numbers. The true fix for that belongs in the upstream trace producer.
🤖 Generated with Claude Code