Conversation
…tic agent; will require iteration
…unts mismatch AMD capture traces sometimes record extra HIP dispatch API calls (hipExtModuleLaunchKernel, hipLaunchKernel) that get consolidated during graph optimization, causing a count mismatch vs graph kernels. Previously the merge was skipped entirely for that execution root, leaving its kernels as flat children of hipGraphLaunch with no cpu_op ancestry. Adds _align_capture_to_graph which scans forward through capture dispatch events to match each graph kernel by name, discarding any unmatched extras. verify_subtree_events now returns a (success, aligned_capture_events) tuple so the caller can proceed with the aligned subset when counts differ but names align. Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
…aph_capture_changes
Update
Some things to be addressed in the future:
A note on comments: The rest is resolved. When I didn't write out a justification, the reasons for resolving them were either "the file/function in question is stripped away entirely," or "the code is improved and the issue fixed". |
| - If **Graph replay + capture**, ask for the **Capture Folder Path(s)**: | ||
| - `standalone`: one folder → `<capture_folder_path_1>`. Ask: "Please provide the full path to the graph capture traces folder" | ||
| - `comparative`: one folder per trace → `<capture_folder_path_1>` (primary/trace1) and `<capture_folder_path_2>` (comparison/trace2). Ask: "Please provide the graph capture traces folder for the primary trace and for the comparison trace." | ||
| - **Comparative + graph replay** (do not abort): collect capture folders for both traces when available. If capture is not available, the comparison uses the semantic path (see Step 0.5). |
There was a problem hiding this comment.
"do not abort" seems redundant
I would instead reframe this section as, keeping 2 as is, something like
3. Graph replay only (<inference_exec_mode> = graph_replay_only):
standalone: Abortcomparative: Semantic analysis
|
|
||
| ## Step 0.5: Comparison Method (comparative only) | ||
|
|
||
| For `standalone`, skip this step. |
There was a problem hiding this comment.
This might be removable with the prev. comment
| ## Step 1: Generate Performance Report | ||
|
|
||
| Use **`<analysis_mode>`** to determine which CLI tool to run and then **`<comparison_scope>`** to determine arguments. | ||
| Use **`<analysis_mode>`** to determine which CLI tool to run and then **`<comparison_scope>`** (and, for comparative, **`<comparison_method>`** from Step 0.5) to determine arguments. |
There was a problem hiding this comment.
Use <analysis_mode> to determine which CLI tool to run and then <comparison_scope> to determine arguments. can stay as is
|
|
||
| ## Step 1.5: Semantic Comparative Ordering (`<comparison_method>` = `semantic` only) | ||
|
|
||
| When `<comparison_scope>` = `comparative` and `<comparison_method>` = `semantic`, run Step 1 in this order: |
There was a problem hiding this comment.
<inference_exec_mode> = graph_replay_only and scope comparative directly implies semantic, would just simplify the verbiage here
'''
Step 1.5: Semantic Comparative Ordering (<inference_exec_mode> = graph_replay_only )
- ....
- ...
'''
| - **GPU Graph Replay**: raw trace JSON contains `hipGraphLaunch` or `cudaGraphLaunch`. | ||
| - **Default mode** (analysis_mode = `default`): Inform the user with `[DIAG:trace_quality:GPU_GRAPH_REPLAY]` that GPU graph replay was detected and that the default analysis mode supports typical PyTorch traces. **Abort** -- do not retry or continue. | ||
| - **Inference mode** (analysis_mode = `inference`): Graph launches are expected and supported if graph capture folder is provided, do not abort. If inference_exec_mode is `eager` (no capture folder was provided), continue. | ||
| - **Comparative scope**: graph replay is **supported**; the comparison method (tracediff+capture vs semantic) was set in Step 0.5 from capture availability, with no trace classification. Ensure capture folders were collected for both traces when available. |
There was a problem hiding this comment.
would just remove 692-696. Seems redundant with all that's been added
| @@ -0,0 +1,137 @@ | |||
| <!-- | |||
| Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. | |||
There was a problem hiding this comment.
Note to change copyright dates to 2026
| ```json | ||
| { | ||
| "context_renames": { | ||
| "(platform 1 name):6": "qkv_projection", |
There was a problem hiding this comment.
Feedback for follow up PR: Create a util function for this along with a validator, JSON generation leads to token wastage.
| @@ -0,0 +1,75 @@ | |||
| ############################################################################### | |||
| # Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. | |||
| def parse_filename_metadata(filepath: str) -> Dict[str, Any]: | ||
| """ | ||
| Parse isl, osl, conc, tp from trace filename. | ||
| Example: mi355_tp1_isl1024_osl8_conc4_opt_asm64x256.pt.trace.json.gz |
There was a problem hiding this comment.
Recommend removing trace name
| return result, kernels | ||
|
|
||
|
|
||
| def _write_split_regions(split_result, trace_path, output_dir): # pragma: no cover |
There was a problem hiding this comment.
Clarifying question: are all intermediates for semantic stored inside a separate directory? Just making sure it's inside a sub-dir in the results directory of the agent
| return n | ||
|
|
||
|
|
||
| def load_json(path): |
There was a problem hiding this comment.
I believe there's a top level DataLoader class for opening traces
There was a problem hiding this comment.
Can this be merged with another file? Or do you prefer leaving it separate
|
|
||
|
|
||
| def _load(path): | ||
| return load_json(path) |
There was a problem hiding this comment.
Redundant load? Can directly call helper function
| TraceLens/PerfModel/benchmarking/* | ||
| TraceLens/PerfModel/origami_helper.py | ||
| TraceLens/PerfModel/run_perf_model.py | ||
| # pattern_finder.py is slated for replacement by an external package; omit until then |
There was a problem hiding this comment.
Recommending aligning file nomenclature with other set of evals
| @@ -0,0 +1,8 @@ | |||
| # Expanded fixtures -- regenerated from fixtures/*.tar.gz by run_partial_tests.sh. | |||
| # Only the tarballs under fixtures/ are committed (matches the e2e_tests_* convention). | |||
| /semantic_purity_deepseek_r1/ | |||
There was a problem hiding this comment.
Results of tests should be in a separate directory. Check other evals directory for structure
There was a problem hiding this comment.
This should go a level above in the .gitignore under evals directory.
| <!-- | ||
| Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. | ||
|
|
||
| See LICENSE for license information. |
There was a problem hiding this comment.
Recommend merging this with the README in evals. Two levels of README seems messy. Can come in a follow up PR.
| # below the worst healthy run and ~10x above collapse, so ordinary bucketing | ||
| # variance never false-alarms while any real collapse fails hard. | ||
| MIN_SHARED_BUCKETS = { | ||
| "semantic_purity_deepseek_r1": 10, |
There was a problem hiding this comment.
Is this needed? Adding a new trace would require updating this then. Would suggest just a single value
| CANDIDATE_RELPATH = os.path.join("tracediff_output", "diff_stats.csv") | ||
|
|
||
|
|
||
| def _write(results_path: str, rows: list[dict]) -> None: |
There was a problem hiding this comment.
Confirming there is no such function inside the eval_utils?
| semantic_partition_scripted_evals.py records per-run LCA-partition purity | ||
| metrics but does not gate on them (see that module's docstring) -- the | ||
| semantic-bucketing method has real run-to-run variance (observed on | ||
| Qwen3-30B-A3B), so a single run is not a reliable regression signal. |
There was a problem hiding this comment.
Specific comment needs to be removed
There was a problem hiding this comment.
Receommend renaming all these as test_analysis_agent_semantic)...
There was a problem hiding this comment.
Additional comments/clarifications added.
@amoskvic could you please take a look?
- Addressing comments on code
- Synching changes to staging_agent's latest PR
- PR also requires updating the main TraceLens Agent README and the docs
@Ahmedhasssan-aig could you review the evals directory?
@kyle-hoffmeyer @ajassani on the Reporting and split_trace_annotation and a general review too
| "--comparison_json_path; unlike --comparison_json_path it may be " | ||
| "combined with --capture_folder." |
There was a problem hiding this comment.
Docstring is false. --comparison_json_path can be used with --capture_folder
| type=str, | ||
| default=None, | ||
| help=( | ||
| "Path to a precomputed TraceDiff-schema diff_stats.csv (e.g. from " |
There was a problem hiding this comment.
If the schema of the CSV output of semantic analysis is the same as TraceDiff, then maybe we generalize this to just say "Path to precomputed TraceDiff output". This would be useful in general for developers who have TraceDiff output and want to generate a comparative report without running through TraceDiff again.
I'd also change flag name to be more interpretable. Maybe "precomputed_tracediff_csv"?
Overview
This PR introduces a revamped semantic analysis approach (fallback for the comparative graph mode, when there is no graph capture), as well as a new type of eval (partial eval): evaluation based on a partial execution of the general agentic workflow, with pass/fail determined by quality metrics derived from a gold standard.
General approach
The philosophy was to try to keep the changes to the main orchestrator to the absolute minimum. When the orchestrator detects the fallback condition (comparative + graph, but no capture info), a semantic subagent is invoked. The semantic subagent produces a diff_stats file using an LLM-driven analysis, with an analogous structure to a regular diff_stats. After that, the main orchestrator picks up from there (the new
--precomputed_diff_stats_csvflag ongenerate_perf_report_pytorch.py/generate_perf_report_pytorch_inference.py(skips the internal TraceDiff and loads the semantic diff_stats.csv directly)).Structure
The evals live in
agent_evals/Analysis/partial_tests/, a new folder alongside the existing full-orchestrator eval harness. The main entry point isagent_evals/Analysis/partial_tests/run_partial_tests.sh. It invokes the semantic-comparison-agent workflow on the DECODE-only trace pairs listed inpartial_test_cases.csv(one row per model: DeepSeek-R1, Qwen3-30B-A3B), then compares the resultingdiff_stats.csvwith the gold standard one (analysis_output_ref/semantic_purity_gold_diff_stats.csv, obtained by running the usual comparative mode with capture info on the same DECODE trace pair). Helper functions inagent_evals/Analysis/eval_utils/compare_lca_partitions.py(shared withtests/test_compare_lca_partitions.py) are primarily for computing the quality metrics to compare two different diff_stats files;partial_tests/eval_utils/semantic_partition_scripted_evals.pyrecords per-run metrics (informational), andpartial_tests/eval_utils/semantic_purity_aggregate.pyis the actual pass/fail gate (averagesstrict_forwardacross repeats against a per-model floor).The semantic agent logic itself lives in
TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md(plus its three sub-agents:kernel-stem-preprocessing-agent.md,kernel-unification-agent.md,kernel-coherence-agent.md), with helper python functions inTraceLens/Agent/Analysis/semantic_analyses/(extract_trace_data.py,extract_tree_context.py,pattern_finder.py,build_semantic_labels.py,kernel_unification.py,kernel_coherence.py,generate_semantic_diff.py,match_and_compare.py) andTraceLens/Agent/Analysis/utils/classify_kernels.py.Validation
The changes were validated using the approach described above, with the current solution strongly outperforming the previous semantic analysis approach and a number of simpler baselines (e.g. random kernel grouping). One limitation: as of the time of the creation of this PR, the tests were run from a local agent, not using the on-cluster docker. This extra verification step is in progress.
Extra notes:
agent (
semantic-harmonization-agent.md) and its python backend (harmonization.py).with a small margin (see
semantic_purity_aggregate.pydocstring).