From fea42add52e8eae2d3b3a02d2b7ffe62db362862 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Wed, 3 Jun 2026 14:47:20 -0400 Subject: [PATCH 01/50] add graph capture + tracediff extension support --- .../generate_perf_report_pytorch_inference.py | 56 +++++++++++++++---- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/TraceLens/Reporting/generate_perf_report_pytorch_inference.py b/TraceLens/Reporting/generate_perf_report_pytorch_inference.py index d5d74b851..cb140f021 100644 --- a/TraceLens/Reporting/generate_perf_report_pytorch_inference.py +++ b/TraceLens/Reporting/generate_perf_report_pytorch_inference.py @@ -547,6 +547,7 @@ def generate_perf_report_pytorch( topk_ops: Optional[int] = None, topk_roofline_ops: Optional[int] = None, comparison_json_path: Optional[str] = None, + comparison_augmented_tree: Optional[TraceToTree] = None, extension_file: Optional[str] = None, # for gemm simulator / Origami (Origami requires --enable_origami when arch is set) python_path: Optional[str] = None, @@ -564,7 +565,14 @@ def generate_perf_report_pytorch( gpu_arch=gpu_arch, ) add_python_func = ( - True if (group_by_parent_module or include_call_stack is True) else False + True + if ( + group_by_parent_module + or include_call_stack is True + or augmented_tree is not None + or comparison_augmented_tree is not None + ) + else False ) if augmented_tree is not None: perf_analyzer = TreePerfAnalyzer( @@ -918,13 +926,24 @@ def generate_perf_report_pytorch( # Run TraceDiff when a comparison trace is provided. diff_stats_df is generated _tracediff_diff_stats: Optional[pd.DataFrame] = None if comparison_json_path and not df_unified_perf.empty: - perf_analyzer2 = TreePerfAnalyzer.from_file( - profile_filepath=comparison_json_path, - python_path=perf_analyzer.python_path, - include_unlinked_kernels=perf_analyzer.include_unlinked_kernels, - enable_pseudo_ops=enable_pseudo_ops, - add_python_func=perf_analyzer.add_python_func, - ) + if comparison_augmented_tree is not None: + perf_analyzer2 = TreePerfAnalyzer( + tree=comparison_augmented_tree, + arch=gpu_arch_json, + python_path=python_path, + include_unlinked_kernels=include_unlinked_kernels, + add_python_func=add_python_func, + enable_pseudo_ops=enable_pseudo_ops, + rebuild_tree=False, + ) + else: + perf_analyzer2 = TreePerfAnalyzer.from_file( + profile_filepath=comparison_json_path, + python_path=perf_analyzer.python_path, + include_unlinked_kernels=perf_analyzer.include_unlinked_kernels, + enable_pseudo_ops=enable_pseudo_ops, + add_python_func=perf_analyzer.add_python_func, + ) perf_analyzer2.tree.apply_annotation( name_filters=["vllm::unified_attention_with_output"] ) @@ -1307,6 +1326,12 @@ def main(): required=False, help="Path to the capture trace folder", ) + parser.add_argument( + "--comparison_capture_folder", + type=str, + required=False, + help="Path to the capture trace folder for the comparison trace", + ) parser.add_argument( "--group_by_num_kernels", action="store_true", @@ -1329,10 +1354,9 @@ def main(): ) args = parser.parse_args() - if args.capture_folder and args.comparison_json_path: + if args.comparison_capture_folder and not args.comparison_json_path: parser.error( - "--capture_folder and --comparison_json_path cannot be used together. " - "The TraceDiff comparison extension does not support graph capture traces." + "--comparison_capture_folder requires --comparison_json_path." ) if args.capture_folder: classify_graph_capture_trace(args.capture_folder) @@ -1342,6 +1366,15 @@ def main(): ) else: graph_tree = None + comparison_graph_tree = None + if args.comparison_capture_folder: + classify_graph_capture_trace(args.comparison_capture_folder) + comp_metadata = os.path.join( + args.comparison_capture_folder, "execution_details.json" + ) + comparison_graph_tree = merge_capture_trace_into_graph( + args.comparison_capture_folder, comp_metadata, args.comparison_json_path + ) generate_perf_report_pytorch( profile_json_path=args.profile_json_path, augmented_tree=graph_tree, @@ -1360,6 +1393,7 @@ def main(): topk_ops=args.topk_ops, topk_roofline_ops=args.topk_roofline_ops, comparison_json_path=args.comparison_json_path, + comparison_augmented_tree=comparison_graph_tree, extension_file=args.extension_file, python_path=args.python_path, gpu_arch_json_path=args.gpu_arch_json_path, From 20a28b29bcaa577cd3c40843672268df2e36ad43 Mon Sep 17 00:00:00 2001 From: Spandan More Date: Thu, 4 Jun 2026 11:42:43 -0700 Subject: [PATCH 02/50] staging: Initial Commit --- .../agents/semantic-comparison-agent.md | 285 ++++++ .../agents/semantic-harmonization-agent.md | 177 ++++ .../Analysis/semantic_analyses/__init__.py | 7 + .../Analysis/semantic_analyses/_helpers.py | 73 ++ .../semantic_analyses/annotation_metadata.py | 199 ++++ .../build_semantic_labels.py | 244 +++++ .../semantic_analyses/extract_trace_data.py | 362 +++++++ .../semantic_analyses/extract_tree_context.py | 313 ++++++ .../generate_semantic_diff.py | 430 ++++++++ .../semantic_analyses/harmonization.py | 831 ++++++++++++++++ .../semantic_analyses/match_and_compare.py | 320 ++++++ .../semantic_analyses/pattern_finder.py | 938 ++++++++++++++++++ .../semantic_analyses/trace_split_adapter.py | 228 +++++ 13 files changed, 4407 insertions(+) create mode 100644 TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md create mode 100644 TraceLens/Agent/Analysis/.cursor/agents/semantic-harmonization-agent.md create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/__init__.py create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/_helpers.py create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/annotation_metadata.py create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/harmonization.py create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/pattern_finder.py create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py diff --git a/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md new file mode 100644 index 000000000..478cb531f --- /dev/null +++ b/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md @@ -0,0 +1,285 @@ + + +--- +name: semantic-comparison-agent +description: End-to-end semantic gap analysis for two GPU traces. Runs deterministic breakdown per trace (extraction + tree context + classification + pattern finding + label assembly), then a single LLM harmonization pass to assign and unify semantic_block names, followed by comparison pipeline and stakeholder gap analysis report. +triggers: + - semantic comparison + - semantic gap analysis + - compare two traces semantically + - trace comparison +tools: + - terminal + - file_read + - file_write +--- + +# Semantic Comparison + +Orchestrate end-to-end semantic comparison of two GPU traces. The user +provides two raw trace files and the orchestrator handles everything: +deterministic parallel breakdown (no LLM), single-pass LLM harmonization +that assigns and unifies semantic_block names, comparison pipeline, and +final stakeholder report. + +Use vendor-agnostic terminology (GPU kernels, vendor GEMM library, etc.) +except when quoting actual kernel names from traces. + +--- + +## Workflow Steps + +``` +0. Query User Inputs +1. Semantic Breakdown (PARALLEL shell commands, one per trace) +2. Semantic Harmonization (single agent, cross-trace) +3. Generate TraceDiff Output (script) +4. Generate Comparison CSV (script) +8. Write Gap Analysis Report (LLM) +9. Validate Report +``` + +--- + +## Step 0: Query User Inputs + +Ask the user for: + +**Required:** +- Trace A path (.json or .json.gz) +- Trace B path (.json or .json.gz) +- Short labels for each trace (e.g., MI355 / B200) + +**Optional:** +- Output directory (default: `comparison_output/`) +- Capture trace A/B paths (for graph-mode traces with companion captures) + +**Auto-detection:** If the user provides a directory, look for paired +`*_graph*` and `*_capture*` files. + +**vLLM / annotated traces** are auto-detected by `extract_trace_data.py`. +No special flag is needed -- the script probes for annotation iterations +and splits into per-region subdirectories automatically. + +--- + +## Step 1: Semantic Breakdown (Deterministic, PARALLEL) + +Breakdown is fully deterministic -- no LLM calls. Run both traces as +**parallel shell commands** (NOT Task subagents) so the orchestrator +blocks until both finish. + +Reference: `TraceLens/AgenticMode/SemanticComparison/.cursor/agents/semantic-breakdown-agent.md` + +### 1.1 Per-trace Pipeline + +Run the full breakdown for **both traces in a single shell call** using +background jobs + `wait`. The extraction step auto-detects vLLM +annotation regions; no special flag is needed. For vLLM traces the +output directory will contain per-region subdirs; the remaining steps +(`extract_tree_context.py`, `pattern_finder.py`, `classify_kernels.py`, +`build_semantic_labels.py`) support `--regions-dir` / per-region paths +and must be run for **every** region. + +```bash +SCRIPTS=TraceLens/Agent/Analysis/semantic_analyses +CLASSIFY=TraceLens/Agent/Analysis/utils/classify_kernels.py +DIR_A=/_work/ +DIR_B=/_work/ +mkdir -p $DIR_A $DIR_B + +run_breakdown() { + local TRACE=$1 DIR=$2 + + # Extract (auto-splits vLLM traces into region subdirs) + python $SCRIPTS/extract_trace_data.py $TRACE -o $DIR/ + + # Check whether extraction produced region subdirs or a flat file + if ls $DIR/*/extracted.json >/dev/null 2>&1; then + # Multi-region: tree context once, then per-region steps + python $SCRIPTS/extract_tree_context.py $TRACE --regions-dir $DIR/ + for REGION in $DIR/*/; do + python $SCRIPTS/pattern_finder.py $REGION/extracted.json -o $REGION/pattern.json & + python $CLASSIFY $REGION/extracted.json -o $REGION/classified.json & + done + wait + for REGION in $DIR/*/; do + python $SCRIPTS/build_semantic_labels.py \ + $REGION/extracted.json $REGION/classified.json $REGION/pattern.json \ + --tree-context $REGION/tree_context.json \ + -o $REGION/semantic_labels.json + done + else + # Single-trace + python $SCRIPTS/extract_tree_context.py $TRACE $DIR/extracted.json -o $DIR/tree_context.json + python $SCRIPTS/pattern_finder.py $DIR/extracted.json -o $DIR/pattern.json & + python $CLASSIFY $DIR/extracted.json -o $DIR/classified.json & + wait + python $SCRIPTS/build_semantic_labels.py \ + $DIR/extracted.json $DIR/classified.json $DIR/pattern.json \ + --tree-context $DIR/tree_context.json \ + -o $DIR/semantic_labels.json + fi +} + +run_breakdown $DIR_A & +run_breakdown $DIR_B & +wait +``` + +Add `--capture-trace ` to `extract_tree_context.py` when a +companion capture trace is provided. + +**Output directories:** +- Trace A: `/_work//` +- Trace B: `/_work//` + +For multi-region traces, each directory contains per-region subdirs +(e.g., `decode_only_3/`, `prefill_only_1024/`). + +### 1.2 Verify Breakdown Outputs + +**CRITICAL: DO NOT proceed to Step 2 until both breakdowns have +completed and outputs are verified.** + +After both breakdowns complete, verify that `semantic_labels.json` exists +(in each region subdir for multi-region traces, or directly in the trace +directory for single-trace). If either trace failed, report the error +and stop. + +--- + +## Step 2: Semantic Harmonization (LLM -- Label + Harmonize) + +The harmonization agent is the **only LLM call** in the pipeline. It +assigns descriptive `semantic_block` names to each block AND ensures +cross-trace consistency. The enriched context includes `cpu_ops`, +`nn_module`, kernel names, and `perf_category` per block. + +### 2.1 Read the Agent Definition + +Read: `TraceLens/Agent/Analysis/.cursor/agents/semantic-harmonization-agent.md` + +### 2.2 Launch Harmonization Agent + +``` +---BEGIN AGENT INSTRUCTIONS--- + +---END AGENT INSTRUCTIONS--- + +**Execution Context:** +- Trace A directory: /_work// +- Trace B directory: /_work// +- Output directory: /_work/ +- Name A: +- Name B: + +Follow the agent instructions above to label and harmonize the blocks. +Return the summary described in the "Return Value" section. +``` + +For multi-region vLLM: run once per matching region pair. + +### 2.3 Verify Harmonization + +Check that `alignment.json`, `harmonization_context.json`, and +`harmonization_corrections.json` exist in `/_work/`. +Verify that `semantic_labels.json` files now contain `semantic_block` +fields on all kernels. + +--- + +## Step 3: Generate TraceDiff Output [S] + +```bash +python TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py \ + /_work//semantic_labels.json \ + /_work//semantic_labels.json \ + --name-a --name-b \ + -o /tracediff_output/ +``` + +Produces in `/tracediff_output/`: +- `diff_stats.csv` -- per-kernel rows matching TraceDiff schema +- `diff_stats_unique_args_summary.csv` -- aggregated by semantic block +- `cpu_op_map.json`, `cpu_op_map_trace1.json`, `cpu_op_map_trace2.json` +- `merged_tree_output.txt` + +This is a **final deliverable** directory for downstream TraceDiff consumers. + +--- + +## Step 4: Generate Comparison CSV [S] + +**Single-region mode:** +```bash +python TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ + /_work//semantic_labels.json \ + /_work//semantic_labels.json \ + --name-a --name-b \ + -o /_work/comparison.csv +``` + +**Multi-region mode (vLLM):** +```bash +python TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ + --regions-dir-a /_work/ \ + --regions-dir-b /_work/ \ + --name-a --name-b \ + -o /_work/comparison.csv +``` + +--- + +## Step 8: Write Gap Analysis Report [LLM] + +Read the report template from: +`TraceLens/AgenticMode/SemanticComparison/.cursor/agents/gap-analysis-report-template.md` + +Using `_work/comparison.csv`, `_work/priority.json`, and both +`_work//semantic_labels.json` files, produce +`/semantic_comparison_report.md` following the template. + +--- + +## Step 9: Validate Report + +- All `priority.json` entries appear in the P1/P2/P3 section +- All semantic blocks from `comparison.csv` appear in detailed analysis +- No blocks are missing + +Prompt the user to review the report. + +--- + +## Key Principles + +1. **Seamless flow** -- user provides two trace paths, orchestrator handles + everything +2. **Parallel breakdown** -- both traces processed as parallel shell jobs +3. **Cross-trace harmonization** -- separate step unifies labels for + consistent comparison +4. **Vendor-agnostic language** -- generic terms for all recommendations +5. **Complete coverage** -- every semantic block appears in the report +6. **No script creation** -- subagents use only existing scripts + +--- + +## Final Deliverables + +``` +/ + comparison_report.xlsx # Multi-sheet Excel workbook + semantic_comparison_report.md # Stakeholder gap analysis report + tracediff_output/ # TraceDiff-compatible output + diff_stats.csv + diff_stats_unique_args_summary.csv + cpu_op_map.json + cpu_op_map_trace1.json + cpu_op_map_trace2.json + merged_tree_output.txt +``` diff --git a/TraceLens/Agent/Analysis/.cursor/agents/semantic-harmonization-agent.md b/TraceLens/Agent/Analysis/.cursor/agents/semantic-harmonization-agent.md new file mode 100644 index 000000000..b49d387d2 --- /dev/null +++ b/TraceLens/Agent/Analysis/.cursor/agents/semantic-harmonization-agent.md @@ -0,0 +1,177 @@ + + +# Semantic Harmonization Agent + +Rename positionally-indexed `semantic_block` names to descriptive labels +and ensure cross-trace consistency across two independently-broken-down traces. + +The breakdown step produces per-kernel data with `perf_category`, `cpu_op`, +`nn_module`, `layer`, `region`, and a positionally-indexed `semantic_block` +like `GEMM_0`, `GEMM_1`, `Normalization_0`, `SDPA_0`. Each indexed name +is globally unique across all regions. This agent renames them to +descriptive functional labels (e.g., `GEMM_0` -> "QKV Projection", +`GEMM_1` -> "Output Projection"). + +**Scripts directory:** `TraceLens/Agent/Analysis/semantic_analyses/` + +## Rules + +1. **No new files.** Use only existing scripts. +2. **No kernel reordering.** Only modify labels on existing kernels. +3. **perf_category is locked.** Non-"Others" values from the regex + classifier are definitive. You may only change `perf_category` for + "Others" blocks. You may promote a base category to a sub-category + (e.g., "GEMM" to "GEMM-MoE") but never change the base type. +4. **Standard categories only:** GEMM, GEMM-MoE, SDPA, SDPA-GDN, + Normalization, Elementwise, Elementwise-MoE, Quantization, MemCpy, + Communication, Others. +5. **Cross-trace consistency.** The same operation on both traces MUST get + the same `semantic_block` name. + +## Required Execution Context + +- ``, `` -- paths to each trace's `semantic_labels.json` +- `` -- directory for harmonization outputs +- ``, `` -- short labels for each trace +- **Harmonization context** -- the full `harmonization_context.json` + contents are provided inline in your prompt. Do NOT re-read this file + from disk; use the JSON provided directly. + +## Workflow + +### Step 1: Rename indexed blocks + harmonize + +The harmonization context is provided inline in your prompt. Each aligned +block row shows the indexed `semantic_block` name (e.g., `GEMM_0`, +`SDPA_0`) along with kernel names, cpu_ops, nn_module, input_dims, and +perf_category for both traces. + +#### 1a: Rename each indexed block to a descriptive name + +Use the following signals to determine the functional role of each block: + +- **`cpu_ops`**: The most informative signal. Maps like: + - `aten::mm`, `aten::addmm` -> projection / linear layer + - `aten::scaled_dot_product_attention`, `aiter::fmha*` -> attention + - `aten::layer_norm`, `*rmsnorm*` -> normalization + - `aten::silu`, `aten::gelu` -> activation function + - `aten::embedding` -> embedding lookup +- **`input_dims`**: Tensor shapes from the cpu_op parent (e.g., `[[B, S, H], [H, H]]`). + Matching shapes across traces strongly suggests equivalent operations -- + two GEMM blocks with `[B, S, 5120] x [5120, 5120]` are likely the same projection. +- **`perf_category`**: Confirms the operation type (GEMM, SDPA, Normalization, etc.) +- **`nn_module`**: Provides the neural network module context (e.g., "WanTransformerBlock", "SelfAttention") +- **`kernel_names`**: Kernel function names can hint at the operation +- **Position in the layer cycle**: The index suffix indicates position -- `GEMM_0` is the first GEMM in the cycle, `GEMM_3` is the fourth, etc. + +**Label selection (MANDATORY):** +- The context includes a `label_catalog` mapping each `perf_category` to + a list of standard semantic labels. +- You **MUST** use a catalog label when the block's functional role matches + one. Do NOT invent a custom name if a catalog entry already covers the + operation. +- If you invent a custom label, you **MUST** explain in the `reason` field + why no catalog label was appropriate. +- **Do NOT split operations that belong together.** Multiple GEMM blocks + that form a single logical projection (e.g., Q, K, V) should share one + catalog label like "QKV Projection" -- NOT three separate labels like + "Q Projection", "K Projection", "V Projection". +- **Communication blocks** should use the catalog label matching the + collective type (AllReduce, AllGather, AllToAll, ReduceScatter) without + directional or positional qualifiers. Use "AllToAll", NOT "AllToAll + Pre-Self-Attn". +- **Do NOT add implementation-specific suffixes** like "(SP)", "(Full Seq)", + or hardware-specific qualifiers. Labels should be hardware-agnostic + functional names. + +#### 1b: Harmonize across traces + +- **Matched blocks**: Assign the **same** descriptive name to both sides. +- **Only-in-X blocks**: Assign a name based on the available signals for that trace. +- **Category validation**: Apply Rule 3 (perf_category locking). +- **nn_module unification**: Use consistent `nn_module` values for matched blocks. +- **Pre-layer and post-layer positional mismatches are expected.** Different + implementations may order preamble/epilogue operations differently. + When a matched pair performs genuinely different operations on each side, + use the `trace` field (see Step 2) to assign different descriptive names + to each side. Do NOT force a single name onto unrelated operations. + +### Step 1c: Validate completeness before writing corrections + +Before proceeding to Step 2, verify that **every** indexed block from the +alignment table has a corresponding `label_renames` entry in your plan. + +- Count your entries: you need one entry per unique indexed block name + across both traces. +- If a matched pair has different indexed names on each side (e.g., MI355 + has `GEMM_5` and B200 has `GEMM_1`), you need **two** entries -- one per + trace, using the `trace` field. +- If any indexed blocks are missing, add them now. Do NOT proceed with a + partial list. + +### Step 2: Output corrections + +Write `/harmonization_corrections.json`: + +**`trace` field:** Each `label_renames` entry supports an optional `trace` +field. When omitted, the rename applies to both traces. When set (e.g., +`"trace": "MI355"`), it applies only to that trace's labels file. + +**Use the `trace` field when:** +- A matched pair has different indexed names on each side (e.g., MI355 + `GEMM_5` matched with B200 `GEMM_1` -- write two entries, one per trace). +- A matched pair needs different descriptive names because the underlying + operations genuinely differ between traces. + +```json +{ + "label_renames": [ + {"old_semantic_block": "GEMM_0", "new_semantic_block": "QKV Projection", + "new_nn_module": "SelfAttention", "reason": "first GEMM, cpu_op is aten::mm under attention module"}, + {"old_semantic_block": "SDPA_0", "new_semantic_block": "Attention", + "reason": "scaled dot-product attention block"}, + {"old_semantic_block": "GEMM_5", "new_semantic_block": "Embedding Projection", + "trace": "MI355", "reason": "MI355-only preamble GEMM for timestep embedding"}, + {"old_semantic_block": "GEMM_1", "new_semantic_block": "Embedding Projection", + "trace": "B200", "reason": "B200-only preamble GEMM for patch embedding"} + ], + "category_corrections": [ + {"semantic_block": "GEMM_5", "new_perf_category": "GEMM-MoE", "reason": "expert GEMM in MoE layer"} + ], + "kernel_reassignments": [ + {"trace": "MI355", "kernel_indices": [42, 43], "from_semantic_block": "GEMM_0", + "to_semantic_block": "Elementwise_0", "reason": "misclassified elementwise kernels"} + ] +} +``` + +`label_renames` is the primary output: every indexed block should get a +descriptive functional name. The `old_semantic_block` field targets the +specific indexed block (e.g., `GEMM_0`, `GEMM_1` -- each is globally +unique). + +`category_corrections` and `kernel_reassignments` are optional edge-case +fixes. Any list can be empty if no corrections are needed. + +### Step 3: Apply corrections + +**Apply corrections exactly ONCE.** The apply script modifies label files +in-place. Do NOT apply corrections incrementally or re-run the apply script. +If you missed blocks, you must start from the original (unmodified) labels. + +```bash +python TraceLens/Agent/Analysis/semantic_analyses/harmonization.py apply-corrections \ + --corrections /harmonization_corrections.json \ + --labels-a \ + --labels-b \ + --name-a --name-b +``` + +## Return Value + +Return: `status` (SUCCESS/ERROR), `blocks_labeled`, `corrections_applied`, +`kernel_reassignments`, and any warnings. diff --git a/TraceLens/Agent/Analysis/semantic_analyses/__init__.py b/TraceLens/Agent/Analysis/semantic_analyses/__init__.py new file mode 100644 index 000000000..35a14a24b --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/__init__.py @@ -0,0 +1,7 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""TraceLens Agent Semantic Comparison Scripts""" diff --git a/TraceLens/Agent/Analysis/semantic_analyses/_helpers.py b/TraceLens/Agent/Analysis/semantic_analyses/_helpers.py new file mode 100644 index 000000000..09d1fb028 --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/_helpers.py @@ -0,0 +1,73 @@ +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +""" +Shared helper functions for the semantic_analyses scripts. + +Merged from the former trace_breakdown/_helpers.py (build_rle, detect_period) +and trace_comparison/_helpers.py (load_labels). +""" + +import json + + +def build_rle(kernel_indices, cls_by_idx): + """Run-length encode kernel indices by perf_category. + + Returns list of (perf_category, count, [kernel_indices], [kernel_types]). + """ + if not kernel_indices: + return [] + + def _cls(idx): + c = cls_by_idx.get(idx, {}) + return c.get("perf_category", "Others"), c.get("kernel_type", "Unknown") + + first_cat, first_kt = _cls(kernel_indices[0]) + groups = [] + cur_cat = first_cat + cur_indices = [kernel_indices[0]] + cur_types = [first_kt] + + for idx in kernel_indices[1:]: + cat, kt = _cls(idx) + if cat == cur_cat: + cur_indices.append(idx) + cur_types.append(kt) + else: + groups.append((cur_cat, len(cur_indices), cur_indices[:], cur_types[:])) + cur_cat = cat + cur_indices = [idx] + cur_types = [kt] + + groups.append((cur_cat, len(cur_indices), cur_indices[:], cur_types[:])) + return groups + + +def detect_period(rle_groups): + """Find the shortest repeating period in an RLE group sequence. + + Returns the period length (number of RLE groups per super-cycle). + """ + cats = [g[0] for g in rle_groups] + n = len(cats) + if n < 6: + return n + + for p in range(3, n // 2 + 1): + prefix = cats[:p] + matches = sum(1 for i in range(p, n) if cats[i] == prefix[i % p]) + total = n - p + if total > 0 and matches / total > 0.85 and total >= 2 * p: + return p + + return n + + +def load_labels(path): + """Load a semantic_labels.json file.""" + with open(path) as f: + return json.load(f) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/annotation_metadata.py b/TraceLens/Agent/Analysis/semantic_analyses/annotation_metadata.py new file mode 100644 index 000000000..805ef370f --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/annotation_metadata.py @@ -0,0 +1,199 @@ +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +""" +Multi-source metadata gathering for roofline analysis. + +Gathers metadata from annotation, filename (isl/osl/conc), trace Input Dims, +and user input. Runs sanity checks and merges into a unified dict. +""" + +import logging +import re +from typing import Any, Dict, List, Optional + +logger = logging.getLogger(__name__) + +# Filename regex: isl1024, osl8, conc4, tp1 +FILENAME_ISL_RE = re.compile(r"isl(\d+)", re.I) +FILENAME_OSL_RE = re.compile(r"osl(\d+)", re.I) +FILENAME_CONC_RE = re.compile(r"conc(\d+)", re.I) +FILENAME_TP_RE = re.compile(r"tp(\d+)", re.I) + + +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 + """ + basename = filepath.split("/")[-1] if "/" in filepath else filepath + result = {} + m = FILENAME_ISL_RE.search(basename) + if m: + result["isl"] = int(m.group(1)) + m = FILENAME_OSL_RE.search(basename) + if m: + result["osl"] = int(m.group(1)) + m = FILENAME_CONC_RE.search(basename) + if m: + result["conc"] = int(m.group(1)) + m = FILENAME_TP_RE.search(basename) + if m: + result["tp"] = int(m.group(1)) + if "isl" in result and "conc" in result: + result["num_tokens_prefill"] = result["isl"] * result["conc"] + if "conc" in result: + result["num_tokens_decode"] = result["conc"] + return result + + +def parse_trace_input_dims(events: List[dict]) -> Dict[str, Any]: + """ + Aggregate N_Q, N_KV from kernel Input Dims (for attention kernels). + Returns block-level aggregates when available. + For multi-layer models, each layer has one attention kernel with same N_Q/N_KV. + """ + nq_values = [] + nkv_values = [] + for e in events: + if e.get("cat") != "kernel": + continue + name = e.get("name", "") + if "unified_attention" not in name and "attention" not in name.lower(): + continue + dims = e.get("args", {}).get("Input Dims") + if not dims or len(dims) < 2: + continue + try: + q_shape = dims[0] + k_shape = dims[1] + if isinstance(q_shape, (list, tuple)) and len(q_shape) >= 3: + nq = q_shape[0] if len(q_shape) == 3 else q_shape[-3] + nq_values.append(nq) + if isinstance(k_shape, (list, tuple)) and len(k_shape) >= 3: + nkv = k_shape[-3] if len(k_shape) >= 3 else k_shape[0] + nkv_values.append(nkv) + except (IndexError, TypeError): + continue + result = {} + if nq_values: + result["trace_avg_nq"] = sum(nq_values) // len(nq_values) + result["trace_attention_kernel_count"] = len(nq_values) + if nkv_values: + result["trace_avg_nkv"] = sum(nkv_values) // len(nkv_values) + return result + + +def run_sanity_checks( + annotation_meta: Dict[str, Any], + filename_meta: Dict[str, Any], + trace_meta: Dict[str, Any], + user_meta: Dict[str, Any], +) -> List[str]: + """Cross-validate metadata from different sources. Returns list of warning messages.""" + warnings = [] + batch_ann = annotation_meta.get("batch_size") + batch_file = None + if "isl" in filename_meta and "conc" in filename_meta: + batch_file = filename_meta["isl"] * filename_meta["conc"] + if batch_ann is not None and batch_file is not None: + if abs(batch_ann - batch_file) > max(1, 0.1 * batch_ann): + warnings.append( + f"Batch size mismatch: annotation={batch_ann}, filename(isl*conc)={batch_file}" + ) + num_tokens_user = user_meta.get("num_tokens") + if num_tokens_user is not None and batch_ann is not None: + if abs(num_tokens_user - batch_ann) > max(1, 0.1 * batch_ann): + warnings.append( + f"num_tokens mismatch: user={num_tokens_user}, annotation batch_size={batch_ann}" + ) + ctx_ann = annotation_meta.get("context_sum") + ctx_trace = trace_meta.get("trace_avg_nq") + if ctx_ann is not None and ctx_trace is not None: + if abs(ctx_ann - ctx_trace) > max(1, 0.2 * ctx_ann): + warnings.append( + f"Context sum mismatch: annotation={ctx_ann}, trace avg N_Q={ctx_trace}" + ) + return warnings + + +def merge_metadata( + annotation_meta: Optional[Dict[str, Any]] = None, + filename_meta: Optional[Dict[str, Any]] = None, + trace_meta: Optional[Dict[str, Any]] = None, + user_meta: Optional[Dict[str, Any]] = None, +) -> Dict[str, Any]: + """ + Merge metadata from all sources. Prefer annotation for per-iteration, + filename for run config, trace for per-kernel accuracy, user for overrides. + """ + merged = {} + annotation_meta = annotation_meta or {} + filename_meta = filename_meta or {} + trace_meta = trace_meta or {} + user_meta = user_meta or {} + merged["annotation"] = annotation_meta + merged["filename"] = filename_meta + merged["trace"] = trace_meta + merged["user"] = user_meta + num_tokens = ( + user_meta.get("num_tokens") + or annotation_meta.get("batch_size") + or filename_meta.get("num_tokens_prefill") + or filename_meta.get("num_tokens_decode") + ) + context_length = ( + user_meta.get("context_length") + or annotation_meta.get("context_sum") + or annotation_meta.get("generation_sum") + or filename_meta.get("isl") + or num_tokens + ) + merged["num_tokens"] = num_tokens + merged["context_length"] = context_length + merged["batch_size"] = annotation_meta.get("batch_size") or num_tokens + merged["context_sum"] = annotation_meta.get("context_sum") + merged["generation_sum"] = annotation_meta.get("generation_sum") + warnings = run_sanity_checks(annotation_meta, filename_meta, trace_meta, user_meta) + for w in warnings: + logger.warning("Metadata sanity check: %s", w) + merged["_warnings"] = warnings + return merged + + +def gather_metadata( + trace_path: str, + events: Optional[List[dict]] = None, + annotation_meta: Optional[Dict[str, Any]] = None, + num_tokens: Optional[int] = None, + context_length: Optional[int] = None, +) -> Dict[str, Any]: + """ + Gather metadata from all available sources. + + Args: + trace_path: Path to trace file (for filename parsing) + events: Trace events (for Input Dims); if None, trace Input Dims are skipped + annotation_meta: Pre-parsed annotation metadata (e.g., from vllm_trace_split) + num_tokens: User-provided num_tokens + context_length: User-provided context_length + + Returns: + Merged metadata dict with num_tokens, context_length, batch_size, etc. + """ + filename_meta = parse_filename_metadata(trace_path) + trace_meta = parse_trace_input_dims(events or []) + user_meta = {} + if num_tokens is not None: + user_meta["num_tokens"] = num_tokens + if context_length is not None: + user_meta["context_length"] = context_length + return merge_metadata( + annotation_meta=annotation_meta, + filename_meta=filename_meta, + trace_meta=trace_meta, + user_meta=user_meta, + ) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py new file mode 100644 index 000000000..b055441e6 --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py @@ -0,0 +1,244 @@ +#!/usr/bin/env python3 +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +""" +Build semantic_labels.json deterministically from breakdown artifacts. + +Combines extracted.json + classified.json + pattern.json + tree_context.json +into the labeled kernel format consumed by the comparison pipeline. + +Each kernel gets a positionally-indexed ``semantic_block`` name (e.g. +``GEMM_0``, ``GEMM_1``, ``Normalization_0``) derived from its position +within the repeating layer cycle. A global counter ensures block names +are unique across regions (pre-layer, body, post-layer, secondary). +The harmonization agent later renames these to descriptive labels +(e.g. ``QKV Projection``). + +Per-kernel output fields: + index, name, dur, perf_category, semantic_block, region, nn_module, + cpu_op, input_dims, layer. + +Usage: + python build_semantic_labels.py extracted.json classified.json pattern.json \ + --tree-context tree_context.json [-o semantic_labels.json] +""" + +import argparse +import json +import os +import sys + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from _helpers import build_rle, detect_period + + +def _deepest_module(nn_module_stack): + """Extract the deepest nn.Module name from the stack list. + + Input like: ["nn.Module: WanTransformer3DModel > nn.Module: WanTransformerBlock"] + Returns: "WanTransformerBlock" + """ + if not nn_module_stack: + return "" + last_entry = nn_module_stack[-1] + parts = last_entry.split(" > ") + deepest = parts[-1] + if deepest.startswith("nn.Module: "): + deepest = deepest[len("nn.Module: "):] + return deepest + + +def _build_cycle_names(body_rle, period, cat_counter): + """Build positionally-indexed block names for one layer cycle. + + Uses *cat_counter* (mutated in-place) so indices are globally unique + across regions. Returns a list of length ``period`` like + ``["GEMM_2", "Normalization_1", "GEMM_3", "SDPA_0", ...]``. + """ + if period <= 0: + return [] + cycle_names = [] + for cat, _count, _indices, _types in body_rle[:period]: + idx = cat_counter.get(cat, 0) + cat_counter[cat] = idx + 1 + cycle_names.append(f"{cat}_{idx}") + return cycle_names + + +def _build_region_block_names(index_set, cls_by_idx, cat_counter): + """Build indexed block names for a region of kernels. + + Groups consecutive kernels by perf_category and assigns globally + unique ``Category_N`` names using *cat_counter* (mutated in-place). + Returns a mapping ``{kernel_index: "Category_N"}``. + """ + if not index_set: + return {} + sorted_indices = sorted(index_set) + groups = [] + cur_cat = cls_by_idx.get(sorted_indices[0], {}).get("perf_category", "Others") + cur_group = [sorted_indices[0]] + for idx in sorted_indices[1:]: + cat = cls_by_idx.get(idx, {}).get("perf_category", "Others") + if cat == cur_cat: + cur_group.append(idx) + else: + groups.append((cur_cat, cur_group)) + cur_cat = cat + cur_group = [idx] + groups.append((cur_cat, cur_group)) + + result = {} + for cat, indices in groups: + n = cat_counter.get(cat, 0) + cat_counter[cat] = n + 1 + block_name = f"{cat}_{n}" + for idx in indices: + result[idx] = block_name + return result + + +def build_labels(extracted, classified, pattern, tree_context=None): + """Build semantic_labels.json from breakdown artifacts.""" + kernels = extracted["kernels"] + total_kernels = len(kernels) + + cls_by_idx = {c["index"]: c for c in classified["classified_kernels"]} + tree_by_idx = {} + if tree_context: + tree_by_idx = {k["index"]: k for k in tree_context["kernels"]} + + preamble_set = set(pattern.get("preamble_indices", [])) + epilogue_set = set(pattern.get("epilogue_indices", [])) + secondary_set = set(pattern.get("secondary_stream_indices", [])) + body_indices = [ + i + for i in range(total_kernels) + if i not in preamble_set and i not in epilogue_set and i not in secondary_set + ] + + body_rle = build_rle(body_indices, cls_by_idx) + period = detect_period(body_rle) + num_layers = len(body_rle) // period if period > 0 else 0 + + cat_counter = {} + + preamble_blocks = _build_region_block_names( + preamble_set, cls_by_idx, cat_counter + ) + cycle_names = _build_cycle_names(body_rle, period, cat_counter) + epilogue_blocks = _build_region_block_names( + epilogue_set, cls_by_idx, cat_counter + ) + secondary_blocks = _build_region_block_names( + secondary_set, cls_by_idx, cat_counter + ) + + body_index_to_rle_group = {} + for g_idx, (_cat, _count, indices, _types) in enumerate(body_rle): + for idx in indices: + body_index_to_rle_group[idx] = g_idx + + labeled_kernels = [] + for i in range(total_kernels): + k = kernels[i] + c = cls_by_idx.get(i, {}) + tc = tree_by_idx.get(i, {}) + + entry = { + "index": i, + "name": k["name"], + "dur": k["dur"], + "perf_category": c.get("perf_category", "Others"), + "nn_module": _deepest_module(tc.get("nn_module_stack", [])), + "cpu_op": tc.get("cpu_op_name", ""), + "input_dims": tc.get("input_dims", []), + } + + if i in body_index_to_rle_group: + g_idx = body_index_to_rle_group[i] + entry["region"] = "body" + entry["layer"] = g_idx // period if period > 0 else 0 + entry["semantic_block"] = cycle_names[g_idx % period] + elif i in preamble_blocks: + entry["region"] = "pre" + entry["layer"] = None + entry["semantic_block"] = preamble_blocks[i] + elif i in epilogue_blocks: + entry["region"] = "post" + entry["layer"] = None + entry["semantic_block"] = epilogue_blocks[i] + elif i in secondary_blocks: + entry["region"] = "secondary" + entry["layer"] = None + entry["semantic_block"] = secondary_blocks[i] + else: + entry["region"] = "body" + entry["layer"] = None + entry["semantic_block"] = c.get("perf_category", "Others") + "_0" + + labeled_kernels.append(entry) + + result = { + "source_file": extracted.get("source_file", ""), + "total_kernel_time_us": round( + extracted.get("metadata", {}).get("total_kernel_time_us", 0), 2 + ), + "model_info": { + "num_layers": num_layers, + "period": period, + "graph_mode": extracted.get("metadata", {}).get("is_graph_mode", False), + }, + "labeled_kernels": labeled_kernels, + } + return result + + +def main(): + parser = argparse.ArgumentParser( + description="Build semantic_labels.json deterministically from breakdown artifacts" + ) + parser.add_argument("extracted_json", help="Path to extracted.json") + parser.add_argument("classified_json", help="Path to classified.json") + parser.add_argument("pattern_json", help="Path to pattern.json") + parser.add_argument( + "--tree-context", help="Path to tree_context.json (optional, enriches nn_module and cpu_op)" + ) + parser.add_argument("-o", "--output", help="Output JSON path (default: stdout)") + args = parser.parse_args() + + with open(args.extracted_json) as f: + extracted = json.load(f) + with open(args.classified_json) as f: + classified = json.load(f) + with open(args.pattern_json) as f: + pattern = json.load(f) + + tree_context = None + if args.tree_context: + with open(args.tree_context) as f: + tree_context = json.load(f) + + result = build_labels(extracted, classified, pattern, tree_context) + + output = json.dumps(result, indent=2) + if args.output: + with open(args.output, "w") as f: + f.write(output) + n = len(result["labeled_kernels"]) + info = result["model_info"] + print( + f"Wrote {args.output} ({n} kernels, {info['num_layers']} layers, " + f"period {info['period']})", + file=sys.stderr, + ) + else: + print(output) + + +if __name__ == "__main__": + main() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py new file mode 100644 index 000000000..8b190a981 --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py @@ -0,0 +1,362 @@ +#!/usr/bin/env python3 +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +""" +Step 1+3: Load a Chrome trace JSON and extract structured data. + +Outputs a JSON with: + - ordered kernel list (name, duration, timestamp) + - python call stack (nested) + - metadata (categories, graph mode detection, total kernel time) + +vLLM traces with annotation iterations are auto-detected and split into +per-region subdirectories. Pass ``--no-split`` to force single-file mode. + +Usage: + python extract_trace_data.py -o output_dir/ +""" + +import argparse +import gzip +import json +import logging +import os +import sys +from collections import Counter + +from trace_split_adapter import split_vllm_trace, get_steady_state_key +from annotation_metadata import gather_metadata + +try: + from TraceLens import GPUEventAnalyser +except ImportError: + GPUEventAnalyser = None + +logger = logging.getLogger(__name__) + + +def load_trace(path_or_data): + """Load trace from path (str) or use dict directly.""" + if isinstance(path_or_data, dict): + data = path_or_data + else: + opener = gzip.open if path_or_data.endswith(".gz") else open + with opener(path_or_data, "rt") as f: + data = json.load(f) + events = data.get("traceEvents", []) + by_cat = {} + for e in events: + if not isinstance(e, dict): + continue + cat = e.get("cat", "unknown") + by_cat.setdefault(cat, []).append(e) + for cat in by_cat: + by_cat[cat].sort(key=lambda e: e.get("ts", 0)) + return data, by_cat + + +def get_stream_id(event): + """Get stream from args['stream'] or tid (fallback for magic-trace style).""" + stream = event.get("args", {}).get("stream") + if stream is not None: + try: + return int(stream) + except (TypeError, ValueError): + pass + tid = event.get("tid") + if tid is not None: + try: + return int(tid) + except (TypeError, ValueError): + pass + return None + + +def filter_to_primary_stream(by_cat): + """If multiple streams in kernel events, keep only primary (most kernels). + + Skips filtering when secondary streams carry significant compute (>5% + of total kernel time), since some runtimes schedule MoE / communication + kernels on secondary CUDA streams. + """ + kernels = by_cat.get("kernel", []) + if not kernels: + return + stream_counts = Counter( + get_stream_id(k) for k in kernels if get_stream_id(k) is not None + ) + if len(stream_counts) <= 1: + return + total_time = sum(k.get("dur", 0) for k in kernels) + primary = max(stream_counts, key=stream_counts.get) + secondary_time = sum( + k.get("dur", 0) + for k in kernels + if get_stream_id(k) != primary and get_stream_id(k) is not None + ) + if total_time > 0 and secondary_time / total_time > 0.05: + logger.info( + "Keeping all %d streams: secondary streams have %.1f%% of kernel time", + len(stream_counts), + 100 * secondary_time / total_time, + ) + return + by_cat["kernel"] = [k for k in kernels if get_stream_id(k) == primary] + + +def extract_kernel_sequence(by_cat): + kernels = by_cat.get("kernel", []) + memcpy = by_cat.get("gpu_memcpy", []) + combined = sorted(kernels + memcpy, key=lambda e: e["ts"]) + return [ + { + "name": k["name"], + "cat": k.get("cat", "kernel"), + "dur": k["dur"], + "ts": k["ts"], + "args": k.get("args", {}), + "stream_id": get_stream_id(k), + } + for k in combined + ] + + +def detect_graph_mode(by_cat): + rt = by_cat.get("cuda_runtime", []) + graph_launches = [e for e in rt if "GraphLaunch" in e.get("name", "")] + return len(graph_launches) > 0, graph_launches + + +def extract_python_callstack(by_cat): + pyfuncs = sorted(by_cat.get("python_function", []), key=lambda e: e["ts"]) + for p in pyfuncs: + p["_end"] = p["ts"] + p["dur"] + stack = [] + result = [] + for p in pyfuncs: + while stack and stack[-1]["_end"] <= p["ts"]: + stack.pop() + result.append({"name": p["name"], "dur": p["dur"], "depth": len(stack)}) + stack.append(p) + return result + + +def run_assertions(data, by_cat, kernels, is_graph_mode, strict=True): + errors = [] + + if "traceEvents" not in data: + errors.append("A1.1 FAIL: Missing traceEvents key") + + required_cats = {"kernel", "cpu_op"} if strict else {"kernel"} + missing = required_cats - set(by_cat.keys()) + if missing: + errors.append(f"A1.2 FAIL: Missing categories: {missing}") + + if len(kernels) == 0: + errors.append("A1.3 FAIL: No GPU kernels found") + + for i, k in enumerate(kernels): + if k["dur"] <= 0: + errors.append( + f"A3.2 FAIL: Kernel {i} ({k['name'][:50]}) has non-positive duration {k['dur']}" + ) + break + + timestamps = [k["ts"] for k in kernels] + for i in range(1, len(timestamps)): + if timestamps[i] < timestamps[i - 1]: + errors.append(f"A3.1 FAIL: Kernel timestamps not monotonic at index {i}") + break + + total_time = sum(k["dur"] for k in kernels) + if total_time <= 0: + errors.append("A1.5 FAIL: Zero total kernel time") + + return errors + + +def compute_gpu_timeline_metrics(events): + """ + Run GPUEventAnalyser on events and return gpu_timeline dict for metadata. + Returns None if GPUEventAnalyser unavailable or fails. + """ + if GPUEventAnalyser is None: + return None + try: + # Ensure events have UID (required by GPUEventAnalyser for overlap computation) + for i, e in enumerate(events): + if "UID" not in e: + e["UID"] = i + analyzer = GPUEventAnalyser(events) + metrics = analyzer.compute_metrics() + total = metrics.get("total_time", 0) + busy = metrics.get("busy_time", 0) + idle = metrics.get("idle_time", 0) + if total <= 0: + return None + return { + "busy_time_us": round(metrics.get("busy_time", 0), 2), + "idle_time_us": round(metrics.get("idle_time", 0), 2), + "total_time_us": round(total, 2), + "computation_time_us": round(metrics.get("computation_time", 0), 2), + "exposed_comm_time_us": round(metrics.get("exposed_comm_time", 0), 2), + "exposed_memcpy_time_us": round(metrics.get("exposed_memcpy_time", 0), 2), + "idle_pct": round(100 * idle / total, 1), + "busy_pct": round(100 * busy / total, 1), + } + except Exception as e: + logger.warning("GPUEventAnalyser failed: %s", e) + return None + + +def extract_and_build_result(data, by_cat, source_file, region_metadata=None): + """Build extraction result dict.""" + kernels = extract_kernel_sequence(by_cat) + is_graph_mode, graph_launches = detect_graph_mode(by_cat) + callstack = extract_python_callstack(by_cat) + total_kernel_time = sum(k["dur"] for k in kernels) + categories_found = sorted(by_cat.keys()) + result = { + "source_file": source_file, + "metadata": { + "total_kernels": len(kernels), + "total_kernel_time_us": round(total_kernel_time, 2), + "is_graph_mode": is_graph_mode, + "graph_launch_count": len(graph_launches), + "categories": categories_found, + "has_python_stack": len(callstack) > 0, + }, + "kernels": kernels, + "python_callstack": callstack, + } + if region_metadata: + result["region_metadata"] = region_metadata + return result, kernels + + +def _resolve_output_dir(output_arg): + """Resolve -o to a directory path, handling the .json suffix case. + + When auto-split detects regions, -o is treated as a directory. If the + caller passed something like ``$DIR/extracted.json`` (intending a file), + strip the trailing ``.json`` component and use the parent directory so + that region subdirs land in ``$DIR/`` rather than inside a rogue + ``extracted.json/`` directory. + """ + if not output_arg: + return "." + if output_arg.endswith(".json") or output_arg.endswith(".json.gz"): + return os.path.dirname(output_arg) or "." + return output_arg + + +def _write_split_regions(split_result, trace_path, output_dir): + """Write per-region extracted.json + metadata.json files.""" + os.makedirs(output_dir, exist_ok=True) + for trace_dict, region_meta in split_result: + key = get_steady_state_key(region_meta) + region_dir = os.path.join(output_dir, key) + os.makedirs(region_dir, exist_ok=True) + merged_meta = gather_metadata( + trace_path, + trace_dict.get("traceEvents", []), + annotation_meta=region_meta, + ) + gpu_timeline = compute_gpu_timeline_metrics( + trace_dict.get("traceEvents", []) + ) + if gpu_timeline: + merged_meta["gpu_timeline"] = gpu_timeline + region_meta = {**region_meta, "gpu_timeline": gpu_timeline} + data, by_cat = load_trace(trace_dict) + filter_to_primary_stream(by_cat) + kernels_tmp = extract_kernel_sequence(by_cat) + is_graph_tmp, _ = detect_graph_mode(by_cat) + errors = run_assertions( + data, by_cat, kernels_tmp, is_graph_tmp, strict=False + ) + if errors: + print(f"Skipping {key}: {'; '.join(errors)}", file=sys.stderr) + continue + result, kernels = extract_and_build_result( + data, by_cat, trace_path, region_metadata=region_meta + ) + extracted_path = os.path.join(region_dir, "extracted.json") + meta_path = os.path.join(region_dir, "metadata.json") + with open(extracted_path, "w") as f: + json.dump(result, f, indent=2) + with open(meta_path, "w") as f: + json.dump(merged_meta, f, indent=2) + print( + f"Wrote {extracted_path} ({len(kernels)} kernels)", file=sys.stderr + ) + + +def main(): + parser = argparse.ArgumentParser( + description="Extract structured data from a Chrome trace JSON" + ) + parser.add_argument("trace", help="Path to trace JSON file") + parser.add_argument( + "-o", + "--output", + help="Output directory. Single-trace writes extracted.json inside " + "it; multi-region (vLLM) writes per-region subdirectories.", + ) + parser.add_argument( + "--split-vllm", + action="store_true", + help="(deprecated, now auto-detected) kept for backward compatibility", + ) + parser.add_argument( + "--no-split", + action="store_true", + help="Skip annotation auto-detection; always extract as one trace", + ) + args = parser.parse_args() + + # --- Auto-detect vLLM annotation regions (unless suppressed) ----------- + if not args.no_split: + split_result = split_vllm_trace(args.trace) + if split_result: + output_dir = _resolve_output_dir(args.output) + _write_split_regions(split_result, args.trace, output_dir) + return + + # --- Single-trace extraction ------------------------------------------- + data, by_cat = load_trace(args.trace) + kernels = extract_kernel_sequence(by_cat) + is_graph_mode, graph_launches = detect_graph_mode(by_cat) + callstack = extract_python_callstack(by_cat) + + errors = run_assertions(data, by_cat, kernels, is_graph_mode) + if errors: + for e in errors: + print(e, file=sys.stderr) + sys.exit(1) + + result, _ = extract_and_build_result(data, by_cat, args.trace) + output = json.dumps(result, indent=2) + + if args.output: + out_path = args.output + if os.path.isdir(out_path) or out_path.endswith("/"): + os.makedirs(out_path, exist_ok=True) + out_path = os.path.join(out_path, "extracted.json") + with open(out_path, "w") as f: + f.write(output) + print( + f"Wrote {out_path} ({len(kernels)} kernels, " + f"{sum(k['dur'] for k in kernels):.1f}us total)", + file=sys.stderr, + ) + else: + print(output) + + +if __name__ == "__main__": + main() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py new file mode 100644 index 000000000..0e4dc8705 --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py @@ -0,0 +1,313 @@ +#!/usr/bin/env python3 +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +""" +Extract trace tree context (cpu_op ancestors, nn_module_stack) for each kernel. + +Builds a TraceToTree from the raw trace and matches each kernel from +extracted.json to its tree event, walking the parent chain to find +cpu_op ancestors and nn_module_stack information. + +The output is raw data with no semantic interpretation -- downstream +LLM steps decide how to use cpu_op names and nn_module_stack for labeling. + +Usage (single region): + python extract_tree_context.py [-o tree_context.json] + +Usage (batch -- all regions share one tree build): + python extract_tree_context.py --regions-dir / + +Capture-trace augmentation (graph-mode traces): + python extract_tree_context.py \ + --capture-trace [-o tree_context.json] +""" + +import argparse +import json +import os +import sys + +_this_dir = os.path.dirname(os.path.abspath(__file__)) +_repo_root = os.path.abspath(os.path.join(_this_dir, "..", "..", "..", "..")) +if _repo_root not in sys.path: + sys.path.insert(0, _repo_root) + +from TraceLens.util import DataLoader, TraceEventUtils +from TraceLens.Trace2Tree.trace_to_tree import TraceToTree + + +def load_and_build_tree(trace_path, capture_trace_path=None): + """Load a trace file and build a TraceToTree. + + When capture_trace_path is provided, merges the capture-phase tree into + the graph-replay tree so that GPU kernels inherit cpu_op ancestors from + the capture recording. This restores near-100% tree coverage for + graph-mode traces. + """ + if capture_trace_path: + from TraceLens.Trace2Tree.trace_capture_merge import ( + merge_capture_trace_into_graph, + ) + + print( + f"Merging capture trace {capture_trace_path} into {trace_path}...", + file=sys.stderr, + ) + return merge_capture_trace_into_graph(capture_trace_path, trace_path) + + data = DataLoader.load_data(trace_path) + events = data.get("traceEvents", []) + _, non_meta_events = TraceEventUtils.split_event_list(events) + tree = TraceToTree(non_meta_events, prune_nongpu_paths=True) + tree.build_tree(add_python_func=True, link_fwd_bwd=False) + return tree + + +def _build_ts_index(tree): + """Build (name, ts) -> [event] index for fast matching.""" + index = {} + for event in tree.events: + key = (event.get("name"), event.get("ts")) + index.setdefault(key, []).append(event) + return index + + +def _find_tree_event(ts_index, name, ts, dur): + """Find a tree event matching by name, timestamp, and duration.""" + candidates = ts_index.get((name, ts), []) + if len(candidates) == 1: + return candidates[0] + for c in candidates: + if c.get("dur") == dur: + return c + return candidates[0] if candidates else None + + +def _find_cpu_op_ancestor(tree, event): + """Walk up parent chain to find nearest cpu_op ancestor. + + Returns (cpu_op_name, callstack_str, nn_module_stack_list, input_dims). + """ + current = event + nn_module = event.get("nn_module_stack", []) + + while True: + parent = tree.get_parent_event(current) + if parent is None: + return "", "", nn_module or [], [] + if tree.event_to_category(parent) == "cpu_op": + callstack = tree.traverse_parents_and_get_callstack(parent) + if not nn_module: + nn_module = parent.get("nn_module_stack", []) + args = parent.get("args", {}) + input_dims = args.get("Input Dims", []) or [] + return parent.get("name", ""), callstack, nn_module or [], input_dims + if not nn_module: + nn_module = parent.get("nn_module_stack", []) + current = parent + + +def extract_tree_context(tree, extracted_data, ts_index=None, capture_augmented=False): + """Match extracted kernels to tree events and extract context. + + Args: + tree: TraceToTree instance. + extracted_data: dict from extract_trace_data.py with "kernels" list. + ts_index: optional pre-built (name, ts) index from _build_ts_index(). + Pass this when processing multiple regions against the same tree. + capture_augmented: if True, the tree was built with capture-trace + augmentation and the flag is propagated into the output JSON. + + Returns dict with per-kernel tree context, labeled/unlabeled indices, + and coverage stats. + """ + kernels = extracted_data["kernels"] + if ts_index is None: + ts_index = _build_ts_index(tree) + + labeled_indices = [] + unlabeled_indices = [] + kernel_contexts = [] + + for i, kernel in enumerate(kernels): + tree_event = _find_tree_event( + ts_index, kernel["name"], kernel["ts"], kernel["dur"] + ) + + if tree_event is None: + kernel_contexts.append( + { + "index": i, + "cpu_op_name": "", + "cpu_op_callstack": "", + "nn_module_stack": [], + "input_dims": [], + } + ) + unlabeled_indices.append(i) + continue + + cpu_op_name, callstack, nn_module, input_dims = _find_cpu_op_ancestor( + tree, tree_event + ) + + kernel_contexts.append( + { + "index": i, + "cpu_op_name": cpu_op_name, + "cpu_op_callstack": callstack, + "nn_module_stack": nn_module, + "input_dims": input_dims, + } + ) + + if cpu_op_name: + labeled_indices.append(i) + else: + unlabeled_indices.append(i) + + total = len(kernels) + coverage = len(labeled_indices) / total if total > 0 else 0.0 + + result = { + "source_file": extracted_data.get("source_file", ""), + "total_kernels": total, + "coverage": round(coverage, 4), + "labeled_count": len(labeled_indices), + "unlabeled_count": len(unlabeled_indices), + "capture_augmented": capture_augmented, + "labeled_indices": labeled_indices, + "unlabeled_indices": unlabeled_indices, + "kernels": kernel_contexts, + } + return result + + +def _find_region_subdirs(regions_dir): + """Find subdirectories containing extracted.json.""" + regions = [] + for name in sorted(os.listdir(regions_dir)): + subdir = os.path.join(regions_dir, name) + if os.path.isdir(subdir) and os.path.isfile( + os.path.join(subdir, "extracted.json") + ): + regions.append((name, subdir)) + return regions + + +def _process_single( + tree, ts_index, extracted_path, output_path, capture_augmented=False +): + """Process one extracted.json against a pre-built tree and ts_index.""" + with open(extracted_path) as f: + extracted = json.load(f) + + n_kernels = len(extracted["kernels"]) + print(f" Matching {n_kernels} kernels...", file=sys.stderr, end=" ") + result = extract_tree_context( + tree, extracted, ts_index=ts_index, capture_augmented=capture_augmented + ) + print(f"{result['coverage']:.1%} coverage", file=sys.stderr) + + with open(output_path, "w") as f: + json.dump(result, f, indent=2) + return result + + +def main(): + parser = argparse.ArgumentParser( + description="Extract trace tree context (cpu_op, nn_module) for each kernel" + ) + parser.add_argument("trace", help="Path to raw trace file (.json or .json.gz)") + parser.add_argument( + "extracted_json", + nargs="?", + default=None, + help="Path to extracted.json (single-region mode)", + ) + parser.add_argument( + "-o", "--output", help="Output JSON path (single-region: default stdout)" + ) + parser.add_argument( + "--regions-dir", + help="Batch mode: directory containing region subdirs " + "with extracted.json. Builds tree once, writes " + "tree_context.json into each region subdir.", + ) + parser.add_argument( + "--capture-trace", + help="Path to a capture-phase trace file. When provided, the " + "capture tree is merged into the graph-replay tree before " + "extracting context, restoring cpu_op ancestry for kernels " + "that would otherwise be hidden under cudaGraphLaunch.", + ) + args = parser.parse_args() + + if not args.extracted_json and not args.regions_dir: + parser.error("provide either extracted_json or --regions-dir") + + capture_augmented = args.capture_trace is not None + + print(f"Building trace tree from {args.trace}...", file=sys.stderr) + tree = load_and_build_tree(args.trace, capture_trace_path=args.capture_trace) + ts_index = _build_ts_index(tree) + + if capture_augmented: + print("Capture-trace augmentation active", file=sys.stderr) + + if args.regions_dir: + regions = _find_region_subdirs(args.regions_dir) + if not regions: + print( + f"No region subdirs with extracted.json in {args.regions_dir}", + file=sys.stderr, + ) + sys.exit(1) + print(f"Batch mode: {len(regions)} regions found", file=sys.stderr) + for name, subdir in regions: + print(f"Region '{name}':", file=sys.stderr) + extracted_path = os.path.join(subdir, "extracted.json") + output_path = os.path.join(subdir, "tree_context.json") + _process_single( + tree, + ts_index, + extracted_path, + output_path, + capture_augmented=capture_augmented, + ) + print( + f"Wrote tree_context.json to {len(regions)} region subdirs", file=sys.stderr + ) + else: + with open(args.extracted_json) as f: + extracted = json.load(f) + + print( + f"Matching {len(extracted['kernels'])} kernels to tree events...", + file=sys.stderr, + ) + result = extract_tree_context( + tree, extracted, ts_index=ts_index, capture_augmented=capture_augmented + ) + + print( + f"Tree context: {result['labeled_count']}/{result['total_kernels']} " + f"kernels have cpu_op ancestors ({result['coverage']:.1%})", + file=sys.stderr, + ) + + output = json.dumps(result, indent=2) + if args.output: + with open(args.output, "w") as f: + f.write(output) + print(f"Wrote {args.output}", file=sys.stderr) + else: + print(output) + + +if __name__ == "__main__": + main() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py b/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py new file mode 100644 index 000000000..ab8e0a433 --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py @@ -0,0 +1,430 @@ +#!/usr/bin/env python3 +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +""" +Generate TraceDiff-compatible output from two semantic breakdowns. + +Takes two semantic_labels.json files (from the semantic breakdown pipeline) +and produces output files identical in schema to TraceDiff's +print_tracediff_report_files(), enabling the existing comparative mode +(tracelens_diff_analyzer.py) to consume graph-mode trace comparisons. + +Instead of the Wagner-Fischer DP tree-merge algorithm, kernels are matched +across traces by their semantic_block label. + +Input: + - Two semantic_labels.json files (one per trace) + +Output (in output directory): + - diff_stats.csv + - diff_stats_unique_args_summary.csv + - cpu_op_map.json + - cpu_op_map_trace1.json + - cpu_op_map_trace2.json + - merged_tree_output.txt + +Usage: + python generate_semantic_diff.py \\ + trace_a/semantic_labels.json trace_b/semantic_labels.json \\ + --name-a MI355 --name-b B200 \\ + -o output_dir/ +""" + +import argparse +import json +import os +import sys +from collections import OrderedDict + +import pandas as pd + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from _helpers import load_labels + + +# --------------------------------------------------------------------------- +# diff_stats.csv generation +# --------------------------------------------------------------------------- + + +def build_diff_stats(labeled_a, labeled_b): + """Build a list of row dicts matching TraceDiff's diff_stats.csv schema. + + Each kernel becomes one row. Kernels are grouped by semantic_block, + which is the functional label (e.g. "QKV Projection") when available. + + The kernel's ``nn_module`` field is used for the nn_module columns. + Falls back to perf_category. + + Returns (rows, block_id_map) where block_id_map is {semantic_block: int}. + """ + all_blocks_ordered = list( + OrderedDict.fromkeys( + [k["semantic_block"] for k in labeled_a] + + [k["semantic_block"] for k in labeled_b] + ) + ) + block_id_map = {block: idx for idx, block in enumerate(all_blocks_ordered)} + + def _nn_module(k): + if k.get("nn_module"): + return k["nn_module"] + return k.get("perf_category", "Others") + + def _format_dims(dims_list): + if not dims_list: + return "" + parts = [] + for d in dims_list: + if isinstance(d, (list, tuple)): + parts.append(str(tuple(d))) + else: + parts.append(str(d)) + return ", ".join(parts) + + rows = [] + for source_tag, kernels in [ + ("trace1", labeled_a), + ("trace2", labeled_b), + ]: + for k in kernels: + block = k["semantic_block"] + nn_mod = _nn_module(k) + cpu_op = k.get("cpu_op", "") or block + rows.append( + { + "name": k["name"], + "cpu_op_name": cpu_op, + "source": source_tag, + "Input Dims": _format_dims(k.get("input_dims", [])), + "Input Strides": "", + "Input type": "", + "Concrete Inputs": "", + "kernel_time": k["dur"], + "lowest_common_ancestor_name": block, + "lowest_common_ancestor_id": block_id_map[block], + "nn_module_stack": nn_mod, + "nn_module_parent": nn_mod, + } + ) + + return rows, block_id_map + + +# --------------------------------------------------------------------------- +# diff_stats_unique_args_summary.csv generation +# --------------------------------------------------------------------------- + + +def build_unique_args_summary(diff_stats_df): + """Aggregate diff_stats rows by all non-metric columns. + + Mirrors TraceDiff.get_df_diff_stats_unique_args() with sum aggregation + on kernel_time. + """ + metric_columns = ["kernel_time"] + grouping_cols = [ + c + for c in diff_stats_df.columns + if c not in metric_columns and c != "lowest_common_ancestor_id" + ] + + agg_dict = {mcol: ["sum", "mean"] for mcol in metric_columns} + for col in grouping_cols: + agg_dict[col] = "first" + + try: + df_agg = diff_stats_df.groupby(grouping_cols, dropna=False).agg(agg_dict) + df_agg["operation_count"] = diff_stats_df.groupby( + grouping_cols, dropna=False + ).size() + except TypeError: + str_cols = [f"{col}_str_repr" for col in grouping_cols] + df_temp = diff_stats_df.copy() + for col, str_col in zip(grouping_cols, str_cols): + df_temp[str_col] = df_temp[col].astype(str) + df_agg = df_temp.groupby(str_cols, dropna=False).agg(agg_dict) + df_agg["operation_count"] = df_temp.groupby(str_cols, dropna=False).size() + + df_agg.columns = ["_".join(col).strip() for col in df_agg.columns.values] + df_agg = df_agg.reset_index(drop=True) + + rename_map = {} + for col in grouping_cols: + col_first = f"{col}_first" + if col_first in df_agg.columns: + rename_map[col_first] = col + df_agg = df_agg.rename(columns=rename_map) + + primary_cols = grouping_cols + metric_cols = [] + for metric in metric_columns: + for agg in ["sum", "mean"]: + col_name = f"{metric}_{agg}" + if col_name in df_agg.columns: + metric_cols.append(col_name) + metric_cols = list(dict.fromkeys(metric_cols)) + other_cols = [ + col for col in df_agg.columns if col not in primary_cols + metric_cols + ] + df_agg = df_agg[primary_cols + metric_cols + other_cols] + + df_agg = df_agg.rename(columns={"operation_count_": "operation_count"}) + if "operation_count" in df_agg.columns: + cols = list(df_agg.columns) + cols.remove("operation_count") + cols.insert(1, "operation_count") + df_agg = df_agg[cols] + + sort_col = "kernel_time_sum" + if sort_col in df_agg.columns: + df_agg = df_agg.sort_values(by=sort_col, ascending=False, ignore_index=True) + + return df_agg + + +# --------------------------------------------------------------------------- +# cpu_op_map JSON generation +# --------------------------------------------------------------------------- + + +def build_cpu_op_maps(diff_stats_df): + """Build cpu_op_map dicts analogous to TraceDiff.get_cpu_op_to_kernels_json(). + + Returns (cpu_op_map, cpu_op_map_trace1_df, cpu_op_map_trace2_df). + """ + cpu_op_map = {} + for cpu_op in diff_stats_df["cpu_op_name"].unique(): + cpu_op_map[cpu_op] = {} + sub = diff_stats_df[diff_stats_df["cpu_op_name"] == cpu_op] + for source, group in sub.groupby("source"): + cpu_op_map[cpu_op][source] = { + "kernels": sorted(list(group["name"].unique())), + "nn_module_parents": sorted(list(group["nn_module_parent"].unique())), + } + + cpu_op_map_trace1 = ( + diff_stats_df[diff_stats_df["source"] == "trace1"] + .groupby("cpu_op_name") + .agg({"name": lambda x: sorted(set(x))}) + .sort_index() + ) + cpu_op_map_trace2 = ( + diff_stats_df[diff_stats_df["source"] == "trace2"] + .groupby("cpu_op_name") + .agg({"name": lambda x: sorted(set(x))}) + .sort_index() + ) + + return cpu_op_map, cpu_op_map_trace1, cpu_op_map_trace2 + + +# --------------------------------------------------------------------------- +# merged_tree_output.txt generation +# --------------------------------------------------------------------------- + + +def build_merged_tree_text(block_id_map, labeled_a, labeled_b, name_a, name_b): + """Build a text tree representation mimicking TraceDiff's merged tree. + + Structure: + Root + └── + ├── (combined / trace1-only / trace2-only) + │ ├── kernel_name_a [trace1] + │ └── kernel_name_b [trace2] + """ + blocks_a = OrderedDict() + for k in labeled_a: + b = k["semantic_block"] + blocks_a.setdefault(b, []).append(k["name"]) + blocks_b = OrderedDict() + for k in labeled_b: + b = k["semantic_block"] + blocks_b.setdefault(b, []).append(k["name"]) + + block_nn_module = {} + for k in labeled_a + labeled_b: + b = k["semantic_block"] + if b not in block_nn_module: + if k.get("nn_module"): + block_nn_module[b] = k["nn_module"] + else: + block_nn_module[b] = k.get("perf_category", "Others") + + all_blocks = list(block_id_map.keys()) + + groups = OrderedDict() + for block in all_blocks: + g = block_nn_module.get(block, "Others") + groups.setdefault(g, []).append(block) + + lines = [] + lines.append(f"└── Root ({name_a} vs {name_b})") + + group_list = list(groups.items()) + for gi, (group_name, group_blocks) in enumerate(group_list): + is_last_group = gi == len(group_list) - 1 + g_connector = "└── " if is_last_group else "├── " + g_prefix = " " if is_last_group else "│ " + lines.append(f" {g_connector}{group_name}") + + for bi, block in enumerate(group_blocks): + is_last_block = bi == len(group_blocks) - 1 + b_connector = "└── " if is_last_block else "├── " + b_prefix = " " if is_last_block else "│ " + + in_a = block in blocks_a + in_b = block in blocks_b + + if in_a and in_b: + label = block + elif in_a: + label = f">> trace1: {block}" + else: + label = f"<< trace2: {block}" + + lines.append(f" {g_prefix}{b_connector}{label}") + + kernels_a = blocks_a.get(block, []) + kernels_b = blocks_b.get(block, []) + kernel_names_a = sorted(set(kernels_a)) + kernel_names_b = sorted(set(kernels_b)) + + all_kernel_entries = [(kn, "trace1") for kn in kernel_names_a] + [ + (kn, "trace2") for kn in kernel_names_b + ] + + for ki, (kn, src) in enumerate(all_kernel_entries): + is_last_kernel = ki == len(all_kernel_entries) - 1 + k_connector = "└── " if is_last_kernel else "├── " + if in_a and in_b: + k_line = kn + elif src == "trace1": + k_line = f">> {src}: {kn}" + else: + k_line = f"<< {src}: {kn}" + lines.append(f" {g_prefix}{b_prefix}{k_connector}{k_line}") + + return "\n".join(lines) + + +# --------------------------------------------------------------------------- +# Output writer +# --------------------------------------------------------------------------- + + +def write_outputs( + output_dir, + diff_stats_df, + summary_df, + cpu_op_map, + cpu_op_map_trace1, + cpu_op_map_trace2, + merged_tree_text, +): + """Write all output files to output_dir.""" + os.makedirs(output_dir, exist_ok=True) + + diff_stats_df.to_csv(os.path.join(output_dir, "diff_stats.csv"), index=False) + + summary_df.to_csv( + os.path.join(output_dir, "diff_stats_unique_args_summary.csv"), index=False + ) + + with open(os.path.join(output_dir, "cpu_op_map.json"), "w") as f: + json.dump(cpu_op_map, f, indent=2, ensure_ascii=False) + + with open(os.path.join(output_dir, "cpu_op_map_trace1.json"), "w") as f: + json.dump(cpu_op_map_trace1.to_dict()["name"], f, indent=2, ensure_ascii=False) + + with open(os.path.join(output_dir, "cpu_op_map_trace2.json"), "w") as f: + json.dump(cpu_op_map_trace2.to_dict()["name"], f, indent=2, ensure_ascii=False) + + with open(os.path.join(output_dir, "merged_tree_output.txt"), "w") as f: + f.write(merged_tree_text + "\n") + + +# --------------------------------------------------------------------------- +# Main +# --------------------------------------------------------------------------- + + +def main(): + parser = argparse.ArgumentParser( + description="Generate TraceDiff-compatible output from two semantic breakdowns" + ) + parser.add_argument("trace_a", help="Path to trace A semantic_labels.json") + parser.add_argument("trace_b", help="Path to trace B semantic_labels.json") + parser.add_argument("--name-a", default="trace_a", help="Short name for trace A") + parser.add_argument("--name-b", default="trace_b", help="Short name for trace B") + parser.add_argument( + "-o", + "--output", + default="semantic_diff_output", + help="Output directory (default: semantic_diff_output)", + ) + args = parser.parse_args() + + data_a = load_labels(args.trace_a) + data_b = load_labels(args.trace_b) + + labeled_a = data_a["labeled_kernels"] + labeled_b = data_b["labeled_kernels"] + + print(f"Trace A ({args.name_a}): {len(labeled_a)} kernels", file=sys.stderr) + print(f"Trace B ({args.name_b}): {len(labeled_b)} kernels", file=sys.stderr) + + rows, block_id_map = build_diff_stats(labeled_a, labeled_b) + diff_stats_df = pd.DataFrame(rows) + + summary_df = build_unique_args_summary(diff_stats_df) + + cpu_op_map, cpu_op_map_trace1, cpu_op_map_trace2 = build_cpu_op_maps(diff_stats_df) + + merged_tree_text = build_merged_tree_text( + block_id_map, labeled_a, labeled_b, args.name_a, args.name_b + ) + + write_outputs( + args.output, + diff_stats_df, + summary_df, + cpu_op_map, + cpu_op_map_trace1, + cpu_op_map_trace2, + merged_tree_text, + ) + + blocks_a = set(k["semantic_block"] for k in labeled_a) + blocks_b = set(k["semantic_block"] for k in labeled_b) + matched = blocks_a & blocks_b + only_a = blocks_a - blocks_b + only_b = blocks_b - blocks_a + + print(f"\nSemantic blocks: {len(block_id_map)} total", file=sys.stderr) + print(f" Matched (in both traces): {len(matched)}", file=sys.stderr) + if only_a: + print(f" Only in {args.name_a}: {sorted(only_a)}", file=sys.stderr) + if only_b: + print(f" Only in {args.name_b}: {sorted(only_b)}", file=sys.stderr) + + print(f"\nOutput written to: {args.output}/", file=sys.stderr) + print(f" diff_stats.csv ({len(diff_stats_df)} rows)", file=sys.stderr) + print( + f" diff_stats_unique_args_summary.csv ({len(summary_df)} rows)", + file=sys.stderr, + ) + print( + f" cpu_op_map.json, cpu_op_map_trace1.json, cpu_op_map_trace2.json", + file=sys.stderr, + ) + print(f" merged_tree_output.txt", file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/harmonization.py b/TraceLens/Agent/Analysis/semantic_analyses/harmonization.py new file mode 100644 index 000000000..1e4969529 --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/harmonization.py @@ -0,0 +1,831 @@ +#!/usr/bin/env python3 +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +""" +Cross-trace semantic harmonization (single LLM-assisted step). + +This module consolidates the harmonization cluster into one file with three +subcommands: + + align Align two independently-labeled semantic_labels.json files + using Needleman-Wunsch DP and emit alignment.json. + prepare-context Build a compact review context (harmonization_context.json) + from the alignment + both traces for the LLM agent. + apply-corrections Apply the agent's harmonization_corrections.json back onto + the two semantic_labels.json files in place. + +The reference label catalog (formerly semantic_label_catalog.py) is included +in-file as SEMANTIC_LABEL_CATALOG. + +Usage: + python harmonization.py align \ + --labels-a /semantic_labels.json \ + --labels-b /semantic_labels.json \ + --name-a MI355 --name-b B200 \ + -o alignment.json + + python harmonization.py prepare-context \ + --alignment alignment.json \ + --labels-a /semantic_labels.json \ + --labels-b /semantic_labels.json \ + --name-a MI355 --name-b B200 \ + -o harmonization_context.json + + python harmonization.py apply-corrections \ + --corrections harmonization_corrections.json \ + --labels-a /semantic_labels.json \ + --labels-b /semantic_labels.json \ + --name-a MI355 --name-b B200 +""" + +import argparse +import json +import re +import sys +from collections import OrderedDict + + +# =========================================================================== +# Reference label catalog (formerly semantic_label_catalog.py) +# =========================================================================== +# +# The harmonization agent uses this catalog to pick consistent, broad labels +# for semantic blocks. Labels from the catalog are preferred; the agent may +# invent a custom label only when no catalog entry fits. +# +# To extend: add new entries to the appropriate perf_category list. + +SEMANTIC_LABEL_CATALOG = { + "GEMM": [ + "QKV Projection", + "Output Projection", + "FFN Gate+Up", + "FFN Down", + "Embedding Projection", + "Output Head", + ], + "GEMM-MoE": [ + "MoE Expert GEMM", + "MoE Shared Expert GEMM", + ], + "SDPA": [ + "Attention", + ], + "Normalization": [ + "Pre-Attn Norm", + "Post-Attn Norm", + "FFN Norm", + "Final Norm", + ], + "Elementwise": [ + "Residual Add", + "Activation", + "Rotary Embedding", + "Attention Output Gate", + "KV Cache Store", + "Embedding", + ], + "Elementwise-MoE": [ + "MoE Routing", + "MoE Finalize", + ], + "Communication": [ + "AllReduce", + "AllGather", + "ReduceScatter", + "AllToAll", + ], + "Quantization": [ + "Quantize", + "Dequantize", + ], + "MemCpy": [ + "MemCpy", + ], +} + + +# =========================================================================== +# align: cross-trace semantic block alignment (Needleman-Wunsch) +# =========================================================================== + + +def _block_key(kernel): + """Get the grouping key for a kernel: semantic_block if present, else perf_category.""" + return kernel.get("semantic_block", kernel.get("perf_category", "Others")) + + +def _build_block_sequence(labels_data): + """Build an ordered sequence of semantic blocks from labeled kernels. + + Groups consecutive kernels with the same grouping key into blocks. + The key is semantic_block when present, otherwise perf_category. + Returns list of dicts with block info. + """ + kernels = labels_data["labeled_kernels"] + if not kernels: + return [] + + def _finish_block(block_key, cat, module, indices, dur, names, cpu_ops): + return { + "semantic_block": block_key, + "perf_category": cat, + "nn_module": module, + "kernel_count": len(indices), + "total_dur_us": round(dur, 2), + "kernel_indices": indices, + "unique_kernel_names": sorted(names), + "cpu_ops": sorted(cpu_ops - {""}), + "layer": kernels[indices[0]].get("layer"), + } + + blocks = [] + cur_block = _block_key(kernels[0]) + cur_cat = kernels[0].get("perf_category", "Others") + cur_module = kernels[0].get("nn_module", "") + cur_indices = [0] + cur_dur = kernels[0]["dur"] + cur_names = {kernels[0]["name"]} + cur_cpu_ops = {kernels[0].get("cpu_op", "")} + + for i, k in enumerate(kernels[1:], 1): + block = _block_key(k) + if block == cur_block: + cur_indices.append(i) + cur_dur += k["dur"] + cur_names.add(k["name"]) + cur_cpu_ops.add(k.get("cpu_op", "")) + else: + blocks.append( + _finish_block(cur_block, cur_cat, cur_module, cur_indices, cur_dur, cur_names, cur_cpu_ops) + ) + cur_block = block + cur_cat = k.get("perf_category", "Others") + cur_module = k.get("nn_module", "") + cur_indices = [i] + cur_dur = k["dur"] + cur_names = {k["name"]} + cur_cpu_ops = {k.get("cpu_op", "")} + + blocks.append( + _finish_block(cur_block, cur_cat, cur_module, cur_indices, cur_dur, cur_names, cur_cpu_ops) + ) + return blocks + + +def _detect_layer_cycle(blocks): + """Extract one layer cycle from the block sequence. + + Finds the repeating portion by looking for the first block with + layer=0 and then finding where layer=1 starts. + Returns (cycle_blocks, cycle_start_idx, cycle_end_idx). + """ + first_layer0 = None + first_layer1 = None + + for i, b in enumerate(blocks): + layer = b.get("layer") + if layer == 0 and first_layer0 is None: + first_layer0 = i + elif layer == 1 and first_layer0 is not None and first_layer1 is None: + first_layer1 = i + break + + if first_layer0 is not None and first_layer1 is not None: + return blocks[first_layer0:first_layer1], first_layer0, first_layer1 + if first_layer0 is not None: + return blocks[first_layer0:], first_layer0, len(blocks) + return blocks, 0, len(blocks) + + +def _has_descriptive_semantic_block(block): + """True if the block has a semantic_block that isn't just a perf_category fallback.""" + sb = block.get("semantic_block", "") + return sb and sb != block.get("perf_category", "Others") + + +def _block_similarity(ba, bb): + """Compute similarity score between two blocks for DP alignment. + + Scoring: + - Same descriptive semantic_block name: +3 (strong match) + - Same perf_category: +2 + - Same nn_module: +1 + - Overlapping kernel names: +0.5 + - Overlapping cpu_ops: +0.5 + - Different perf_category: -1 + """ + score = 0.0 + + has_desc_a = _has_descriptive_semantic_block(ba) + has_desc_b = _has_descriptive_semantic_block(bb) + + if has_desc_a and has_desc_b and ba["semantic_block"] == bb["semantic_block"]: + score += 3.0 + elif ba["perf_category"] == bb["perf_category"]: + score += 2.0 + else: + base_a = ba["perf_category"].split("-")[0] + base_b = bb["perf_category"].split("-")[0] + if base_a == base_b: + score += 1.5 + else: + score -= 1.0 + + if ba.get("nn_module") and ba["nn_module"] == bb.get("nn_module"): + score += 1.0 + + names_a = set(ba.get("unique_kernel_names", [])) + names_b = set(bb.get("unique_kernel_names", [])) + if names_a & names_b: + score += 0.5 + + ops_a = set(ba.get("cpu_ops", [])) + ops_b = set(bb.get("cpu_ops", [])) + if ops_a & ops_b: + score += 0.5 + + return score + + +def needleman_wunsch(blocks_a, blocks_b, gap_penalty=-0.5): + """Align two block sequences using Needleman-Wunsch DP. + + Returns list of (block_a_or_None, block_b_or_None, idx_a, idx_b) tuples. + """ + na = len(blocks_a) + nb = len(blocks_b) + + score = [[0.0] * (nb + 1) for _ in range(na + 1)] + trace = [[0] * (nb + 1) for _ in range(na + 1)] + + for i in range(1, na + 1): + score[i][0] = score[i - 1][0] + gap_penalty + trace[i][0] = 1 + for j in range(1, nb + 1): + score[0][j] = score[0][j - 1] + gap_penalty + trace[0][j] = 2 + + for i in range(1, na + 1): + for j in range(1, nb + 1): + s = _block_similarity(blocks_a[i - 1], blocks_b[j - 1]) + diag = score[i - 1][j - 1] + s + up = score[i - 1][j] + gap_penalty + left = score[i][j - 1] + gap_penalty + + best = max(diag, up, left) + score[i][j] = best + if best == diag: + trace[i][j] = 0 + elif best == up: + trace[i][j] = 1 + else: + trace[i][j] = 2 + + alignment = [] + i, j = na, nb + while i > 0 or j > 0: + if i > 0 and j > 0 and trace[i][j] == 0: + alignment.append((blocks_a[i - 1], blocks_b[j - 1], i - 1, j - 1)) + i -= 1 + j -= 1 + elif i > 0 and (j == 0 or trace[i][j] == 1): + alignment.append((blocks_a[i - 1], None, i - 1, None)) + i -= 1 + else: + alignment.append((None, blocks_b[j - 1], None, j - 1)) + j -= 1 + + alignment.reverse() + return alignment + + +def build_alignment_output(alignment, name_a, name_b, labels_a, labels_b): + """Build the alignment.json output.""" + rows = [] + for ba, bb, idx_a, idx_b in alignment: + row = OrderedDict() + + if ba and bb: + row["match_status"] = "matched" + elif ba: + row["match_status"] = f"only_in_{name_a}" + else: + row["match_status"] = f"only_in_{name_b}" + + if ba: + row[f"semantic_block_{name_a}"] = ba["semantic_block"] + row[f"perf_category_{name_a}"] = ba["perf_category"] + row[f"nn_module_{name_a}"] = ba.get("nn_module", "") + row[f"kernel_count_{name_a}"] = ba["kernel_count"] + row[f"total_dur_us_{name_a}"] = ba["total_dur_us"] + names = ba.get("unique_kernel_names", []) + row[f"kernel_names_{name_a}"] = names[:5] + row[f"cpu_ops_{name_a}"] = ba.get("cpu_ops", []) + else: + row[f"semantic_block_{name_a}"] = None + row[f"perf_category_{name_a}"] = None + row[f"nn_module_{name_a}"] = None + row[f"kernel_count_{name_a}"] = 0 + row[f"total_dur_us_{name_a}"] = 0 + row[f"kernel_names_{name_a}"] = [] + row[f"cpu_ops_{name_a}"] = [] + + if bb: + row[f"semantic_block_{name_b}"] = bb["semantic_block"] + row[f"perf_category_{name_b}"] = bb["perf_category"] + row[f"nn_module_{name_b}"] = bb.get("nn_module", "") + row[f"kernel_count_{name_b}"] = bb["kernel_count"] + row[f"total_dur_us_{name_b}"] = bb["total_dur_us"] + names = bb.get("unique_kernel_names", []) + row[f"kernel_names_{name_b}"] = names[:5] + row[f"cpu_ops_{name_b}"] = bb.get("cpu_ops", []) + else: + row[f"semantic_block_{name_b}"] = None + row[f"perf_category_{name_b}"] = None + row[f"nn_module_{name_b}"] = None + row[f"kernel_count_{name_b}"] = 0 + row[f"total_dur_us_{name_b}"] = 0 + row[f"kernel_names_{name_b}"] = [] + row[f"cpu_ops_{name_b}"] = [] + + rows.append(row) + + matched = sum(1 for r in rows if r["match_status"] == "matched") + only_a = sum(1 for r in rows if r["match_status"] == f"only_in_{name_a}") + only_b = sum(1 for r in rows if r["match_status"] == f"only_in_{name_b}") + + output = OrderedDict() + output["name_a"] = name_a + output["name_b"] = name_b + output["summary"] = { + "total_aligned_rows": len(rows), + "matched": matched, + f"only_in_{name_a}": only_a, + f"only_in_{name_b}": only_b, + } + output["model_info_a"] = labels_a.get("model_info", {}) + output["model_info_b"] = labels_b.get("model_info", {}) + output["alignment_table"] = rows + return output + + +def _build_region_blocks(labels_data, region): + """Build a deduplicated block sequence for a region (pre/post). + + Unlike _build_block_sequence which groups by consecutive position, + this merges all kernels sharing the same semantic_block name into one + block. This handles interleaving with other kernel types. + Returns blocks in order of first kernel appearance. + """ + kernels = labels_data["labeled_kernels"] + block_map = OrderedDict() + for i, k in enumerate(kernels): + if k.get("region") != region: + continue + sb = k.get("semantic_block", "") + if sb not in block_map: + block_map[sb] = { + "semantic_block": sb, + "perf_category": k.get("perf_category", "Others"), + "nn_module": k.get("nn_module", ""), + "kernel_count": 0, + "total_dur_us": 0.0, + "kernel_indices": [], + "unique_kernel_names": set(), + "cpu_ops": set(), + "layer": k.get("layer"), + } + entry = block_map[sb] + entry["kernel_count"] += 1 + entry["total_dur_us"] += k["dur"] + entry["kernel_indices"].append(i) + entry["unique_kernel_names"].add(k["name"]) + entry["cpu_ops"].add(k.get("cpu_op", "")) + + blocks = [] + for entry in block_map.values(): + entry["total_dur_us"] = round(entry["total_dur_us"], 2) + entry["unique_kernel_names"] = sorted(entry["unique_kernel_names"]) + entry["cpu_ops"] = sorted(entry["cpu_ops"] - {""}) + blocks.append(entry) + return blocks + + +def _filter_by_region(labels, region): + """Return a copy of labels_data containing only kernels in *region*.""" + filtered = dict(labels) + filtered["labeled_kernels"] = [ + k for k in labels["labeled_kernels"] + if k.get("region") == region + ] + return filtered + + +def run_alignment(labels_a, labels_b, name_a="trace_a", name_b="trace_b"): + """Run the full cross-trace block alignment pipeline. + + Aligns pre-layer, cycle, and post-layer regions separately, then + concatenates them into a single alignment table. Secondary stream + blocks are excluded (different GPU stream, no cross-trace match). + """ + body_a = _filter_by_region(labels_a, "body") + body_b = _filter_by_region(labels_b, "body") + + body_blocks_a = _build_block_sequence(body_a) + body_blocks_b = _build_block_sequence(body_b) + + cycle_a, _, _ = _detect_layer_cycle(body_blocks_a) + cycle_b, _, _ = _detect_layer_cycle(body_blocks_b) + + pre_a = _build_region_blocks(labels_a, "pre") + pre_b = _build_region_blocks(labels_b, "pre") + epi_a = _build_region_blocks(labels_a, "post") + epi_b = _build_region_blocks(labels_b, "post") + + print( + f"{name_a}: pre {len(pre_a)}, cycle {len(cycle_a)}, post {len(epi_a)}", + file=sys.stderr, + ) + print( + f"{name_b}: pre {len(pre_b)}, cycle {len(cycle_b)}, post {len(epi_b)}", + file=sys.stderr, + ) + + alignment = [] + if pre_a or pre_b: + alignment.extend(needleman_wunsch(pre_a, pre_b)) + alignment.extend(needleman_wunsch(cycle_a, cycle_b)) + if epi_a or epi_b: + alignment.extend(needleman_wunsch(epi_a, epi_b)) + + matched = sum(1 for ba, bb, _, _ in alignment if ba and bb) + print( + f"Alignment: {matched} matched, " + f"{sum(1 for ba, bb, _, _ in alignment if ba and not bb)} {name_a}-only, " + f"{sum(1 for ba, bb, _, _ in alignment if not ba and bb)} {name_b}-only", + file=sys.stderr, + ) + + return build_alignment_output(alignment, name_a, name_b, labels_a, labels_b) + + +# =========================================================================== +# prepare-context: compact LLM review context +# =========================================================================== + +_INDEXED_RE = re.compile(r"^[A-Z][\w-]*_\d+$") + + +def _collect_block_details(labels_data): + """Build per-block summary from semantic_labels.json.""" + block_map = OrderedDict() + for k in labels_data["labeled_kernels"]: + block = k.get("semantic_block", k.get("perf_category", "Others")) + if block not in block_map: + block_map[block] = { + "kernel_count": 0, + "total_dur_us": 0.0, + "perf_category": k.get("perf_category", "Others"), + "nn_module": k.get("nn_module", ""), + "kernel_names": set(), + "cpu_ops": set(), + "input_dims": None, + } + entry = block_map[block] + entry["kernel_count"] += 1 + entry["total_dur_us"] += k["dur"] + kname = k["name"] + if len(kname) > 120: + kname = kname[:120] + "..." + entry["kernel_names"].add(kname) + cpu_op = k.get("cpu_op", "") + if cpu_op: + entry["cpu_ops"].add(cpu_op) + if entry["input_dims"] is None: + dims = k.get("input_dims", []) + if dims: + entry["input_dims"] = dims + + for entry in block_map.values(): + entry["kernel_names"] = sorted(entry["kernel_names"])[:10] + entry["cpu_ops"] = sorted(entry["cpu_ops"]) + entry["total_dur_us"] = round(entry["total_dur_us"], 2) + if entry["input_dims"] is None: + entry["input_dims"] = [] + + return block_map + + +def build_harmonization_context(alignment_data, labels_a, labels_b, name_a, name_b): + """Build the full harmonization context for LLM review.""" + details_a = _collect_block_details(labels_a) + details_b = _collect_block_details(labels_b) + + enriched_rows = [] + for row in alignment_data["alignment_table"]: + enriched = OrderedDict(row) + + block_a = row.get(f"semantic_block_{name_a}") + block_b = row.get(f"semantic_block_{name_b}") + + if block_a and block_a in details_a: + da = details_a[block_a] + enriched[f"kernel_names_detail_{name_a}"] = da["kernel_names"] + enriched[f"cpu_ops_detail_{name_a}"] = da["cpu_ops"] + if da["input_dims"]: + enriched[f"input_dims_{name_a}"] = da["input_dims"] + if block_b and block_b in details_b: + db = details_b[block_b] + enriched[f"kernel_names_detail_{name_b}"] = db["kernel_names"] + enriched[f"cpu_ops_detail_{name_b}"] = db["cpu_ops"] + if db["input_dims"]: + enriched[f"input_dims_{name_b}"] = db["input_dims"] + + label_match = "same" + if block_a and block_b: + if block_a == block_b: + label_match = "same" + elif row.get(f"perf_category_{name_a}") == row.get( + f"perf_category_{name_b}" + ): + label_match = "different_name_same_category" + else: + label_match = "different" + elif block_a: + label_match = f"only_in_{name_a}" + else: + label_match = f"only_in_{name_b}" + + enriched["label_match"] = label_match + enriched_rows.append(enriched) + + total_a = labels_a.get("total_kernel_time_us", 0) + total_b = labels_b.get("total_kernel_time_us", 0) + + context = OrderedDict() + context["name_a"] = name_a + context["name_b"] = name_b + context["model_info_a"] = labels_a.get("model_info", {}) + context["model_info_b"] = labels_b.get("model_info", {}) + context["trace_summary"] = { + f"total_kernel_time_us_{name_a}": total_a, + f"total_kernel_time_us_{name_b}": total_b, + f"total_blocks_{name_a}": len(details_a), + f"total_blocks_{name_b}": len(details_b), + } + context["alignment_summary"] = alignment_data.get("summary", {}) + context["label_catalog"] = SEMANTIC_LABEL_CATALOG + + already_matched = 0 + rows_needing_work = [] + for r in enriched_rows: + if r["label_match"] != "same": + rows_needing_work.append(r) + else: + block = ( + r.get(f"semantic_block_{name_a}") + or r.get(f"semantic_block_{name_b}") + or "" + ) + if _INDEXED_RE.match(block): + r["label_match"] = "needs_rename" + rows_needing_work.append(r) + else: + already_matched += 1 + + context["already_matched"] = already_matched + context["harmonization_needed"] = len(rows_needing_work) + context["alignment_table"] = rows_needing_work + + return context + + +# =========================================================================== +# apply-corrections: write the agent's corrections back to the labels files +# =========================================================================== + + +def _apply_renames(kernels, renames, trace_name): + """Rename existing semantic_block values.""" + count = 0 + rename_map = {} + for r in renames: + if r.get("trace") and r["trace"] != trace_name: + continue + rename_map[r["old_semantic_block"]] = r + + for kernel in kernels: + old = kernel.get("semantic_block", "") + if old in rename_map: + r = rename_map[old] + kernel["semantic_block"] = r["new_semantic_block"] + if "new_perf_category" in r and r["new_perf_category"]: + kernel["perf_category"] = r["new_perf_category"] + if "new_nn_module" in r and r["new_nn_module"]: + kernel["nn_module"] = r["new_nn_module"] + count += 1 + + return count + + +def _apply_category_corrections(kernels, corrections, trace_name): + """Apply perf_category corrections.""" + count = 0 + corr_map = {} + for c in corrections: + if c.get("trace") and c["trace"] != trace_name: + continue + corr_map[c["semantic_block"]] = c["new_perf_category"] + + for kernel in kernels: + block = kernel.get("semantic_block", "") + if block in corr_map: + kernel["perf_category"] = corr_map[block] + count += 1 + + return count + + +def _apply_kernel_reassignments(kernels, reassignments, trace_name): + """Move individual kernels between semantic blocks.""" + count = 0 + for ra in reassignments: + if ra.get("trace") and ra["trace"] != trace_name: + continue + indices = set(ra["kernel_indices"]) + new_block = ra["to_semantic_block"] + for kernel in kernels: + if kernel["index"] in indices: + kernel["semantic_block"] = new_block + count += 1 + + return count + + +def apply_corrections(labels_path, corrections_data, trace_name): + """Apply all correction types to a semantic_labels.json file.""" + with open(labels_path) as f: + data = json.load(f) + + kernels = data["labeled_kernels"] + stats = {} + + renames = corrections_data.get("label_renames", []) + if renames: + stats["renames"] = _apply_renames(kernels, renames, trace_name) + + cat_corrections = corrections_data.get("category_corrections", []) + if cat_corrections: + stats["category_corrections"] = _apply_category_corrections( + kernels, cat_corrections, trace_name + ) + + reassignments = corrections_data.get("kernel_reassignments", []) + if reassignments: + stats["kernel_reassignments"] = _apply_kernel_reassignments( + kernels, reassignments, trace_name + ) + + with open(labels_path, "w") as f: + json.dump(data, f, indent=2) + + return stats + + +# =========================================================================== +# CLI +# =========================================================================== + + +def cmd_align(args): + with open(args.labels_a) as f: + labels_a = json.load(f) + with open(args.labels_b) as f: + labels_b = json.load(f) + + result = run_alignment(labels_a, labels_b, args.name_a, args.name_b) + + with open(args.output, "w") as f: + json.dump(result, f, indent=2) + + print( + f"Wrote {args.output} ({result['summary']['total_aligned_rows']} rows, " + f"{result['summary']['matched']} matched)", + file=sys.stderr, + ) + + +def cmd_prepare_context(args): + with open(args.alignment) as f: + alignment_data = json.load(f) + with open(args.labels_a) as f: + labels_a = json.load(f) + with open(args.labels_b) as f: + labels_b = json.load(f) + + context = build_harmonization_context( + alignment_data, labels_a, labels_b, args.name_a, args.name_b + ) + + with open(args.output, "w") as f: + json.dump(context, f, indent=2) + + print( + f"Wrote {args.output} ({len(context['alignment_table'])} rows, " + f"{context['harmonization_needed']} needing harmonization)", + file=sys.stderr, + ) + + +def cmd_apply_corrections(args): + with open(args.corrections) as f: + corrections_data = json.load(f) + + stats_a = apply_corrections(args.labels_a, corrections_data, args.name_a) + stats_b = apply_corrections(args.labels_b, corrections_data, args.name_b) + + total_a = sum(stats_a.values()) + total_b = sum(stats_b.values()) + + if total_a == 0 and total_b == 0: + print("No corrections applied.", file=sys.stderr) + else: + print( + f"Applied to {args.name_a}: {stats_a}", + file=sys.stderr, + ) + print( + f"Applied to {args.name_b}: {stats_b}", + file=sys.stderr, + ) + + +def main(): + parser = argparse.ArgumentParser( + description="Cross-trace semantic harmonization (align / prepare-context / apply-corrections)" + ) + sub = parser.add_subparsers(dest="command", required=True) + + p_align = sub.add_parser( + "align", + help="Align semantic blocks across two independently-labeled traces", + ) + p_align.add_argument( + "--labels-a", required=True, help="Path to trace A semantic_labels.json" + ) + p_align.add_argument( + "--labels-b", required=True, help="Path to trace B semantic_labels.json" + ) + p_align.add_argument("--name-a", default="trace_a", help="Short name for trace A") + p_align.add_argument("--name-b", default="trace_b", help="Short name for trace B") + p_align.add_argument( + "-o", "--output", required=True, help="Output alignment JSON path" + ) + p_align.set_defaults(func=cmd_align) + + p_prep = sub.add_parser( + "prepare-context", + help="Prepare LLM context for cross-trace semantic harmonization", + ) + p_prep.add_argument( + "--alignment", required=True, help="Path to alignment.json from the align step" + ) + p_prep.add_argument( + "--labels-a", required=True, help="Path to trace A semantic_labels.json" + ) + p_prep.add_argument( + "--labels-b", required=True, help="Path to trace B semantic_labels.json" + ) + p_prep.add_argument("--name-a", default="trace_a", help="Short name for trace A") + p_prep.add_argument("--name-b", default="trace_b", help="Short name for trace B") + p_prep.add_argument("-o", "--output", required=True, help="Output JSON path") + p_prep.set_defaults(func=cmd_prepare_context) + + p_apply = sub.add_parser( + "apply-corrections", + help="Apply harmonization corrections to semantic_labels.json files", + ) + p_apply.add_argument( + "--corrections", required=True, help="Path to harmonization_corrections.json" + ) + p_apply.add_argument( + "--labels-a", required=True, help="Path to trace A semantic_labels.json" + ) + p_apply.add_argument( + "--labels-b", required=True, help="Path to trace B semantic_labels.json" + ) + p_apply.add_argument("--name-a", default="trace_a", help="Short name for trace A") + p_apply.add_argument("--name-b", default="trace_b", help="Short name for trace B") + p_apply.set_defaults(func=cmd_apply_corrections) + + args = parser.parse_args() + args.func(args) + + +if __name__ == "__main__": + main() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py b/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py new file mode 100644 index 000000000..b648ff287 --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python3 +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +""" +Match two semantic breakdowns and compute comparison stats. + +Takes two semantic_labels.json files (one per trace) that have already been +individually broken down with matching semantic_block vocabularies. + +Input: two semantic_labels.json files +Output: comparison.csv + +Usage: + python match_and_compare.py \ + --name-a MI355 --name-b B200 \ + [-o comparison.csv] + + For multi-region (per steady-state), use --regions-dir-a and --regions-dir-b: + python match_and_compare.py --regions-dir-a output/MI355 --regions-dir-b output/B200 \ + --name-a MI355 --name-b B200 -o comparison.csv + + This matches regions by subdir name (e.g. prefill_only_3072) and compares + only corresponding regions (apples-to-apples). +""" + +import argparse +import csv +import json +import os +import sys +from collections import OrderedDict + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from _helpers import load_labels + + + +def aggregate(labeled_kernels): + """Aggregate labeled kernels by semantic_block. + + Carries forward perf_category and nn_module from kernel data. + """ + blocks = OrderedDict() + for k in labeled_kernels: + block = k["semantic_block"] + if block not in blocks: + blocks[block] = { + "names": set(), + "durs": [], + "count": 0, + "perf_category": k.get("perf_category"), + "nn_module": k.get("nn_module"), + } + b = blocks[block] + b["names"].add(k["name"]) + b["durs"].append(k["dur"]) + b["count"] += 1 + return blocks + + +def load_metadata(path): + """Load metadata.json and return gpu_timeline dict if present.""" + if not path or not os.path.exists(path): + return None + try: + with open(path) as f: + meta = json.load(f) + return meta.get("gpu_timeline") + except (json.JSONDecodeError, OSError): + return None + + +def build_comparison( + agg_a, + agg_b, + total_a, + total_b, + name_a, + name_b, + region=None, + gpu_timeline_a=None, + gpu_timeline_b=None, +): + """Build comparison rows for all semantic blocks present in either trace.""" + all_blocks = list(OrderedDict.fromkeys(list(agg_a.keys()) + list(agg_b.keys()))) + has_gpu_timeline = gpu_timeline_a is not None and gpu_timeline_b is not None + + rows = [] + for i, block in enumerate(all_blocks): + a = agg_a.get(block, {"names": set(), "durs": [], "count": 0}) + b = agg_b.get(block, {"names": set(), "durs": [], "count": 0}) + + a_total = sum(a["durs"]) + b_total = sum(b["durs"]) + a_avg = a_total / a["count"] if a["count"] else 0 + b_avg = b_total / b["count"] if b["count"] else 0 + a_pct = 100 * a_total / total_a if total_a > 0 else 0 + b_pct = 100 * b_total / total_b if total_b > 0 else 0 + ratio = a_total / b_total if b_total > 0 else float("inf") + gap = a_total - b_total + + row = OrderedDict() + if region is not None: + row["region"] = region + row["semantic_block"] = block + kernel_names_a_str = " | ".join(sorted(a["names"])) + kernel_names_b_str = " | ".join(sorted(b["names"])) + row["perf_category"] = ( + a.get("perf_category") or b.get("perf_category") or "Others" + ) + row["nn_module"] = a.get("nn_module") or b.get("nn_module") or "" + row["algorithm_order"] = i + 1 + row[f"{name_a}_kernel_names"] = kernel_names_a_str + row[f"{name_a}_kernel_count"] = a["count"] + row[f"{name_a}_total_us"] = round(a_total, 2) + row[f"{name_a}_avg_us"] = round(a_avg, 2) + row[f"{name_a}_pct"] = round(a_pct, 1) + row[f"{name_b}_kernel_names"] = kernel_names_b_str + row[f"{name_b}_kernel_count"] = b["count"] + row[f"{name_b}_total_us"] = round(b_total, 2) + row[f"{name_b}_avg_us"] = round(b_avg, 2) + row[f"{name_b}_pct"] = round(b_pct, 1) + row[f"{name_a}_vs_{name_b}_ratio"] = ( + round(ratio, 3) if ratio != float("inf") else "inf" + ) + row[f"{name_a}_minus_{name_b}_us"] = round(gap, 2) + + if has_gpu_timeline: + row[f"{name_a}_busy_ms"] = round( + gpu_timeline_a.get("busy_time_us", 0) / 1000, 2 + ) + row[f"{name_a}_idle_pct"] = gpu_timeline_a.get("idle_pct") + row[f"{name_b}_busy_ms"] = round( + gpu_timeline_b.get("busy_time_us", 0) / 1000, 2 + ) + row[f"{name_b}_idle_pct"] = gpu_timeline_b.get("idle_pct") + + rows.append(row) + return rows + + +def run_assertions(rows, labeled_a, labeled_b, total_a, total_b, name_a, name_b): + errors = [] + + a_count = sum(r[f"{name_a}_kernel_count"] for r in rows) + if a_count != len(labeled_a): + errors.append( + f"A6.1 FAIL: {name_a} kernel count mismatch: {a_count} matched vs {len(labeled_a)} total" + ) + + b_count = sum(r[f"{name_b}_kernel_count"] for r in rows) + if b_count != len(labeled_b): + errors.append( + f"A6.2 FAIL: {name_b} kernel count mismatch: {b_count} matched vs {len(labeled_b)} total" + ) + + a_time = sum(r[f"{name_a}_total_us"] for r in rows) + if abs(a_time - total_a) > 1.0: + errors.append( + f"A6.3 FAIL: {name_a} time mismatch: {a_time:.1f} vs {total_a:.1f}" + ) + b_time = sum(r[f"{name_b}_total_us"] for r in rows) + if abs(b_time - total_b) > 1.0: + errors.append( + f"A6.3 FAIL: {name_b} time mismatch: {b_time:.1f} vs {total_b:.1f}" + ) + + a_pct = sum(r[f"{name_a}_pct"] for r in rows) + if abs(a_pct - 100.0) > 2.0: + errors.append(f"A7.2 FAIL: {name_a} percentages sum to {a_pct:.1f}%") + b_pct = sum(r[f"{name_b}_pct"] for r in rows) + if abs(b_pct - 100.0) > 2.0: + errors.append(f"A7.2 FAIL: {name_b} percentages sum to {b_pct:.1f}%") + + for r in rows: + a_t = r[f"{name_a}_total_us"] + b_t = r[f"{name_b}_total_us"] + if b_t > 0: + expected_ratio = round(a_t / b_t, 3) + actual_ratio = r[f"{name_a}_vs_{name_b}_ratio"] + if actual_ratio != "inf" and abs(expected_ratio - actual_ratio) > 0.1: + errors.append( + f"A7.5 FAIL: {r['semantic_block']}: ratio mismatch " + f"{expected_ratio} vs {actual_ratio}" + ) + + return errors + + +def main(): + parser = argparse.ArgumentParser(description="Compare two semantic breakdowns") + parser.add_argument( + "trace_a", nargs="?", help="Path to trace A semantic_labels.json" + ) + parser.add_argument( + "trace_b", nargs="?", help="Path to trace B semantic_labels.json" + ) + parser.add_argument( + "--regions-dir-a", + help="Dir with per-region subdirs (e.g. prefill_only_3072/semantic_labels.json)", + ) + parser.add_argument( + "--regions-dir-b", help="Dir with per-region subdirs for trace B" + ) + parser.add_argument("--name-a", default="trace_a", help="Short name for trace A") + parser.add_argument("--name-b", default="trace_b", help="Short name for trace B") + parser.add_argument( + "--region", + help="Region descriptor (e.g. prefill_only_3072) for multi-section reports", + ) + parser.add_argument( + "-o", "--output", default="comparison.csv", help="Output CSV path" + ) + args = parser.parse_args() + + all_rows = [] + fieldnames = None + + if args.regions_dir_a and args.regions_dir_b: + regions_a = { + d + for d in os.listdir(args.regions_dir_a) + if os.path.isdir(os.path.join(args.regions_dir_a, d)) + } + regions_b = { + d + for d in os.listdir(args.regions_dir_b) + if os.path.isdir(os.path.join(args.regions_dir_b, d)) + } + common_regions = sorted(regions_a & regions_b) + for region in common_regions: + labels_a = os.path.join(args.regions_dir_a, region, "semantic_labels.json") + labels_b = os.path.join(args.regions_dir_b, region, "semantic_labels.json") + metadata_a_path = os.path.join(args.regions_dir_a, region, "metadata.json") + metadata_b_path = os.path.join(args.regions_dir_b, region, "metadata.json") + if not os.path.exists(labels_a) or not os.path.exists(labels_b): + continue + data_a = load_labels(labels_a) + data_b = load_labels(labels_b) + labeled_a = data_a["labeled_kernels"] + labeled_b = data_b["labeled_kernels"] + total_a = data_a.get( + "total_kernel_time_us", sum(k["dur"] for k in labeled_a) + ) + total_b = data_b.get( + "total_kernel_time_us", sum(k["dur"] for k in labeled_b) + ) + gpu_timeline_a = load_metadata(metadata_a_path) + gpu_timeline_b = load_metadata(metadata_b_path) + agg_a = aggregate(labeled_a) + agg_b = aggregate(labeled_b) + rows = build_comparison( + agg_a, + agg_b, + total_a, + total_b, + args.name_a, + args.name_b, + region=region, + gpu_timeline_a=gpu_timeline_a, + gpu_timeline_b=gpu_timeline_b, + ) + all_rows.extend(rows) + if fieldnames is None and rows: + fieldnames = list(rows[0].keys()) + if not all_rows: + print("No matching regions found", file=sys.stderr) + sys.exit(1) + else: + if not args.trace_a or not args.trace_b: + parser.error( + "Provide trace_a and trace_b, or --regions-dir-a and --regions-dir-b" + ) + data_a = load_labels(args.trace_a) + data_b = load_labels(args.trace_b) + labeled_a = data_a["labeled_kernels"] + labeled_b = data_b["labeled_kernels"] + total_a = data_a.get("total_kernel_time_us", sum(k["dur"] for k in labeled_a)) + total_b = data_b.get("total_kernel_time_us", sum(k["dur"] for k in labeled_b)) + agg_a = aggregate(labeled_a) + agg_b = aggregate(labeled_b) + all_rows = build_comparison( + agg_a, + agg_b, + total_a, + total_b, + args.name_a, + args.name_b, + region=args.region, + ) + fieldnames = list(all_rows[0].keys()) if all_rows else [] + if all_rows: + errors = run_assertions( + all_rows, + labeled_a, + labeled_b, + total_a, + total_b, + args.name_a, + args.name_b, + ) + for e in errors: + print(e, file=sys.stderr) + if any("FAIL" in e for e in errors): + sys.exit(1) + + if fieldnames and all_rows: + with open(args.output, "w", newline="") as f: + writer = csv.DictWriter(f, fieldnames=fieldnames) + writer.writeheader() + writer.writerows(all_rows) + print(f"Wrote {args.output} ({len(all_rows)} rows)", file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/pattern_finder.py b/TraceLens/Agent/Analysis/semantic_analyses/pattern_finder.py new file mode 100644 index 000000000..7854242eb --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/pattern_finder.py @@ -0,0 +1,938 @@ +#!/usr/bin/env python3 +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +""" +Discover repeating kernel patterns in GPU traces using loop detection. + +Handles multi-stream traces by detecting the primary GPU stream (most +kernels) and running pattern discovery on that stream only. All output +indices refer to the **original** kernel list so downstream tools do not +need to know about the stream split. + +The loop-detection engine (data classes + iterative pattern-finding +algorithm with extension, splitting, and rotation) is included in-file. + +Usage: + python pattern_finder.py [-o pattern.json] +""" + +from __future__ import annotations + +import argparse +import json +import logging +import sys +from collections import Counter +from dataclasses import dataclass +from typing import Dict, List, Optional, Set, Tuple, Union + +logger = logging.getLogger(__name__) + + +# =========================================================================== +# Loop-detection engine (formerly kernel_loop_detection.py) +# =========================================================================== + +# --------------------------------------------------------------------------- +# Data classes +# --------------------------------------------------------------------------- + + +@dataclass(slots=True) +class Operation: + name: str + ts: float + dur: float + + +@dataclass(slots=True) +class GPUOperation(Operation): + external_id: Optional[int] = None + correlation: Optional[int] = None + cat: str = "" + stream: Optional[int] = None + + @property + def end_ts(self) -> float: + return self.ts + self.dur + + +# --------------------------------------------------------------------------- +# Patterns – shared pattern vocabulary +# --------------------------------------------------------------------------- + + +class Patterns: + __slots__ = ("patterns", "pattern_operation_names", "operation_name_to_idx") + + def __init__( + self, + patterns: Optional[List[List[int]]] = None, + pattern_operation_names: Optional[Dict[int, str]] = None, + operation_name_to_idx: Optional[Dict[str, int]] = None, + ): + self.patterns: List[List[int]] = patterns if patterns is not None else [] + self.pattern_operation_names: Dict[int, str] = ( + pattern_operation_names if pattern_operation_names is not None else {} + ) + self.operation_name_to_idx: Dict[str, int] = ( + operation_name_to_idx if operation_name_to_idx is not None else {} + ) + if self.pattern_operation_names and not self.operation_name_to_idx: + self.operation_name_to_idx = { + name: idx for idx, name in self.pattern_operation_names.items() + } + elif self.operation_name_to_idx and not self.pattern_operation_names: + self.pattern_operation_names = { + idx: name for name, idx in self.operation_name_to_idx.items() + } + + def get_pattern_name(self, pattern_idx: int) -> str: + if pattern_idx < 0 or pattern_idx >= len(self.patterns): + return "?" + if pattern_idx < 26: + return chr(ord("A") + pattern_idx) + offset = pattern_idx - 26 + letter = chr(ord("A") + (offset % 26)) + suffix = (offset // 26) + 1 + return f"{letter}{suffix}" + + def _validate_pattern_indices_mapped(self) -> None: + if not self.patterns: + return + for op_name, op_idx in self.operation_name_to_idx.items(): + if op_idx not in self.pattern_operation_names: + self.pattern_operation_names[op_idx] = op_name + used_indices = {op_idx for pattern in self.patterns for op_idx in pattern} + missing = sorted( + idx for idx in used_indices if idx not in self.pattern_operation_names + ) + if missing: + raise ValueError( + "All pattern indices must map to operation names. " + f"Missing mappings for indices: {missing}" + ) + + +# --------------------------------------------------------------------------- +# LoopStructures – per-stream detection results +# --------------------------------------------------------------------------- + + +class LoopStructures: + + def __init__( + self, + operations: List[Operation], + _patterns_obj: Optional[Patterns] = None, + stream_id: Optional[int] = None, + ): + self.operations = operations + self.stream_id = stream_id + self.sequences: List[List[List[int]]] = [] + self._patterns_obj: Patterns + + if _patterns_obj is not None: + self._patterns_obj = _patterns_obj + else: + self._patterns_obj = Patterns() + if operations: + unique_names: List[str] = [] + seen: set = set() + for op in operations: + if op.name not in seen: + unique_names.append(op.name) + seen.add(op.name) + self._patterns_obj.pattern_operation_names = { + i: name for i, name in enumerate(unique_names) + } + self._patterns_obj.operation_name_to_idx = { + name: idx + for idx, name in self._patterns_obj.pattern_operation_names.items() + } + + if self.operations: + for op in self.operations: + if op.name not in self._patterns_obj.operation_name_to_idx: + new_idx = len(self._patterns_obj.operation_name_to_idx) + self._patterns_obj.operation_name_to_idx[op.name] = new_idx + self._patterns_obj.pattern_operation_names[new_idx] = op.name + + self._patterns_obj._validate_pattern_indices_mapped() + + # -- Property wrappers --------------------------------------------------- + + @property + def patterns(self) -> List[List[int]]: + return self._patterns_obj.patterns + + @property + def pattern_operation_names(self) -> Dict[int, str]: + return self._patterns_obj.pattern_operation_names + + @property + def operation_name_to_idx(self) -> Dict[str, int]: + return self._patterns_obj.operation_name_to_idx + + def get_pattern_name(self, pattern_idx: int) -> str: + return self._patterns_obj.get_pattern_name(pattern_idx) + + # -- Coverage helpers ---------------------------------------------------- + + def get_covered_indices( + self, + pattern_indices: Optional[Union[int, List[int]]] = None, + ) -> set: + covered: set = set() + if pattern_indices is None: + patterns_to_include = range(len(self.patterns)) + elif isinstance(pattern_indices, int): + patterns_to_include = [pattern_indices] + else: + patterns_to_include = pattern_indices + for idx in patterns_to_include: + if idx < len(self.sequences): + for seq in self.sequences[idx]: + covered.update(seq) + return covered + + def _get_pattern_coverage(self, pattern_idx: Optional[int] = None) -> float: + if not self.operations: + return 0.0 + covered_indices = self.get_covered_indices(pattern_idx) + return len(covered_indices) / len(self.operations) + + def get_pattern_coverage(self) -> float: + return self._get_pattern_coverage() + + +# =========================================================================== +# Algorithm – iterative pattern finding with extension, splitting, rotation +# =========================================================================== + + +def get_operation_frequencies(loop_structures: LoopStructures) -> Counter: + covered = loop_structures.get_covered_indices() + unused_op_indices = [ + loop_structures.operation_name_to_idx[op.name] + for i, op in enumerate(loop_structures.operations) + if i not in covered + ] + return Counter(unused_op_indices) + + +# --------------------------------------------------------------------------- +# Pattern extension +# --------------------------------------------------------------------------- + + +def extend_pattern( + loop_structures: LoopStructures, + pattern_idx: int, + min_loop_count: int, + min_pattern_length: int, + snippets: bool = False, +) -> int: + covered = loop_structures.get_covered_indices( + [i for i in range(len(loop_structures.patterns)) if i != pattern_idx] + ) + best_agree = 0 + + while True: + sequences = loop_structures.sequences[pattern_idx] + names_before = [ + ( + loop_structures.operations[seq[0] - 1].name + if not (seq[0] == 0 or seq[0] - 1 in covered) + else None + ) + for i, seq in enumerate(sequences) + ] + names_after = [ + ( + loop_structures.operations[seq[-1] + 1].name + if not ( + seq[-1] == len(loop_structures.operations) - 1 + or seq[-1] + 1 in covered + ) + else None + ) + for i, seq in enumerate(sequences) + ] + + extendable_before = sum(1 for name in names_before if name is not None) + extendable_after = sum(1 for name in names_after if name is not None) + if extendable_before < min_loop_count and extendable_after < min_loop_count: + best_agree = max(extendable_before, extendable_after) + break + + name_counts_before = Counter( + n for n in names_before if n is not None + ).most_common(1) + name_counts_after = Counter( + n for n in names_after if n is not None + ).most_common(1) + + kernel_before, agree_before = ( + name_counts_before[0] if name_counts_before else (None, 0) + ) + kernel_after, agree_after = ( + name_counts_after[0] if name_counts_after else (None, 0) + ) + best_agree = max(agree_before, agree_after) + + if agree_before < min_loop_count and agree_after < min_loop_count: + break + + current_seq_count = len(sequences) + if ( + snippets + and len(loop_structures.patterns[pattern_idx]) >= min_pattern_length + and best_agree < current_seq_count + ): + break + + extend_before = agree_before >= agree_after and agree_before >= min_loop_count + kernel_name = kernel_before if extend_before else kernel_after + op_idx = loop_structures.operation_name_to_idx[kernel_name] + + if extend_before: + loop_structures.patterns[pattern_idx].insert(0, op_idx) + else: + loop_structures.patterns[pattern_idx].append(op_idx) + + new_sequences = [] + for i, seq in enumerate(sequences): + if extend_before: + if names_before[i] == kernel_name: + new_start = seq[0] - 1 + if new_sequences and new_sequences[-1][-1] >= new_start: + continue + seq.insert(0, new_start) + new_sequences.append(seq) + else: + if names_after[i] == kernel_name: + if new_sequences and new_sequences[-1][-1] >= seq[0]: + continue + seq.append(seq[-1] + 1) + new_sequences.append(seq) + + loop_structures.sequences[pattern_idx] = new_sequences + + if len(new_sequences) >= min_pattern_length and any( + new_sequences[i - 1][-1] + 1 == new_sequences[i][0] + and new_sequences[i][-1] + 1 == new_sequences[i + 1][0] + for i in range(1, len(new_sequences) - 1) + ): + break + + return best_agree + + +# --------------------------------------------------------------------------- +# Pattern splitting +# --------------------------------------------------------------------------- + + +def _analyze_pattern_for_splits( + loop_structures: LoopStructures, + pattern_idx: int, + min_pattern_length: int, + split_pattern_length_limit: int, +) -> List[List[int]]: + pattern = loop_structures.patterns[pattern_idx] + if len(pattern) <= split_pattern_length_limit: + return [] + if not loop_structures.sequences[pattern_idx]: + return [] + + mini_operations = [ + GPUOperation( + name=loop_structures.pattern_operation_names[op_idx], + ts=0.0, + dur=0.0, + ) + for op_idx in pattern + ] + + mini_ls = find_kernel_loops_single_stream( + mini_operations, + min_loop_count=2, + min_pattern_length=min_pattern_length, + split_pattern_length_limit=split_pattern_length_limit, + ) + + if not mini_ls.patterns: + return [] + + sub_patterns: List[List[int]] = [] + for sp_idx, mini_seqs in enumerate(mini_ls.sequences): + all_consecutive = len(mini_seqs) >= 2 and all( + mini_seqs[i][0] == mini_seqs[i - 1][-1] + 1 + for i in range(1, len(mini_seqs)) + ) + if not all_consecutive: + continue + global_pat = [ + loop_structures.operation_name_to_idx[mini_ls.pattern_operation_names[mi]] + for mi in mini_ls.patterns[sp_idx] + ] + sub_patterns.append(global_pat) + + return sub_patterns + + +def _apply_pattern_split( + loop_structures: LoopStructures, + pattern_idx: int, + sub_patterns: List[List[int]], +) -> None: + loop_structures.patterns.pop(pattern_idx) + loop_structures.sequences.pop(pattern_idx) + + affected_indices: Set[int] = set() + for _sp_idx, pat in enumerate(sub_patterns): + existing_idx = next( + (i for i, p in enumerate(loop_structures.patterns) if p == pat), + None, + ) + if existing_idx is not None: + affected_indices.add(existing_idx) + else: + loop_structures.patterns.append(pat) + loop_structures.sequences.append([]) + affected_indices.add(len(loop_structures.patterns) - 1) + + for pidx in sorted(affected_indices): + all_seqs = find_pattern_occurrences(loop_structures, pidx) + loop_structures.sequences[pidx] = all_seqs + + +def split_long_pattern( + loop_structures: LoopStructures, + pattern_idx: int, + min_pattern_length: int, + split_pattern_length_limit: int, +) -> bool: + sub_patterns = _analyze_pattern_for_splits( + loop_structures, + pattern_idx, + min_pattern_length, + split_pattern_length_limit, + ) + if not sub_patterns: + return False + _apply_pattern_split(loop_structures, pattern_idx, sub_patterns) + return True + + +# --------------------------------------------------------------------------- +# Pattern rotation +# --------------------------------------------------------------------------- + + +def rotate_pattern(loop_structures: LoopStructures, pattern_idx: int) -> bool: + pattern = loop_structures.patterns[pattern_idx] + sequences = loop_structures.sequences[pattern_idx] + pattern_len = len(pattern) + + shift_steps = 0 + while shift_steps < pattern_len: + all_match = all( + seq[-1] + shift_steps < len(loop_structures.operations) + and loop_structures.operation_name_to_idx[ + loop_structures.operations[seq[-1] + shift_steps].name + ] + == pattern[shift_steps] + for seq in sequences + ) + if all_match: + shift_steps += 1 + else: + break + + shift_steps -= 1 + if shift_steps < 0: + return False + + loop_structures.patterns[pattern_idx] = ( + pattern[shift_steps:] + pattern[:shift_steps] + ) + loop_structures.sequences[pattern_idx] = [ + list(range(seq[0] + shift_steps, seq[-1] + shift_steps + 1)) + for seq in sequences + ] + sequences = loop_structures.sequences[pattern_idx] + + covered = loop_structures.get_covered_indices( + [i for i in range(len(loop_structures.patterns)) if i != pattern_idx] + ) + + new_sequences = [] + for i, seq in enumerate(sequences): + if i > 0 and sequences[i - 1][-1] + 1 == seq[0]: + continue + potential_start = seq[0] - pattern_len + if potential_start >= 0 and all( + (potential_start + j) not in covered for j in range(pattern_len) + ): + if all( + loop_structures.operation_name_to_idx[ + loop_structures.operations[potential_start + j].name + ] + == loop_structures.patterns[pattern_idx][j] + for j in range(pattern_len) + ): + new_sequences.append( + list(range(potential_start, potential_start + pattern_len)) + ) + covered.update(range(potential_start, potential_start + pattern_len)) + + if new_sequences: + loop_structures.sequences[pattern_idx] = sorted( + sequences + new_sequences, + key=lambda seq: seq[0], + ) + return True + + +# --------------------------------------------------------------------------- +# Pattern occurrence finding +# --------------------------------------------------------------------------- + + +def find_pattern_occurrences( + loop_structures: LoopStructures, + pattern_idx: int, +) -> List[List[int]]: + pattern = loop_structures.patterns[pattern_idx] + pattern_len = len(pattern) + + covered = loop_structures.get_covered_indices( + [i for i in range(len(loop_structures.patterns)) if i != pattern_idx] + ) + + op_name_indices = [ + loop_structures.operation_name_to_idx[op.name] + for op in loop_structures.operations + ] + + first_element = pattern[0] + max_start = len(loop_structures.operations) - pattern_len + + candidates = [] + for i in range(max_start + 1): + if op_name_indices[i] != first_element or i in covered: + continue + if all((i + j) not in covered for j in range(1, pattern_len)) and all( + op_name_indices[i + j] == pattern[j] for j in range(1, pattern_len) + ): + candidates.append(i) + + sequences = [] + for i in candidates: + if sequences and i < sequences[-1][-1] + 1: + continue + sequences.append(list(range(i, i + pattern_len))) + + return sequences + + +# --------------------------------------------------------------------------- +# Seed pattern creation +# --------------------------------------------------------------------------- + + +def get_new_pattern_to_start( + loop_structures: LoopStructures, + operations: List[GPUOperation], + min_loop_count: int, + failed_ops: Optional[Set[int]] = None, +) -> Optional[Tuple[List[int], List[List[int]]]]: + if failed_ops is None: + failed_ops = set() + + covered = loop_structures.get_covered_indices() + unused_op_indices = [ + loop_structures.operation_name_to_idx[op.name] + for i, op in enumerate(operations) + if i not in covered + ] + op_frequencies = Counter(unused_op_indices) + if not op_frequencies: + return None + + for most_frequent_kernel, freq in op_frequencies.most_common(): + if most_frequent_kernel in failed_ops or freq < min_loop_count: + continue + kernel_name = loop_structures.pattern_operation_names[most_frequent_kernel] + new_pattern = [most_frequent_kernel] + new_sequences = [ + [i] + for i, op in enumerate(operations) + if op.name == kernel_name and i not in covered + ] + if len(new_sequences) >= min_loop_count: + return (new_pattern, new_sequences) + + return None + + +# =========================================================================== +# Loop detection main entry point +# =========================================================================== + + +def find_kernel_loops_single_stream( + operations: List[GPUOperation], + min_loop_count: int = 20, + min_pattern_length: int = 5, + split_pattern_length_limit: int = 35, + loop_structures: Optional[LoopStructures] = None, + stream_id: Optional[int] = None, + snippets: bool = False, +) -> LoopStructures: + """Find repeating kernel patterns in a single-stream operation list.""" + + if stream_id is None and operations: + streams_in_ops = {op.stream for op in operations} + if len(streams_in_ops) == 1: + stream_id = next(iter(streams_in_ops)) + + if loop_structures is not None: + if loop_structures.operations != operations: + raise ValueError("loop_structures must have the same operations list") + else: + loop_structures = LoopStructures(operations=operations, stream_id=stream_id) + + mpl_schedule = list(range(max(20, min_pattern_length), min_pattern_length - 1, -1)) + + if min_loop_count > 20: + pass_schedule: List[Tuple[int, int]] = [ + (mpl, min_loop_count) for mpl in mpl_schedule + ] + else: + mlc_start = max(20, min_loop_count) + pass_schedule = [(mpl, mlc_start) for mpl in mpl_schedule] + if min_loop_count < 20: + _mlc_relaxed = list(range(19, min_loop_count - 1, -1)) + pass_schedule += [(min_pattern_length, mlc) for mlc in _mlc_relaxed] + + max_iterations_per_pass = 50 + + extension_cache: Dict[int, Tuple[int, int, int]] = {} + split_analysis_cache: Dict[Tuple[int, ...], List[List[int]]] = {} + + for current_min_pattern_length, current_min_loop_count in pass_schedule: + if loop_structures._get_pattern_coverage() >= 1.0: + break + + failed_ops = { + op + for op, (alen, _, bagree) in extension_cache.items() + if alen < current_min_pattern_length and bagree < current_min_loop_count + } + + for pidx in range(len(loop_structures.patterns) - 1, -1, -1): + if len(loop_structures.patterns[pidx]) <= split_pattern_length_limit: + continue + pattern_key = tuple(loop_structures.patterns[pidx]) + sub_patterns = split_analysis_cache.get(pattern_key) + if not sub_patterns: + continue + min_sub_len = min(len(sp) for sp in sub_patterns) + if min_sub_len >= current_min_pattern_length: + _apply_pattern_split(loop_structures, pidx, sub_patterns) + + iteration = 0 + while iteration < max_iterations_per_pass: + pattern_idx = len(loop_structures.patterns) + + result = get_new_pattern_to_start( + loop_structures, + operations, + current_min_loop_count, + failed_ops, + ) + if result is None: + break + + new_pattern, new_sequences = result + pattern_init_op = new_pattern[0] + loop_structures.patterns.append(new_pattern) + loop_structures.sequences.append(new_sequences) + pattern_idx = len(loop_structures.patterns) - 1 + + if loop_structures._get_pattern_coverage() >= 1.0: + iteration += 1 + continue + + stop_best_agree = extend_pattern( + loop_structures, + pattern_idx, + current_min_loop_count, + current_min_pattern_length, + snippets=snippets, + ) + + pattern_len = len(loop_structures.patterns[pattern_idx]) + seq_count = len(loop_structures.sequences[pattern_idx]) + + if pattern_len < min_pattern_length: + if loop_structures._get_pattern_coverage() < 1.0: + loop_structures.patterns.pop() + loop_structures.sequences.pop() + extension_cache[pattern_init_op] = ( + pattern_len, + seq_count, + stop_best_agree, + ) + failed_ops.add(pattern_init_op) + + elif pattern_len > split_pattern_length_limit: + pattern_key = tuple(loop_structures.patterns[pattern_idx]) + if pattern_key not in split_analysis_cache: + sub_patterns = _analyze_pattern_for_splits( + loop_structures, + pattern_idx, + min_pattern_length, + split_pattern_length_limit, + ) + split_analysis_cache[pattern_key] = sub_patterns + else: + sub_patterns = split_analysis_cache[pattern_key] + + if sub_patterns: + min_sub_len = min(len(sp) for sp in sub_patterns) + if min_sub_len >= current_min_pattern_length: + _apply_pattern_split( + loop_structures, + pattern_idx, + sub_patterns, + ) + else: + all_seqs = find_pattern_occurrences(loop_structures, pattern_idx) + loop_structures.sequences[pattern_idx] = all_seqs + + iteration += 1 + + return loop_structures + + +# =========================================================================== +# Pattern finder – trace-level repeating-pattern discovery +# =========================================================================== + + +def _kernels_to_gpu_operations(kernels): + """Convert extracted kernel dicts to GPUOperation objects.""" + return [ + GPUOperation(name=k["name"], ts=k.get("ts", 0.0), dur=k.get("dur", 0.0)) + for k in kernels + ] + + +def _detect_primary_stream(kernels): + """Identify the primary stream when multiple streams are present. + + Returns (primary_stream_id, idx_map, secondary_indices) where + - primary_stream_id is the stream with the most kernels (None if single-stream) + - idx_map maps dense primary-only indices back to original indices + - secondary_indices is a sorted list of original indices on non-primary streams + If only one stream exists, returns (None, None, []). + """ + stream_counts = Counter(k.get("stream_id") for k in kernels) + non_null = {s: c for s, c in stream_counts.items() if s is not None} + + if len(non_null) <= 1: + return None, None, [] + + primary = max(non_null, key=non_null.get) + idx_map = [] + secondary = [] + for i, k in enumerate(kernels): + sid = k.get("stream_id") + if sid == primary or sid is None: + idx_map.append(i) + else: + secondary.append(i) + + return primary, idx_map, secondary + + +def find_repeating_pattern( + extracted_data, min_loop_count=10, min_pattern_length=3, max_pattern_length=100 +): + """Discover repeating kernel patterns in a trace. + + Automatically detects multi-stream traces and runs pattern discovery + on the primary stream only, remapping indices to the original list. + + Args: + extracted_data: dict from extract_trace_data.py with "kernels" list + min_loop_count: minimum number of pattern repetitions required + min_pattern_length: minimum ops in a pattern to keep + max_pattern_length: maximum ops before splitting into sub-patterns + + Returns: + dict with: + - patterns: list of discovered patterns, each a list of kernel names + - sequences: for each pattern, list of (start_idx, end_idx) tuples + (indices into the original kernel list) + - pattern_labels: letter labels for each pattern (A, B, C, ...) + - coverage: fraction of primary-stream kernels covered by patterns + - total_kernels: total number of kernels in the trace + - preamble_indices: kernel indices before the first pattern occurrence + that are not covered by any pattern (original indices) + - epilogue_indices: kernel indices after the last pattern occurrence + that are not covered by any pattern (original indices) + - primary_stream_id: stream used for pattern discovery (None if single-stream) + - secondary_stream_indices: kernel indices on non-primary streams + """ + kernels = extracted_data["kernels"] + n = len(kernels) + + primary_sid, idx_map, secondary_indices = _detect_primary_stream(kernels) + + if idx_map is not None: + primary_kernels = [kernels[i] for i in idx_map] + else: + primary_kernels = kernels + idx_map = list(range(n)) + + ops = _kernels_to_gpu_operations(primary_kernels) + + loop_structures = find_kernel_loops_single_stream( + ops, + min_loop_count=min_loop_count, + min_pattern_length=min_pattern_length, + split_pattern_length_limit=max_pattern_length, + ) + + patterns = [] + sequences = [] + pattern_labels = [] + for pidx, pat_indices in enumerate(loop_structures.patterns): + pat_names = [loop_structures.pattern_operation_names[i] for i in pat_indices] + patterns.append(pat_names) + pattern_labels.append(loop_structures.get_pattern_name(pidx)) + + seqs = [] + for seq in loop_structures.sequences[pidx]: + orig_start = idx_map[seq[0]] + orig_end = idx_map[seq[-1]] + seqs.append((orig_start, orig_end)) + sequences.append(seqs) + + coverage = loop_structures.get_pattern_coverage() + + covered_dense = loop_structures.get_covered_indices() + covered_orig = set(idx_map[i] for i in covered_dense) + + primary_first = n + primary_last = -1 + if sequences: + for start, end in sequences[0]: + primary_first = min(primary_first, start) + primary_last = max(primary_last, end) + + secondary_set = set(secondary_indices) + preamble_indices = [ + i + for i in range(primary_first) + if i not in covered_orig and i not in secondary_set + ] + epilogue_indices = [ + i + for i in range(primary_last + 1, n) + if i not in covered_orig and i not in secondary_set + ] + + return { + "patterns": patterns, + "sequences": sequences, + "pattern_labels": pattern_labels, + "coverage": coverage, + "total_kernels": n, + "preamble_indices": preamble_indices, + "epilogue_indices": epilogue_indices, + "primary_stream_id": primary_sid, + "secondary_stream_indices": secondary_indices, + } + + +def main(): + parser = argparse.ArgumentParser( + description="Discover repeating kernel patterns in a GPU trace" + ) + parser.add_argument("extracted_json", help="Path to extracted trace data JSON") + parser.add_argument("-o", "--output", help="Output JSON path (default: stdout)") + parser.add_argument( + "--min-loop-count", + type=int, + default=10, + help="Minimum pattern repetitions (default: 10)", + ) + parser.add_argument( + "--min-pattern-length", + type=int, + default=3, + help="Minimum ops per pattern (default: 3)", + ) + parser.add_argument( + "--max-pattern-length", + type=int, + default=100, + help="Maximum ops before splitting (default: 100)", + ) + args = parser.parse_args() + + with open(args.extracted_json) as f: + extracted = json.load(f) + + result = find_repeating_pattern( + extracted, + min_loop_count=args.min_loop_count, + min_pattern_length=args.min_pattern_length, + max_pattern_length=args.max_pattern_length, + ) + + if result["primary_stream_id"] is not None: + print( + f"Multi-stream: primary={result['primary_stream_id']}, " + f"{len(result['secondary_stream_indices'])} secondary kernels", + file=sys.stderr, + ) + + for i, (pat, label) in enumerate(zip(result["patterns"], result["pattern_labels"])): + n_seqs = len(result["sequences"][i]) + print( + f"Pattern {label}: {len(pat)} kernels, {n_seqs} occurrences", + file=sys.stderr, + ) + + print( + f"Coverage: {result['coverage']:.1%} of {result['total_kernels']} kernels", + file=sys.stderr, + ) + print( + f"Preamble: {len(result['preamble_indices'])} kernels, " + f"Epilogue: {len(result['epilogue_indices'])} kernels", + file=sys.stderr, + ) + + output = json.dumps(result, indent=2) + if args.output: + with open(args.output, "w") as f: + f.write(output) + print(f"Wrote {args.output}", file=sys.stderr) + else: + print(output) + + +if __name__ == "__main__": + main() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py b/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py new file mode 100644 index 000000000..9c7d9b86a --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py @@ -0,0 +1,228 @@ +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +""" +Adapter for TraceUtils split_inference_trace_annotation.py. + +Invokes TraceLens.TraceUtils.split_inference_trace_annotation as a subprocess +and converts its output to the format expected by extract_trace_data.py: +[(trace_dict, region_metadata), ...]. + +Usage: + from trace_split_adapter import split_vllm_trace, get_steady_state_key + result = split_vllm_trace("trace.json.gz") + if result: + for trace_dict, metadata in result: + key = get_steady_state_key(metadata) +""" + +import gzip +import json +import os +import subprocess +import sys +import tempfile +from typing import List, Optional, Tuple + + +def get_steady_state_key(metadata: dict) -> str: + """Return a key for grouping by steady-state region. + + For single-iteration data the key encodes (type, token_count) so that + corresponding iterations from two traces match by directory name. + """ + ctx = metadata.get("context_requests", 0) + gen = metadata.get("generation_requests", 0) + ctx_sum = metadata.get("context_sum", 0) + gen_sum = metadata.get("generation_sum", 0) + batch = metadata.get("batch_size", 0) + + if ctx > 0 and gen == 0: + return f"prefill_only_{ctx_sum}" + if ctx == 0 and gen > 0: + return f"decode_only_{gen_sum}" + if ctx > 0 and gen > 0: + return f"prefill_decode_{ctx_sum}_{gen_sum}" + return f"prefill_decode_{batch}_{batch}" + + +def _get_tracelens_root() -> str: + """Resolve TraceLens package root (tracelens_private/ or repo root).""" + # trace_split_adapter.py is at TraceLens/AgenticMode/SemanticComparison/trace_breakdown/ + this_file = os.path.abspath(__file__) + trace_breakdown = os.path.dirname(this_file) + semantic = os.path.dirname(trace_breakdown) + agentic = os.path.dirname(semantic) + tracelens_pkg = os.path.dirname(agentic) + root = os.path.dirname(tracelens_pkg) + return root + + +def _phase_to_region_meta(phase: dict) -> dict: + """Map TraceUtils phase dict to region_meta expected by extract_trace_data.""" + num_prefill = phase.get("num_prefill", 0) + num_prefilldecode = phase.get("num_prefilldecode", 0) + num_decode = phase.get("num_decode", 0) + avg_bs = phase.get("avg_bs", 0) + avg_conc = phase.get("avg_conc", 0) + + if num_prefill > 0 and num_prefilldecode == 0 and num_decode == 0: + # Prefill-only + return { + "context_requests": num_prefill, + "generation_requests": 0, + "context_sum": avg_bs, + "generation_sum": 0, + "batch_size": avg_bs, + "num_requests": avg_conc, + } + if num_prefill == 0 and num_prefilldecode == 0 and num_decode > 0: + # Decode-only + return { + "context_requests": 0, + "generation_requests": num_decode, + "context_sum": 0, + "generation_sum": avg_bs, + "batch_size": avg_bs, + "num_requests": avg_conc, + } + # Prefill-decode (or combined) + return { + "context_requests": num_prefill + num_prefilldecode, + "generation_requests": num_decode + num_prefilldecode, + "context_sum": avg_bs, + "generation_sum": avg_bs, + "batch_size": avg_bs, + "num_requests": avg_conc, + } + + +def _load_trace(path: str) -> dict: + """Load trace JSON from .json or .json.gz file.""" + if path.endswith(".gz"): + with gzip.open(path, "rt") as f: + return json.load(f) + with open(path, "r") as f: + return json.load(f) + + +def _is_single_iteration(phase: dict) -> bool: + """True if phase represents a single annotation iteration.""" + total = ( + phase.get("num_prefill", 0) + + phase.get("num_prefilldecode", 0) + + phase.get("num_decode", 0) + ) + return total <= 1 + + +def _iter_type_key(phase: dict) -> str: + """Group key for deduplicating single iterations by type + token count.""" + np = phase.get("num_prefill", 0) + npd = phase.get("num_prefilldecode", 0) + nd = phase.get("num_decode", 0) + bs = phase.get("avg_bs", 0) + if np > 0: + return f"prefill_{bs}" + if npd > 0: + return f"prefilldecode_{bs}" + if nd > 0: + return f"decode_{bs}" + return f"empty_{bs}" + + +def split_vllm_trace(trace_path: str) -> Optional[List[Tuple[dict, dict]]]: + """ + Split a vLLM trace using TraceUtils split_inference_trace_annotation. + + Uses --store-single-iteration to get per-annotation-iteration data, + then selects one representative iteration per unique (type, token_count) + group. This matches the reference analysis style of showing per-step + averages rather than multi-step totals. + + Returns None if no annotation iterations are found (caller should fall back + to full trace). + """ + root = _get_tracelens_root() + env = os.environ.copy() + if "PYTHONPATH" in env: + env["PYTHONPATH"] = root + os.pathsep + env["PYTHONPATH"] + else: + env["PYTHONPATH"] = root + + with tempfile.TemporaryDirectory(prefix="trace_split_") as tmpdir: + cmd = [ + sys.executable, + "-m", + "TraceLens.TraceUtils.split_inference_trace_annotation", + trace_path, + "-o", + tmpdir, + "--find-steady-state", + "--store-single-iteration", + "--iterations", + "all", + ] + result = subprocess.run( + cmd, + cwd=root, + env=env, + capture_output=True, + text=True, + ) + if result.returncode != 0: + print( + f"TraceUtils split failed (exit {result.returncode}): {result.stderr}", + file=sys.stderr, + ) + return None + + details_path = os.path.join(tmpdir, "execution_details.json") + if not os.path.isfile(details_path): + return None + + with open(details_path, "r") as f: + execution_details = json.load(f) + + if not execution_details: + return None + + # Collect single-iteration entries, grouped by type+token_count + groups: dict = {} # iter_type_key -> list of (entry, phase) + for entry in execution_details: + out_path = entry.get("output_path") + if not out_path or not os.path.isfile(out_path): + continue + phase = entry.get("phase") or {} + if not _is_single_iteration(phase): + continue + total_steps = ( + phase.get("num_prefill", 0) + + phase.get("num_prefilldecode", 0) + + phase.get("num_decode", 0) + ) + if total_steps == 0: + continue + key = _iter_type_key(phase) + groups.setdefault(key, []).append((entry, phase)) + + # Pick the median-busy-time representative from each group + output = [] + for key, entries in groups.items(): + entries.sort(key=lambda ep: ep[0].get("gpu_busy_duration", 0)) + mid = len(entries) // 2 + entry, phase = entries[mid] + region_meta = _phase_to_region_meta(phase) + if "gpu_duration" in entry: + region_meta["traceutils_gpu_duration_us"] = entry["gpu_duration"] + if "gpu_busy_duration" in entry: + region_meta["traceutils_gpu_busy_duration_us"] = entry[ + "gpu_busy_duration" + ] + trace_dict = _load_trace(entry["output_path"]) + output.append((trace_dict, region_meta)) + + return output if output else None From d147736221c85a0feb657ab80d773d2013b0367e Mon Sep 17 00:00:00 2001 From: Spandan More Date: Thu, 4 Jun 2026 11:53:46 -0700 Subject: [PATCH 03/50] refactor: removed gap report generation from semantic agent --- .../agents/semantic-comparison-agent.md | 48 ++++--------------- 1 file changed, 8 insertions(+), 40 deletions(-) diff --git a/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md index 478cb531f..f4f82b3a8 100644 --- a/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md +++ b/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md @@ -6,16 +6,8 @@ See LICENSE for license information. --- name: semantic-comparison-agent -description: End-to-end semantic gap analysis for two GPU traces. Runs deterministic breakdown per trace (extraction + tree context + classification + pattern finding + label assembly), then a single LLM harmonization pass to assign and unify semantic_block names, followed by comparison pipeline and stakeholder gap analysis report. -triggers: - - semantic comparison - - semantic gap analysis - - compare two traces semantically - - trace comparison -tools: - - terminal - - file_read - - file_write +description: End-to-end semantic comparison of two GPU traces. Runs deterministic breakdown per trace (extraction + tree context + classification + pattern finding + label assembly), then a single LLM harmonization pass to assign and unify semantic_block names, followed by a comparison pipeline. +model: claude-opus-4-7-high --- # Semantic Comparison @@ -23,8 +15,7 @@ tools: Orchestrate end-to-end semantic comparison of two GPU traces. The user provides two raw trace files and the orchestrator handles everything: deterministic parallel breakdown (no LLM), single-pass LLM harmonization -that assigns and unifies semantic_block names, comparison pipeline, and -final stakeholder report. +that assigns and unifies semantic_block names, and the comparison pipeline. Use vendor-agnostic terminology (GPU kernels, vendor GEMM library, etc.) except when quoting actual kernel names from traces. @@ -39,8 +30,6 @@ except when quoting actual kernel names from traces. 2. Semantic Harmonization (single agent, cross-trace) 3. Generate TraceDiff Output (script) 4. Generate Comparison CSV (script) -8. Write Gap Analysis Report (LLM) -9. Validate Report ``` --- @@ -73,8 +62,6 @@ Breakdown is fully deterministic -- no LLM calls. Run both traces as **parallel shell commands** (NOT Task subagents) so the orchestrator blocks until both finish. -Reference: `TraceLens/AgenticMode/SemanticComparison/.cursor/agents/semantic-breakdown-agent.md` - ### 1.1 Per-trace Pipeline Run the full breakdown for **both traces in a single shell call** using @@ -235,27 +222,6 @@ python TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ --- -## Step 8: Write Gap Analysis Report [LLM] - -Read the report template from: -`TraceLens/AgenticMode/SemanticComparison/.cursor/agents/gap-analysis-report-template.md` - -Using `_work/comparison.csv`, `_work/priority.json`, and both -`_work//semantic_labels.json` files, produce -`/semantic_comparison_report.md` following the template. - ---- - -## Step 9: Validate Report - -- All `priority.json` entries appear in the P1/P2/P3 section -- All semantic blocks from `comparison.csv` appear in detailed analysis -- No blocks are missing - -Prompt the user to review the report. - ---- - ## Key Principles 1. **Seamless flow** -- user provides two trace paths, orchestrator handles @@ -264,7 +230,7 @@ Prompt the user to review the report. 3. **Cross-trace harmonization** -- separate step unifies labels for consistent comparison 4. **Vendor-agnostic language** -- generic terms for all recommendations -5. **Complete coverage** -- every semantic block appears in the report +5. **Complete coverage** -- every semantic block is labeled and compared 6. **No script creation** -- subagents use only existing scripts --- @@ -273,8 +239,10 @@ Prompt the user to review the report. ``` / - comparison_report.xlsx # Multi-sheet Excel workbook - semantic_comparison_report.md # Stakeholder gap analysis report + _work/ + /semantic_labels.json # Per-trace semantic labels + /semantic_labels.json + comparison.csv # Cross-trace comparison tracediff_output/ # TraceDiff-compatible output diff_stats.csv diff_stats_unique_args_summary.csv From 3518c702772c5432aa86bbda4cabfa852d2ace68 Mon Sep 17 00:00:00 2001 From: Spandan More Date: Thu, 4 Jun 2026 16:48:00 -0700 Subject: [PATCH 04/50] fix: added compatibility updated fields to tracediff output for mapping --- .../agents/semantic-comparison-agent.md | 12 +++++++++++ .../build_semantic_labels.py | 5 +++-- .../semantic_analyses/extract_tree_context.py | 2 ++ .../generate_semantic_diff.py | 20 +++++++++++++++++-- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md index f4f82b3a8..6f29cb2aa 100644 --- a/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md +++ b/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md @@ -198,6 +198,18 @@ Produces in `/tracediff_output/`: This is a **final deliverable** directory for downstream TraceDiff consumers. +**Perf-report enrichment compatibility:** `diff_stats.csv` carries a +per-kernel `gpu_op_uid` (the TraceTree UID, identical to the perf report's +`kernel_details[].gpu_op_uid`) and a per-LCA `busy_time`. This makes it +consumable by `enrich_perf_report_dict_inplace` in +`TraceLens/Reporting/tracediff_comparison_extension.py`, which matches +diff rows to `unified_perf_summary` rows via `gpu_op_uid` and adds the +speedup / delta / LCA columns. The enrichment is invoked at the +orchestrator layer (passing the semantic `diff_stats` plus the trace-1 +`df_unified_perf`); `generate_perf_report_pytorch.py` is unchanged and +retains its own in-memory TraceDiff path for the `--comparison_json_path` +flow. + --- ## Step 4: Generate Comparison CSV [S] diff --git a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py index b055441e6..717164b1e 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py @@ -19,8 +19,8 @@ (e.g. ``QKV Projection``). Per-kernel output fields: - index, name, dur, perf_category, semantic_block, region, nn_module, - cpu_op, input_dims, layer. + index, name, dur, gpu_op_uid, perf_category, semantic_block, region, + nn_module, cpu_op, input_dims, layer. Usage: python build_semantic_labels.py extracted.json classified.json pattern.json \ @@ -153,6 +153,7 @@ def build_labels(extracted, classified, pattern, tree_context=None): "index": i, "name": k["name"], "dur": k["dur"], + "gpu_op_uid": tc.get("gpu_op_uid"), "perf_category": c.get("perf_category", "Others"), "nn_module": _deepest_module(tc.get("nn_module_stack", [])), "cpu_op": tc.get("cpu_op_name", ""), diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py index 0e4dc8705..41f787ab4 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py @@ -142,6 +142,7 @@ def extract_tree_context(tree, extracted_data, ts_index=None, capture_augmented= kernel_contexts.append( { "index": i, + "gpu_op_uid": None, "cpu_op_name": "", "cpu_op_callstack": "", "nn_module_stack": [], @@ -158,6 +159,7 @@ def extract_tree_context(tree, extracted_data, ts_index=None, capture_augmented= kernel_contexts.append( { "index": i, + "gpu_op_uid": tree_event.get("UID"), "cpu_op_name": cpu_op_name, "cpu_op_callstack": callstack, "nn_module_stack": nn_module, diff --git a/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py b/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py index ab8e0a433..5e192467e 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py @@ -20,7 +20,9 @@ - Two semantic_labels.json files (one per trace) Output (in output directory): - - diff_stats.csv + - diff_stats.csv (includes per-kernel ``gpu_op_uid`` -- the TraceTree UID -- + and per-LCA ``busy_time``, so the output is consumable by the perf-report + comparison enrichment in tracediff_comparison_extension.py) - diff_stats_unique_args_summary.csv - cpu_op_map.json - cpu_op_map_trace1.json @@ -109,6 +111,7 @@ def _format_dims(dims_list): "lowest_common_ancestor_id": block_id_map[block], "nn_module_stack": nn_mod, "nn_module_parent": nn_mod, + "gpu_op_uid": k.get("gpu_op_uid"), } ) @@ -127,10 +130,13 @@ def build_unique_args_summary(diff_stats_df): on kernel_time. """ metric_columns = ["kernel_time"] + # gpu_op_uid is unique per kernel (would explode groups) and busy_time is + # a derived per-LCA aggregate, so neither belongs in the grouping key. + excluded_cols = {"lowest_common_ancestor_id", "gpu_op_uid", "busy_time"} grouping_cols = [ c for c in diff_stats_df.columns - if c not in metric_columns and c != "lowest_common_ancestor_id" + if c not in metric_columns and c not in excluded_cols ] agg_dict = {mcol: ["sum", "mean"] for mcol in metric_columns} @@ -382,6 +388,16 @@ def main(): rows, block_id_map = build_diff_stats(labeled_a, labeled_b) diff_stats_df = pd.DataFrame(rows) + # Per-LCA block total kernel time, broadcast to each row (mirrors + # TraceDiff's busy_time, which is identical for every row in an LCA + # group). semantic_labels.json has no timestamps, so sum-of-durations + # is used as the busy-time proxy (exact for non-overlapping kernels). + diff_stats_df["busy_time"] = ( + diff_stats_df.groupby(["source", "lowest_common_ancestor_id"])["kernel_time"] + .transform("sum") + .round(3) + ) + summary_df = build_unique_args_summary(diff_stats_df) cpu_op_map, cpu_op_map_trace1, cpu_op_map_trace2 = build_cpu_op_maps(diff_stats_df) From 694e0bb3ec54ce2f3e7c292e65bec461e7f35476 Mon Sep 17 00:00:00 2001 From: Spandan More Date: Thu, 4 Jun 2026 17:17:01 -0700 Subject: [PATCH 05/50] feat: appended kernel list with communication kernels --- TraceLens/Agent/Analysis/utils/classify_kernels.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/TraceLens/Agent/Analysis/utils/classify_kernels.py b/TraceLens/Agent/Analysis/utils/classify_kernels.py index 39d3d1a40..bae3190c7 100644 --- a/TraceLens/Agent/Analysis/utils/classify_kernels.py +++ b/TraceLens/Agent/Analysis/utils/classify_kernels.py @@ -203,6 +203,16 @@ (r"(?i)\bnorm\b", "Normalization", 1), (r"(?i)rocprim|hipcub", "Elementwise", 1), (r"(?i)cub::DeviceScan|DeviceRadixSort|DeviceReduce", "Elementwise", 1), + # ---- Triton fused ops near collectives (NOT actual collectives) ---- + (r"(?i)^triton_.*(?:all_to_all|allreduce|all_reduce|allgather|all_gather|reduce_scatter)", "Elementwise", 21), + # ---- Communication (priority 20) ---- + (r"(?i)nccl|rccl", "Communication", 20), + (r"(?i)allreduce|all_reduce|allgather|all_gather|reduce_scatter|all_to_all|alltoall", "Communication", 20), + (r"(?i)broadcast|bcast|send_recv|sendrecv|isend|irecv|cross_device_reduce", "Communication", 20), + # ---- Layout / data-movement elementwise ---- + (r"(?i)permute|transpose|nchwToNhwc|nhwcToNchw|clone|_unsafe_view|slice|copy|_cat_|clamp|indexSelect", "Elementwise", 10), + # ---- addmm into GEMM catch-all (source had gemm|matmul|bmm|addmm) ---- + (r"(?i)addmm", "GEMM", 5), ] COMPILED_RULES = [ @@ -232,6 +242,7 @@ "Quantization": "Quantization", "Elementwise": "Elementwise", "MemCpy": "MemCpy", + "Communication": "Communication", "Unknown": "Others", } From 88ab6bd1ee75b2cbd9ae339a05692665b09e2be7 Mon Sep 17 00:00:00 2001 From: Spandan More Date: Fri, 5 Jun 2026 16:40:27 -0700 Subject: [PATCH 06/50] feat: initial changes to the analysis orchestrator to integrate semantic agent; will require iteration --- .../.cursor/skills/analysis-orchestrator.md | 78 +++++- .../semantic_analyses/extract_tree_context.py | 11 +- .../Analysis/utils/comparison_routing.py | 226 ++++++++++++++++++ .../Reporting/generate_perf_report_pytorch.py | 30 ++- .../generate_perf_report_pytorch_inference.py | 34 ++- 5 files changed, 365 insertions(+), 14 deletions(-) create mode 100644 TraceLens/Agent/Analysis/utils/comparison_routing.py diff --git a/TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md b/TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md index 2519ba9ba..308488fa6 100644 --- a/TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md +++ b/TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md @@ -51,7 +51,7 @@ Use vendor-agnostic terminology throughout such as GPU kernels, collective commu optionally invoke agent_extension.py (when present), then embed the PNG into the report. ``` -**Subagent usage:** Only invoke Task subagents in steps that explicitly say "subagent" (Steps 6, 7, 9). All other steps (including Step 7.5) must be performed directly by the orchestrator using the command prefix. +**Subagent usage:** Only invoke Task subagents in steps that explicitly say "subagent" (Step 1.S semantic diff, Steps 6, 7, 9). All other steps (including Step 7.5) must be performed directly by the orchestrator using the command prefix. --- @@ -93,9 +93,10 @@ Use vendor-agnostic terminology throughout such as GPU kernels, collective commu - If **Inference (vLLM/SGLang)** is selected, ask **Execution Mode** → ``: 1. **Eager mode** (`` = `eager`) — only the trace file is needed 2. **Graph replay + capture** (`` = `graph_capture`) — also requires a capture folder path - - If **Graph replay + capture**, ask for **Capture Folder Path** → ``: - - Ask: "Please provide the full path to the graph capture traces folder" - - **Unsupported combination:** If `` = `graph_capture` **and** `` = `comparative`, stop immediately. Inform the user: "Graph replay + capture mode is not yet supported for comparative analysis. Please provide eager mode traces instead." Do not misinterpret as two standalone analyses. Do **not** proceed to Step 1 or beyond. + - If **Graph replay + capture**, ask for the **Capture Folder Path(s)**: + - `standalone`: one folder → ``. Ask: "Please provide the full path to the graph capture traces folder" + - `comparative`: one folder per trace → `` (primary/trace1) and `` (comparison/trace2). Ask: "Please provide the graph capture traces folder for the primary trace and for the comparison trace." + - **Comparative + graph replay is routed in Step 0.5** (do not abort): collect capture folders for both traces, and Step 0.5 decides tracediff vs semantic. 5. **Environment Setup** - Ask: "Are you running locally or on a cluster?" @@ -151,9 +152,28 @@ If this fails, check that `` is the **parent** of TraceLens (not --- +## Step 0.5: Comparison Method Detection (comparative only) + +For `standalone`, skip this step — `` is unused. + +For `comparative`, auto-detect the comparison path (structural **TraceDiff** vs **semantic**). Pass `--capture{1,2}-available` for any trace that had a capture folder collected, so a graph-mode trace with capture is not needlessly routed to semantic: + +```bash + python3 TraceLens/Agent/Analysis/utils/comparison_routing.py \ + \ + --platform1 --platform2 \ + [--capture1-available] [--capture2-available] +``` + +Set `` to the printed `method` field and echo `reasons`. The script routes to `semantic` only when the frameworks differ or a trace is graph-mode with no capture available; otherwise `tracediff`. + +If `method` is `semantic` and a graph-mode trace is involved but capture folders were not collected in Step 0, ask for them now: `` (trace1) and `` (trace2). + +--- + ## Step 1: Generate Performance Report -Use **``** to determine which CLI tool to run and then **``** to determine arguments. +Use **``** to determine which CLI tool to run and then **``** (and, for comparative, **``** from Step 0.5) to determine arguments. For all of these scripts below, look at the environment variable TL_EXTENSION to recursively search for a file called .json. Do not look for .json; it is not needed. If it is not found also look in TraceLens/Agent/Analysis/utils/arch/.json. @@ -173,14 +193,17 @@ All commands below append `` and ``, resolved by `/perf_report_trace1.xlsx --output_csvs_dir /perf_report_trace1_csvs` | | `comparative` trace2 | `--profile_json_path --output_xlsx_path /perf_report_trace2.xlsx --output_csvs_dir /perf_report_trace2_csvs` | -**``** — extension flags: +**``** — extension flags (the comparative trace1 value depends on ``): | scope | value | |-------|-------| | `standalone` | none | -| `comparative` trace1 | `--comparison_json_path ` | +| `comparative` trace1, `` = `tracediff` | `--comparison_json_path ` | +| `comparative` trace1, `` = `semantic` | `--precomputed_diff_stats_csv /_semantic/tracediff_output/diff_stats.csv` | | `comparative` trace2 | none | +For the **semantic** comparative method, the semantic diff must be generated **before** the trace1 report (so its `diff_stats.csv` exists). Follow the ordering in **Step 1.S** below. Both methods converge on the same artifacts: an enriched `perf_report_trace1_csvs/unified_perf_summary.csv` plus a `perf_report_trace1_csvs/diff_stats.csv`, so Steps 2-11 are identical for either method. + --- **Default (training and non-vLLM/SGLang eager inference)** (`` = `default`): @@ -225,6 +248,42 @@ All commands below append `` and ``, resolved by ` ``` +(For comparative graph mode, the trace2 report uses `--capture_folder `.) + +--- + +## Step 1.S: Semantic Comparative Ordering (`` = `semantic` only) + +When `` = `comparative` and `` = `semantic`, run Step 1 in this order so the trace1 report can consume the semantic diff: + +1. **Trace2 report** — run the analysis-mode CLI above for trace2 using the `comparative` trace2 `` and empty `` (identical to the TraceDiff path). For graph mode add `--capture_folder `. + +2. **Semantic diff (subagent)** — launch a Task subagent that reads and follows the FULL instructions in `TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md`. Prompt context: + +``` +Read and follow the FULL instructions in: + TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md + +**Execution Context:** +- Trace A (primary/trace1): (platform ) +- Trace B (comparison/trace2): (platform ) +- Labels: name-a trace1, name-b trace2 +- Output directory: /_semantic/ +- Command prefix: read /cache/cmd_prefix.txt — substitute {CMD} +- Capture folders (graph mode only): trace1 , trace2 + +Run the full semantic comparison through "Generate TraceDiff Output" so that +/_semantic/tracediff_output/diff_stats.csv is produced. Return "DONE". +``` + + Verify `/_semantic/tracediff_output/diff_stats.csv` exists before continuing. If it is missing, retry the subagent once; if it still fails, stop and report. + +3. **Trace1 report** — run the analysis-mode CLI for trace1 with the `comparative` trace1 `` and `` = `--precomputed_diff_stats_csv /_semantic/tracediff_output/diff_stats.csv`. For graph mode also add `--capture_folder `. This produces the enriched `unified_perf_summary` and the `diff_stats` sheet in `perf_report_trace1_csvs` (same enrichment as the tracediff path). + +4. **Confirm** `/perf_report_trace1_csvs/diff_stats.csv` exists (written by the report script). If absent, copy `/_semantic/tracediff_output/diff_stats.csv` to that path so the comparative fusion step (Steps 2-5) can read it. + +After Step 1.S, proceed to Steps 2-5 unchanged. + --- ## Steps 2-5: Prepare Category Data @@ -607,5 +666,6 @@ If Steps 1 or many of Steps 2-5 fail or produce unexpected results, check whethe - **Torch Compile**: `ops_summary.csv` contains op names matching `triton_poi_fused_*`, `triton_red_fused_*`, `triton_per_fused_*`, or `CompiledFunction`. If found, inform the user. - **GPU Graph Replay**: raw trace JSON contains `hipGraphLaunch` or `cudaGraphLaunch`. - - **Default mode** (analysis_mode = `default`): Inform the user 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** (`` = `comparative`): graph replay is **supported via the semantic comparison path** (Step 0.5 routes it; do not abort). Ensure capture folders were collected for both traces and follow Step 1.S. + - **Default mode, standalone** (analysis_mode = `default`): Inform the user that GPU graph replay was detected and that the default analysis mode supports typical PyTorch traces. **Abort** -- do not retry or continue. + - **Inference mode, standalone** (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. diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py index 41f787ab4..389ecb872 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py @@ -36,7 +36,7 @@ if _repo_root not in sys.path: sys.path.insert(0, _repo_root) -from TraceLens.util import DataLoader, TraceEventUtils +from TraceLens.util import DataLoader from TraceLens.Trace2Tree.trace_to_tree import TraceToTree @@ -61,8 +61,13 @@ def load_and_build_tree(trace_path, capture_trace_path=None): data = DataLoader.load_data(trace_path) events = data.get("traceEvents", []) - _, non_meta_events = TraceEventUtils.split_event_list(events) - tree = TraceToTree(non_meta_events, prune_nongpu_paths=True) + # Pass the full traceEvents list (do NOT strip metadata first) so that the + # per-event UID -- assigned as the enumerate() index in TraceToTree -- is + # identical to the one produced by TreePerfAnalyzer.from_file (which also + # builds from data["traceEvents"] as-is). This keeps the diff_stats + # gpu_op_uid aligned with the perf report's kernel_details gpu_op_uid so + # the comparison enrichment can map semantic rows onto perf-summary rows. + tree = TraceToTree(events, prune_nongpu_paths=True) tree.build_tree(add_python_func=True, link_fwd_bwd=False) return tree diff --git a/TraceLens/Agent/Analysis/utils/comparison_routing.py b/TraceLens/Agent/Analysis/utils/comparison_routing.py new file mode 100644 index 000000000..fc7056154 --- /dev/null +++ b/TraceLens/Agent/Analysis/utils/comparison_routing.py @@ -0,0 +1,226 @@ +#!/usr/bin/env python3 +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Trace origin/type detection for comparative-analysis routing. + +Decides, from a cheap one-pass scan of a Chrome/PyTorch trace, whether a +comparative run should use the structural TraceDiff path or the semantic +comparison path. + +Two layers: + * ``classify_trace(trace_path)`` -> {framework, exec_mode, annotated} + determines a single trace's origin/type. + * ``classify_comparison_method(trace1, trace2, capture1_available, + capture2_available, platform1, platform2)`` + -> {method, reasons, trace1_kind, trace2_kind} + applies the semantic-vs-tracediff rule across the two traces. + +The routing principle is "semantic only when TraceDiff cannot work": the +structural TraceDiff path needs an alignable CPU-op tree on both sides, so +the semantic path is used only when (a) the two traces come from different +frameworks (their CPU-op trees do not align), or (b) a trace is graph-mode +with no capture trace available (no CPU-op tree to diff against). Everything +else -- including same-framework cross-platform eager traces -- stays on +TraceDiff. + +This intentionally avoids the heavyweight ``split_vllm_trace()`` (which spawns +a subprocess and fully splits the trace); detection only needs a lightweight +scan of ``traceEvents``. + +Usage: + python comparison_routing.py \ + --platform1 MI300X --platform2 MI355X \ + --capture1-available --capture2-available +""" + +import argparse +import gzip +import json +import re +import sys + +# Iteration-annotation markers. Mirrors +# ``TraceLens.TraceUtils.split_inference_trace_annotation.ANNOTATION_PATTERN`` +# so detection stays consistent with the trace splitter. These match the +# per-iteration ``user_annotation`` events emitted by vLLM/SGLang. +ANNOTATION_PATTERN = [ + re.compile( + r"execute_\d+_context_\d+\(sq\d+sk\d+sqsq\d+sqsk\d+\)_generation_\d+\(sq\d+sk\d+sqsq\d+sqsk\d+\)" + ), + re.compile(r"execute_context_\d+\(\d+\)_generation_\d+\(\d+\)"), + re.compile(r"execute_new_\d+_cached_\d+"), + re.compile(r"execute_context_\d+\(\d+_\d+\)_generation_\d+\(\d+\)"), +] + + +def _load_events(trace_path): + """Load ``traceEvents`` from a .json or .json.gz Chrome trace.""" + opener = gzip.open if trace_path.endswith(".gz") else open + with opener(trace_path, "rt") as f: + data = json.load(f) + return data.get("traceEvents", []) + + +def classify_trace(trace_path): + """Determine a single trace's origin/type from a cheap one-pass scan. + + Returns: + dict with + - ``framework``: "vllm" | "sglang" | "plain" + - ``exec_mode``: "graph" | "eager" + - ``annotated``: bool (an inference-framework trace, i.e. carries + vLLM/SGLang annotations / namespaces) + """ + events = _load_events(trace_path) + + has_graph_launch = False + has_vllm = False + has_sglang = False + has_annotation = False + + for e in events: + if not isinstance(e, dict): + continue + name = e.get("name", "") + if not isinstance(name, str): + continue + cat = e.get("cat", "") + + # exec_mode: same substring test as extract_trace_data.detect_graph_mode + # (covers both cudaGraphLaunch and hipGraphLaunch). + if not has_graph_launch and cat == "cuda_runtime" and "GraphLaunch" in name: + has_graph_launch = True + + # Framework markers appear in python_function / user_annotation names + # (module namespaces and file paths). + if not has_sglang and "sglang" in name: + has_sglang = True + if not has_vllm and "vllm" in name: + has_vllm = True + + # Per-iteration annotations indicate an inference workload. + if not has_annotation and cat == "user_annotation": + if any(p.match(name) for p in ANNOTATION_PATTERN): + has_annotation = True + + if has_sglang: + framework = "sglang" + elif has_vllm: + framework = "vllm" + else: + framework = "plain" + + annotated = has_annotation or framework in ("vllm", "sglang") + + return { + "framework": framework, + "exec_mode": "graph" if has_graph_launch else "eager", + "annotated": annotated, + } + + +def classify_comparison_method( + trace1, + trace2, + capture1_available=False, + capture2_available=False, + platform1=None, + platform2=None, +): + """Decide between the structural TraceDiff path and the semantic path. + + Routes to ``semantic`` only when TraceDiff cannot work, i.e. when ANY of: + - the two traces come from different frameworks (their CPU-op trees do + not align, so TraceDiff cannot match them), or + - a trace is graph-mode AND has no capture trace available (no CPU-op + tree to diff against). + + Everything else stays on ``tracediff``. In particular, a platform + difference does NOT force semantic: same-framework cross-platform eager + traces keep an alignable CPU-op tree (only kernel names/durations differ), + which TraceDiff handles. ``platform1``/``platform2`` are accepted only for + human-readable reasons, never for the decision. + + Args: + capture1_available / capture2_available: whether a capture trace was + collected for the corresponding trace (needed to give a graph-mode + trace an alignable CPU-op tree). Capture availability is external + to the trace JSON, so it must be supplied by the caller. + + Returns: + dict with ``method`` ("semantic"|"tracediff"), a human-readable + ``reasons`` list, and the per-trace ``classify_trace`` results. + """ + k1 = classify_trace(trace1) + k2 = classify_trace(trace2) + + reasons = [] + if k1["framework"] != k2["framework"]: + reasons.append( + f"frameworks differ ({k1['framework']} vs {k2['framework']})" + ) + if k1["exec_mode"] == "graph" and not capture1_available: + reasons.append("trace1 is graph-mode with no capture trace available") + if k2["exec_mode"] == "graph" and not capture2_available: + reasons.append("trace2 is graph-mode with no capture trace available") + + method = "semantic" if reasons else "tracediff" + + return { + "method": method, + "reasons": reasons, + "trace1_kind": k1, + "trace2_kind": k2, + } + + +def main(): + parser = argparse.ArgumentParser( + description=( + "Classify two traces and decide TraceDiff vs semantic comparison. " + "Prints the decision as JSON." + ) + ) + parser.add_argument("trace1", help="Path to primary trace (.json/.json.gz)") + parser.add_argument("trace2", help="Path to comparison trace (.json/.json.gz)") + parser.add_argument( + "--platform1", + default=None, + help="Platform of trace1 (informational only; not used for the decision)", + ) + parser.add_argument( + "--platform2", + default=None, + help="Platform of trace2 (informational only; not used for the decision)", + ) + parser.add_argument( + "--capture1-available", + action="store_true", + help="A capture trace was collected for trace1 (gives a graph-mode " + "trace an alignable CPU-op tree for TraceDiff)", + ) + parser.add_argument( + "--capture2-available", + action="store_true", + help="A capture trace was collected for trace2", + ) + args = parser.parse_args() + + result = classify_comparison_method( + args.trace1, + args.trace2, + capture1_available=args.capture1_available, + capture2_available=args.capture2_available, + platform1=args.platform1, + platform2=args.platform2, + ) + json.dump(result, sys.stdout, indent=2) + sys.stdout.write("\n") + + +if __name__ == "__main__": + main() diff --git a/TraceLens/Reporting/generate_perf_report_pytorch.py b/TraceLens/Reporting/generate_perf_report_pytorch.py index e6365cacc..7cb83fb54 100644 --- a/TraceLens/Reporting/generate_perf_report_pytorch.py +++ b/TraceLens/Reporting/generate_perf_report_pytorch.py @@ -267,6 +267,10 @@ def generate_perf_report_pytorch( topk_ops: Optional[int] = None, topk_roofline_ops: Optional[int] = None, comparison_json_path: Optional[str] = None, + # precomputed diff_stats.csv (e.g. from the semantic comparison path); when + # set, the internal TraceDiff is skipped and this CSV is used as-is to + # enrich the report. Mutually exclusive with comparison_json_path. + precomputed_diff_stats_csv: Optional[str] = None, extension_file: Optional[str] = None, # for gemm simulator / Origami (Origami requires --enable_origami when arch is set) python_path: Optional[str] = None, @@ -629,7 +633,10 @@ def generate_perf_report_pytorch( # Add unified perf metrics table (ops with perf models + leaf ops with GPU kernels) df_unified_perf = perf_analyzer.build_df_unified_perf_table() - # Run TraceDiff when a comparison trace is provided. diff_stats_df is generated + # Obtain the comparison diff_stats. Normally generated by running + # TraceDiff against a comparison trace; alternatively a precomputed + # diff_stats.csv (e.g. from the semantic comparison path) can be + # supplied, in which case the internal TraceDiff is skipped. _tracediff_diff_stats: Optional[pd.DataFrame] = None if comparison_json_path and not df_unified_perf.empty: perf_analyzer2 = TreePerfAnalyzer.from_file( @@ -645,6 +652,8 @@ def generate_perf_report_pytorch( td = TraceDiff(perf_analyzer.tree, perf_analyzer2.tree) td.generate_tracediff_report() _tracediff_diff_stats = td.diff_stats_df + elif precomputed_diff_stats_csv and not df_unified_perf.empty: + _tracediff_diff_stats = pd.read_csv(precomputed_diff_stats_csv) if not df_unified_perf.empty: df_unified_perf_summary = perf_analyzer.summarize_df_unified_perf_table( @@ -978,6 +987,19 @@ def main(): ), ) + parser.add_argument( + "--precomputed_diff_stats_csv", + type=str, + default=None, + help=( + "Path to a precomputed TraceDiff-schema diff_stats.csv (e.g. from " + "the semantic comparison path). When set, the internal TraceDiff " + "is skipped and this CSV is used to enrich unified_perf_summary " + "and emit the diff_stats sheet. Mutually exclusive with " + "--comparison_json_path." + ), + ) + parser.add_argument( "--extension_file", type=str, @@ -1042,6 +1064,11 @@ def main(): ) args = parser.parse_args() + if args.comparison_json_path and args.precomputed_diff_stats_csv: + parser.error( + "--comparison_json_path and --precomputed_diff_stats_csv cannot be " + "used together; provide only one comparison diff_stats source." + ) generate_perf_report_pytorch( profile_json_path=args.profile_json_path, output_xlsx_path=args.output_xlsx_path, @@ -1060,6 +1087,7 @@ def main(): topk_ops=args.topk_ops, topk_roofline_ops=args.topk_roofline_ops, comparison_json_path=args.comparison_json_path, + precomputed_diff_stats_csv=args.precomputed_diff_stats_csv, extension_file=args.extension_file, python_path=args.python_path, gpu_arch_json_path=args.gpu_arch_json_path, diff --git a/TraceLens/Reporting/generate_perf_report_pytorch_inference.py b/TraceLens/Reporting/generate_perf_report_pytorch_inference.py index d5d74b851..058836cc5 100644 --- a/TraceLens/Reporting/generate_perf_report_pytorch_inference.py +++ b/TraceLens/Reporting/generate_perf_report_pytorch_inference.py @@ -547,6 +547,10 @@ def generate_perf_report_pytorch( topk_ops: Optional[int] = None, topk_roofline_ops: Optional[int] = None, comparison_json_path: Optional[str] = None, + # precomputed diff_stats.csv (e.g. from the semantic comparison path); when + # set, the internal TraceDiff is skipped and this CSV is used as-is to + # enrich the report. Mutually exclusive with comparison_json_path. + precomputed_diff_stats_csv: Optional[str] = None, extension_file: Optional[str] = None, # for gemm simulator / Origami (Origami requires --enable_origami when arch is set) python_path: Optional[str] = None, @@ -915,7 +919,10 @@ def generate_perf_report_pytorch( include_nccl=collective_analysis ) - # Run TraceDiff when a comparison trace is provided. diff_stats_df is generated + # Obtain the comparison diff_stats. Normally generated by running + # TraceDiff against a comparison trace; alternatively a precomputed + # diff_stats.csv (e.g. from the semantic comparison path) can be + # supplied, in which case the internal TraceDiff is skipped. _tracediff_diff_stats: Optional[pd.DataFrame] = None if comparison_json_path and not df_unified_perf.empty: perf_analyzer2 = TreePerfAnalyzer.from_file( @@ -931,6 +938,8 @@ def generate_perf_report_pytorch( td = TraceDiff(perf_analyzer.tree, perf_analyzer2.tree) td.generate_tracediff_report() _tracediff_diff_stats = td.diff_stats_df + elif precomputed_diff_stats_csv and not df_unified_perf.empty: + _tracediff_diff_stats = pd.read_csv(precomputed_diff_stats_csv) if not df_unified_perf.empty: df_unified_perf_summary = perf_analyzer.summarize_df_unified_perf_table( @@ -1280,6 +1289,20 @@ def main(): ), ) + parser.add_argument( + "--precomputed_diff_stats_csv", + type=str, + default=None, + help=( + "Path to a precomputed TraceDiff-schema diff_stats.csv (e.g. from " + "the semantic comparison path). When set, the internal TraceDiff " + "is skipped and this CSV is used to enrich unified_perf_summary " + "and emit the diff_stats sheet. Mutually exclusive with " + "--comparison_json_path; unlike --comparison_json_path it may be " + "combined with --capture_folder." + ), + ) + parser.add_argument( "--extension_file", type=str, @@ -1334,6 +1357,14 @@ def main(): "--capture_folder and --comparison_json_path cannot be used together. " "The TraceDiff comparison extension does not support graph capture traces." ) + if args.comparison_json_path and args.precomputed_diff_stats_csv: + parser.error( + "--comparison_json_path and --precomputed_diff_stats_csv cannot be " + "used together; provide only one comparison diff_stats source." + ) + # NOTE: --capture_folder + --precomputed_diff_stats_csv IS allowed: the + # precomputed (e.g. semantic) diff_stats does not run the internal + # TraceDiff, so graph capture traces can be compared via this path. if args.capture_folder: classify_graph_capture_trace(args.capture_folder) metadata_json_path = os.path.join(args.capture_folder, "execution_details.json") @@ -1360,6 +1391,7 @@ def main(): topk_ops=args.topk_ops, topk_roofline_ops=args.topk_roofline_ops, comparison_json_path=args.comparison_json_path, + precomputed_diff_stats_csv=args.precomputed_diff_stats_csv, extension_file=args.extension_file, python_path=args.python_path, gpu_arch_json_path=args.gpu_arch_json_path, From 356d9fe1a16eba100b0cd782e3250be93df3db63 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Wed, 10 Jun 2026 16:13:19 -0700 Subject: [PATCH 07/50] prevent caches from overlapping --- .../Trace2Tree/trace_capture_merge_experimental.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py index df7f875c1..225bf45b8 100644 --- a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py +++ b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py @@ -260,10 +260,11 @@ def _get_cached_capture_tree(key, filepath, TreePerfAnalyzer): tuples — one per capture root — pre-computed from :func:`get_subtree_events`. """ - if key in _capture_tree_cache: - _capture_tree_cache.move_to_end(key) + cache_key = (key, os.path.abspath(filepath)) + if cache_key in _capture_tree_cache: + _capture_tree_cache.move_to_end(cache_key) print("Cache hit for capture tree (key={})".format(key)) - return _capture_tree_cache[key] + return _capture_tree_cache[cache_key] print("Loading capture trace: {} (key={})".format(filepath, key)) capture_perf_analyzer = TreePerfAnalyzer.from_file(filepath, add_python_func=True) @@ -281,10 +282,10 @@ def _get_cached_capture_tree(key, filepath, TreePerfAnalyzer): filtered_uids = {e[UID] for e in capture_filtered_events} capture_root_data.append((capture_events, filtered_uids)) - _capture_tree_cache[key] = (capture_tree, capture_roots, capture_root_data) + _capture_tree_cache[cache_key] = (capture_tree, capture_roots, capture_root_data) if len(_capture_tree_cache) > _CAPTURE_TREE_CACHE_MAX_SIZE: - evicted_key, _ = _capture_tree_cache.popitem(last=False) - print("Evicted capture tree cache entry (key={})".format(evicted_key)) + evicted_cache_key, _ = _capture_tree_cache.popitem(last=False) + print("Evicted capture tree cache entry (key={})".format(evicted_cache_key[0])) return capture_tree, capture_roots, capture_root_data From 890a00d64254b7516d453a59874b5af8f84ea958 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Wed, 10 Jun 2026 17:10:30 -0700 Subject: [PATCH 08/50] fix(capture_merge): use greedy alignment when capture/graph kernel counts 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 --- .../trace_capture_merge_experimental.py | 103 ++++++++++++++---- 1 file changed, 81 insertions(+), 22 deletions(-) diff --git a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py index 225bf45b8..9af80fae1 100644 --- a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py +++ b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py @@ -58,37 +58,96 @@ def get_subtree_events(tree, event, cat_filter=None, name_filter=None): return list_events, list_filtered_events +def _align_capture_to_graph(capture_events, graph_events): + """ + Greedily align capture dispatch events to graph kernel events by name. + + For each graph kernel, scan forward through capture_events until a + dispatch whose args.kernel matches is found, skipping any unmatched + dispatches along the way. Unmatched capture events at the tail are + discarded. Returns the aligned capture list (same length as + graph_events), or None if any graph kernel cannot be matched. + """ + + def capture_kernel_name(event): + return event.get("args", {}).get("kernel", event["name"]) + + aligned = [] + ci = 0 + for g_event in graph_events: + g_name = g_event["name"] + matched = False + while ci < len(capture_events): + c_event = capture_events[ci] + ci += 1 + c_name = capture_kernel_name(c_event) + # Memcpy/Memset events carry no kernel arg — match by position + if "Memcpy" in c_event["name"] or "Memset" in c_event["name"]: + aligned.append(c_event) + matched = True + break + if c_name == g_name: + aligned.append(c_event) + matched = True + break + if not matched: + return None + return aligned + + def verify_subtree_events(capture_events, graph_events): + """ + Verify that capture dispatch events align 1-to-1 with graph kernel events. + + If counts match, check names directly. If counts differ, attempt greedy + alignment via _align_capture_to_graph: extra capture dispatches are + discarded and the aligned list is returned so the caller can proceed. + + Returns: + (success, aligned_capture_events) where success is 1 on full match, + 2 on successful greedy alignment (with discards), and 0 on failure. + """ + def capture_kernel_name(event): + return event.get("args", {}).get("kernel", event["name"]) + if len(capture_events) != len(graph_events): print( "Mismatch in number of events: Capture {}, Graph {}".format( len(capture_events), len(graph_events) ) ) - return 0 - else: - # print("=========matching ========") - for j, i in zip(capture_events, graph_events): - if "kernel" not in j.get("args", {}).keys(): - if "Memcpy" in j["name"] or "Memset" in j["name"]: - continue - warnings.warn( - "Kernel name missing in capture event args, " - "alignment has not been verified", - stacklevel=2, + aligned = _align_capture_to_graph(capture_events, graph_events) + if aligned is not None: + print( + "Greedy alignment succeeded: matched {} capture events to {} graph kernels " + "({} capture events discarded).".format( + len(aligned), + len(graph_events), + len(capture_events) - len(aligned), ) + ) + return 2, aligned + return 0, capture_events + + for j, i in zip(capture_events, graph_events): + if "kernel" not in j.get("args", {}).keys(): + if "Memcpy" in j["name"] or "Memset" in j["name"]: continue - if i["name"] != j.get("args", {}).get("kernel", j["name"]): - print( - "Mismatch in kernel name: {} vs {}".format( - i["name"], j.get("args", {}).get("kernel", j["name"]) - ) + warnings.warn( + "Kernel name missing in capture event args, " + "alignment has not been verified", + stacklevel=2, + ) + continue + if i["name"] != j.get("args", {}).get("kernel", j["name"]): + print( + "Mismatch in kernel name: {} vs {}".format( + i["name"], j.get("args", {}).get("kernel", j["name"]) ) - return 0 - # print( - # "Subtree events match successfully with {} events".format(len(capture_events)) - # ) - return 1 + ) + return 0, capture_events + + return 1, capture_events def update_subtree_uids_and_timestamps( @@ -549,7 +608,7 @@ def merge_capture_trace_into_graph( graph_tree, g_root, cat_filter=["kernel", "gpu_memset", "gpu_memcpy"] ) - verify_success = verify_subtree_events( + verify_success, capture_filtered_events = verify_subtree_events( capture_filtered_events, graph_filtered_events ) From 64e6b0a19474a5a383a3a594e9e004f2ed682cc3 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Thu, 11 Jun 2026 09:06:19 -0700 Subject: [PATCH 09/50] dont treat hipgraphlaunch as cuda_runtime --- TraceLens/TraceDiff/trace_diff.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/TraceLens/TraceDiff/trace_diff.py b/TraceLens/TraceDiff/trace_diff.py index 103932c33..daddb4c21 100644 --- a/TraceLens/TraceDiff/trace_diff.py +++ b/TraceLens/TraceDiff/trace_diff.py @@ -348,11 +348,20 @@ def safe_children(uid2node, uid): return [] return node.get("children", []) + _GRAPH_LAUNCH_NAMES = {"hipGraphLaunch", "cudaGraphLaunch"} + def subtree_contains_cuda_runtime(uid, uid2node): - """Return True if this node is a cuda_runtime node.""" + """Return True if this node is a cuda_runtime node. + + Graph launch events (hipGraphLaunch, cudaGraphLaunch) are exempt: + they are platform-specific names for the same operation and should + be matched by position rather than forced through Wagner-Fischer. + """ node = uid2node.get(uid) if not node or not isinstance(node, dict): return False + if node.get("name") in _GRAPH_LAUNCH_NAMES: + return False cat = node.get("cat") or node.get("category") if cat == "cuda_runtime" or cat == "cuda_driver": return True From 7bfd0ba8ee9f4170ed5e7d3f4cf4604fd4a56099 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Fri, 12 Jun 2026 09:27:46 -0700 Subject: [PATCH 10/50] keep traversing when one node has only one child --- TraceLens/TraceDiff/trace_diff.py | 35 +++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/TraceLens/TraceDiff/trace_diff.py b/TraceLens/TraceDiff/trace_diff.py index daddb4c21..62d63a8a7 100644 --- a/TraceLens/TraceDiff/trace_diff.py +++ b/TraceLens/TraceDiff/trace_diff.py @@ -552,6 +552,41 @@ def traverse_and_merge(uid1, uid2): nn_module_stack = node2.get("nn_module_stack", "") children1, children2 = get_children_with_missing(uid1, uid2) + + # Flatten transparent wrapper layers on whichever side has exactly + # one gpu-path child, until counts match or a cpu_op (real op) or + # dead end is reached. This handles call-stack depth asymmetries + # between backends (e.g. AMD adds an extra utils.py: run wrapper + # that CUDA doesn't have) without confusing them with kernel-fusion + # differences, where the single child would be a cpu_op and we stop. + while len(children1) != len(children2): + if len(children1) == 1: + node = baseline_uid2node.get(children1[0]) + if not node or tree1.event_to_category(node) == "cpu_op": + break + deeper = [ + c + for c in node.get("children", []) + if self.is_gpu_path(baseline_uid2node.get(c)) + ] + if not deeper: + break + children1 = deeper + elif len(children2) == 1: + node = variant_uid2node.get(children2[0]) + if not node or tree2.event_to_category(node) == "cpu_op": + break + deeper = [ + c + for c in node.get("children", []) + if self.is_gpu_path(variant_uid2node.get(c)) + ] + if not deeper: + break + children2 = deeper + else: + break + any_cuda_runtime = any( subtree_contains_cuda_runtime(c, baseline_uid2node) for c in children1 ) or any( From d3501ed3ebbd2bd9f5fce8b8e545020948c603bb Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Fri, 12 Jun 2026 09:27:58 -0700 Subject: [PATCH 11/50] greedy matching --- .../trace_capture_merge_experimental.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py index 9af80fae1..d467b304f 100644 --- a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py +++ b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py @@ -188,15 +188,19 @@ def update_subtree_uids_and_timestamps( print( "Warning: parent UID {} not found in mapping".format(parent_uid) ) - # Update timestamps + # Update timestamps: scale capture time into the graph replay window. + # The capture ran for capture_dur; the graph replay runs for g_root_dur. + # We shift each event's ts by (new_start_ts - original_start_ts) and + # scale both the offset and dur by (g_root_dur / capture_dur) so that + # the entire capture subtree fits proportionally within the replay window. original_start_ts = subtree_events[0]["ts"] - ts_offset = new_start_ts - original_start_ts - # for event in subtree_filtered_events: - # event[UID]=uid_mapping[event[UID]] + capture_dur = subtree_events[0].get("dur", g_root_dur) or g_root_dur + scale = g_root_dur / capture_dur if capture_dur > 0 else 1.0 for event in subtree_events: - event["ts"] += ts_offset - event["ts"] = new_start_ts - event["dur"] = g_root_dur + relative_ts = event["ts"] - original_start_ts + event["ts"] = new_start_ts + relative_ts * scale + if "dur" in event: + event["dur"] = event["dur"] * scale for i in capture_tree.cpu_root_nodes: if i in uid_mapping: cpu_root_nodes.append(uid_mapping[i]) From bc937e6c4f3a77510180344bc856713ca10a4e97 Mon Sep 17 00:00:00 2001 From: Spandan More Date: Fri, 19 Jun 2026 11:07:24 -0700 Subject: [PATCH 12/50] Bug fix with empty rows in sem agent comparative final output --- .../Analysis/utils/orchestrator_prepare.py | 48 ++++++- .../utils/templates/analysis_template.md | 9 +- .../Reporting/generate_perf_report_pytorch.py | 14 ++ .../generate_perf_report_pytorch_inference.py | 14 ++ .../tracediff_comparison_extension.py | 129 +++++++++++++++++- 5 files changed, 205 insertions(+), 9 deletions(-) diff --git a/TraceLens/Agent/Analysis/utils/orchestrator_prepare.py b/TraceLens/Agent/Analysis/utils/orchestrator_prepare.py index f076bb4ef..2c96e42a6 100644 --- a/TraceLens/Agent/Analysis/utils/orchestrator_prepare.py +++ b/TraceLens/Agent/Analysis/utils/orchestrator_prepare.py @@ -18,7 +18,7 @@ import sys import traceback from collections import defaultdict -from typing import Any +from typing import Any, Optional import pandas as pd sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) @@ -737,6 +737,26 @@ def _build_trace2_ops_summary_by_enhanced_category(trace2_csv_dir: str) -> list: return json.loads(grouped.to_json(orient="records")) +def _load_trace2_aligned_by_category(trace1_csv_dir: str) -> Optional[list]: + """Load the semantic-aligned trace2 per-category summary, if present. + + The perf-report script writes ``trace2_aligned_by_category.csv`` into the + trace1 CSV dir when a precomputed/in-memory diff is enriched. Unlike the + per-framework ``_build_trace2_ops_summary_by_enhanced_category`` (which + categorizes trace2 by its own op names), this rolls trace2 kernel time up + to *trace1* categories via the LCA alignment, so the comparative Top-Ops + table compares like-for-like across frameworks. Returns ``None`` when the + artifact is absent (caller falls back to the per-framework breakdown). + """ + aligned_path = os.path.join(trace1_csv_dir, "trace2_aligned_by_category.csv") + if not os.path.isfile(aligned_path): + return None + df = pd.read_csv(aligned_path) + if df.empty or "op category" not in df.columns: + return None + return json.loads(df.to_json(orient="records")) + + def _gpu_utilization_metrics_from_gpu_timeline_df(gpu_timeline: pd.DataFrame) -> dict: """Build the same gpu_utilization dict used in category_manifest from gpu_timeline.csv rows.""" gpu_data = {} @@ -868,9 +888,28 @@ def main(): os.path.join(output_dir, "metadata", "trace2_gpu_utilization.json"), "w" ) as f: json.dump(trace2_gpu_utilization, f, indent=2) - trace2_ops_summary_by_category = _build_trace2_ops_summary_by_enhanced_category( - trace2_csv_dir + # Per-framework breakdown (trace2 categorized by its own op names). Kept + # for reference; it mis-compares when frameworks differ (the source of + # the 0 ms Top-Ops artifact). + trace2_ops_summary_by_category_raw = ( + _build_trace2_ops_summary_by_enhanced_category(trace2_csv_dir) ) + # Preferred: trace2 time rolled up to trace1 categories via the semantic + # LCA alignment. Falls back to the per-framework breakdown when the + # aligned artifact is unavailable (e.g. no diff was enriched). + trace2_aligned = _load_trace2_aligned_by_category(trace1_csv_dir) + if trace2_aligned is not None: + trace2_ops_summary_by_category = trace2_aligned + print( + " trace2_ops_summary_by_category: using semantic-aligned " + "per-category totals (LCA-mapped to trace1 categories)" + ) + else: + trace2_ops_summary_by_category = trace2_ops_summary_by_category_raw + print( + " trace2_ops_summary_by_category: aligned artifact missing; " + "falling back to per-framework breakdown" + ) print(f"\nGPU Utilization Metrics:") print(f" Total Time: {gpu_utilization_metrics['total_time_ms']:.2f} ms") @@ -1524,6 +1563,9 @@ def main(): if comparison_scope == "comparative" and trace2_gpu_utilization is not None: manifest["trace2_gpu_utilization"] = trace2_gpu_utilization manifest["trace2_ops_summary_by_category"] = trace2_ops_summary_by_category + manifest["trace2_ops_summary_by_category_raw"] = ( + trace2_ops_summary_by_category_raw + ) manifest_file = f"{output_dir}/category_data/category_manifest.json" with open(manifest_file, "w") as f: diff --git a/TraceLens/Agent/Analysis/utils/templates/analysis_template.md b/TraceLens/Agent/Analysis/utils/templates/analysis_template.md index ddf364695..73d60695d 100644 --- a/TraceLens/Agent/Analysis/utils/templates/analysis_template.md +++ b/TraceLens/Agent/Analysis/utils/templates/analysis_template.md @@ -90,8 +90,10 @@ section that has STANDALONE / COMPARATIVE variants. Delete the unused variant. [1 paragraph comparative overview: summarize which trace is faster overall, by how much, and the dominant gap categories] - | Metric | Trace 1 - () | Trace 2 - () | Difference | |--------|----------------------------|-------------------------------|------------| @@ -142,8 +144,9 @@ One row per entry in `priority_data.json::priorities[]`, in array order (no mani -`Trace 2 Time (ms)` = matching `manifest.trace2_ops_summary_by_category[]["total_direct_kernel_time_ms"]` where `"op category"` matches the row Category **case-insensitively**; use — if no match. +`Trace 2 Time (ms)` = matching `manifest.trace2_ops_summary_by_category[]["total_direct_kernel_time_ms"]` where `"op category"` matches the row Category **case-insensitively**; use — if no match. This field is the semantic-aligned trace2 total (trace2 kernel time rolled up to trace1 categories via the LCA alignment), so it is consistent with the Detailed Analysis cards' per-op Trace 2 times. (`manifest.trace2_ops_summary_by_category_raw` holds the legacy per-framework breakdown for reference only — do NOT use it here.) `Difference (ms)` = Trace 2 Time − Trace 1 Time. +Note: `% of Compute Time` is Trace 1 kernel time / Trace 1 compute-only time; for communication categories (e.g. collectives) this can exceed 100% because the kernel time is not compute-bound — report the value as computed. | Rank | Category | Trace 1 Time (ms) | Trace 2 Time (ms) | % of Compute Time | Ops | Difference (ms) | |------|----------|-------------------|-------------------|-------------------|-----|-----------------| diff --git a/TraceLens/Reporting/generate_perf_report_pytorch.py b/TraceLens/Reporting/generate_perf_report_pytorch.py index 7cb83fb54..d7147444d 100644 --- a/TraceLens/Reporting/generate_perf_report_pytorch.py +++ b/TraceLens/Reporting/generate_perf_report_pytorch.py @@ -703,6 +703,20 @@ def generate_perf_report_pytorch( ) dict_name2df["diff_stats"] = _tracediff_diff_stats + from TraceLens.Reporting.tracediff_comparison_extension import ( + aligned_trace2_summary_by_category, + ) + + _aligned_t2 = aligned_trace2_summary_by_category( + _tracediff_diff_stats, + df_unified_perf, + df_unified_perf_summary, + ) + if _aligned_t2: + dict_name2df["trace2_aligned_by_category"] = pd.DataFrame( + _aligned_t2 + ) + if include_overlap_info: df_unified_perf_summary_overlapping_kernels = ( perf_analyzer.summarize_df_unified_perf_table( diff --git a/TraceLens/Reporting/generate_perf_report_pytorch_inference.py b/TraceLens/Reporting/generate_perf_report_pytorch_inference.py index 058836cc5..aef915191 100644 --- a/TraceLens/Reporting/generate_perf_report_pytorch_inference.py +++ b/TraceLens/Reporting/generate_perf_report_pytorch_inference.py @@ -989,6 +989,20 @@ def generate_perf_report_pytorch( ) dict_name2df["diff_stats"] = _tracediff_diff_stats + from TraceLens.Reporting.tracediff_comparison_extension import ( + aligned_trace2_summary_by_category, + ) + + _aligned_t2 = aligned_trace2_summary_by_category( + _tracediff_diff_stats, + df_unified_perf, + df_unified_perf_summary, + ) + if _aligned_t2: + dict_name2df["trace2_aligned_by_category"] = pd.DataFrame( + _aligned_t2 + ) + if include_overlap_info: df_unified_perf_summary_overlapping_kernels = ( perf_analyzer.summarize_df_unified_perf_table( diff --git a/TraceLens/Reporting/tracediff_comparison_extension.py b/TraceLens/Reporting/tracediff_comparison_extension.py index d51c128cc..2ead81b70 100644 --- a/TraceLens/Reporting/tracediff_comparison_extension.py +++ b/TraceLens/Reporting/tracediff_comparison_extension.py @@ -22,6 +22,7 @@ from __future__ import annotations +from collections import defaultdict from typing import Any, Dict, List, Optional, Set, Tuple import numpy as np @@ -237,12 +238,22 @@ def _build_lca_metadata( return out lca_trace2_time = trace2.groupby("lowest_common_ancestor_id")["busy_time"].first() + # Number of trace2 kernel invocations per LCA group. lca_count_trace2 reports + # the count of the *dominant* mapped LCA (the one contributing the most trace2 + # kernel time) so it is comparable to trace1's op-invocation count -- rather + # than the number of matched LCA groups, which is meaningless as an op count + # for ops that span multiple LCAs (e.g. a custom all-reduce whose op owns both + # a MemCpy and an AllReduce LCA). + lca_trace2_count = trace2.groupby("lowest_common_ancestor_id").size() for lca_id, grp in trace1.groupby("lowest_common_ancestor_id"): t1_total = float(grp["busy_time"].iloc[0]) t2_total = float(lca_trace2_time.get(lca_id, 0.0)) has_trace2_match = bool(_trace2_gpu_op_uid_set_for_lca(trace2, lca_id)) + t2_count_this_lca = ( + int(lca_trace2_count.get(lca_id, 0)) if has_trace2_match else 0 + ) names = grp["lowest_common_ancestor_name"].dropna() lca_display_name = str(names.iloc[0]) if not names.empty else None @@ -261,7 +272,8 @@ def _build_lca_metadata( "lca_names": [lca_display_name], "lca_total_kernel_time_trace1_us": t1_total, "lca_total_kernel_time_trace2_us": t2_total, - "lca_count_trace2": 1 if has_trace2_match else 0, + "lca_count_trace2": t2_count_this_lca, + "_dominant_t2_time": t2_total, } else: existing = out[key] @@ -270,8 +282,13 @@ def _build_lca_metadata( existing["lca_names"].append(lca_display_name) existing["lca_total_kernel_time_trace1_us"] += t1_total existing["lca_total_kernel_time_trace2_us"] += t2_total - if has_trace2_match: - existing["lca_count_trace2"] += 1 + if t2_total > existing["_dominant_t2_time"]: + existing["_dominant_t2_time"] = t2_total + existing["lca_count_trace2"] = t2_count_this_lca + + # Drop the private dominant-time helper so the output schema is unchanged. + for meta in out.values(): + meta.pop("_dominant_t2_time", None) return out @@ -351,6 +368,112 @@ def _ins(name: str, series) -> None: return df +def aligned_trace2_summary_by_category( + diff_stats_df: pd.DataFrame, + df_unified_perf: pd.DataFrame, + unified_perf_summary: pd.DataFrame, + category_col: str = "op category", +) -> List[Dict[str, Any]]: + """Roll trace2 kernel time up to **trace1** categories via the LCA alignment. + + The per-trace ``ops_summary_by_category`` of trace2 is computed from + trace2's *own* categorization, which does not survive a cross-framework + comparison (e.g. a vLLM custom all-reduce attributed to a compute-kernel + category vs. an SGLang NCCL collective counted as exposed communication). + Joining the two per-trace breakdowns by category *name* therefore produces + spurious near-zero trace2 times for categories that exist on only one side. + + This helper instead attributes each diff_stats LCA group's trace2 time to a + single trace1 category -- the category that owns the largest share of that + LCA's trace1 kernel time -- so the resulting per-category totals are aligned + with the same semantic blocks the Detailed Analysis cards already use. + + Returns a list of dicts matching the ``trace2_ops_summary_by_category`` + schema (``op category``, ``Count``, ``total_direct_kernel_time_ms``, + ``Percentage (%)``, ``Cumulative Percentage (%)``), sorted by time desc. + Returns ``[]`` when alignment data is unavailable (caller should fall back). + """ + if ( + diff_stats_df is None + or diff_stats_df.empty + or df_unified_perf is None + or df_unified_perf.empty + or unified_perf_summary is None + or unified_perf_summary.empty + or category_col not in unified_perf_summary.columns + ): + return [] + + uid_to_row_idx = _build_uid_to_row_idx(df_unified_perf, unified_perf_summary) + if not uid_to_row_idx: + return [] + + row_idx_to_cat: Dict[Any, str] = { + idx: str(unified_perf_summary.at[idx, category_col]) + for idx in unified_perf_summary.index + } + + df = diff_stats_df.dropna(subset=["lowest_common_ancestor_id"]) + if df.empty: + return [] + trace1 = df[df["source"] == "trace1"] + trace2 = df[df["source"] == "trace2"] + if trace1.empty: + return [] + + lca_trace2_time = trace2.groupby("lowest_common_ancestor_id")["busy_time"].first() + lca_trace2_count = trace2.groupby("lowest_common_ancestor_id").size() + + cat_time_us: Dict[str, float] = defaultdict(float) + cat_count: Dict[str, int] = defaultdict(int) + + for lca_id, grp in trace1.groupby("lowest_common_ancestor_id"): + # Pick the dominant trace1 category for this LCA, weighting each mapped + # summary row by its diff_stats kernel_time. + cat_weight: Dict[str, float] = defaultdict(float) + for _, row in grp.iterrows(): + key = _resolve_diff_row_to_key(row, uid_to_row_idx) + if key is None: + continue + cat = row_idx_to_cat.get(key) + if cat is None: + continue + try: + kt = float(row.get("kernel_time", 0.0) or 0.0) + except (TypeError, ValueError): + kt = 0.0 + cat_weight[cat] += kt + if not cat_weight: + continue + dominant_cat = max(cat_weight.items(), key=lambda kv: kv[1])[0] + + t2_us = float(lca_trace2_time.get(lca_id, 0.0) or 0.0) + cat_time_us[dominant_cat] += t2_us + cat_count[dominant_cat] += int(lca_trace2_count.get(lca_id, 0)) + + if not cat_time_us: + return [] + + total_ms = sum(cat_time_us.values()) / 1000.0 + rows = sorted(cat_time_us.items(), key=lambda kv: kv[1], reverse=True) + summary: List[Dict[str, Any]] = [] + cumulative = 0.0 + for cat, time_us in rows: + time_ms = time_us / 1000.0 + pct = (time_ms / total_ms * 100.0) if total_ms > 0 else 0.0 + cumulative += pct + summary.append( + { + "op category": cat, + "Count": cat_count.get(cat, 0), + "total_direct_kernel_time_ms": round(time_ms, 10), + "Percentage (%)": round(pct, 10), + "Cumulative Percentage (%)": round(cumulative, 10), + } + ) + return summary + + def enrich_perf_report_dict_inplace( perf_dfs: Dict[str, pd.DataFrame], diff_stats_df: pd.DataFrame, From c3c955656efd664591ec811d0ddac1389faaebfb Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Thu, 4 Jun 2026 15:45:33 -0400 Subject: [PATCH 13/50] made regex more robust --- TraceLens/Trace2Tree/trace_capture_merge_experimental.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py index d467b304f..af43ab14a 100644 --- a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py +++ b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py @@ -32,7 +32,7 @@ re.compile( r"execute_\d+_context_\d+\(sq\d+sk\d+sqsq\d+sqsk\d+\)_generation_\d+\(sq\d+sk\d+sqsq\d+sqsk\d+\)" ), - re.compile(r"execute_context_\d+\(\d+\)_generation_\d+\(\d+\)"), + re.compile(r"execute_context_\d+\([\d_]+\)_generation_\d+\([\d_]+\)"), ) From 5d927d2bc8ef4c816cf59af894642aa2172cab92 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Wed, 24 Jun 2026 21:32:10 -0400 Subject: [PATCH 14/50] collapse single node children during WF matching --- TraceLens/TraceDiff/trace_diff.py | 268 ++++++++++++++++++++++++------ 1 file changed, 218 insertions(+), 50 deletions(-) diff --git a/TraceLens/TraceDiff/trace_diff.py b/TraceLens/TraceDiff/trace_diff.py index 62d63a8a7..d7784085f 100644 --- a/TraceLens/TraceDiff/trace_diff.py +++ b/TraceLens/TraceDiff/trace_diff.py @@ -417,34 +417,51 @@ def sort_by_ts(uids, uid2node): gpu_children2, variant_uid2node ) + def collapse_single_gpu_child(uid, uid2node, tree_obj): + """ + Descend through single-GPU-path-child wrapper nodes until reaching + a node with != 1 GPU-path child, a cpu_op, or a dead end. + Returns the uid of the deepest reachable node. + """ + current = uid + while True: + node = uid2node.get(current) + if not node or tree_obj.event_to_category(node) == "cpu_op": + break + gpu_kids = [ + c + for c in node.get("children", []) + if uid2node.get(c) and self.is_gpu_path(uid2node[c]) + ] + if len(gpu_kids) != 1: + break + current = gpu_kids[0] + return current + def check_diff_children(ops, uid1, uid2, children1, children2): """ Reduce spurious delete/insert pairs by flattening redundant wrapper nodes. - For every delete-node (baseline) and insert-node (variant) pair, considers three cases - (kernels and kernel launchers are skipped): + For every delete-node (baseline) and insert-node (variant) pair, considers + three cases (kernels and kernel launchers are skipped): 1. variant children include a node with the same name as the baseline node - -> Remove the variant node and reparent its children to the variant's parent node (uid2). + -> Remove the variant node and reparent its children to uid2. 2. baseline children include a node with the same name as the variant node - -> Remove the baseline node and reparent its children to the baseline's parent node (uid1). + -> Remove the baseline node and reparent its children to uid1. 3. Both nodes have children and the two child lists (by normalized name) are equal -> Remove both nodes and reparent their children to uid2 and uid1 respectively. Mutates the baseline and variant trees in place. If any removals were applied, recomputes children and Wagner-Fischer ops for the current node. Returns the - (possibly updated) ops list. + (possibly updated) ops, children1, children2. """ delete_indices = [i for op, i, j in ops if op == "delete"] insert_indices = [j for op, i, j in ops if op == "insert"] - remove_insert = ( - {} - ) # uid_i -> list of child uids to splice in (insert node's children) - remove_delete = ( - {} - ) # uid_d -> list of child uids to splice in (delete node's children) + remove_insert = {} # uid_i -> list of child uids to splice in + remove_delete = {} # uid_d -> list of child uids to splice in skip_cats = ("kernel", "cuda_runtime") for i in delete_indices: for j in insert_indices: @@ -553,52 +570,130 @@ def traverse_and_merge(uid1, uid2): children1, children2 = get_children_with_missing(uid1, uid2) - # Flatten transparent wrapper layers on whichever side has exactly - # one gpu-path child, until counts match or a cpu_op (real op) or - # dead end is reached. This handles call-stack depth asymmetries - # between backends (e.g. AMD adds an extra utils.py: run wrapper - # that CUDA doesn't have) without confusing them with kernel-fusion - # differences, where the single child would be a cpu_op and we stop. - while len(children1) != len(children2): - if len(children1) == 1: - node = baseline_uid2node.get(children1[0]) - if not node or tree1.event_to_category(node) == "cpu_op": - break - deeper = [ - c - for c in node.get("children", []) - if self.is_gpu_path(baseline_uid2node.get(c)) - ] - if not deeper: - break - children1 = deeper - elif len(children2) == 1: - node = variant_uid2node.get(children2[0]) - if not node or tree2.event_to_category(node) == "cpu_op": - break - deeper = [ - c - for c in node.get("children", []) - if self.is_gpu_path(variant_uid2node.get(c)) - ] - if not deeper: + def collapse_single_child_wrappers(children1, children2, + eff_uid1=None, eff_uid2=None): + """Flatten transparent wrapper layers on whichever side has + exactly one gpu-path child, until counts match or a cpu_op + (real op) or dead end is reached. This handles call-stack + depth asymmetries between backends without confusing them + with kernel-fusion differences. + + Also tracks the effective uid for each side: the last + single-child node descended through, so the caller can + use the collapsed-to node instead of the original uid.""" + while len(children1) != len(children2): + if len(children1) == 1: + node = baseline_uid2node.get(children1[0]) + if not node or tree1.event_to_category(node) == "cpu_op": + break + deeper = [ + c + for c in node.get("children", []) + if self.is_gpu_path(baseline_uid2node.get(c)) + ] + if not deeper: + break + eff_uid1 = children1[0] + children1 = deeper + elif len(children2) == 1: + node = variant_uid2node.get(children2[0]) + if not node or tree2.event_to_category(node) == "cpu_op": + break + deeper = [ + c + for c in node.get("children", []) + if self.is_gpu_path(variant_uid2node.get(c)) + ] + if not deeper: + break + eff_uid2 = children2[0] + children2 = deeper + else: break - children2 = deeper + return children1, children2, eff_uid1, eff_uid2 + + def collapse_and_align(children1, children2, + eff_uid1=None, eff_uid2=None): + """Collapse single-child wrappers, then align via + positional matching or Wagner-Fischer.""" + children1, children2, eff_uid1, eff_uid2 = ( + collapse_single_child_wrappers( + children1, children2, eff_uid1, eff_uid2 + ) + ) + any_cr = any( + subtree_contains_cuda_runtime(c, baseline_uid2node) + for c in children1 + ) or any( + subtree_contains_cuda_runtime(c, variant_uid2node) + for c in children2 + ) + if len(children1) == len(children2) and not any_cr: + ops = [("match", i, i) for i in range(len(children1))] else: - break + ops = self.wagner_fischer(children1, children2, wf_cache) + return ops, children1, children2, eff_uid1, eff_uid2 - any_cuda_runtime = any( - subtree_contains_cuda_runtime(c, baseline_uid2node) for c in children1 - ) or any( - subtree_contains_cuda_runtime(c, variant_uid2node) for c in children2 + ops, children1, children2, eff_uid1, eff_uid2 = ( + collapse_and_align(children1, children2) ) - if len(children1) == len(children2) and not any_cuda_runtime: - ops = [("match", i, i) for i in range(len(children1))] - else: - ops = self.wagner_fischer(children1, children2, wf_cache) + + # check_diff_children may mutate the tree and re-read children + # from the original UIDs, which can undo the collapsing above. + # If it made changes, re-collapse and re-align. + if any(op != "match" for op, _, _ in ops): ops, children1, children2 = check_diff_children( ops, uid1, uid2, children1, children2 ) + ops, children1, children2, eff_uid1, eff_uid2 = ( + collapse_and_align( + children1, children2, eff_uid1, eff_uid2 + ) + ) + + # If collapsing descended through single-child wrappers, + # update uid1/uid2 to the collapsed-to node so the merged + # event (and LCA name) reflects the actual comparison point. + if eff_uid1 is not None: + uid1 = eff_uid1 + node1 = baseline_uid2node.get(uid1) + if eff_uid2 is not None: + uid2 = eff_uid2 + node2 = variant_uid2node.get(uid2) + + # For any remaining unaligned ops, collapse each unmatched node + # down through single-GPU-path-child wrappers to the first + # descendant with >1 GPU-path children, then re-run Wagner-Fischer + # on those collapsed nodes to find additional matches. + unmatched_idx1 = [i for op, i, j in ops if op == "delete"] + unmatched_idx2 = [j for op, i, j in ops if op == "insert"] + if unmatched_idx1 and unmatched_idx2: + collapsed1 = [ + collapse_single_gpu_child(children1[i], baseline_uid2node, tree1) + for i in unmatched_idx1 + ] + collapsed2 = [ + collapse_single_gpu_child(children2[j], variant_uid2node, tree2) + for j in unmatched_idx2 + ] + collapsed_ops = self.wagner_fischer(collapsed1, collapsed2, wf_cache) + new_ops = [(op, i, j) for op, i, j in ops if op == "match"] + for cop, ci, cj in collapsed_ops: + if cop == "match": + orig_i = unmatched_idx1[ci] + orig_j = unmatched_idx2[cj] + children1[orig_i] = collapsed1[ci] + children2[orig_j] = collapsed2[cj] + new_ops.append(("match", orig_i, orig_j)) + elif cop == "delete": + orig_i = unmatched_idx1[ci] + children1[orig_i] = collapsed1[ci] + new_ops.append(("delete", orig_i, None)) + elif cop == "insert": + orig_j = unmatched_idx2[cj] + children2[orig_j] = collapsed2[cj] + new_ops.append(("insert", None, orig_j)) + ops = new_ops child_merged_ids = [] for op, i, j in ops: @@ -987,6 +1082,35 @@ def get_kernel_info_subtree(root_uid, tree_uid2node): kernel_time = GPUEventAnalyser(gpu_events).compute_metrics()["busy_time"] return kernel_names, kernel_time + def get_callstack(gpu_event, uid2node): + """Walk from gpu_event up to root, collecting op names root-first.""" + stack = [] + uid = gpu_event.get("parent") + while uid is not None: + n = uid2node.get(uid) + if n is None: + break + name = n.get("name", "") + if name: + stack.append(name) + uid = n.get("parent") + stack.reverse() + return ", ".join(stack) + + def get_gpu_path_child_names(uid, uid2node, tree_num): + """Return semicolon-joined names of GPU-path children of the given node.""" + if uid is None: + return "" + node = uid2node.get(uid) + if node is None: + return "" + names = [] + for cuid in node.get("children", []): + cn = uid2node.get(cuid) + if cn and self.is_gpu_path(cn): + names.append(self._get_op_name(cuid, tree_num) or "") + return "; ".join(names) + rows = [] visited_stats_nodes = set() @@ -1072,12 +1196,21 @@ def _compute_lca_busy_time(gpu_event_uids, uid2node): gpu_event_uids2, variant_uid2node ) + lca_children_t1 = get_gpu_path_child_names( + node["uid1"], baseline_uid2node, 1 + ) + lca_children_t2 = get_gpu_path_child_names( + node["uid2"], variant_uid2node, 2 + ) + def add_rows( gpu_event_uids, tree_obj, uid2node, source, lca_busy_time, + lca_children_t1, + lca_children_t2, ): tree_num = 1 if source == "trace1" else 2 for gpu_uid in gpu_event_uids: @@ -1116,6 +1249,8 @@ def add_rows( "busy_time": lca_busy_time, "lowest_common_ancestor_name": lca_name, "lowest_common_ancestor_id": node["merged_id"], + "lca_children_t1": lca_children_t1, + "lca_children_t2": lca_children_t2, "gpu_op_uid": gpu_uid, "nn_module_stack": ";".join( str(x) @@ -1126,6 +1261,9 @@ def add_rows( "nn_module_parent": ( parent_node.get("nn_module_stack") or [""] )[-1], + "cpu_op_callstack": get_callstack( + gpu_event, uid2node + ), } ) @@ -1135,6 +1273,8 @@ def add_rows( baseline_uid2node, "trace1", busy_time1, + lca_children_t1, + lca_children_t2, ) add_rows( @@ -1143,6 +1283,8 @@ def add_rows( variant_uid2node, "trace2", busy_time2, + lca_children_t1, + lca_children_t2, ) visited_stats_nodes.add(merged_id) @@ -1163,9 +1305,17 @@ def add_rows( lca = merged_id_to_event[lca_id] lca_name = self._get_op_name(lca["uid1"], 1) lca_name = re.sub(r"\(\d+\)", "", lca_name) + lca_children_t1 = get_gpu_path_child_names( + lca["uid1"], baseline_uid2node, 1 + ) + lca_children_t2 = get_gpu_path_child_names( + lca["uid2"], variant_uid2node, 2 + ) else: lca_name = None # Root node has no LCA lca_id = None + lca_children_t1 = "" + lca_children_t2 = "" # Get all GPU kernels from trace1's branch gpu_event_uids = event1.get("gpu_events", []) @@ -1214,6 +1364,8 @@ def add_rows( "busy_time": lca_busy, "lowest_common_ancestor_name": lca_name, "lowest_common_ancestor_id": lca_id, + "lca_children_t1": lca_children_t1, + "lca_children_t2": lca_children_t2, "gpu_op_uid": gpu_uid, "nn_module_stack": ";".join( str(x) @@ -1222,6 +1374,9 @@ def add_rows( "nn_module_parent": ( parent_node.get("nn_module_stack") or [""] )[-1], + "cpu_op_callstack": get_callstack( + gpu_event, baseline_uid2node + ), } ) @@ -1236,9 +1391,17 @@ def add_rows( lca = merged_id_to_event[lca_id] lca_name = self._get_op_name(lca["uid2"], 2) lca_name = re.sub(r"\(\d+\)", "", lca_name) + lca_children_t1 = get_gpu_path_child_names( + lca["uid1"], baseline_uid2node, 1 + ) + lca_children_t2 = get_gpu_path_child_names( + lca["uid2"], variant_uid2node, 2 + ) else: lca_name = None # Root node has no LCA lca_id = None + lca_children_t1 = "" + lca_children_t2 = "" # Get all GPU kernels from trace2's branch gpu_event_uids = event2.get("gpu_events", []) @@ -1287,6 +1450,8 @@ def add_rows( "busy_time": lca_busy, "lowest_common_ancestor_name": lca_name, "lowest_common_ancestor_id": lca_id, + "lca_children_t1": lca_children_t1, + "lca_children_t2": lca_children_t2, "gpu_op_uid": gpu_uid, "nn_module_stack": ";".join( str(x) @@ -1295,6 +1460,9 @@ def add_rows( "nn_module_parent": ( parent_node.get("nn_module_stack") or [""] )[-1], + "cpu_op_callstack": get_callstack( + gpu_event, variant_uid2node + ), } ) From a2559afeffe7ff38a0d8b277764fe7c52de54bc1 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Thu, 25 Jun 2026 03:52:44 -0400 Subject: [PATCH 15/50] stop collapsing when kernel launcher is encountered --- TraceLens/TraceDiff/trace_diff.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TraceLens/TraceDiff/trace_diff.py b/TraceLens/TraceDiff/trace_diff.py index d7784085f..4187411c1 100644 --- a/TraceLens/TraceDiff/trace_diff.py +++ b/TraceLens/TraceDiff/trace_diff.py @@ -426,7 +426,7 @@ def collapse_single_gpu_child(uid, uid2node, tree_obj): current = uid while True: node = uid2node.get(current) - if not node or tree_obj.event_to_category(node) == "cpu_op": + if not node or tree_obj.event_to_category(node) in ("cpu_op", "cuda_runtime"): break gpu_kids = [ c From 8d7dd6933cee28661cf6db440c227c5958b32936 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Thu, 25 Jun 2026 16:32:42 -0400 Subject: [PATCH 16/50] remove timestamp shifting logic --- .../trace_capture_merge_experimental.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py index af43ab14a..7742514e1 100644 --- a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py +++ b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py @@ -188,19 +188,15 @@ def update_subtree_uids_and_timestamps( print( "Warning: parent UID {} not found in mapping".format(parent_uid) ) - # Update timestamps: scale capture time into the graph replay window. - # The capture ran for capture_dur; the graph replay runs for g_root_dur. - # We shift each event's ts by (new_start_ts - original_start_ts) and - # scale both the offset and dur by (g_root_dur / capture_dur) so that - # the entire capture subtree fits proportionally within the replay window. + # Update timestamps original_start_ts = subtree_events[0]["ts"] - capture_dur = subtree_events[0].get("dur", g_root_dur) or g_root_dur - scale = g_root_dur / capture_dur if capture_dur > 0 else 1.0 + ts_offset = new_start_ts - original_start_ts + # for event in subtree_filtered_events: + # event[UID]=uid_mapping[event[UID]] for event in subtree_events: - relative_ts = event["ts"] - original_start_ts - event["ts"] = new_start_ts + relative_ts * scale - if "dur" in event: - event["dur"] = event["dur"] * scale + event["ts"] += ts_offset + event["ts"] = new_start_ts + event["dur"] = g_root_dur for i in capture_tree.cpu_root_nodes: if i in uid_mapping: cpu_root_nodes.append(uid_mapping[i]) From 565642f9674b46c626a46e63f3eb78f9bb5791c0 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Thu, 25 Jun 2026 16:40:40 -0400 Subject: [PATCH 17/50] formatting --- .../trace_capture_merge_experimental.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py index 7742514e1..632bf1454 100644 --- a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py +++ b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py @@ -319,13 +319,12 @@ def _get_cached_capture_tree(key, filepath, TreePerfAnalyzer): tuples — one per capture root — pre-computed from :func:`get_subtree_events`. """ - cache_key = (key, os.path.abspath(filepath)) - if cache_key in _capture_tree_cache: - _capture_tree_cache.move_to_end(cache_key) - print("Cache hit for capture tree (key={})".format(key)) - return _capture_tree_cache[cache_key] + if key in _capture_tree_cache: + _capture_tree_cache.move_to_end(key) + print("Cache hit for capture tree (key={})".format(key[0])) + return _capture_tree_cache[key] - print("Loading capture trace: {} (key={})".format(filepath, key)) + print("Loading capture trace: {} (key={})".format(filepath, key[0])) capture_perf_analyzer = TreePerfAnalyzer.from_file(filepath, add_python_func=True) capture_tree = capture_perf_analyzer.tree capture_roots = find_capture_roots(capture_tree) @@ -341,10 +340,10 @@ def _get_cached_capture_tree(key, filepath, TreePerfAnalyzer): filtered_uids = {e[UID] for e in capture_filtered_events} capture_root_data.append((capture_events, filtered_uids)) - _capture_tree_cache[cache_key] = (capture_tree, capture_roots, capture_root_data) + _capture_tree_cache[key] = (capture_tree, capture_roots, capture_root_data) if len(_capture_tree_cache) > _CAPTURE_TREE_CACHE_MAX_SIZE: - evicted_cache_key, _ = _capture_tree_cache.popitem(last=False) - print("Evicted capture tree cache entry (key={})".format(evicted_cache_key[0])) + evicted_key, _ = _capture_tree_cache.popitem(last=False) + print("Evicted capture tree cache entry (key={})".format(evicted_key[0])) return capture_tree, capture_roots, capture_root_data @@ -580,8 +579,9 @@ def merge_capture_trace_into_graph( mode = "PIECEWISE" else: mode = "FULL" - key = "{}_{}".format(closest_batch_size, mode) - filepath = capture_map[key] + str_key = "{}_{}".format(closest_batch_size, mode) + filepath = capture_map[str_key] + key = (str_key, os.path.abspath(filepath)) capture_tree, capture_roots, capture_root_data = _get_cached_capture_tree( key, filepath, TreePerfAnalyzer ) From b025e56641c51af0fad86365e442d9e6bb5ba466 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Thu, 25 Jun 2026 17:01:46 -0400 Subject: [PATCH 18/50] moving things around --- .../trace_capture_merge_experimental.py | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py index 632bf1454..216c49167 100644 --- a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py +++ b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py @@ -58,6 +58,10 @@ def get_subtree_events(tree, event, cat_filter=None, name_filter=None): return list_events, list_filtered_events +def _capture_kernel_name(event): + return event.get("args", {}).get("kernel", event["name"]) + + def _align_capture_to_graph(capture_events, graph_events): """ Greedily align capture dispatch events to graph kernel events by name. @@ -69,9 +73,6 @@ def _align_capture_to_graph(capture_events, graph_events): graph_events), or None if any graph kernel cannot be matched. """ - def capture_kernel_name(event): - return event.get("args", {}).get("kernel", event["name"]) - aligned = [] ci = 0 for g_event in graph_events: @@ -80,9 +81,10 @@ def capture_kernel_name(event): while ci < len(capture_events): c_event = capture_events[ci] ci += 1 - c_name = capture_kernel_name(c_event) - # Memcpy/Memset events carry no kernel arg — match by position - if "Memcpy" in c_event["name"] or "Memset" in c_event["name"]: + c_name = _capture_kernel_name(c_event) + # Memcpy/Memset events carry no kernel arg — match when both sides agree + if ("Memcpy" in c_event["name"] and "Memcpy" in g_name) or \ + ("Memset" in c_event["name"] and "Memset" in g_name): aligned.append(c_event) matched = True break @@ -107,9 +109,6 @@ def verify_subtree_events(capture_events, graph_events): (success, aligned_capture_events) where success is 1 on full match, 2 on successful greedy alignment (with discards), and 0 on failure. """ - def capture_kernel_name(event): - return event.get("args", {}).get("kernel", event["name"]) - if len(capture_events) != len(graph_events): print( "Mismatch in number of events: Capture {}, Graph {}".format( @@ -139,10 +138,10 @@ def capture_kernel_name(event): stacklevel=2, ) continue - if i["name"] != j.get("args", {}).get("kernel", j["name"]): + if i["name"] != _capture_kernel_name(j): print( "Mismatch in kernel name: {} vs {}".format( - i["name"], j.get("args", {}).get("kernel", j["name"]) + i["name"], _capture_kernel_name(j) ) ) return 0, capture_events From f116da23d045eaa0771304c89df9d8e7006cb470 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Fri, 26 Jun 2026 01:01:19 -0400 Subject: [PATCH 19/50] formatting --- .../generate_perf_report_pytorch_inference.py | 4 +- .../trace_capture_merge_experimental.py | 5 +- TraceLens/TraceDiff/trace_diff.py | 252 ++---------------- 3 files changed, 24 insertions(+), 237 deletions(-) diff --git a/TraceLens/Reporting/generate_perf_report_pytorch_inference.py b/TraceLens/Reporting/generate_perf_report_pytorch_inference.py index 41dc3bf39..9f87ace7f 100644 --- a/TraceLens/Reporting/generate_perf_report_pytorch_inference.py +++ b/TraceLens/Reporting/generate_perf_report_pytorch_inference.py @@ -1369,9 +1369,7 @@ def main(): args = parser.parse_args() if args.comparison_capture_folder and not args.comparison_json_path: - parser.error( - "--comparison_capture_folder requires --comparison_json_path." - ) + parser.error("--comparison_capture_folder requires --comparison_json_path.") if args.capture_folder: classify_graph_capture_trace(args.capture_folder) metadata_json_path = os.path.join(args.capture_folder, "execution_details.json") diff --git a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py index 216c49167..572d7190f 100644 --- a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py +++ b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py @@ -83,8 +83,9 @@ def _align_capture_to_graph(capture_events, graph_events): ci += 1 c_name = _capture_kernel_name(c_event) # Memcpy/Memset events carry no kernel arg — match when both sides agree - if ("Memcpy" in c_event["name"] and "Memcpy" in g_name) or \ - ("Memset" in c_event["name"] and "Memset" in g_name): + if ("Memcpy" in c_event["name"] and "Memcpy" in g_name) or ( + "Memset" in c_event["name"] and "Memset" in g_name + ): aligned.append(c_event) matched = True break diff --git a/TraceLens/TraceDiff/trace_diff.py b/TraceLens/TraceDiff/trace_diff.py index 4187411c1..103932c33 100644 --- a/TraceLens/TraceDiff/trace_diff.py +++ b/TraceLens/TraceDiff/trace_diff.py @@ -348,20 +348,11 @@ def safe_children(uid2node, uid): return [] return node.get("children", []) - _GRAPH_LAUNCH_NAMES = {"hipGraphLaunch", "cudaGraphLaunch"} - def subtree_contains_cuda_runtime(uid, uid2node): - """Return True if this node is a cuda_runtime node. - - Graph launch events (hipGraphLaunch, cudaGraphLaunch) are exempt: - they are platform-specific names for the same operation and should - be matched by position rather than forced through Wagner-Fischer. - """ + """Return True if this node is a cuda_runtime node.""" node = uid2node.get(uid) if not node or not isinstance(node, dict): return False - if node.get("name") in _GRAPH_LAUNCH_NAMES: - return False cat = node.get("cat") or node.get("category") if cat == "cuda_runtime" or cat == "cuda_driver": return True @@ -417,51 +408,34 @@ def sort_by_ts(uids, uid2node): gpu_children2, variant_uid2node ) - def collapse_single_gpu_child(uid, uid2node, tree_obj): - """ - Descend through single-GPU-path-child wrapper nodes until reaching - a node with != 1 GPU-path child, a cpu_op, or a dead end. - Returns the uid of the deepest reachable node. - """ - current = uid - while True: - node = uid2node.get(current) - if not node or tree_obj.event_to_category(node) in ("cpu_op", "cuda_runtime"): - break - gpu_kids = [ - c - for c in node.get("children", []) - if uid2node.get(c) and self.is_gpu_path(uid2node[c]) - ] - if len(gpu_kids) != 1: - break - current = gpu_kids[0] - return current - def check_diff_children(ops, uid1, uid2, children1, children2): """ Reduce spurious delete/insert pairs by flattening redundant wrapper nodes. - For every delete-node (baseline) and insert-node (variant) pair, considers - three cases (kernels and kernel launchers are skipped): + For every delete-node (baseline) and insert-node (variant) pair, considers three cases + (kernels and kernel launchers are skipped): 1. variant children include a node with the same name as the baseline node - -> Remove the variant node and reparent its children to uid2. + -> Remove the variant node and reparent its children to the variant's parent node (uid2). 2. baseline children include a node with the same name as the variant node - -> Remove the baseline node and reparent its children to uid1. + -> Remove the baseline node and reparent its children to the baseline's parent node (uid1). 3. Both nodes have children and the two child lists (by normalized name) are equal -> Remove both nodes and reparent their children to uid2 and uid1 respectively. Mutates the baseline and variant trees in place. If any removals were applied, recomputes children and Wagner-Fischer ops for the current node. Returns the - (possibly updated) ops, children1, children2. + (possibly updated) ops list. """ delete_indices = [i for op, i, j in ops if op == "delete"] insert_indices = [j for op, i, j in ops if op == "insert"] - remove_insert = {} # uid_i -> list of child uids to splice in - remove_delete = {} # uid_d -> list of child uids to splice in + remove_insert = ( + {} + ) # uid_i -> list of child uids to splice in (insert node's children) + remove_delete = ( + {} + ) # uid_d -> list of child uids to splice in (delete node's children) skip_cats = ("kernel", "cuda_runtime") for i in delete_indices: for j in insert_indices: @@ -569,131 +543,18 @@ def traverse_and_merge(uid1, uid2): nn_module_stack = node2.get("nn_module_stack", "") children1, children2 = get_children_with_missing(uid1, uid2) - - def collapse_single_child_wrappers(children1, children2, - eff_uid1=None, eff_uid2=None): - """Flatten transparent wrapper layers on whichever side has - exactly one gpu-path child, until counts match or a cpu_op - (real op) or dead end is reached. This handles call-stack - depth asymmetries between backends without confusing them - with kernel-fusion differences. - - Also tracks the effective uid for each side: the last - single-child node descended through, so the caller can - use the collapsed-to node instead of the original uid.""" - while len(children1) != len(children2): - if len(children1) == 1: - node = baseline_uid2node.get(children1[0]) - if not node or tree1.event_to_category(node) == "cpu_op": - break - deeper = [ - c - for c in node.get("children", []) - if self.is_gpu_path(baseline_uid2node.get(c)) - ] - if not deeper: - break - eff_uid1 = children1[0] - children1 = deeper - elif len(children2) == 1: - node = variant_uid2node.get(children2[0]) - if not node or tree2.event_to_category(node) == "cpu_op": - break - deeper = [ - c - for c in node.get("children", []) - if self.is_gpu_path(variant_uid2node.get(c)) - ] - if not deeper: - break - eff_uid2 = children2[0] - children2 = deeper - else: - break - return children1, children2, eff_uid1, eff_uid2 - - def collapse_and_align(children1, children2, - eff_uid1=None, eff_uid2=None): - """Collapse single-child wrappers, then align via - positional matching or Wagner-Fischer.""" - children1, children2, eff_uid1, eff_uid2 = ( - collapse_single_child_wrappers( - children1, children2, eff_uid1, eff_uid2 - ) - ) - any_cr = any( - subtree_contains_cuda_runtime(c, baseline_uid2node) - for c in children1 - ) or any( - subtree_contains_cuda_runtime(c, variant_uid2node) - for c in children2 - ) - if len(children1) == len(children2) and not any_cr: - ops = [("match", i, i) for i in range(len(children1))] - else: - ops = self.wagner_fischer(children1, children2, wf_cache) - return ops, children1, children2, eff_uid1, eff_uid2 - - ops, children1, children2, eff_uid1, eff_uid2 = ( - collapse_and_align(children1, children2) + any_cuda_runtime = any( + subtree_contains_cuda_runtime(c, baseline_uid2node) for c in children1 + ) or any( + subtree_contains_cuda_runtime(c, variant_uid2node) for c in children2 ) - - # check_diff_children may mutate the tree and re-read children - # from the original UIDs, which can undo the collapsing above. - # If it made changes, re-collapse and re-align. - if any(op != "match" for op, _, _ in ops): + if len(children1) == len(children2) and not any_cuda_runtime: + ops = [("match", i, i) for i in range(len(children1))] + else: + ops = self.wagner_fischer(children1, children2, wf_cache) ops, children1, children2 = check_diff_children( ops, uid1, uid2, children1, children2 ) - ops, children1, children2, eff_uid1, eff_uid2 = ( - collapse_and_align( - children1, children2, eff_uid1, eff_uid2 - ) - ) - - # If collapsing descended through single-child wrappers, - # update uid1/uid2 to the collapsed-to node so the merged - # event (and LCA name) reflects the actual comparison point. - if eff_uid1 is not None: - uid1 = eff_uid1 - node1 = baseline_uid2node.get(uid1) - if eff_uid2 is not None: - uid2 = eff_uid2 - node2 = variant_uid2node.get(uid2) - - # For any remaining unaligned ops, collapse each unmatched node - # down through single-GPU-path-child wrappers to the first - # descendant with >1 GPU-path children, then re-run Wagner-Fischer - # on those collapsed nodes to find additional matches. - unmatched_idx1 = [i for op, i, j in ops if op == "delete"] - unmatched_idx2 = [j for op, i, j in ops if op == "insert"] - if unmatched_idx1 and unmatched_idx2: - collapsed1 = [ - collapse_single_gpu_child(children1[i], baseline_uid2node, tree1) - for i in unmatched_idx1 - ] - collapsed2 = [ - collapse_single_gpu_child(children2[j], variant_uid2node, tree2) - for j in unmatched_idx2 - ] - collapsed_ops = self.wagner_fischer(collapsed1, collapsed2, wf_cache) - new_ops = [(op, i, j) for op, i, j in ops if op == "match"] - for cop, ci, cj in collapsed_ops: - if cop == "match": - orig_i = unmatched_idx1[ci] - orig_j = unmatched_idx2[cj] - children1[orig_i] = collapsed1[ci] - children2[orig_j] = collapsed2[cj] - new_ops.append(("match", orig_i, orig_j)) - elif cop == "delete": - orig_i = unmatched_idx1[ci] - children1[orig_i] = collapsed1[ci] - new_ops.append(("delete", orig_i, None)) - elif cop == "insert": - orig_j = unmatched_idx2[cj] - children2[orig_j] = collapsed2[cj] - new_ops.append(("insert", None, orig_j)) - ops = new_ops child_merged_ids = [] for op, i, j in ops: @@ -1082,35 +943,6 @@ def get_kernel_info_subtree(root_uid, tree_uid2node): kernel_time = GPUEventAnalyser(gpu_events).compute_metrics()["busy_time"] return kernel_names, kernel_time - def get_callstack(gpu_event, uid2node): - """Walk from gpu_event up to root, collecting op names root-first.""" - stack = [] - uid = gpu_event.get("parent") - while uid is not None: - n = uid2node.get(uid) - if n is None: - break - name = n.get("name", "") - if name: - stack.append(name) - uid = n.get("parent") - stack.reverse() - return ", ".join(stack) - - def get_gpu_path_child_names(uid, uid2node, tree_num): - """Return semicolon-joined names of GPU-path children of the given node.""" - if uid is None: - return "" - node = uid2node.get(uid) - if node is None: - return "" - names = [] - for cuid in node.get("children", []): - cn = uid2node.get(cuid) - if cn and self.is_gpu_path(cn): - names.append(self._get_op_name(cuid, tree_num) or "") - return "; ".join(names) - rows = [] visited_stats_nodes = set() @@ -1196,21 +1028,12 @@ def _compute_lca_busy_time(gpu_event_uids, uid2node): gpu_event_uids2, variant_uid2node ) - lca_children_t1 = get_gpu_path_child_names( - node["uid1"], baseline_uid2node, 1 - ) - lca_children_t2 = get_gpu_path_child_names( - node["uid2"], variant_uid2node, 2 - ) - def add_rows( gpu_event_uids, tree_obj, uid2node, source, lca_busy_time, - lca_children_t1, - lca_children_t2, ): tree_num = 1 if source == "trace1" else 2 for gpu_uid in gpu_event_uids: @@ -1249,8 +1072,6 @@ def add_rows( "busy_time": lca_busy_time, "lowest_common_ancestor_name": lca_name, "lowest_common_ancestor_id": node["merged_id"], - "lca_children_t1": lca_children_t1, - "lca_children_t2": lca_children_t2, "gpu_op_uid": gpu_uid, "nn_module_stack": ";".join( str(x) @@ -1261,9 +1082,6 @@ def add_rows( "nn_module_parent": ( parent_node.get("nn_module_stack") or [""] )[-1], - "cpu_op_callstack": get_callstack( - gpu_event, uid2node - ), } ) @@ -1273,8 +1091,6 @@ def add_rows( baseline_uid2node, "trace1", busy_time1, - lca_children_t1, - lca_children_t2, ) add_rows( @@ -1283,8 +1099,6 @@ def add_rows( variant_uid2node, "trace2", busy_time2, - lca_children_t1, - lca_children_t2, ) visited_stats_nodes.add(merged_id) @@ -1305,17 +1119,9 @@ def add_rows( lca = merged_id_to_event[lca_id] lca_name = self._get_op_name(lca["uid1"], 1) lca_name = re.sub(r"\(\d+\)", "", lca_name) - lca_children_t1 = get_gpu_path_child_names( - lca["uid1"], baseline_uid2node, 1 - ) - lca_children_t2 = get_gpu_path_child_names( - lca["uid2"], variant_uid2node, 2 - ) else: lca_name = None # Root node has no LCA lca_id = None - lca_children_t1 = "" - lca_children_t2 = "" # Get all GPU kernels from trace1's branch gpu_event_uids = event1.get("gpu_events", []) @@ -1364,8 +1170,6 @@ def add_rows( "busy_time": lca_busy, "lowest_common_ancestor_name": lca_name, "lowest_common_ancestor_id": lca_id, - "lca_children_t1": lca_children_t1, - "lca_children_t2": lca_children_t2, "gpu_op_uid": gpu_uid, "nn_module_stack": ";".join( str(x) @@ -1374,9 +1178,6 @@ def add_rows( "nn_module_parent": ( parent_node.get("nn_module_stack") or [""] )[-1], - "cpu_op_callstack": get_callstack( - gpu_event, baseline_uid2node - ), } ) @@ -1391,17 +1192,9 @@ def add_rows( lca = merged_id_to_event[lca_id] lca_name = self._get_op_name(lca["uid2"], 2) lca_name = re.sub(r"\(\d+\)", "", lca_name) - lca_children_t1 = get_gpu_path_child_names( - lca["uid1"], baseline_uid2node, 1 - ) - lca_children_t2 = get_gpu_path_child_names( - lca["uid2"], variant_uid2node, 2 - ) else: lca_name = None # Root node has no LCA lca_id = None - lca_children_t1 = "" - lca_children_t2 = "" # Get all GPU kernels from trace2's branch gpu_event_uids = event2.get("gpu_events", []) @@ -1450,8 +1243,6 @@ def add_rows( "busy_time": lca_busy, "lowest_common_ancestor_name": lca_name, "lowest_common_ancestor_id": lca_id, - "lca_children_t1": lca_children_t1, - "lca_children_t2": lca_children_t2, "gpu_op_uid": gpu_uid, "nn_module_stack": ";".join( str(x) @@ -1460,9 +1251,6 @@ def add_rows( "nn_module_parent": ( parent_node.get("nn_module_stack") or [""] )[-1], - "cpu_op_callstack": get_callstack( - gpu_event, variant_uid2node - ), } ) From fb57556a40edf5936db8e66717191dfcc1dbcdbb Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Fri, 26 Jun 2026 01:26:19 -0400 Subject: [PATCH 20/50] print warning if graph root has no kernels --- TraceLens/Trace2Tree/trace_capture_merge_experimental.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py index 572d7190f..e6dcb890c 100644 --- a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py +++ b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py @@ -608,6 +608,14 @@ def merge_capture_trace_into_graph( graph_tree, g_root, cat_filter=["kernel", "gpu_memset", "gpu_memcpy"] ) + if len(graph_filtered_events) == 0: + print( + "Warning: no kernel events in graph root {}; skipping merge".format( + g_root["name"] + ) + ) + continue + verify_success, capture_filtered_events = verify_subtree_events( capture_filtered_events, graph_filtered_events ) From b29c6fd3be249f0439e2d6ce45b8b88d549119ea Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Tue, 30 Jun 2026 18:48:42 -0400 Subject: [PATCH 21/50] positional + name matching iif name matching alone fails --- .../trace_capture_merge_experimental.py | 67 ++- TraceLens/TraceDiff/trace_diff.py | 390 ++++++++++++++---- 2 files changed, 368 insertions(+), 89 deletions(-) diff --git a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py index e6dcb890c..57ebd5f8d 100644 --- a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py +++ b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py @@ -17,7 +17,7 @@ import sys import time -from collections import OrderedDict +from collections import OrderedDict, defaultdict from typing import Any, Dict, List, Optional, Tuple import json import os @@ -98,17 +98,62 @@ def _align_capture_to_graph(capture_events, graph_events): return aligned +def _align_capture_to_graph_by_group(capture_events, graph_events): + """ + Align capture dispatch events to graph kernel events by grouping on kernel + name and matching positionally within each group. + Returns the capture events reordered to match graph_events order, or None + if any kernel name has a count mismatch between capture and graph. + """ + + capture_groups = defaultdict(list) + for e in capture_events: + capture_groups[_capture_kernel_name(e)].append(e) + + graph_groups = defaultdict(list) + for e in graph_events: + graph_groups[e["name"]].append(e) + + # Verify per-name counts match + all_names = set(capture_groups) | set(graph_groups) + for name in all_names: + if len(capture_groups[name]) != len(graph_groups[name]): + print( + "Group alignment: count mismatch for kernel '{}': " + "capture={} graph={}".format( + name, len(capture_groups[name]), len(graph_groups[name]) + ) + ) + return None + + # Reassemble capture events in graph order using per-group position + group_idx = defaultdict(int) + aligned = [] + for g_event in graph_events: + name = g_event["name"] + idx = group_idx[name] + aligned.append(capture_groups[name][idx]) + group_idx[name] += 1 + + return aligned + + def verify_subtree_events(capture_events, graph_events): """ Verify that capture dispatch events align 1-to-1 with graph kernel events. - If counts match, check names directly. If counts differ, attempt greedy - alignment via _align_capture_to_graph: extra capture dispatches are - discarded and the aligned list is returned so the caller can proceed. + Alignment is attempted in three stages: + 1. Direct positional match — succeeds when both sequences are already + in the same order (return code 1). + 2. Greedy forward-scan by name — handles count mismatches by discarding + extra capture dispatches (return code 2). + 3. Group-by-name positional match — handles cases where the HIP graph + scheduler reorders independent nodes relative to CPU dispatch order + (return code 3). See docs/capture_merge_error.md. Returns: - (success, aligned_capture_events) where success is 1 on full match, - 2 on successful greedy alignment (with discards), and 0 on failure. + (success, aligned_capture_events) where success is 1, 2, or 3 on + success and 0 on failure. """ if len(capture_events) != len(graph_events): print( @@ -140,11 +185,11 @@ def verify_subtree_events(capture_events, graph_events): ) continue if i["name"] != _capture_kernel_name(j): - print( - "Mismatch in kernel name: {} vs {}".format( - i["name"], _capture_kernel_name(j) - ) - ) + # Counts match but order differs. Group by name and match positionally within each group. + aligned = _align_capture_to_graph_by_group(capture_events, graph_events) + if aligned is not None: + print("Group-by-name alignment succeeded.") + return 3, aligned return 0, capture_events return 1, capture_events diff --git a/TraceLens/TraceDiff/trace_diff.py b/TraceLens/TraceDiff/trace_diff.py index 103932c33..3bce6f96f 100644 --- a/TraceLens/TraceDiff/trace_diff.py +++ b/TraceLens/TraceDiff/trace_diff.py @@ -19,6 +19,8 @@ from TraceLens import TraceToTree from ..TreePerf import GPUEventAnalyser +_TRACELENS_DEBUG = os.environ.get("TRACELENS_DEBUG", "0") == "1" +_GRAPH_LAUNCH_NAMES = ["hipGraphLaunch", "cudaGraphLaunch"] class TraceDiff: def __init__(self, tree1: TraceToTree, tree2: TraceToTree): @@ -230,7 +232,7 @@ def _get_top_level_root(self, tree: TraceToTree, start_uid: int) -> int: if len(children) == 1: child = tree.get_UID2event(children[0]) child_cat = child.get("cat") or child.get("category") - if child_cat in ("cpu_op", "cuda_runtime"): + if child_cat in ("cpu_op", "cuda_runtime") and child.get("name") not in _GRAPH_LAUNCH_NAMES: break current = child else: @@ -348,11 +350,15 @@ def safe_children(uid2node, uid): return [] return node.get("children", []) + _GRAPH_LAUNCH_NAMES = {"hipGraphLaunch", "cudaGraphLaunch"} + def subtree_contains_cuda_runtime(uid, uid2node): - """Return True if this node is a cuda_runtime node.""" + """Return True if this node is a cuda_runtime node. Graph launch events (hipGraphLaunch, cudaGraphLaunch) are exempt.""" node = uid2node.get(uid) if not node or not isinstance(node, dict): return False + if node.get("name") in _GRAPH_LAUNCH_NAMES: + return False cat = node.get("cat") or node.get("category") if cat == "cuda_runtime" or cat == "cuda_driver": return True @@ -408,38 +414,62 @@ def sort_by_ts(uids, uid2node): gpu_children2, variant_uid2node ) - def check_diff_children(ops, uid1, uid2, children1, children2): + def collapse_single_gpu_child(uid, uid2node, tree_obj): """ - Reduce spurious delete/insert pairs by flattening redundant wrapper nodes. - - For every delete-node (baseline) and insert-node (variant) pair, considers three cases - (kernels and kernel launchers are skipped): - - 1. variant children include a node with the same name as the baseline node - -> Remove the variant node and reparent its children to the variant's parent node (uid2). - - 2. baseline children include a node with the same name as the variant node - -> Remove the baseline node and reparent its children to the baseline's parent node (uid1). + Descend through single-GPU-path-child wrapper nodes until reaching + a node with != 1 GPU-path child, a cpu_op, or a dead end. + Returns (uid, gpu_path_children) of the deepest reachable node. + gpu_path_children is the list of GPU-path children at that node + (empty if stopped at a cpu_op, cuda_runtime, or missing node). + """ + current = uid + gpu_kids = [] + while True: + node = uid2node.get(current) + if not node or ( + tree_obj.event_to_category(node) == "cuda_runtime" + and node.get("name") not in _GRAPH_LAUNCH_NAMES + ): + break + kids = [ + c + for c in node.get("children", []) + if uid2node.get(c) and self.is_gpu_path(uid2node[c]) + ] + if len(kids) != 1: + gpu_kids = kids + break + current = kids[0] + return current, gpu_kids + + def reconcile_unmatched(ops, children1, children2): + """Reduce spurious delete/insert pairs by detecting wrapper nodes. + + For every delete-node (baseline) and insert-node (variant) pair, + checks three cases (kernels and cuda_runtime are skipped): + + 1. Deleted name appears in inserted node's GPU-path children + -> substitute inserted UID with its GPU-path children. + 2. Inserted name appears in deleted node's GPU-path children + -> substitute deleted UID with its GPU-path children. + 3. Both have GPU-path children with identical normalized name lists + -> substitute both with their GPU-path children. + + Does NOT mutate the tree. Returns (changed, new_children1, new_children2). + """ + delete_indices = [i for op, i, _ in ops if op == "delete"] + insert_indices = [j for op, _, j in ops if op == "insert"] - 3. Both nodes have children and the two child lists (by normalized name) are equal - -> Remove both nodes and reparent their children to uid2 and uid1 respectively. + if not delete_indices or not insert_indices: + return False, children1, children2 - Mutates the baseline and variant trees in place. If any removals were applied, - recomputes children and Wagner-Fischer ops for the current node. Returns the - (possibly updated) ops list. - """ - delete_indices = [i for op, i, j in ops if op == "delete"] - insert_indices = [j for op, i, j in ops if op == "insert"] - remove_insert = ( - {} - ) # uid_i -> list of child uids to splice in (insert node's children) - remove_delete = ( - {} - ) # uid_d -> list of child uids to splice in (delete node's children) + sub1 = {} # index in children1 -> replacement UIDs + sub2 = {} # index in children2 -> replacement UIDs skip_cats = ("kernel", "cuda_runtime") - for i in delete_indices: - for j in insert_indices: - uid_d, uid_i = children1[i], children2[j] + + for di in delete_indices: + for ii in insert_indices: + uid_d, uid_i = children1[di], children2[ii] node_d = baseline_uid2node.get(uid_d) node_i = variant_uid2node.get(uid_i) cat_d = ( @@ -452,53 +482,60 @@ def check_diff_children(ops, uid1, uid2, children1, children2): if node_i else None ) - if cat_d in skip_cats or cat_i in skip_cats: + if (cat_d in skip_cats and node_d.get("name") not in _GRAPH_LAUNCH_NAMES) or (cat_i in skip_cats and node_i.get("name") not in _GRAPH_LAUNCH_NAMES): continue name_d = get_name_uid(uid_d, 1) name_i = get_name_uid(uid_i, 2) - imm_d = safe_children(baseline_uid2node, uid_d) - imm_i = safe_children(variant_uid2node, uid_i) + imm_d = [ + c + for c in safe_children(baseline_uid2node, uid_d) + if baseline_uid2node.get(c) + and self.is_gpu_path(baseline_uid2node[c]) + ] + imm_i = [ + c + for c in safe_children(variant_uid2node, uid_i) + if variant_uid2node.get(c) + and self.is_gpu_path(variant_uid2node[c]) + ] names_imm_d = [get_name_uid(c, 1) for c in imm_d] names_imm_i = [get_name_uid(c, 2) for c in imm_i] if name_d and any(get_name_uid(c, 2) == name_d for c in imm_i): - remove_insert[uid_i] = imm_i + sub2[ii] = imm_i if name_i and any(get_name_uid(c, 1) == name_i for c in imm_d): - remove_delete[uid_d] = imm_d + sub1[di] = imm_d if imm_d and imm_i and names_imm_d == names_imm_i: - remove_insert[uid_i] = imm_i - remove_delete[uid_d] = imm_d - if remove_insert: - parent_node = variant_uid2node.get(uid2) - if parent_node is not None: - new_children = [] - for c in parent_node.get("children", []): - if c in remove_insert: - new_children.extend(remove_insert[c]) - else: - new_children.append(c) - parent_node["children"] = new_children - for uid_i, imm_i in remove_insert.items(): - for c in imm_i: - child_node = variant_uid2node.get(c) - child_node["parent"] = uid2 - if remove_delete: - parent_node = baseline_uid2node.get(uid1) - if parent_node is not None: - new_children = [] - for c in parent_node.get("children", []): - if c in remove_delete: - new_children.extend(remove_delete[c]) - else: - new_children.append(c) - parent_node["children"] = new_children - for uid_d, imm_d in remove_delete.items(): - for c in imm_d: - child_node = baseline_uid2node.get(c) - child_node["parent"] = uid1 - if remove_insert or remove_delete: - children1, children2 = get_children_with_missing(uid1, uid2) - ops = self.wagner_fischer(children1, children2, wf_cache) - return ops, children1, children2 + sub1[di] = imm_d + sub2[ii] = imm_i + + if not sub1 and not sub2: + return False, children1, children2 + + # Apply substitutions (expand wrapper UIDs to their children) + new_children1 = [] + for idx, c in enumerate(children1): + if idx in sub1: + new_children1.extend(sub1[idx]) + else: + new_children1.append(c) + + new_children2 = [] + for idx, c in enumerate(children2): + if idx in sub2: + new_children2.extend(sub2[idx]) + else: + new_children2.append(c) + + # Sort by timestamp to match get_children_with_missing behavior + def sort_by_ts(uids, uid2node): + nodes = [(uid2node.get(u), u) for u in uids] + nodes.sort(key=lambda x: x[0].get("ts", 0) if x[0] else 0) + return [u for _, u in nodes] + + new_children1 = sort_by_ts(new_children1, baseline_uid2node) + new_children2 = sort_by_ts(new_children2, variant_uid2node) + + return True, new_children1, new_children2 def traverse_and_merge(uid1, uid2): key = (uid1, uid2) @@ -543,18 +580,91 @@ def traverse_and_merge(uid1, uid2): nn_module_stack = node2.get("nn_module_stack", "") children1, children2 = get_children_with_missing(uid1, uid2) - any_cuda_runtime = any( + + # --- Phase 1: List-level collapse --- + # If one side has exactly 1 GPU child while the other has more, + # descend the single child through wrappers to find the branch point. + if len(children1) != len(children2): + if len(children1) == 1: + collapsed, deeper = collapse_single_gpu_child( + children1[0], baseline_uid2node, tree1 + ) + if deeper: + uid1 = collapsed + children1 = deeper + elif len(children2) == 1: + collapsed, deeper = collapse_single_gpu_child( + children2[0], variant_uid2node, tree2 + ) + if deeper: + uid2 = collapsed + children2 = deeper + node1 = baseline_uid2node.get(uid1) + node2 = variant_uid2node.get(uid2) + + # --- Phase 2: Alignment on original children --- + any_cr = any( subtree_contains_cuda_runtime(c, baseline_uid2node) for c in children1 ) or any( subtree_contains_cuda_runtime(c, variant_uid2node) for c in children2 ) - if len(children1) == len(children2) and not any_cuda_runtime: + if len(children1) == len(children2) and not any_cr: ops = [("match", i, i) for i in range(len(children1))] else: ops = self.wagner_fischer(children1, children2, wf_cache) - ops, children1, children2 = check_diff_children( - ops, uid1, uid2, children1, children2 - ) + + # --- Phase 3: Reconciliation (replaces check_diff_children) --- + # For unmatched pairs, check if one node is a wrapper around the + # other's operation. Substitutes wrapper UIDs with their GPU-path + # children and re-aligns. Does NOT mutate the tree. + if any(op != "match" for op, _, _ in ops): + changed, recon1, recon2 = reconcile_unmatched(ops, children1, children2) + if changed: + any_cr = any( + subtree_contains_cuda_runtime(c, baseline_uid2node) + for c in recon1 + ) or any( + subtree_contains_cuda_runtime(c, variant_uid2node) + for c in recon2 + ) + if len(recon1) == len(recon2) and not any_cr: + ops = [("match", i, i) for i in range(len(recon1))] + else: + ops = self.wagner_fischer(recon1, recon2, wf_cache) + children1, children2 = recon1, recon2 + + # --- Phase 4: Per-node canonicalization of remaining unmatched --- + # Collapse each unmatched node through single-GPU-path-child + # wrappers and re-align to find additional matches. + unmatched_idx1 = [i for op, i, _ in ops if op == "delete"] + unmatched_idx2 = [j for op, _, j in ops if op == "insert"] + if unmatched_idx1 and unmatched_idx2: + collapsed1 = [ + collapse_single_gpu_child(children1[i], baseline_uid2node, tree1)[0] + for i in unmatched_idx1 + ] + collapsed2 = [ + collapse_single_gpu_child(children2[j], variant_uid2node, tree2)[0] + for j in unmatched_idx2 + ] + collapsed_ops = self.wagner_fischer(collapsed1, collapsed2, wf_cache) + new_ops = [(op, i, j) for op, i, j in ops if op == "match"] + for cop, ci, cj in collapsed_ops: + if cop == "match": + orig_i = unmatched_idx1[ci] + orig_j = unmatched_idx2[cj] + children1[orig_i] = collapsed1[ci] + children2[orig_j] = collapsed2[cj] + new_ops.append(("match", orig_i, orig_j)) + elif cop == "delete": + orig_i = unmatched_idx1[ci] + children1[orig_i] = collapsed1[ci] + new_ops.append(("delete", orig_i, None)) + elif cop == "insert": + orig_j = unmatched_idx2[cj] + children2[orig_j] = collapsed2[cj] + new_ops.append(("insert", None, orig_j)) + ops = new_ops child_merged_ids = [] for op, i, j in ops: @@ -943,10 +1053,39 @@ def get_kernel_info_subtree(root_uid, tree_uid2node): kernel_time = GPUEventAnalyser(gpu_events).compute_metrics()["busy_time"] return kernel_names, kernel_time + def get_callstack(gpu_event, uid2node): + """Walk from gpu_event up to root, collecting op names root-first.""" + stack = [] + uid = gpu_event.get("parent") + while uid is not None: + n = uid2node.get(uid) + if n is None: + break + name = n.get("name", "") + if name: + stack.append(name) + uid = n.get("parent") + stack.reverse() + return ", ".join(stack) + + def get_gpu_path_child_names(uid, uid2node, tree_num): + """Return semicolon-joined names of GPU-path children of the given node.""" + if uid is None: + return "" + node = uid2node.get(uid) + if node is None: + return "" + names = [] + for cuid in node.get("children", []): + cn = uid2node.get(cuid) + if cn and self.is_gpu_path(cn): + names.append(self._get_op_name(cuid, tree_num) or "") + return "; ".join(names) + rows = [] visited_stats_nodes = set() - def traverse(merged_id, combined_parent_node): + def traverse(merged_id, combined_parent_node, root_index=0): if merged_id in visited_stats_nodes: return node = merged_id_to_event[merged_id] @@ -1028,12 +1167,21 @@ def _compute_lca_busy_time(gpu_event_uids, uid2node): gpu_event_uids2, variant_uid2node ) + lca_children_t1 = get_gpu_path_child_names( + node["uid1"], baseline_uid2node, 1 + ) + lca_children_t2 = get_gpu_path_child_names( + node["uid2"], variant_uid2node, 2 + ) + def add_rows( gpu_event_uids, tree_obj, uid2node, source, lca_busy_time, + lca_children_t1, + lca_children_t2, ): tree_num = 1 if source == "trace1" else 2 for gpu_uid in gpu_event_uids: @@ -1072,6 +1220,19 @@ def add_rows( "busy_time": lca_busy_time, "lowest_common_ancestor_name": lca_name, "lowest_common_ancestor_id": node["merged_id"], + **( + { + "lca_children_t1": lca_children_t1, + "lca_children_t2": lca_children_t2, + } + if _TRACELENS_DEBUG + else {} + ), + **( + {"root_index": root_index} + if _TRACELENS_DEBUG + else {} + ), "gpu_op_uid": gpu_uid, "nn_module_stack": ";".join( str(x) @@ -1082,6 +1243,15 @@ def add_rows( "nn_module_parent": ( parent_node.get("nn_module_stack") or [""] )[-1], + **( + { + "callstack": get_callstack( + gpu_event, uid2node + ), + } + if _TRACELENS_DEBUG + else {} + ), } ) @@ -1091,6 +1261,8 @@ def add_rows( baseline_uid2node, "trace1", busy_time1, + lca_children_t1, + lca_children_t2, ) add_rows( @@ -1099,6 +1271,8 @@ def add_rows( variant_uid2node, "trace2", busy_time2, + lca_children_t1, + lca_children_t2, ) visited_stats_nodes.add(merged_id) @@ -1119,9 +1293,17 @@ def add_rows( lca = merged_id_to_event[lca_id] lca_name = self._get_op_name(lca["uid1"], 1) lca_name = re.sub(r"\(\d+\)", "", lca_name) + lca_children_t1 = get_gpu_path_child_names( + lca["uid1"], baseline_uid2node, 1 + ) + lca_children_t2 = get_gpu_path_child_names( + lca["uid2"], variant_uid2node, 2 + ) else: lca_name = None # Root node has no LCA lca_id = None + lca_children_t1 = "" + lca_children_t2 = "" # Get all GPU kernels from trace1's branch gpu_event_uids = event1.get("gpu_events", []) @@ -1170,6 +1352,19 @@ def add_rows( "busy_time": lca_busy, "lowest_common_ancestor_name": lca_name, "lowest_common_ancestor_id": lca_id, + **( + { + "lca_children_t1": lca_children_t1, + "lca_children_t2": lca_children_t2, + } + if _TRACELENS_DEBUG + else {} + ), + **( + {"root_index": root_index} + if _TRACELENS_DEBUG + else {} + ), "gpu_op_uid": gpu_uid, "nn_module_stack": ";".join( str(x) @@ -1178,6 +1373,15 @@ def add_rows( "nn_module_parent": ( parent_node.get("nn_module_stack") or [""] )[-1], + **( + { + "callstack": get_callstack( + gpu_event, baseline_uid2node + ), + } + if _TRACELENS_DEBUG + else {} + ), } ) @@ -1192,9 +1396,17 @@ def add_rows( lca = merged_id_to_event[lca_id] lca_name = self._get_op_name(lca["uid2"], 2) lca_name = re.sub(r"\(\d+\)", "", lca_name) + lca_children_t1 = get_gpu_path_child_names( + lca["uid1"], baseline_uid2node, 1 + ) + lca_children_t2 = get_gpu_path_child_names( + lca["uid2"], variant_uid2node, 2 + ) else: lca_name = None # Root node has no LCA lca_id = None + lca_children_t1 = "" + lca_children_t2 = "" # Get all GPU kernels from trace2's branch gpu_event_uids = event2.get("gpu_events", []) @@ -1243,6 +1455,19 @@ def add_rows( "busy_time": lca_busy, "lowest_common_ancestor_name": lca_name, "lowest_common_ancestor_id": lca_id, + **( + { + "lca_children_t1": lca_children_t1, + "lca_children_t2": lca_children_t2, + } + if _TRACELENS_DEBUG + else {} + ), + **( + {"root_index": root_index} + if _TRACELENS_DEBUG + else {} + ), "gpu_op_uid": gpu_uid, "nn_module_stack": ";".join( str(x) @@ -1251,6 +1476,15 @@ def add_rows( "nn_module_parent": ( parent_node.get("nn_module_stack") or [""] )[-1], + **( + { + "callstack": get_callstack( + gpu_event, variant_uid2node + ), + } + if _TRACELENS_DEBUG + else {} + ), } ) @@ -1264,11 +1498,11 @@ def add_rows( if should_traverse_children: for cid in node["children"]: - traverse(cid, node) + traverse(cid, node, root_index) return - for root_id in merged_root_ids: - traverse(root_id, None) + for root_index, root_id in enumerate(merged_root_ids): + traverse(root_id, None, root_index) df = pd.DataFrame(rows) From 35e9b5ad7945b633a54c3cebfec9508021789a75 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Wed, 1 Jul 2026 18:42:39 -0400 Subject: [PATCH 22/50] remove gate --- TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md | 1 - 1 file changed, 1 deletion(-) diff --git a/TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md b/TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md index d9ecc9412..45583f946 100644 --- a/TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md +++ b/TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md @@ -95,7 +95,6 @@ Use vendor-agnostic terminology throughout such as GPU kernels, collective commu 2. **Graph replay + capture** (`` = `graph_capture`) — also requires a capture folder path - If **Graph replay + capture**, ask for **Capture Folder Path** → ``: - Ask: "Please provide the full path to the graph capture traces folder" - - **Unsupported combination:** If `` = `graph_capture` **and** `` = `comparative`, stop immediately. Inform the user: "Graph replay + capture mode is not yet supported for comparative analysis. Please provide eager mode traces instead." Do not misinterpret as two standalone analyses. Do **not** proceed to Step 1 or beyond. 5. **Environment Setup** - Ask: "Are you running locally or on a cluster?" From f5cd48d991a864601b128ae321b8829a028a33f9 Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Wed, 1 Jul 2026 19:02:10 -0400 Subject: [PATCH 23/50] support graph capture comparative --- .../Analysis/.cursor/skills/analysis-orchestrator.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md b/TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md index 45583f946..d4b935b48 100644 --- a/TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md +++ b/TraceLens/Agent/Analysis/.cursor/skills/analysis-orchestrator.md @@ -95,6 +95,7 @@ Use vendor-agnostic terminology throughout such as GPU kernels, collective commu 2. **Graph replay + capture** (`` = `graph_capture`) — also requires a capture folder path - If **Graph replay + capture**, ask for **Capture Folder Path** → ``: - Ask: "Please provide the full path to the graph capture traces folder" + - If **Graph replay + capture** and **comparative**, ask for **Trace2 Capture Folder Path** -> `` 5. **Environment Setup** - Ask: "Are you running locally or on a cluster?" @@ -185,6 +186,14 @@ All commands below append `` and ``, resolved by `` | | `comparative` trace2 | none | +**``** — extension flags: + +| scope | value | +|-------|-------| +| `standalone` | none | +| `comparative` trace1 if `` provided | `--comparison_capture_folder ` | +| `comparative` trace2 | none | + **``** — user extension file: | condition | value | @@ -236,6 +245,7 @@ All commands below append `` and ``, resolved by ` \ \ + \ ``` From a760dcf443c75aabd91f324208a78a7b011299db Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Wed, 8 Jul 2026 20:19:18 -0400 Subject: [PATCH 24/50] disambiguate WF candidates with same name. consider cuda_driver as kernel dispatcher --- TraceLens/TraceDiff/trace_diff.py | 337 +++++++++++++++++++++++++++--- 1 file changed, 313 insertions(+), 24 deletions(-) diff --git a/TraceLens/TraceDiff/trace_diff.py b/TraceLens/TraceDiff/trace_diff.py index 3bce6f96f..a66018847 100644 --- a/TraceLens/TraceDiff/trace_diff.py +++ b/TraceLens/TraceDiff/trace_diff.py @@ -22,6 +22,238 @@ _TRACELENS_DEBUG = os.environ.get("TRACELENS_DEBUG", "0") == "1" _GRAPH_LAUNCH_NAMES = ["hipGraphLaunch", "cudaGraphLaunch"] + +_KERNEL_LAUNCH_EQUIVALENTS = { + "hipModuleLaunchKernel": "__kernel_launch__", + "cuLaunchKernel": "__kernel_launch__", +} + + +def _normalize_name_for_comparison(name): + if name is None: + return name + normalized = re.sub(r"0x[0-9a-fA-F]+", "0xXXXX", name) + normalized = re.sub(r"\.py\(\d+\):", ".py:", normalized) + return _KERNEL_LAUNCH_EQUIVALENTS.get(normalized, normalized) + + +def _gpu_path_child_names_at_bfs_levels(uid, uid2node, tree_num, max_depth, normalize_fn, get_name_fn): + """ + Return a list of frozensets, one per BFS level (1..max_depth), each containing + the multiset (as a sorted tuple) of normalized GPU-path child names at that depth + relative to `uid`. + + A node is on the GPU path when it does not have non_gpu_path=True. + """ + def is_gpu_path(node): + return node is not None and not node.get("non_gpu_path", False) + + levels = [] + current_frontier = [uid] + for _ in range(max_depth): + next_frontier = [] + names_this_level = [] + for u in current_frontier: + node = uid2node.get(u) + if not node: + continue + for child_uid in node.get("children", []): + child_node = uid2node.get(child_uid) + if child_node and is_gpu_path(child_node): + next_frontier.append(child_uid) + raw_name = get_name_fn(child_uid, tree_num) + names_this_level.append(normalize_fn(raw_name) if raw_name else None) + levels.append(tuple(sorted(names_this_level))) + current_frontier = next_frontier + if not current_frontier: + break + return levels + + +def _disambiguate_same_name_candidates(ops, children1, children2, + baseline_uid2node, variant_uid2node, + max_depth=4): + """ + Post-WF pass: when a match op pairs trace1[i] with trace2[j] (name N), but + there are also insert ops for other trace2 nodes also named N, WF chose + arbitrarily among equally-named candidates. This function picks the best + candidate using BFS-level GPU-path child name comparison (up to max_depth + levels). Symmetric: also handles multiple trace1 candidates vs one trace2. + + Eviction rule: a candidate is evicted at depth d if the sorted tuple of its + GPU-path child names at BFS level d differs from that of the anchor node, OR + if the candidate has no GPU-path children at any level where the anchor has + some. + + After eviction: + - 1 survivor → that survivor becomes the match; others become inserts/deletes. + - >1 survivors → pick the positionally-first survivor among the original + children list; others become inserts/deletes. + + Does not mutate children1/children2. Returns a new ops list. + """ + normalize = _normalize_name_for_comparison + + def get_name(uid, tree_num): + uid2node = baseline_uid2node if tree_num == 1 else variant_uid2node + node = uid2node.get(uid) + if not node: + return None + name = node.get("name") or node.get("Name") + return name + + def normalized_name(uid, tree_num): + raw = get_name(uid, tree_num) + return normalize(raw) if raw else None + + def bfs_levels(uid, uid2node, tree_num): + return _gpu_path_child_names_at_bfs_levels( + uid, uid2node, tree_num, max_depth, normalize, get_name + ) + + # Index existing ops by type for easy lookup + match_ops = [(i, j) for op, i, j in ops if op == "match"] + delete_idxs = [i for op, i, _ in ops if op == "delete"] # trace1 unmatched + insert_idxs = [j for op, _, j in ops if op == "insert"] # trace2 unmatched + + # Build name → list-of-indices for unmatched nodes on each side + unmatched1_by_name = {} # name -> [idx in children1] + for i in delete_idxs: + n = normalized_name(children1[i], 1) + unmatched1_by_name.setdefault(n, []).append(i) + + unmatched2_by_name = {} # name -> [idx in children2] + for j in insert_idxs: + n = normalized_name(children2[j], 2) + unmatched2_by_name.setdefault(n, []).append(j) + + # Collect reassignments: list of (anchor_i, anchor_j, winner_i, winner_j) + # anchor_* is the original WF match; winner_* is the chosen match after disambiguation. + reassignments = [] # (orig_i, orig_j, new_i, new_j) + + for orig_i, orig_j in match_ops: + name1 = normalized_name(children1[orig_i], 1) + name2 = normalized_name(children2[orig_j], 2) + + # Only act when there are extra same-named candidates on at least one side + extra1 = unmatched1_by_name.get(name1, []) # other trace1 nodes named name1 + extra2 = unmatched2_by_name.get(name2, []) # other trace2 nodes named name2 + + if not extra1 and not extra2: + continue # no ambiguity – leave this match alone + + # --- Disambiguate trace2 candidates against the fixed trace1 anchor --- + if extra2: + anchor_levels = bfs_levels(children1[orig_i], baseline_uid2node, 1) + # candidates: the current WF match + all inserts with the same name + candidates2 = [orig_j] + extra2 + survivors2 = [] + for cj in candidates2: + cand_levels = bfs_levels(children2[cj], variant_uid2node, 2) + evicted = False + for d in range(max(len(anchor_levels), len(cand_levels))): + al = anchor_levels[d] if d < len(anchor_levels) else () + cl = cand_levels[d] if d < len(cand_levels) else () + if al != cl: + evicted = True + break + if not evicted: + survivors2.append(cj) + + if not survivors2: + survivors2 = candidates2 # all evicted → fall back to all + + # Only override WF when disambiguation produced a unique survivor. + # Multiple survivors means subtree structure can't break the tie, so + # WF's global alignment choice (orig_j) is the better tiebreaker. + if len(survivors2) == 1 and survivors2[0] != orig_j: + reassignments.append((orig_i, orig_j, orig_i, survivors2[0])) + + # --- Disambiguate trace1 candidates against the fixed trace2 anchor --- + if extra1: + anchor_levels = bfs_levels(children2[orig_j], variant_uid2node, 2) + candidates1 = [orig_i] + extra1 + survivors1 = [] + for ci in candidates1: + cand_levels = bfs_levels(children1[ci], baseline_uid2node, 1) + evicted = False + for d in range(max(len(anchor_levels), len(cand_levels))): + al = anchor_levels[d] if d < len(anchor_levels) else () + cl = cand_levels[d] if d < len(cand_levels) else () + if al != cl: + evicted = True + break + if not evicted: + survivors1.append(ci) + + if not survivors1: + survivors1 = candidates1 + + # Only override WF when disambiguation produced a unique survivor. + if len(survivors1) == 1 and survivors1[0] != orig_i: + effective_j = reassignments[-1][3] if (extra2 and reassignments and reassignments[-1][0] == orig_i) else orig_j + reassignments.append((orig_i, orig_j, survivors1[0], effective_j)) + + if not reassignments: + return ops + + # Apply reassignments: build a new ops list + # Track which indices are "consumed" by a new match so they don't appear + # as plain delete/insert in the final list. + new_match_pairs = {} # (i, j) -> True for new matches + demoted1 = set() # children1 indices that lose their WF match and become deletes + demoted2 = set() # children2 indices that lose their WF match and become inserts + promoted1 = set() # children1 inserts that become matches + promoted2 = set() # children2 inserts that become matches + + for orig_i, orig_j, new_i, new_j in reassignments: + new_match_pairs[(new_i, new_j)] = True + if new_i != orig_i: + demoted1.add(orig_i) + promoted1.add(new_i) + if new_j != orig_j: + demoted2.add(orig_j) + promoted2.add(new_j) + + final_ops = [] + # Re-emit all original ops, substituting changed matches and handling + # demotions/promotions. + emitted_matches = set() + for op, i, j in ops: + if op == "match": + i_demoted = i in demoted1 + j_demoted = j in demoted2 + if i_demoted and j_demoted: + final_ops.append(("delete", i, None)) + final_ops.append(("insert", None, j)) + elif i_demoted: + # Only trace1 side changed; j is still used in the new match + final_ops.append(("delete", i, None)) + elif j_demoted: + # Only trace2 side changed; i is still used in the new match + final_ops.append(("insert", None, j)) + else: + final_ops.append(("match", i, j)) + emitted_matches.add((i, j)) + elif op == "delete": + if i in promoted1: + pass # will be emitted as part of a new match below + else: + final_ops.append(("delete", i, None)) + elif op == "insert": + if j in promoted2: + pass # will be emitted as part of a new match below + else: + final_ops.append(("insert", None, j)) + + # Emit new match ops for winner pairs not already in the list + for (new_i, new_j) in new_match_pairs: + if (new_i, new_j) not in emitted_matches: + final_ops.append(("match", new_i, new_j)) + + return final_ops + + class TraceDiff: def __init__(self, tree1: TraceToTree, tree2: TraceToTree): self.baseline = tree1 @@ -110,13 +342,7 @@ def _normalize_name_for_comparison(name): Returns: The normalized name, or the original name if it's None """ - if name is None: - return name - # Remove hex memory addresses but keep the "at 0x" part for context - normalized = re.sub(r"0x[0-9a-fA-F]+", "0xXXXX", name) - # Remove line numbers from Python stack frames (filename.py(line_number): function) - normalized = re.sub(r"\.py\(\d+\):", ".py:", normalized) - return normalized + return _normalize_name_for_comparison(name) def _get_op_name(self, uid, tree_num): """ @@ -232,7 +458,7 @@ def _get_top_level_root(self, tree: TraceToTree, start_uid: int) -> int: if len(children) == 1: child = tree.get_UID2event(children[0]) child_cat = child.get("cat") or child.get("category") - if child_cat in ("cpu_op", "cuda_runtime") and child.get("name") not in _GRAPH_LAUNCH_NAMES: + if child_cat in ("cpu_op", "cuda_runtime", "cuda_driver") and child.get("name") not in _GRAPH_LAUNCH_NAMES: break current = child else: @@ -328,6 +554,13 @@ def merge_trees(self): baseline_uid2node = self._get_baseline_uid2node() variant_uid2node = self._get_variant_uid2node() wf_cache = {} + + def aligned_wf(items1, items2): + ops = self.wagner_fischer(items1, items2, wf_cache) + return _disambiguate_same_name_candidates( + ops, items1, items2, baseline_uid2node, variant_uid2node + ) + merged_events = [] merged_id_counter = [0] uid_pair_to_merged_id = {} @@ -417,20 +650,32 @@ def sort_by_ts(uids, uid2node): def collapse_single_gpu_child(uid, uid2node, tree_obj): """ Descend through single-GPU-path-child wrapper nodes until reaching - a node with != 1 GPU-path child, a cpu_op, or a dead end. + a node with != 1 GPU-path child, a cpu_op with a cuda_runtime + child, or a dead end. Returns (uid, gpu_path_children) of the deepest reachable node. gpu_path_children is the list of GPU-path children at that node - (empty if stopped at a cpu_op, cuda_runtime, or missing node). + (empty if stopped at a cuda_runtime or missing node). """ current = uid gpu_kids = [] while True: node = uid2node.get(current) if not node or ( - tree_obj.event_to_category(node) == "cuda_runtime" + tree_obj.event_to_category(node) in ("cuda_runtime", "cuda_driver") and node.get("name") not in _GRAPH_LAUNCH_NAMES ): break + # Stop at cpu_ops that directly launch cuda_runtime/cuda_driver calls + cat = tree_obj.event_to_category(node) + if cat == "cpu_op": + has_cr_child = any( + tree_obj.event_to_category(uid2node[c]) in ("cuda_runtime", "cuda_driver") + and uid2node[c].get("name") not in _GRAPH_LAUNCH_NAMES + for c in node.get("children", []) + if uid2node.get(c) + ) + if has_cr_child: + break kids = [ c for c in node.get("children", []) @@ -465,7 +710,7 @@ def reconcile_unmatched(ops, children1, children2): sub1 = {} # index in children1 -> replacement UIDs sub2 = {} # index in children2 -> replacement UIDs - skip_cats = ("kernel", "cuda_runtime") + skip_cats = ("kernel", "cuda_runtime", "cuda_driver") for di in delete_indices: for ii in insert_indices: @@ -611,7 +856,7 @@ def traverse_and_merge(uid1, uid2): if len(children1) == len(children2) and not any_cr: ops = [("match", i, i) for i in range(len(children1))] else: - ops = self.wagner_fischer(children1, children2, wf_cache) + ops = aligned_wf(children1, children2) # --- Phase 3: Reconciliation (replaces check_diff_children) --- # For unmatched pairs, check if one node is a wrapper around the @@ -620,17 +865,61 @@ def traverse_and_merge(uid1, uid2): if any(op != "match" for op, _, _ in ops): changed, recon1, recon2 = reconcile_unmatched(ops, children1, children2) if changed: - any_cr = any( - subtree_contains_cuda_runtime(c, baseline_uid2node) - for c in recon1 - ) or any( - subtree_contains_cuda_runtime(c, variant_uid2node) - for c in recon2 - ) - if len(recon1) == len(recon2) and not any_cr: - ops = [("match", i, i) for i in range(len(recon1))] + # Preserve Phase 2 match ops: track by UID pair (not index, + # since expansion + re-sort changes indices). + pinned_uid_pairs = [ + (children1[i], children2[j]) + for op_type, i, j in ops if op_type == "match" + ] + + # Locate pinned UIDs in the expanded+re-sorted lists + uid_to_ri = {c: idx for idx, c in enumerate(recon1)} + uid_to_rj = {c: idx for idx, c in enumerate(recon2)} + + new_ops = [] + pinned_ri = set() + pinned_rj = set() + for u1, u2 in pinned_uid_pairs: + ri = uid_to_ri.get(u1) + rj = uid_to_rj.get(u2) + if ri is not None and rj is not None: + new_ops.append(("match", ri, rj)) + pinned_ri.add(ri) + pinned_rj.add(rj) + + # Run WF only on unpinned (expanded/unmatched) indices + free1 = [i for i in range(len(recon1)) if i not in pinned_ri] + free2 = [j for j in range(len(recon2)) if j not in pinned_rj] + + if free1 and free2: + free_items1 = [recon1[i] for i in free1] + free_items2 = [recon2[j] for j in free2] + any_cr = any( + subtree_contains_cuda_runtime(c, baseline_uid2node) + for c in free_items1 + ) or any( + subtree_contains_cuda_runtime(c, variant_uid2node) + for c in free_items2 + ) + if len(free_items1) == len(free_items2) and not any_cr: + free_ops = [("match", i, i) for i in range(len(free_items1))] + else: + free_ops = aligned_wf(free_items1, free_items2) + # Remap free_ops indices back to recon1/recon2 indices + for fop, fi, fj in free_ops: + if fop == "match": + new_ops.append(("match", free1[fi], free2[fj])) + elif fop == "delete": + new_ops.append(("delete", free1[fi], None)) + elif fop == "insert": + new_ops.append(("insert", None, free2[fj])) else: - ops = self.wagner_fischer(recon1, recon2, wf_cache) + for i in free1: + new_ops.append(("delete", i, None)) + for j in free2: + new_ops.append(("insert", None, j)) + + ops = new_ops children1, children2 = recon1, recon2 # --- Phase 4: Per-node canonicalization of remaining unmatched --- @@ -647,7 +936,7 @@ def traverse_and_merge(uid1, uid2): collapse_single_gpu_child(children2[j], variant_uid2node, tree2)[0] for j in unmatched_idx2 ] - collapsed_ops = self.wagner_fischer(collapsed1, collapsed2, wf_cache) + collapsed_ops = aligned_wf(collapsed1, collapsed2) new_ops = [(op, i, j) for op, i, j in ops if op == "match"] for cop, ci, cj in collapsed_ops: if cop == "match": From 000157b6ca3bf01b33cd160be8d23a39591e482a Mon Sep 17 00:00:00 2001 From: Kyle Hoffmeyer Date: Thu, 9 Jul 2026 13:46:22 -0400 Subject: [PATCH 25/50] merge main --- .github/CODEOWNERS | 7 +- .gitignore | 1 + .readthedocs.yaml | 22 + README.md | 48 +- TraceLens/Agent/Analysis/README.md | 2 +- .../skills/magpie-benchmark-profiling.md | 18 +- TraceLens/Agent/Profiling/README.md | 2 +- TraceLens/PerfModel/extensions/__init__.py | 16 + .../attention_perf_model_extensions.py | 87 +- ...ustom_collectives_perf_model_extensions.py | 31 + .../extensions/moe_perf_model_extensions.py | 238 ++- .../extensions/perf_model_extensions.py | 430 ++++- .../extensions/pseudo_ops_perf_utils.py | 23 +- TraceLens/PerfModel/torch_op_mapping.py | 2 - .../generate_perf_report_pytorch_inference.py | 6 +- .../trace_capture_merge_experimental.py | 132 +- TraceLens/Trace2Tree/trace_to_tree.py | 74 +- .../split_inference_trace_annotation.py | 230 ++- TraceLens/TreePerf/tree_perf.py | 9 +- TraceLens/util.py | 183 +- docs/.gitignore | 6 + docs/about/license.md | 34 + docs/about/release-notes.md | 103 ++ docs/conf.py | 51 + docs/how-to/collective-report.md | 176 ++ docs/how-to/compare-traces.md | 192 +++ docs/how-to/event-replay.md | 112 ++ docs/how-to/generate-perf-report-jax.md | 104 ++ .../generate-perf-report-pytorch-inference.md | 93 + docs/how-to/generate-perf-report-pytorch.md | 207 +++ docs/how-to/generate-perf-report-rocprof.md | 143 ++ docs/how-to/generate-reports.md | 26 + docs/how-to/trace-fusion.md | 133 ++ docs/index.rst | 44 + docs/install/installation.md | 115 ++ docs/reference/api-reference.md | 212 +++ docs/reference/compatibility.md | 95 + docs/sphinx/_toc.yml.in | 52 + docs/sphinx/requirements.txt | 1 + docs/what-is-tracelens.md | 104 ++ {docs => docs_original}/Agentic_Mode.md | 0 {docs => docs_original}/EventReplay.md | 0 {docs => docs_original}/Inference_analysis.md | 11 +- {docs => docs_original}/NcclAnalyser.md | 0 {docs => docs_original}/Trace2Tree.md | 0 {docs => docs_original}/TraceDiff.md | 0 {docs => docs_original}/TraceFusion.md | 0 ...formance Analysis - Adeem Jassani, AMD.pdf | Bin {docs => docs_original}/TreePerf.md | 0 .../compare_perf_reports_pytorch.md | 0 .../conceptual/aimodels_gemms.md | 0 .../conceptual/anomaly_detection_guide.ipynb | 0 .../distributed_profiling_guide.ipynb | 0 .../imgs/profiling_analysis_fig1.png | Bin .../imgs/profiling_analysis_fig2.png | Bin .../imgs/profiling_analysis_fig3.png | Bin .../imgs/profiling_analysis_fig4.png | Bin .../imgs/profiling_analysis_fig5.png | Bin .../imgs/profiling_analysis_fig6.png | Bin .../conceptual/shape_metadata_guide.md | 0 .../conceptual/torch_profiling_analysis.md | 0 .../conceptual/torch_profiling_guide.ipynb | 0 .../conceptual/trace2tree_motivation.md | 0 {docs => docs_original}/gemm_dim_eff.md | 0 ...te_multi_rank_collective_report_pytorch.md | 0 .../generate_perf_report.md | 0 .../generate_perf_report_rocprof.md | 0 .../generate_perf_report_rocprof_pftrace.md | 0 {docs => docs_original}/gpu_event_analyser.md | 0 {docs => docs_original}/jax_analyses.md | 0 {docs => docs_original}/locate_node.PNG | Bin .../origami_with_tracelens.md | 0 .../perf_report_columns.md | 0 .../triton_perf_model_walkthrough.md | 0 .../inference_analysis/build_docker_vllm.sh | 16 +- .../eagle_draft_cuda_graph_runner.patch | 61 + ...eagle_draft_extend_cuda_graph_runner.patch | 61 + .../sglang_0_5_11/kernel_shape_profiler.patch | 281 ++- ...eagle_draft_extend_cuda_graph_runner.patch | 61 + .../eagle_draft_cuda_graph_runner.patch | 61 + ...eagle_draft_extend_cuda_graph_runner.patch | 61 + .../sglang_0_5_12/kernel_shape_profiler.patch | 281 ++- ...eagle_draft_extend_cuda_graph_runner.patch | 61 + .../vllm_patches/config_vllm_v0.22.0.patch | 245 +++ .../vllm_patches/config_vllm_v0.23.0.patch | 245 +++ .../vllm_patches/config_vllm_v0.24.0.patch | 245 +++ examples/custom_workflows/trace_checker.py | 1528 +++++++++++++++++ tests/test_inference_perf_report.py | 10 + .../capture_traces/bs_32_rank0.json.gz | Bin 0 -> 1217245 bytes .../capture_traces/execution_details.json | 7 + .../sglang_decode/perf_csvs/GEMM.csv | 10 + .../perf_csvs/InferenceAttention_fwd.csv | 3 + .../sglang_decode/perf_csvs/RMSNorm_fwd.csv | 5 + .../sglang_decode/perf_csvs/Reduce_fwd.csv | 3 + .../sglang_decode/perf_csvs/RoPE_fwd.csv | 2 + .../perf_csvs/UnaryElementwise.csv | 10 + .../sglang_decode/perf_csvs/gpu_timeline.csv | 9 + .../sglang_decode/perf_csvs/ops_summary.csv | 22 + .../perf_csvs/ops_summary_by_category.csv | 17 + .../perf_csvs/ops_unique_args.csv | 30 + .../perf_csvs/unified_perf_summary.csv | 30 + .../sglang_Qwen3-8B_decode.json.gz | Bin 0 -> 36647 bytes .../sglang_prefilldecode/perf_csvs/GEMM.csv | 10 + .../perf_csvs/InferenceAttention_fwd.csv | 3 + .../perf_csvs/RMSNorm_fwd.csv | 5 + .../perf_csvs/Reduce_fwd.csv | 4 + .../perf_csvs/RoPE_fwd.csv | 2 + .../perf_csvs/UnaryElementwise.csv | 11 + .../perf_csvs/gpu_timeline.csv | 9 + .../perf_csvs/ops_summary.csv | 28 + .../perf_csvs/ops_summary_by_category.csv | 18 + .../perf_csvs/ops_unique_args.csv | 39 + .../perf_csvs/unified_perf_summary.csv | 37 + .../sglang_Qwen3-8B_prefilldecode.json.gz | Bin 0 -> 1174357 bytes .../capture_traces/execution_details.json | 0 ...ank_0.1773709742341309550.pt.trace.json.gz | Bin .../graph_execution.json.gz | Bin .../graph_execution_perf_report.xlsx | Bin .../perf_csvs/GEMM.csv | 0 .../perf_csvs/InferenceAttention_fwd.csv | 0 .../perf_csvs/MoE_unfused_fwd.csv | 0 .../perf_csvs/RMSNorm_fwd.csv | 0 .../perf_csvs/UnaryElementwise.csv | 0 .../perf_csvs/gpu_timeline.csv | 0 .../perf_csvs/ops_summary.csv | 0 .../perf_csvs/ops_summary_by_category.csv | 0 .../perf_csvs/ops_unique_args.csv | 0 .../perf_csvs/unified_perf_summary.csv | 0 .../capture_traces/execution_details.json | 0 ...ank_0.1773709679453551615.pt.trace.json.gz | Bin .../graph_execution.json.gz | Bin .../perf_csvs/GEMM.csv | 0 .../perf_csvs/InferenceAttention_fwd.csv | 0 .../perf_csvs/MoE_unfused_fwd.csv | 0 .../perf_csvs/RMSNorm_fwd.csv | 0 .../perf_csvs/UnaryElementwise.csv | 0 .../perf_csvs/gpu_timeline.csv | 0 .../perf_csvs/ops_summary.csv | 0 .../perf_csvs/ops_summary_by_category.csv | 0 .../perf_csvs/ops_unique_args.csv | 0 .../perf_csvs/unified_perf_summary.csv | 0 141 files changed, 6817 insertions(+), 289 deletions(-) create mode 100644 .readthedocs.yaml create mode 100644 docs/.gitignore create mode 100644 docs/about/license.md create mode 100644 docs/about/release-notes.md create mode 100644 docs/conf.py create mode 100644 docs/how-to/collective-report.md create mode 100644 docs/how-to/compare-traces.md create mode 100644 docs/how-to/event-replay.md create mode 100644 docs/how-to/generate-perf-report-jax.md create mode 100644 docs/how-to/generate-perf-report-pytorch-inference.md create mode 100644 docs/how-to/generate-perf-report-pytorch.md create mode 100644 docs/how-to/generate-perf-report-rocprof.md create mode 100644 docs/how-to/generate-reports.md create mode 100644 docs/how-to/trace-fusion.md create mode 100644 docs/index.rst create mode 100644 docs/install/installation.md create mode 100644 docs/reference/api-reference.md create mode 100644 docs/reference/compatibility.md create mode 100644 docs/sphinx/_toc.yml.in create mode 100644 docs/sphinx/requirements.txt create mode 100644 docs/what-is-tracelens.md rename {docs => docs_original}/Agentic_Mode.md (100%) rename {docs => docs_original}/EventReplay.md (100%) rename {docs => docs_original}/Inference_analysis.md (98%) rename {docs => docs_original}/NcclAnalyser.md (100%) rename {docs => docs_original}/Trace2Tree.md (100%) rename {docs => docs_original}/TraceDiff.md (100%) rename {docs => docs_original}/TraceFusion.md (100%) rename {docs => docs_original}/TraceLens - Democratizing AI Performance Analysis - Adeem Jassani, AMD.pdf (100%) rename {docs => docs_original}/TreePerf.md (100%) rename {docs => docs_original}/compare_perf_reports_pytorch.md (100%) rename {docs => docs_original}/conceptual/aimodels_gemms.md (100%) rename {docs => docs_original}/conceptual/anomaly_detection_guide.ipynb (100%) rename {docs => docs_original}/conceptual/distributed_profiling_guide.ipynb (100%) rename {docs => docs_original}/conceptual/imgs/profiling_analysis_fig1.png (100%) rename {docs => docs_original}/conceptual/imgs/profiling_analysis_fig2.png (100%) rename {docs => docs_original}/conceptual/imgs/profiling_analysis_fig3.png (100%) rename {docs => docs_original}/conceptual/imgs/profiling_analysis_fig4.png (100%) rename {docs => docs_original}/conceptual/imgs/profiling_analysis_fig5.png (100%) rename {docs => docs_original}/conceptual/imgs/profiling_analysis_fig6.png (100%) rename {docs => docs_original}/conceptual/shape_metadata_guide.md (100%) rename {docs => docs_original}/conceptual/torch_profiling_analysis.md (100%) rename {docs => docs_original}/conceptual/torch_profiling_guide.ipynb (100%) rename {docs => docs_original}/conceptual/trace2tree_motivation.md (100%) rename {docs => docs_original}/gemm_dim_eff.md (100%) rename {docs => docs_original}/generate_multi_rank_collective_report_pytorch.md (100%) rename {docs => docs_original}/generate_perf_report.md (100%) rename {docs => docs_original}/generate_perf_report_rocprof.md (100%) rename {docs => docs_original}/generate_perf_report_rocprof_pftrace.md (100%) rename {docs => docs_original}/gpu_event_analyser.md (100%) rename {docs => docs_original}/jax_analyses.md (100%) rename {docs => docs_original}/locate_node.PNG (100%) rename {docs => docs_original}/origami_with_tracelens.md (100%) rename {docs => docs_original}/perf_report_columns.md (100%) rename {docs => docs_original}/triton_perf_model_walkthrough.md (100%) create mode 100644 examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/eagle_draft_cuda_graph_runner.patch create mode 100644 examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/eagle_draft_extend_cuda_graph_runner.patch create mode 100644 examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/multi_layer_eagle_draft_extend_cuda_graph_runner.patch create mode 100644 examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/eagle_draft_cuda_graph_runner.patch create mode 100644 examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/eagle_draft_extend_cuda_graph_runner.patch create mode 100644 examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/multi_layer_eagle_draft_extend_cuda_graph_runner.patch create mode 100644 examples/custom_workflows/inference_analysis/vllm_patches/config_vllm_v0.22.0.patch create mode 100644 examples/custom_workflows/inference_analysis/vllm_patches/config_vllm_v0.23.0.patch create mode 100644 examples/custom_workflows/inference_analysis/vllm_patches/config_vllm_v0.24.0.patch create mode 100644 examples/custom_workflows/trace_checker.py create mode 100644 tests/traces/inference/sglang_decode/capture_traces/bs_32_rank0.json.gz create mode 100644 tests/traces/inference/sglang_decode/capture_traces/execution_details.json create mode 100644 tests/traces/inference/sglang_decode/perf_csvs/GEMM.csv create mode 100644 tests/traces/inference/sglang_decode/perf_csvs/InferenceAttention_fwd.csv create mode 100644 tests/traces/inference/sglang_decode/perf_csvs/RMSNorm_fwd.csv create mode 100644 tests/traces/inference/sglang_decode/perf_csvs/Reduce_fwd.csv create mode 100644 tests/traces/inference/sglang_decode/perf_csvs/RoPE_fwd.csv create mode 100644 tests/traces/inference/sglang_decode/perf_csvs/UnaryElementwise.csv create mode 100644 tests/traces/inference/sglang_decode/perf_csvs/gpu_timeline.csv create mode 100644 tests/traces/inference/sglang_decode/perf_csvs/ops_summary.csv create mode 100644 tests/traces/inference/sglang_decode/perf_csvs/ops_summary_by_category.csv create mode 100644 tests/traces/inference/sglang_decode/perf_csvs/ops_unique_args.csv create mode 100644 tests/traces/inference/sglang_decode/perf_csvs/unified_perf_summary.csv create mode 100644 tests/traces/inference/sglang_decode/sglang_Qwen3-8B_decode.json.gz create mode 100644 tests/traces/inference/sglang_prefilldecode/perf_csvs/GEMM.csv create mode 100644 tests/traces/inference/sglang_prefilldecode/perf_csvs/InferenceAttention_fwd.csv create mode 100644 tests/traces/inference/sglang_prefilldecode/perf_csvs/RMSNorm_fwd.csv create mode 100644 tests/traces/inference/sglang_prefilldecode/perf_csvs/Reduce_fwd.csv create mode 100644 tests/traces/inference/sglang_prefilldecode/perf_csvs/RoPE_fwd.csv create mode 100644 tests/traces/inference/sglang_prefilldecode/perf_csvs/UnaryElementwise.csv create mode 100644 tests/traces/inference/sglang_prefilldecode/perf_csvs/gpu_timeline.csv create mode 100644 tests/traces/inference/sglang_prefilldecode/perf_csvs/ops_summary.csv create mode 100644 tests/traces/inference/sglang_prefilldecode/perf_csvs/ops_summary_by_category.csv create mode 100644 tests/traces/inference/sglang_prefilldecode/perf_csvs/ops_unique_args.csv create mode 100644 tests/traces/inference/sglang_prefilldecode/perf_csvs/unified_perf_summary.csv create mode 100644 tests/traces/inference/sglang_prefilldecode/sglang_Qwen3-8B_prefilldecode.json.gz rename tests/traces/inference/{graph_full => vllm_decode_full}/capture_traces/execution_details.json (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/capture_traces/graph_capture_rank_0.1773709742341309550.pt.trace.json.gz (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/graph_execution.json.gz (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/graph_execution_perf_report.xlsx (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/perf_csvs/GEMM.csv (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/perf_csvs/InferenceAttention_fwd.csv (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/perf_csvs/MoE_unfused_fwd.csv (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/perf_csvs/RMSNorm_fwd.csv (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/perf_csvs/UnaryElementwise.csv (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/perf_csvs/gpu_timeline.csv (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/perf_csvs/ops_summary.csv (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/perf_csvs/ops_summary_by_category.csv (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/perf_csvs/ops_unique_args.csv (100%) rename tests/traces/inference/{graph_full => vllm_decode_full}/perf_csvs/unified_perf_summary.csv (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/capture_traces/execution_details.json (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/capture_traces/graph_capture_rank_0.1773709679453551615.pt.trace.json.gz (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/graph_execution.json.gz (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/perf_csvs/GEMM.csv (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/perf_csvs/InferenceAttention_fwd.csv (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/perf_csvs/MoE_unfused_fwd.csv (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/perf_csvs/RMSNorm_fwd.csv (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/perf_csvs/UnaryElementwise.csv (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/perf_csvs/gpu_timeline.csv (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/perf_csvs/ops_summary.csv (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/perf_csvs/ops_summary_by_category.csv (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/perf_csvs/ops_unique_args.csv (100%) rename tests/traces/inference/{graph_piecewise => vllm_prefilldecode_piecewise}/perf_csvs/unified_perf_summary.csv (100%) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0c5f80199..833fa65d1 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -14,7 +14,7 @@ # TraceDiff module and docs require Spandan review /TraceLens/TraceDiff/ @spandoesai -/docs/TraceDiff.md @spandoesai +/docs_original/TraceDiff.md @spandoesai # Extensions and experimental trace merge require Deval review /TraceLens/PerfModel/extensions/ @devalshahamd @@ -25,6 +25,9 @@ /TraceLens/Reporting/generate_perf_report_pytorch_inference.py @devalshahamd /TraceLens/TraceUtils/split_inference_trace_annotation.py @devalshahamd /examples/custom_workflows/inference_analysis/ @devalshahamd -/docs/Inference_analysis.md @devalshahamd +/docs_original/Inference_analysis.md @devalshahamd /tests/test_inference_perf_report.py @devalshahamd /tests/traces/inference/ @devalshahamd + +# Performance tracking require Kyle review +/tests/perf_tracker/ @kyle-hoffmeyer \ No newline at end of file diff --git a/.gitignore b/.gitignore index fd81cb0a9..09dc7947b 100755 --- a/.gitignore +++ b/.gitignore @@ -117,3 +117,4 @@ cmake-build-*/ *.exe *.dll *.dylib +.claude/settings.json diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 000000000..bcf15c580 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,22 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +version: 2 + +sphinx: + configuration: docs/conf.py + +build: + os: ubuntu-22.04 + tools: + python: "3.10" + +python: + install: + - requirements: docs/sphinx/requirements.txt diff --git a/README.md b/README.md index 77e6b3d98..186276aa5 100755 --- a/README.md +++ b/README.md @@ -37,9 +37,9 @@ TraceLens_generate_perf_report_pytorch --profile_json_path path/to/your/trace.js ``` This produces an Excel workbook with GPU timeline breakdown, ops summary, roofline metrics, and more. -See [Performance Report Column Definitions](docs/perf_report_columns.md) for what each column means. +See [Performance Report Column Definitions](docs_original/perf_report_columns.md) for what each column means. -**Don't have a trace yet?** Follow the [PyTorch profiling guide](docs/conceptual/torch_profiling_guide.ipynb), or use the [demo traces](tests/traces) bundled in the repo. +**Don't have a trace yet?** Follow the [PyTorch profiling guide](docs_original/conceptual/torch_profiling_guide.ipynb), or use the [demo traces](tests/traces) bundled in the repo. For the full CLI reference (JAX, rocprofv3, trace comparison, multi-rank collectives), see [Supported Profile Formats](#supported-profile-formats) below. @@ -65,10 +65,10 @@ For community-contributed utilities — including interactive trace dashboards ( | Format | Tool | Documentation | |--------|------|---------------| -| **PyTorch** | `torch.profiler` | [docs/generate_perf_report.md](docs/generate_perf_report.md) | -| **JAX** | XPlane protobuf | [docs/jax_analyses.md](docs/jax_analyses.md) | -| **rocprofv3 JSON** | AMD ROCm rocprofiler-sdk | [docs/generate_perf_report_rocprof.md](docs/generate_perf_report_rocprof.md) | -| **rocprofv3 pftrace** | Perfetto-style | [docs/generate_perf_report_rocprof_pftrace.md](docs/generate_perf_report_rocprof_pftrace.md) | +| **PyTorch** | `torch.profiler` | [docs_original/generate_perf_report.md](docs_original/generate_perf_report.md) | +| **JAX** | XPlane protobuf | [docs_original/jax_analyses.md](docs_original/jax_analyses.md) | +| **rocprofv3 JSON** | AMD ROCm rocprofiler-sdk | [docs_original/generate_perf_report_rocprof.md](docs_original/generate_perf_report_rocprof.md) | +| **rocprofv3 pftrace** | Perfetto-style | [docs_original/generate_perf_report_rocprof_pftrace.md](docs_original/generate_perf_report_rocprof_pftrace.md) | ### PyTorch @@ -76,7 +76,7 @@ For community-contributed utilities — including interactive trace dashboards ( TraceLens_generate_perf_report_pytorch --profile_json_path path/to/your/trace.json ``` -Detailed docs: [generate_perf_report.md](docs/generate_perf_report.md). Supports compressed traces (`.zip`, `.gz`). +Detailed docs: [generate_perf_report.md](docs_original/generate_perf_report.md). Supports compressed traces (`.zip`, `.gz`). ### Compare PyTorch reports @@ -88,7 +88,7 @@ TraceLens_compare_perf_reports_pytorch \ -o comparison.xlsx ``` -Detailed docs: [compare_perf_reports_pytorch.md](docs/compare_perf_reports_pytorch.md). +Detailed docs: [compare_perf_reports_pytorch.md](docs_original/compare_perf_reports_pytorch.md). ### Multi-rank collective report @@ -98,7 +98,7 @@ TraceLens_generate_multi_rank_collective_report_pytorch \ --world_size 8 ``` -Detailed docs: [generate_multi_rank_collective_report_pytorch.md](docs/generate_multi_rank_collective_report_pytorch.md). +Detailed docs: [generate_multi_rank_collective_report_pytorch.md](docs_original/generate_multi_rank_collective_report_pytorch.md). ### rocprofv3 JSON @@ -110,7 +110,7 @@ TraceLens_generate_perf_report_rocprof \ --short_kernel_study --kernel_details ``` -Detailed docs: [generate_perf_report_rocprof.md](docs/generate_perf_report_rocprof.md). +Detailed docs: [generate_perf_report_rocprof.md](docs_original/generate_perf_report_rocprof.md). ### pftrace (rocprofv3 / Perfetto) @@ -139,16 +139,16 @@ Deeper dives on the core modules: | Module | Doc | |--------|-----| -| Trace2Tree | [docs/Trace2Tree.md](docs/Trace2Tree.md) | -| TreePerf | [docs/TreePerf.md](docs/TreePerf.md) | -| NCCL Analyser | [docs/NcclAnalyser.md](docs/NcclAnalyser.md) | -| TraceDiff | [docs/TraceDiff.md](docs/TraceDiff.md) | -| Event Replay | [docs/EventReplay.md](docs/EventReplay.md) | -| TraceFusion | [docs/TraceFusion.md](docs/TraceFusion.md) | -| GPU Event Analyser | [docs/gpu_event_analyser.md](docs/gpu_event_analyser.md) | -| JAX Analyses | [docs/jax_analyses.md](docs/jax_analyses.md) | -| pftrace Reports | [docs/generate_perf_report_rocprof_pftrace.md](docs/generate_perf_report_rocprof_pftrace.md) | -| Performance Report Columns | [docs/perf_report_columns.md](docs/perf_report_columns.md) | +| Trace2Tree | [docs_original/Trace2Tree.md](docs_original/Trace2Tree.md) | +| TreePerf | [docs_original/TreePerf.md](docs_original/TreePerf.md) | +| NCCL Analyser | [docs_original/NcclAnalyser.md](docs_original/NcclAnalyser.md) | +| TraceDiff | [docs_original/TraceDiff.md](docs_original/TraceDiff.md) | +| Event Replay | [docs_original/EventReplay.md](docs_original/EventReplay.md) | +| TraceFusion | [docs_original/TraceFusion.md](docs_original/TraceFusion.md) | +| GPU Event Analyser | [docs_original/gpu_event_analyser.md](docs_original/gpu_event_analyser.md) | +| JAX Analyses | [docs_original/jax_analyses.md](docs_original/jax_analyses.md) | +| pftrace Reports | [docs_original/generate_perf_report_rocprof_pftrace.md](docs_original/generate_perf_report_rocprof_pftrace.md) | +| Performance Report Columns | [docs_original/perf_report_columns.md](docs_original/perf_report_columns.md) | ## Development @@ -166,7 +166,7 @@ Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on branching, commi ## Additional Resources -- [PyTorch Conference 2025 Poster](docs/TraceLens%20-%20Democratizing%20AI%20Performance%20Analysis%20-%20Adeem%20Jassani%2C%20AMD.pdf) -- [GEMMs in AI Models — Conceptual Tutorial](docs/conceptual/aimodels_gemms.md) -- [Trace2Tree Motivation](docs/conceptual/trace2tree_motivation.md) -- [PyTorch Profiling Guide](docs/conceptual/torch_profiling_guide.ipynb) +- [PyTorch Conference 2025 Poster](docs_original/TraceLens%20-%20Democratizing%20AI%20Performance%20Analysis%20-%20Adeem%20Jassani%2C%20AMD.pdf) +- [GEMMs in AI Models — Conceptual Tutorial](docs_original/conceptual/aimodels_gemms.md) +- [Trace2Tree Motivation](docs_original/conceptual/trace2tree_motivation.md) +- [PyTorch Profiling Guide](docs_original/conceptual/torch_profiling_guide.ipynb) diff --git a/TraceLens/Agent/Analysis/README.md b/TraceLens/Agent/Analysis/README.md index ee5a0e9c4..861144d36 100644 --- a/TraceLens/Agent/Analysis/README.md +++ b/TraceLens/Agent/Analysis/README.md @@ -63,7 +63,7 @@ pip install -e . The orchestrator runs against a single PyTorch profiler trace (`.json` or `.json.gz`). Collection is workload-specific: - **Training and eager inference traces**: Instrument your loop with `torch.profiler.profile(...)`, enabling CPU-side call-stack and shape capture (`with_stack=True`, `record_shapes=True`). Profile a representative steady-state window (a handful of training/inference steps, post-warmup) and dump the trace via `prof.export_chrome_trace(...)`. A single rank's trace is sufficient for per-rank analysis. -- **vLLM / SGLang inference traces**: Trace collection has framework-, version-, and execution-mode-specific requirements (custom Docker images or framework patches to add roofline annotations, profiler-config flags for graph-capture profiling, steady-state window selection, optional trace splitting). Follow the canonical guide in [Inference Analysis](../../../docs/Inference_analysis.md). For graph-mode workloads you will produce **two artifacts**: a graph-replay trace and a graph-capture folder; TraceLens (in inference mode with execution mode `graph replay + capture`) merges call-stack and shape information from the capture folder into the replay tree before analysis. +- **vLLM / SGLang inference traces**: Trace collection has framework-, version-, and execution-mode-specific requirements (custom Docker images or framework patches to add roofline annotations, profiler-config flags for graph-capture profiling, steady-state window selection, optional trace splitting). Follow the canonical guide in [Inference Analysis](../../../docs_original/Inference_analysis.md). For graph-mode workloads you will produce **two artifacts**: a graph-replay trace and a graph-capture folder; TraceLens (in inference mode with execution mode `graph replay + capture`) merges call-stack and shape information from the capture folder into the replay tree before analysis. --- diff --git a/TraceLens/Agent/Profiling/.cursor/skills/magpie-benchmark-profiling.md b/TraceLens/Agent/Profiling/.cursor/skills/magpie-benchmark-profiling.md index 6ea803958..4fcb5bd21 100644 --- a/TraceLens/Agent/Profiling/.cursor/skills/magpie-benchmark-profiling.md +++ b/TraceLens/Agent/Profiling/.cursor/skills/magpie-benchmark-profiling.md @@ -172,6 +172,12 @@ The flags below must be applied **regardless** of whether the user chooses targe ##### Common vLLM flags +> **Before setting `EXTRA_VLLM_ARGS` or `EXTRA_SGLANG_ARGS`:** check which script will run. If `benchmark_script` is not set in the YAML, Magpie looks for an InferenceX native script named `gptoss_{precision}_{runner}.sh` (for vLLM) or `dsr1_{precision}_{runner}.sh` (for SGLang) and selects it if found. SSH to the node and check: +> ```bash +> ssh "find /InferenceX/benchmarks -name 'gptoss_*' -o -name 'dsr1_*' | head -5" +> ``` +> If a native script is found (or if `benchmark_script` is explicitly set to an InferenceX native script), `EXTRA_VLLM_ARGS`/`EXTRA_SGLANG_ARGS` will be silently ignored. In that case, **stop and ask the user to set `benchmark_script` in their YAML to the appropriate Magpie generic script** (e.g. `vllm_mi300x.sh`) before proceeding. + Add these flags to `EXTRA_VLLM_ARGS` in the user's YAML config (append to any existing value): ```yaml @@ -284,7 +290,7 @@ If the YAML already has an `EXTRA_VLLM_ARGS` field with existing flags, **append **This patch is always required when using delay + max iterations.** The `run_benchmark_serving` function in `benchmark_lib.sh` **unconditionally overrides** `num_prompts` when `PROFILE=1` — this happens *after* parsing the `--num-prompts` argument, so it stomps whatever value the calling script (e.g. `vllm_mi300x.sh`) passes. Do NOT skip this patch even if the calling script already sets a larger `--num-prompts`. Without this fix, the benchmark finishes before the delay window is reached, and no steady-state trace is captured. ```bash -ssh "sed -i 's/num_prompts=\"\$((max_concurrency \* 1))\"/num_prompts=\"\$((max_concurrency * 10))\"/' \ +ssh "sed -i 's/num_prompts=\"\$max_concurrency\"/num_prompts=\"\$((max_concurrency * 10))\"/' \ /InferenceX/benchmarks/benchmark_lib.sh" ``` @@ -316,7 +322,7 @@ SGLang will skip `start_step` engine iterations (warmup), then profile for `num_ This is the same patch as for vLLM — `benchmark_lib.sh` is shared between both frameworks: ```bash -ssh "sed -i 's/num_prompts=\"\$((max_concurrency \* 1))\"/num_prompts=\"\$((max_concurrency * 10))\"/' \ +ssh "sed -i 's/num_prompts=\"\$max_concurrency\"/num_prompts=\"\$((max_concurrency * 10))\"/' \ /InferenceX/benchmarks/benchmark_lib.sh" ``` @@ -553,9 +559,13 @@ In the Python config dataclass, `TorchProfilerConfig.enabled` defaults to `True` ### 8. `benchmark_lib.sh` unconditionally overrides `num_prompts` when profiling -When `PROFILE=1`, the `run_benchmark_serving` function in `benchmark_lib.sh` **unconditionally** sets `num_prompts="$((max_concurrency * 1))"` *after* parsing all `--num-prompts` arguments. This means even if the calling benchmark script (e.g. `vllm_mi300x.sh`) explicitly passes `--num-prompts $(( $CONC * 10 ))`, that value gets overwritten. When using `delay_iterations` + `max_iterations` for steady-state profiling, you **must** patch `benchmark_lib.sh` to increase this multiplier, otherwise the benchmark ends before the profiling window starts and no trace is captured. +When `PROFILE=1`, the `run_benchmark_serving` function in `benchmark_lib.sh` **unconditionally** sets `num_prompts="$max_concurrency"` *after* parsing all `--num-prompts` arguments. This means even if the calling benchmark script (e.g. `vllm_mi300x.sh`) explicitly passes `--num-prompts $(( $CONC * 10 ))`, that value gets overwritten. When using `delay_iterations` + `max_iterations` for steady-state profiling, you **must** patch `benchmark_lib.sh` to increase this multiplier, otherwise the benchmark ends before the profiling window starts and no trace is captured. + +### 9. `EXTRA_VLLM_ARGS` / `EXTRA_SGLANG_ARGS` are silently ignored by InferenceX native scripts + +InferenceX native scripts (`gptoss_fp4_mi300x.sh`, `dsr1_fp8_mi300x.sh`, etc.) hardcode their own `vllm serve` invocation and do not reference `$EXTRA_VLLM_ARGS`/`EXTRA_SGLANG_ARGS`. Magpie selects these over its own generic scripts for named models, so flags set in `EXTRA_VLLM_ARGS`/`EXTRA_SGLANG_ARGS` silently have no effect. Set `benchmark_script` in the YAML to the appropriate Magpie generic script (e.g. `vllm_mi300x.sh`) to ensure `EXTRA_VLLM_ARGS`/`EXTRA_SGLANG_ARGS` is passed through. -### 9. The `hf_cache_path` field avoids re-downloading models +### 10. The `hf_cache_path` field avoids re-downloading models If the node has a shared HuggingFace cache, set `hf_cache_path` in the config to avoid multi-hour model downloads. This path is mounted into the container. diff --git a/TraceLens/Agent/Profiling/README.md b/TraceLens/Agent/Profiling/README.md index b6b5e41b7..09d2c575c 100644 --- a/TraceLens/Agent/Profiling/README.md +++ b/TraceLens/Agent/Profiling/README.md @@ -151,7 +151,7 @@ The skill parses the `case` blocks of these scripts at runtime to discover curre ## Trace Splitting and Handoff to Analysis -Step 6 produces split traces in `torch_trace/trace_split/` via `TraceLens.TraceUtils.split_inference_trace_annotation`. The skill then prints (but does **not** run) a `generate_perf_report_pytorch_inference.py` command that the user can launch to feed the split traces into the [Analysis Orchestrator](../Analysis/README.md). See [`docs/Inference_analysis.md`](../../../docs/Inference_analysis.md) for splitting heuristics and prefill/decode mix selection. +Step 6 produces split traces in `torch_trace/trace_split/` via `TraceLens.TraceUtils.split_inference_trace_annotation`. The skill then prints (but does **not** run) a `generate_perf_report_pytorch_inference.py` command that the user can launch to feed the split traces into the [Analysis Orchestrator](../Analysis/README.md). See [`docs_original/Inference_analysis.md`](../../../docs_original/Inference_analysis.md) for splitting heuristics and prefill/decode mix selection. ## Bug Reporting diff --git a/TraceLens/PerfModel/extensions/__init__.py b/TraceLens/PerfModel/extensions/__init__.py index b9593f766..d919d5c65 100644 --- a/TraceLens/PerfModel/extensions/__init__.py +++ b/TraceLens/PerfModel/extensions/__init__.py @@ -19,6 +19,9 @@ moe_gptq_awq_down, moe_flydsl_stage1, moe_flydsl_stage2, + sglang_fused_append_shared_experts, + BiasedGroupedTopk, + MoeSortScatterGather, ) from .attention_perf_model_extensions import ( InferenceAttention, @@ -32,6 +35,10 @@ gemm_a8w8_blockscale, aiter_gelu_and_mul, aiter_gelu_tanh_and_mul, + aiter_fused_qk_rope_cat_and_cache_mla, + sglang_quant_dynamic_mxfp4_quant, + aiter_fused_dynamic_mxfp4_quant_moe_sort_hip, + aiter_dynamic_per_group_scaled_quant_fp4, ) from .rmsnorm_perf_model_extensions import ( aiter_rms_norm, @@ -45,6 +52,7 @@ ) from .custom_collectives_perf_model_extensions import ( aiter_fused_allreduce_rmsnorm, + aiter_fused_allreduce_rmsnorm_, custom_ar_all_reduce, aiter_reduce_scatter, aiter_all_gather_reg, @@ -68,6 +76,8 @@ "moe_gptq_awq_down", "moe_flydsl_stage1", "moe_flydsl_stage2", + "BiasedGroupedTopk", + "MoeSortScatterGather", "mha_varlen_fwd", "aiter_fmha_v3_varlen_fwd", "vllm_unified_attention_with_output", @@ -75,6 +85,11 @@ "gemm_a8w8_blockscale", "aiter_gelu_and_mul", "aiter_gelu_tanh_and_mul", + "aiter_fused_qk_rope_cat_and_cache_mla", + "sglang_quant_dynamic_mxfp4_quant", + "aiter_fused_dynamic_mxfp4_quant_moe_sort_hip", + "aiter_dynamic_per_group_scaled_quant_fp4", + "sglang_fused_append_shared_experts", # RMSNorm classes "aiter_rms_norm", "aiter_rmsnorm", @@ -86,6 +101,7 @@ "vllm_rocm_aiter_triton_add_rmsnorm_pad", # Collective classes "aiter_fused_allreduce_rmsnorm", + "aiter_fused_allreduce_rmsnorm_", "custom_ar_all_reduce", "aiter_reduce_scatter", "aiter_all_gather_reg", diff --git a/TraceLens/PerfModel/extensions/attention_perf_model_extensions.py b/TraceLens/PerfModel/extensions/attention_perf_model_extensions.py index e8c5c906d..3bcc4bf02 100644 --- a/TraceLens/PerfModel/extensions/attention_perf_model_extensions.py +++ b/TraceLens/PerfModel/extensions/attention_perf_model_extensions.py @@ -283,6 +283,22 @@ def bytes_func( # Instance methods – work for any subclass with valid param_details # ------------------------------------------------------------------ + def _cap_gen_kv(self, value): + """Cap a generation KV aggregate to the sliding window. + + Opt-in via ``param_details["sliding_window"]`` (W). Generation (decode) + tokens have ``sq = 1``, so each attends to ``min(ctx_i, W)`` KV tokens. + With only aggregates available (``g_sk = Σ ctx``, ``g_sq = #requests``), + ``Σ min(ctx_i, W)`` is approximated by ``min(value, g_sq * W)`` -- exact + when all contexts are on one side of W (typical in steady-state decode), + an upper bound otherwise. No-op when ``sliding_window`` is unset or <= 0, + so non-windowed attention models are unaffected. + """ + w = self.param_details.get("sliding_window") + if w and w > 0 and self.param_details.get("g_sq"): + return min(value, self.param_details["g_sq"] * w) + return value + def flops(self): if self.param_details.get("_no_perf"): return None @@ -296,7 +312,7 @@ def flops(self): self.d_h_v, self.param_details["c_sqsk"], self.param_details["c_sqsq"], - self.param_details["g_sqsk"], + self._cap_gen_kv(self.param_details["g_sqsk"]), ) def bytes(self, bytes_per_element=None): @@ -316,7 +332,7 @@ def bytes(self, bytes_per_element=None): self.param_details["c_sq"], self.param_details["c_sk"], self.param_details["g_sq"], - self.param_details["g_sk"], + self._cap_gen_kv(self.param_details["g_sk"]), bpe, bpe_kv, ) @@ -495,6 +511,73 @@ class vllm_unified_mla_attention_with_output(InferenceAttention): pass +class pa_decode_gluon(InferenceAttention): + """ + Performance model for ``aiter::pa_decode_gluon`` (gluon Triton kernel + ``paged_attention_decode_sliding_window``; inference: ATOM/vLLM). + + Grouped-query paged decode attention over an FP8 E4M3 KV cache. + + Decode-only kernel — it never processes prefill/context requests (a separate + extend kernel does). So ``get_param_details`` forces the context aggregates + (``c_*``) to 0, which collapses the inherited ``flops``/``bytes`` to the + generation-only roofline, and sets ``dtype_KV`` from the FP8 cache. + + Sliding window: the ``sliding_window`` arg (``Concrete Inputs[19]``) caps the + KV each query attends to at ``min(ctx_i, W)``. It is surfaced as + ``param_details["sliding_window"]`` and the base roofline applies the cap + (aggregate approximation ``min(g_sk, g_sq*W)``). ``-1`` layers (full + attention) are unaffected. + """ + + @staticmethod + def get_param_details(event): + try: + annotation = str(event.get("annotation")) + stats = InferenceAttention._parse_chunk_stats(annotation) + + dims = event["args"]["Input Dims"] + types = event["args"]["Input type"] + q_shape = dims[0] + N_Q, H_Q, d_h_qk = q_shape[0], q_shape[1], q_shape[2] + # k_cache: [num_blocks, H_KV, ...] -> H_KV at index 1 + H_KV = dims[2][1] + d_h_v = d_h_qk # logical V head dim matches Q for this kernel + # Decode-only kernel: it never processes prefill/context requests + stats["c_sq"] = stats["c_sk"] = stats["c_sqsq"] = stats["c_sqsk"] = 0 + N_KV = stats["g_sk"] + dtype_Q = types[0] + dtype_KV = types[2] if len(types) > 2 else types[0] + # sliding_window is the positional `sliding_window` arg; <= 0 (e.g. + # -1) means full attention. Capping is applied by the base roofline. + conc = event["args"].get("Concrete Inputs") or [] + try: + sliding_window = int(conc[19]) + except (IndexError, ValueError, TypeError): + sliding_window = 0 + + return { + "B": 1, + "N_Q": N_Q, + "H_Q": H_Q, + "H_V": H_KV, + "H_K": H_KV, + "N_KV": N_KV, + "H_KV": H_KV, + "d_h_qk": d_h_qk, + "d_h_v": d_h_v, + "dropout": 0.0, + "causal": False, + "flash_impl": True, + **stats, + "dtype_Q": dtype_Q, + "dtype_KV": dtype_KV, + "sliding_window": sliding_window, + } + except (NotImplementedError, ValueError, IndexError, KeyError, TypeError): + return InferenceAttention.no_perf_param_details() + + class gdn_attention_core(InferenceAttention): """ Performance model for vllm::gdn_attention_core (Gated Delta Network). diff --git a/TraceLens/PerfModel/extensions/custom_collectives_perf_model_extensions.py b/TraceLens/PerfModel/extensions/custom_collectives_perf_model_extensions.py index 3aea2a303..7bf7b0bd4 100644 --- a/TraceLens/PerfModel/extensions/custom_collectives_perf_model_extensions.py +++ b/TraceLens/PerfModel/extensions/custom_collectives_perf_model_extensions.py @@ -80,6 +80,37 @@ def bytes(self): return bytes_read + bytes_write +class aiter_fused_allreduce_rmsnorm_(aiter_fused_allreduce_rmsnorm): + """ + Performance model for the high-level Python op aiter::fused_allreduce_rmsnorm_. + + Same fused AllReduce + residual-add + RMSNorm math as the base class, but the + recorded argument layout follows the Python wrapper's signature + (inp, res_inp, w, eps, group_name, prefill_support, x_pad_to_multiple, gemma_norm) + rather than the low-level C++ op's (ptr, reg, inp, res_inp, res_out, out, w, eps, ...). + + Expected Input Dims from trace: + [inp_shape, res_inp_shape, w_shape, eps, group_name, prefill_support, x_pad_to_multiple] + e.g. ((64, 7168), (64, 7168), (7168,), (), (), (), ()) + + So inp is at index 0 and weight at index 2 (vs [2] / [6] in the base class). + __init__, flops(), and bytes() are inherited unchanged. + """ + + @staticmethod + def get_param_details(event): + op_shape = tuple(event["args"]["Input Dims"][0]) # inp: [M, N] + dtype_in = event["args"]["Input type"][0] # BFloat16 + stride_input = tuple(event["args"]["Input Strides"][0]) + num_channels = event["args"]["Input Dims"][2][0] # weight.shape[0] = N + return { + "op_shape": op_shape, + "dtype_in": dtype_in, + "stride_input": stride_input, + "num_channels": num_channels, + } + + class custom_ar_all_reduce(CustomCollective): """ Performance model for _C_custom_ar::all_reduce. diff --git a/TraceLens/PerfModel/extensions/moe_perf_model_extensions.py b/TraceLens/PerfModel/extensions/moe_perf_model_extensions.py index b3353138d..43b1da5d3 100644 --- a/TraceLens/PerfModel/extensions/moe_perf_model_extensions.py +++ b/TraceLens/PerfModel/extensions/moe_perf_model_extensions.py @@ -8,7 +8,10 @@ Performance models for pseudo-op extensions. """ -from TraceLens.PerfModel.utils import torch_dtype_map +from math import prod + +from TraceLens.PerfModel.utils import torch_dtype_map, name2bpe +from TraceLens.PerfModel.perf_model import BinaryElementwise DTYPE_TO_BYTES = { "Float8_e4m3fn": 1, @@ -1063,7 +1066,7 @@ def get_param_details(event): Extract MoE dimensions and data types from event args. Expected Input Dims format (from aiter::ck_moe_stage1): - [[tokens, hidden_dim], [E, N, K_packed], [E, hidden_dim, inter_dim_packed], + [[tokens, hidden_dim_packed], [E, N, K_packed], [E, hidden_dim, inter_dim_packed], [sorted_ids], [sorted_expert_ids], [num_valid_ids], [tokens, topk, inter_dim], ...] @@ -1079,12 +1082,13 @@ def get_param_details(event): out_shape = kernel_input_shape[6] num_tokens = input_shape[0] - hidden_dim = input_shape[1] - E, hidden_dim_w2, inter_dim = w2_shape + E, hidden_dim, inter_dim = w2_shape - # Account for INT4 weight packing: w1's K dim may be compressed - int4_war = hidden_dim_w2 // w1_shape[-1] + # Account for FP4/INT4 weight packing: w1's K dim may be compressed. + # The packing factor is the ratio of the unpacked hidden_dim (from w2) + # to w1's packed K dim, and also applies to inter_dim. + int4_war = hidden_dim // w1_shape[-1] inter_dim *= int4_war num_experts = E @@ -1166,7 +1170,7 @@ def get_param_details(event): Extract MoE dimensions and data types from event args. Expected Input Dims format (from aiter::ck_moe_stage2): - [[tokens, topk, inter_dim], [E, N, K], [E, hidden_dim, inter_dim_packed], + [[tokens, topk, inter_dim_packed], [E, N, K_packed], [E, hidden_dim, inter_dim_packed], [sorted_ids], [sorted_expert_ids], [num_valid_ids], [tokens, hidden_dim], ...] @@ -1177,11 +1181,18 @@ def get_param_details(event): kernel_input_shape = args["Input Dims"] input_shape = kernel_input_shape[0] + w1_shape = kernel_input_shape[1] w2_shape = kernel_input_shape[2] num_tokens, topk, inter_dim = input_shape num_experts, hidden_dim, _ = w2_shape + # Account for FP4/INT4 packing: inter_states' last dim (and w2's last + # dim) may be packed. The packing factor is the ratio of the unpacked + # hidden_dim (w2's middle dim) to w1's packed K dim. + int4_war = hidden_dim // w1_shape[-1] if w1_shape else 1 + inter_dim *= int4_war + input_dtype = args["Input type"][0] weight_dtype = args["Input type"][2] @@ -1714,3 +1725,216 @@ def get_compute_precision(self): def get_maf_type(self): return "matrix" + + +class sglang_fused_append_shared_experts(BinaryElementwise): + """ + Performance model for + sglang_profiler::fused_moe_triton_kernels_fused_append_shared_experts. + + Reference implementation: + sglang/python/sglang/srt/layers/moe/fused_moe_triton/ + fused_moe_triton_kernels.py (fused_append_shared_experts) + called from sglang/srt/layers/moe/topk.py:1264 (_post_process_topk_ids) + + Appends shared-expert routing entries onto the per-token (topk_ids, + topk_weights) tensors produced by the router. This is a routing/metadata op: + no GEMM-style arithmetic, dominated by reading + rewriting the small + (num_tokens, topk) id/weight tensors. + + Expected Input Dims from trace: + [0] = (M, topk) ids (int32) + [1] = (M, topk) weights (float32) + + Roofline -- FLOPs: + ~0 (index/weight gather + write); modeled as 1 op/element for a + non-zero roofline floor. + + Roofline -- bytes moved: + read + write both id and weight tensors: + 2 * (M*topk*bpe_ids + M*topk*bpe_wts) + + Reuses core BinaryElementwise (2-input machinery, get_maf_type); + overrides the roofline for the read+write pattern. + """ + + category = "MoE_aux" + bwd_category = None + sheet_category = "MoE_aux" + + @staticmethod + def get_param_details(event): + dims = event["args"]["Input Dims"] + types = event["args"]["Input type"] + ids_shape = tuple(dims[0]) + wts_shape = tuple(dims[1]) if len(dims) > 1 and dims[1] else ids_shape + dtype_ids = types[0] if types else "int" + dtype_wts = types[1] if len(types) > 1 else "float" + return { + "shape_in1": ids_shape, + "shape_in2": wts_shape, + "dtype_in1_in2_out": (dtype_ids, dtype_wts, dtype_wts), + "stride_input1": None, + "stride_input2": None, + "stride_output": None, + } + + def flops(self): + return prod(self.param_details["shape_in1"]) + + def bytes(self): + n_ids = self.nelems_in1 + n_wts = self.nelems_in2 + bpe_ids = self.bpe_in1 or 4 + bpe_wts = self.bpe_in2 or 4 + return 2 * (n_ids * bpe_ids + n_wts * bpe_wts) + + def get_compute_precision(self): + dtype = self.param_details["dtype_in1_in2_out"][1] + return torch_dtype_map(dtype) if dtype else None + + +# ============================================================================== +# MoE routing / sort auxiliary models (non-matmul, MoE_aux) +# ============================================================================== + + +class BiasedGroupedTopk: + """ + Performance model for aiter::biased_grouped_topk_hip (DeepSeek grouped MoE + router top-k). Memory-bound: 1 flop/element over the dominant tensor, bytes + summed over all operands. + + Reference: + sglang/python/sglang/srt/layers/moe/topk.py (biased_grouped_topk). + + Expected Input Dims: + [[M, E], [E], [M, topk], [M, topk], ...] + [0] gating_output (logits) + [1] correction_bias + [2] topk_weights (out) + [3] topk_ids (out) + """ + + category = "MoE_aux" + bwd_category = None + sheet_category = "MoE_aux" + + def __init__(self, event, arch=None, python_path=None): + self.event = event + self.arch = arch + self.python_path = python_path + self.param_details = self.get_param_details(event) + + @staticmethod + def get_param_details(event): + args = event.get("args", {}) + dims = args["Input Dims"] + types = args.get("Input type", []) + operands = [ + (tuple(shape), types[i] if i < len(types) else None) + for i, shape in enumerate(dims) + if shape and all(isinstance(d, int) for d in shape) + ] + return {"operands": operands} + + def flops(self): + operands = self.param_details["operands"] + if not operands: + return 0 + return max(prod(shape) for shape, _ in operands) + + def bytes(self): + total = 0 + for shape, dtype in self.param_details["operands"]: + bpe = name2bpe(dtype) + if bpe is not None: + total += prod(shape) * bpe + return total if total > 0 else None + + def flops_bwd(self): + raise NotImplementedError("Backward pass for MoE top-k routing is not defined.") + + def bytes_bwd(self): + raise NotImplementedError("Backward pass for MoE top-k routing is not defined.") + + def get_compute_precision(self): + operands = self.param_details["operands"] + if not operands: + return None + _, dtype = max(operands, key=lambda o: prod(o[0])) + return torch_dtype_map(dtype) if dtype else None + + def get_maf_type(self): + return "vector" + + +class MoeSortScatterGather: + """ + Performance model for the MoE token sort/scatter kernels + aiter::moe_sorting_fwd and aiter::mxfp4_moe_sort_hip (permute per-token data + into the expert-contiguous layout). Memory-bound: 1 flop/element over the + dominant tensor, bytes summed over all operands. + + Reference: + aiter/aiter/ops/triton/moe_op_mxfp4.py (mxfp4_moe_sort_hip); SGLang + AITER fused_moe sort path (moe_align_block_size). + + Expected Input Dims (examples): + moe_sorting_fwd: [[M, topk], [M, topk], [P], [P], [blocks], [2], + [M, hidden], ...] + mxfp4_moe_sort_hip: [[P, S], [M, S], [P], [2], ...] + """ + + category = "MoE_aux" + bwd_category = None + sheet_category = "MoE_aux" + + def __init__(self, event, arch=None, python_path=None): + self.event = event + self.arch = arch + self.python_path = python_path + self.param_details = self.get_param_details(event) + + @staticmethod + def get_param_details(event): + args = event.get("args", {}) + dims = args.get("Input Dims", []) + types = args.get("Input type", []) + operands = [ + (tuple(shape), types[i] if i < len(types) else None) + for i, shape in enumerate(dims) + if shape and all(isinstance(d, int) for d in shape) + ] + return {"operands": operands} + + def flops(self): + operands = self.param_details["operands"] + if not operands: + return 0 + return max(prod(shape) for shape, _ in operands) + + def bytes(self): + total = 0 + for shape, dtype in self.param_details["operands"]: + bpe = name2bpe(dtype) + if bpe is None: + continue + total += prod(shape) * bpe + return total if total > 0 else None + + def flops_bwd(self): + raise NotImplementedError("Backward pass for MoE sort/scatter is not defined.") + + def bytes_bwd(self): + raise NotImplementedError("Backward pass for MoE sort/scatter is not defined.") + + def get_compute_precision(self): + operands = self.param_details["operands"] + if not operands: + return None + _, dtype = max(operands, key=lambda o: prod(o[0])) + return torch_dtype_map(dtype) if dtype else None + + def get_maf_type(self): + return "vector" diff --git a/TraceLens/PerfModel/extensions/perf_model_extensions.py b/TraceLens/PerfModel/extensions/perf_model_extensions.py index a9fc87f0b..2ea77577a 100644 --- a/TraceLens/PerfModel/extensions/perf_model_extensions.py +++ b/TraceLens/PerfModel/extensions/perf_model_extensions.py @@ -67,18 +67,44 @@ class gemm_a8w8_blockscale(GEMM): @staticmethod def get_param_details(event): - return { + dims = event["args"]["Input Dims"] + types = event["args"].get("Input type", []) or [] + M, K = dims[0][0], dims[0][1] + N = dims[1][0] + details = { "B": 1, - "M": event["args"]["Input Dims"][0][0], - "N": event["args"]["Input Dims"][1][0], - "K": event["args"]["Input Dims"][0][1], + "M": M, + "N": N, + "K": K, "bias": False, "dtype_A_B": ( - event["args"]["Input type"][0], - event["args"]["Input type"][1], + types[0] if len(types) > 0 else "", + types[1] if len(types) > 1 else "", "c10::bfloat16", ), } + # FP8/INT8 block-scale quant config; block sizes derived from scale-tensor shapes. + try: + x_scale, w_scale = dims[2], dims[3] + block_k = ( + (-(-K // x_scale[-1])) if x_scale and x_scale[-1] else None + ) # ceil(K/scale_cols) + block_n = (-(-N // w_scale[0])) if w_scale and w_scale[0] else None + details.update( + { + "quant_scheme": "a8w8_blockscale", + "quant_granularity": "per_block", + "block_k": block_k, + "block_n": block_n, + "scale_dtype": types[2] if len(types) > 2 else "float32", + } + ) + except (IndexError, TypeError, ZeroDivisionError): + pass + # Output spec is inferred (torch traces record input dims only): Y[M, N] in bf16. + details["output_shape"] = (M, N) + details["output_dtype"] = "c10::bfloat16" + return details def bytes(self): dtype_A_B = self.param_details["dtype_A_B"] @@ -375,6 +401,73 @@ def bytes(self): ) +class gemm_a16w16(gemm_a16w16_atomic_): + """ + Performance model for AITER's gemm_a16w16 kernel. + + Computes: Y[M, N] = X[M, K] @ W[N, K].T. Both X and W are BF16/FP16. + + Reference implementation: + aiter/aiter/ops/triton/gemm/basic/gemm_a16w16.py + + Identical roofline to gemm_a16w16_atomic_; only the output dtype handling + differs. The traced arg layout is (x, w, bias, dtype, ...), so Input type[3] + is the output ``dtype`` scalar (recorded as ``Scalar``) rather than a tensor. + The output dtype therefore follows the input (BF16, per the aiter default), + not Input type[3] as in the atomic_ variant (where index 3 is the output + tensor ``y``). flops/bytes/compute-precision are inherited. + """ + + @staticmethod + def get_param_details(event): + dims = event["args"]["Input Dims"] + types = event["args"]["Input type"] + bias = len(dims) > 2 and len(dims[2]) > 0 + return { + "B": 1, + "M": dims[0][0], + "N": dims[1][0], + "K": dims[0][1], + "bias": bias, + "dtype_A_B": (types[0], types[1], types[0]), + } + + +class gemm_a16w16_asm(gemm_a16w16_atomic_): + """ + Performance model for AITER's _gemm_a16w16_asm kernel (the ASM variant of + gemm_a16w16_atomic_). Computes Y[M, N] = X[M, K] @ W[N, K].T with X, W and + output Y all BF16/FP16. + + The ASM kernel has a distinct argument layout from the Triton atomic variant: the output tensor + appears at Input index 2 (shape [M, N]), while Input index 3 is a non-tensor split-K workspace with + dtype "unsigned int." Using the parent's logic to infer the output dtype from index 3 results in + incorrect data movement accounting (Data Moved = NaN); this model explicitly references the correct + output tensor and its dtype. + + Expected Input Dims from trace: + [[M, K], [N, K], [M, N], [split-K workspace], ...] + + Expected Input type from trace: + [dtype_x, dtype_w, dtype_output, ...] + """ + + @staticmethod + def get_param_details(event): + itype = event["args"]["Input type"] + out_dtype = ( + itype[2] if len(itype) > 2 and name2bpe(itype[2]) is not None else itype[0] + ) + return { + "B": 1, + "M": event["args"]["Input Dims"][0][0], + "N": event["args"]["Input Dims"][1][0], + "K": event["args"]["Input Dims"][0][1], + "bias": False, + "dtype_A_B": (itype[0], itype[1], out_dtype), + } + + class GroupQuant(BinaryElementwise): """ Performance model for group quantization. @@ -454,8 +547,8 @@ def flops(self): def get_compute_precision(self): """Return the compute precision for this operation.""" - # Use first input dtype as the compute precision - dtype = self.dtype_in1_in2_out[1] if self.dtype_in1_in2_out else None + # Use the input activation dtype (index 0) as the compute precision; + dtype = self.dtype_in1_in2_out[0] if self.dtype_in1_in2_out else None return torch_dtype_map(dtype) if dtype else None @@ -795,6 +888,34 @@ def bytes(self): return bytes_read + bytes_write_fp4 + bytes_write_scales +class fused_dynamic_mx_quant_moe_sort_hip(fused_flatten_mxfp4_quant): + """ + Performance model for aiter::fused_dynamic_mx_quant_moe_sort_hip + (kernel aiter::fused_mx_quant_moe_sort_kernel). + + Fuses dynamic MXFP4 quantization of the BF16 activation with MoE token sort. + Trace arg layout differs from fused_flatten_mxfp4_quant only in input + position: [0] is the packed FP4 output (M, N/2), [1] the E8M0 block scales, + [2] the BF16 activation input (M, N), and [3]/[4] the int sort arrays. + + Approximation: models the quant traffic over the activation input. The MoE + sort index permutation (small int arrays) and the padded sorted-layout rows + are runtime-dependent and excluded. + """ + + @staticmethod + def get_param_details(event): + op_shape = tuple(event["args"]["Input Dims"][2]) + dtype_in = event["args"]["Input type"][2] + stride_input = tuple(event["args"]["Input Strides"][2]) + return { + "op_shape": op_shape, + "dtype_in_out": (dtype_in, dtype_in), + "stride_input": stride_input, + "stride_output": None, + } + + class aiter_rope_cached_positions_2c_fwd_impl(FusedRoPE): """ Performance model for aiter::rope_cached_positions_2c_fwd_impl. @@ -956,3 +1077,296 @@ def get_maf_type(self): def get_compute_precision(self): dtype = self.param_details.get("dtype") return torch_dtype_map(dtype) if dtype else None + + +class mixed_sample_outer_exponential: + """ + Performance model for ``aiter::mixed_sample_outer_exponential`` (ATOM + ``model_ops/sampler.py``, ``mix_sample_outer_exponential_kernel``). + + Exponential-noise sampling: ``token_id[t] = argmax_v(logits[t,v] / + exp_noise[t,v])`` over the vocab dim. Memory-bound elementwise reduction. + Reads logits ``Input Dims[1]`` [T, V] and exp_noise ``Input Dims[2]``; + FLOPs = 2*T*V, bytes = read logits + read exp_noise + write T int32 ids. + """ + + category = "elementwise" + bwd_category = None + + def __init__(self, event, arch=None, python_path=None): + self.T = self.param_details["T"] + self.V = self.param_details["V"] + self.dtype_logits = self.param_details["dtype_logits"] + self.dtype_noise = self.param_details["dtype_noise"] + logits_shape = tuple(dims[1]) + T = logits_shape[0] if len(logits_shape) >= 1 else 1 + V = logits_shape[1] if len(logits_shape) >= 2 else 1 + dtype_logits = types[1] if len(types) > 1 else "c10::bfloat16" + dtype_noise = types[2] if len(types) > 2 else "float" + return { + "T": T, + "V": V, + "dtype_logits": dtype_logits, + "dtype_noise": dtype_noise, + } + + def flops(self): + return 2 * self.T * self.V + + def bytes(self): + bpe_logits = name2bpe(self.dtype_logits) + bpe_noise = name2bpe(self.dtype_noise) + if bpe_logits is None or bpe_noise is None: + return None + read_logits = self.T * self.V * bpe_logits + read_noise = self.T * self.V * bpe_noise + write_ids = self.T * 4 # int32 token id per row + return read_logits + read_noise + write_ids + + def get_maf_type(self): + return "vector" + + def get_compute_precision(self): + return torch_dtype_map(self.dtype_logits) if self.dtype_logits else None + + +class aiter_fused_qk_rope_cat_and_cache_mla(FusedRoPE): + """ + Performance model for aiter::fused_qk_rope_cat_and_cache_mla + (RoPE on q_pe/k_pe + KV-cache write). + + Reference implementation: + aiter/aiter/ops/triton/fusions/fused_kv_cache.py:88 + (kernel _fused_qk_rope_cat_and_cache_mla_kernel) + + Applies rotary position embedding to the rope (pe) slices of Q and K, + concatenates the nope + pe parts into a single head dim, returns the rotated + Q, and writes the concatenated K (nope || pe) into kv_cache in place at the + slots given by slot_mapping. + + Expected Input Dims from trace: + [0] q_nope = (T, QH, D_lora) + [1] q_pe = (T, QH, D_pe) + [2] k_nope = (T, KH, D_lora) + [3] k_pe = (T, KH, D_pe) + [4] kv_cache = (B_cache, KH, D_lora + D_pe) + ... + + Expected Input type from trace: + [bf16, bf16, bf16, bf16, , ...] + + Roofline -- FLOPs: + RoPE rotates only the pe slices of Q and K. ~3 FLOPs/element. + flops = 3 * (T*QH*D_pe + T*KH*D_pe) + + Roofline -- bytes moved: + read q_nope + q_pe + k_nope + k_pe : nelems * bpe_in + write q_out (T, QH, D_lora+D_pe) : T*QH*(D_lora+D_pe) * bpe_out + write kv rows (T tokens written) : T*KH*(D_lora+D_pe) * bpe_kv + cos/sin/pos are small + cache-resident; omitted. + + """ + + sheet_category = "FusedRoPE" + + def __init__(self, event, arch=None, python_path=None, **kwargs): + self.event = event + self.arch = arch + self.python_path = python_path + self.param_details = self.get_param_details(event) + self.bpe_in = name2bpe(self.param_details["dtype_in"]) + self.bpe_kv = name2bpe(self.param_details["dtype_kv"]) + + @staticmethod + def get_param_details(event): + dims = event["args"]["Input Dims"] + types = event["args"]["Input type"] + q_nope = tuple(dims[0]) + q_pe = tuple(dims[1]) + k_nope = tuple(dims[2]) + T, QH, D_lora = q_nope + D_pe = q_pe[2] + KH = k_nope[1] + dtype_in = types[0] + dtype_kv = types[4] if len(types) > 4 and types[4] else dtype_in + return { + "T": T, + "QH": QH, + "KH": KH, + "D_lora": D_lora, + "D_pe": D_pe, + "dtype_in": dtype_in, + "dtype_kv": dtype_kv, + } + + def flops(self): + p = self.param_details + return 3 * (p["T"] * p["QH"] * p["D_pe"] + p["T"] * p["KH"] * p["D_pe"]) + + def bytes(self): + p = self.param_details + T, QH, KH, D_lora, D_pe = (p["T"], p["QH"], p["KH"], p["D_lora"], p["D_pe"]) + bpe_in = self.bpe_in + if bpe_in is None: + return None + bpe_out = bpe_in # q_out keeps the Q input dtype + bpe_kv = self.bpe_kv if self.bpe_kv is not None else bpe_in + read_q = (T * QH * D_lora + T * QH * D_pe) * bpe_in + read_k = (T * KH * D_lora + T * KH * D_pe) * bpe_in + write_q = T * QH * (D_lora + D_pe) * bpe_out + write_kv = T * KH * (D_lora + D_pe) * bpe_kv + return read_q + read_k + write_q + write_kv + + def get_compute_precision(self): + return torch_dtype_map(self.param_details["dtype_in"]) + + +class fused_qk_rope_concat_and_cache_mla(aiter_fused_qk_rope_cat_and_cache_mla): + """ + Performance model for aiter::fused_qk_rope_concat_and_cache_mla + (kernel fuse_qk_rope_concat_and_cache_mla_per_head_kernel; DeepSeek-V3.1 MLA). + + RoPE on the pe slices of Q/K + static FP8 quant + paged KV-cache write. + Trace arg layout: [0] q_nope (T, QH, D_lora), [1] q_pe (T, QH, D_pe), + [2] kv_c (T, D_lora), [3] k_pe (T, D_pe), [4] kv_cache (FP8 paged), + [5] q_out (T, QH, D_lora + D_pe), FP8. + + the KV is the single MLA latent (kv_c / k_pe are 2D, so KH = 1), + and both q_out and the KV cache are FP8 + (the base assumes q_out keeps the BF16 input dtype). + + Approximation: only the T written KV slots are counted, not the full paged + cache tensor at Input Dims[4]; cos/sin/positions are small / cache-resident; + the per-tensor FP8 quant flops are omitted. + """ + + @staticmethod + def get_param_details(event): + dims = event["args"]["Input Dims"] + types = event["args"]["Input type"] + T, QH, D_lora = tuple(dims[0]) + D_pe = dims[1][2] + KH = 1 # MLA single latent KV head (kv_c / k_pe are 2D [T, D]) + dtype_in = types[0] + dtype_kv = types[4] if len(types) > 4 and types[4] else dtype_in + dtype_out = types[5] if len(types) > 5 and types[5] else dtype_in + return { + "T": T, + "QH": QH, + "KH": KH, + "D_lora": D_lora, + "D_pe": D_pe, + "dtype_in": dtype_in, + "dtype_kv": dtype_kv, + "dtype_out": dtype_out, + } + + def bytes(self): + p = self.param_details + if self.bpe_in is None: + return None + bpe_out = name2bpe(p["dtype_out"]) or self.bpe_in + bpe_kv = self.bpe_kv if self.bpe_kv is not None else self.bpe_in + T, QH, KH, D_lora, D_pe = (p["T"], p["QH"], p["KH"], p["D_lora"], p["D_pe"]) + read_q = (T * QH * D_lora + T * QH * D_pe) * self.bpe_in + read_k = (T * KH * D_lora + T * KH * D_pe) * self.bpe_in + write_q = T * QH * (D_lora + D_pe) * bpe_out + write_kv = T * KH * (D_lora + D_pe) * bpe_kv + return read_q + read_k + write_q + write_kv + + +class sglang_quant_dynamic_mxfp4_quant(fused_flatten_mxfp4_quant): + """ + Performance model for sglang_profiler::quant_dynamic_mxfp4_quant. + + Reference implementation: + aiter/aiter/ops/triton/quant/... dynamic_mxfp4_quant + (sglang quark w4a4 mxfp4 scheme). + + Dynamic MXFP4 activation quant. Single BF16 input (M, N); output is packed + FP4 + per-32-element E8M0 scales. Shares the MXFP4 quant roofline of + fused_flatten_mxfp4_quant (read x + write 0.5 B/elem FP4 + 1/32 B/elem scales). + + Expected Input Dims from trace: + [0] = (M, N) (>2D inputs are flattened along the leading dims) + Expected Input type from trace: + [bf16] + """ + + @staticmethod + def get_param_details(event): + dims = event["args"]["Input Dims"] + types = event["args"]["Input type"] + op_shape = tuple(dims[0]) + dtype_in = types[0] + return { + "op_shape": op_shape, + "dtype_in_out": (dtype_in, dtype_in), + "stride_input": None, + "stride_output": None, + } + + +class aiter_fused_dynamic_mxfp4_quant_moe_sort_hip(fused_flatten_mxfp4_quant): + """ + Performance model for aiter::fused_dynamic_mxfp4_quant_moe_sort_hip. + + Reference implementation: + aiter/aiter/ops/quant.py:1103 (fused_dynamic_mxfp4_quant_moe_sort -> + fused_dynamic_mx_quant_moe_sort; HIP kernel mxfp4_quant_moe_sort_kernel) + + Fuses dynamic MXFP4 activation quant with MoE token sorting. The sort only + touches small index tensors (metadata) and is negligible relative to the + activation quant traffic. + + Expected Input Dims from trace: + [0] out_fp4 = (M, N // 2) packed FP4 + [1] out_scale = (pad_rows, N // 32) E8M0 (sorted layout) + [2] input = (M, N) BF16 <- modeled input + [3] sorted_ids, [4] num_valid_ids (metadata) + """ + + @staticmethod + def get_param_details(event): + dims = event["args"]["Input Dims"] + types = event["args"]["Input type"] + op_shape = tuple(dims[2]) + dtype_in = types[2] + return { + "op_shape": op_shape, + "dtype_in_out": (dtype_in, dtype_in), + "stride_input": None, + "stride_output": None, + } + + +class aiter_dynamic_per_group_scaled_quant_fp4(fused_flatten_mxfp4_quant): + """ + Performance model for aiter::dynamic_per_group_scaled_quant_fp4. + + Reference implementation: + aiter/aiter/ops/quant.py:744 (dynamic_per_group_scaled_quant_fp4 -> + dynamic_per_group_scaled_quant; HIP kernel + dynamic_per_group_scaled_quant_kernel). + + Dynamic per-group (group_size=32) FP4 quant of a BF16 activation. The OUTPUT + tensor is Input Dims[0] and the BF16 input is Input Dims[1] + + Expected Input Dims from trace: + [0] out = (M, N // 2) packed FP4 + [1] input = (M, N) BF16 <- modeled input + [2] scales = (M, N // 32) E8M0 + """ + + @staticmethod + def get_param_details(event): + dims = event["args"]["Input Dims"] + types = event["args"]["Input type"] + op_shape = tuple(dims[1]) + dtype_in = types[1] + return { + "op_shape": op_shape, + "dtype_in_out": (dtype_in, dtype_in), + "stride_input": None, + "stride_output": None, + } diff --git a/TraceLens/PerfModel/extensions/pseudo_ops_perf_utils.py b/TraceLens/PerfModel/extensions/pseudo_ops_perf_utils.py index 737215b17..9c1b29e78 100644 --- a/TraceLens/PerfModel/extensions/pseudo_ops_perf_utils.py +++ b/TraceLens/PerfModel/extensions/pseudo_ops_perf_utils.py @@ -47,6 +47,9 @@ def get_pseudo_op_mappings(): "pseudo_op::moe_flydsl_stage1": moe_perf_model_extensions.moe_flydsl_stage1, "pseudo_op::moe_flydsl_stage2": moe_perf_model_extensions.moe_flydsl_stage2, "sglang_profiler::fused_moe_triton_kernels_invoke_fused_moe_kernel": moe_perf_model_extensions.moe_triton_invoke_grouped_gemm, + "aiter::biased_grouped_topk_hip": moe_perf_model_extensions.BiasedGroupedTopk, + "aiter::moe_sorting_fwd": moe_perf_model_extensions.MoeSortScatterGather, + "aiter::mxfp4_moe_sort_hip": moe_perf_model_extensions.MoeSortScatterGather, # Attention pseudo ops "vllm::unified_attention_with_output": attention_perf_model_extensions.vllm_unified_attention_with_output, "aiter::mha_varlen_fwd": attention_perf_model_extensions.mha_varlen_fwd, @@ -55,10 +58,14 @@ def get_pseudo_op_mappings(): "sglang_profiler::attention_paged_attention_ragged": attention_perf_model_extensions.aiter_paged_attention_ragged, "pseudo_mla_decode_fwd": attention_perf_model_extensions.mla_decode_fwd, "pseudo_mla_prefill_fwd": attention_perf_model_extensions.pseudo_mla_prefill_fwd, + "aiter::pa_decode_gluon": attention_perf_model_extensions.pa_decode_gluon, "sglang_profiler::tilelang_kernel_tilelang_sparse_fwd": attention_perf_model_extensions.mla_tilelang_sparse_fwd, ## Misc ops "aiter::batched_gemm_a16wfp4_": perf_model_extensions.batched_gemm_a16wfp4, "aiter::dynamic_per_token_scaled_quant": perf_model_extensions.per_group_quant, + "aiter::dynamic_per_group_scaled_quant": perf_model_extensions.per_group_quant, + "aiter::fused_add_rmsnorm_pad_": rmsnorm_perf_model_extensions.vllm_rocm_aiter_triton_add_rmsnorm_pad, + "aiter::mixed_sample_outer_exponential": perf_model_extensions.mixed_sample_outer_exponential, "sglang_profiler::fp8_utils_gemm_a8w8_blockscale": perf_model_extensions.gemm_a8w8_blockscale, "sglang_profiler::gemm_a8w8_blockscale_gemm_a8w8_blockscale": perf_model_extensions.gemm_a8w8_blockscale, "vllm::rocm_aiter_triton_gemm_a8w8_blockscale": perf_model_extensions.gemm_a8w8_blockscale, @@ -73,8 +80,11 @@ def get_pseudo_op_mappings(): "aiter::gemm_a8w8_bpreshuffle": perf_model_extensions.gemm_a8w8_blockscale, "vllm::_rocm_aiter_preshuffled_per_token_w8a8_gemm": perf_model_extensions.gemm_a8w8_blockscale, "vllm::rocm_unquantized_gemm": perf_model_extensions.vllm_rocm_unquantized_gemm, + "aiter::gemm_a16w16": perf_model_extensions.gemm_a16w16, + "aiter::fused_dynamic_mx_quant_moe_sort_hip": perf_model_extensions.fused_dynamic_mx_quant_moe_sort_hip, + "aiter::fused_qk_rope_concat_and_cache_mla": perf_model_extensions.fused_qk_rope_concat_and_cache_mla, "aiter::gemm_a16w16_atomic_": perf_model_extensions.gemm_a16w16_atomic_, - "aiter::_gemm_a16w16_asm": perf_model_extensions.gemm_a16w16_atomic_, + "aiter::_gemm_a16w16_asm": perf_model_extensions.gemm_a16w16_asm, "sglang_profiler::gemm_kernels_flydsl_hgemm": perf_model_extensions.gemm_a16w16_atomic_, "aiter::gemm_afp4wfp4_": perf_model_extensions.gemm_afp4wfp4, "sglang_profiler::batched_gemm_a8w8_a_per_token_group_prequant_w_per_batched_tensor_quant_batched_gemm_a8w8_a_per_token_group_prequant_w_per_batched_tensor_quant": perf_model_extensions.batched_gemm_a8w8, @@ -102,8 +112,10 @@ def get_pseudo_op_mappings(): "vllm::rocm_aiter_rmsnorm_with_add_fp8_group_quant": rmsnorm_perf_model_extensions.vllm_rocm_aiter_rmsnorm_with_add_fp8_group_quant, "vllm::rocm_aiter_triton_add_rmsnorm_pad": rmsnorm_perf_model_extensions.vllm_rocm_aiter_triton_add_rmsnorm_pad, "sglang_profiler::fused_mxfp4_quant_fused_rms_mxfp4_quant": rmsnorm_perf_model_extensions.fused_rms_mxfp4_quant, + "aiter::_fuse_rmsnorm_fp4_quant": rmsnorm_perf_model_extensions.fused_rms_mxfp4_quant, ## Collective ops "aiter::fused_allreduce_rmsnorm": custom_collectives_perf_model_extensions.aiter_fused_allreduce_rmsnorm, + "aiter::fused_allreduce_rmsnorm_": custom_collectives_perf_model_extensions.aiter_fused_allreduce_rmsnorm_, "_C_custom_ar::all_reduce": custom_collectives_perf_model_extensions.custom_ar_all_reduce, "aiter::reduce_scatter": custom_collectives_perf_model_extensions.aiter_reduce_scatter, "aiter::all_gather_reg": custom_collectives_perf_model_extensions.aiter_all_gather_reg, @@ -116,6 +128,11 @@ def get_pseudo_op_mappings(): "aiter::linear_attention_with_output_base": attention_perf_model_extensions.gdn_attention_core, ## KV cache ops "sglang::store_cache": perf_model_extensions.sglang_store_cache, + "aiter::fused_qk_rope_cat_and_cache_mla": perf_model_extensions.aiter_fused_qk_rope_cat_and_cache_mla, + "sglang_profiler::fused_moe_triton_kernels_fused_append_shared_experts": moe_perf_model_extensions.sglang_fused_append_shared_experts, + "sglang_profiler::quant_dynamic_mxfp4_quant": perf_model_extensions.sglang_quant_dynamic_mxfp4_quant, + "aiter::fused_dynamic_mxfp4_quant_moe_sort_hip": perf_model_extensions.aiter_fused_dynamic_mxfp4_quant_moe_sort_hip, + "aiter::dynamic_per_group_scaled_quant_fp4": perf_model_extensions.aiter_dynamic_per_group_scaled_quant_fp4, } return pseudo_op_mappings @@ -137,6 +154,8 @@ def get_pseudo_op_category_only_mappings(): # Reference: aiter/aiter/ops/triton/moe_op_mxfp4.py (mxfp4_moe_sort_hip, # fused_dynamic_mxfp4_quant_moe_sort_hip). Memory-bound shuffle/sort ops # with negligible FLOPs; we only classify them. - "aiter::mxfp4_moe_sort_hip": "MoE_aux", "aiter::fused_dynamic_mxfp4_quant_moe_sort_hip": "MoE_aux", + "aiter::unified_attention_with_output_base->_fused_qk_rope_reshape_and_cache_kernel (Synthetic Op)": "FusedRoPE", + "hipModuleLaunchKernel->kv_indices_generate_kernel (Synthetic Op)": "InferenceAttention", + "aiter::get_mla_metadata_v1": "InferenceAttention", } diff --git a/TraceLens/PerfModel/torch_op_mapping.py b/TraceLens/PerfModel/torch_op_mapping.py index f452f149e..a421bc234 100644 --- a/TraceLens/PerfModel/torch_op_mapping.py +++ b/TraceLens/PerfModel/torch_op_mapping.py @@ -42,7 +42,6 @@ "FusedRoPEFuncBackward": "RoPE_bwd", "CrossEntropyFunctionBackward": "CrossEntropy_bwd", # MoE auxiliary ops. - "aiter::moe_sorting_fwd": "MoE_aux", "aiter::moe_sorting_opus_fwd": "MoE_aux", "aiter::moe_align_block_size": "MoE_aux", "_moe_C::moe_align_block_size": "MoE_aux", @@ -51,7 +50,6 @@ "aiter::topk_softmax": "MoE_aux", "aiter::topk_softmax_asm": "MoE_aux", "aiter::topk_sigmoid": "MoE_aux", - "aiter::biased_grouped_topk_hip": "MoE_aux", "aiter::grouped_topk": "MoE_aux", "aiter::moe_fused_gate": "MoE_aux", # InferenceAttention extras (KV-cache writes). diff --git a/TraceLens/Reporting/generate_perf_report_pytorch_inference.py b/TraceLens/Reporting/generate_perf_report_pytorch_inference.py index 9f87ace7f..e67aa1b3d 100644 --- a/TraceLens/Reporting/generate_perf_report_pytorch_inference.py +++ b/TraceLens/Reporting/generate_perf_report_pytorch_inference.py @@ -618,6 +618,7 @@ def generate_perf_report_pytorch( "sglang_profiler::tilelang_kernel_tilelang_sparse_fwd", "sglang_profiler::attention_paged_attention_ragged", "aiter::mha_batch_prefill", + "aiter::pa_decode_gluon", ] ) @@ -1176,15 +1177,14 @@ def _launcher_category(name): # Write CSVs and/or Excel (independent options) if output_csvs_dir: - # Ensure the output directory exists os.makedirs(output_csvs_dir, exist_ok=True) for sheet_name, df in dict_name2df.items(): csv_path = os.path.join(output_csvs_dir, f"{sheet_name}.csv") df.to_csv(csv_path, index=False) print(f"DataFrame '{sheet_name}' written to {csv_path}") - else: + + if output_xlsx_path is not None or output_csvs_dir is None: if output_xlsx_path is None: - # split input path at 'json' and take the first part and append '.xlsx' base_path = profile_json_path.rsplit(".json", 1)[0] output_xlsx_path = base_path + "_perf_report.xlsx" try: diff --git a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py index 57ebd5f8d..0c910ec5f 100644 --- a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py +++ b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py @@ -17,7 +17,7 @@ import sys import time -from collections import OrderedDict, defaultdict +from collections import OrderedDict, deque, defaultdict from typing import Any, Dict, List, Optional, Tuple import json import os @@ -64,7 +64,8 @@ def _capture_kernel_name(event): def _align_capture_to_graph(capture_events, graph_events): """ - Greedily align capture dispatch events to graph kernel events by name. + Robust greedy alignment of capture dispatch events to graph kernel + events in case of minor mismatch due to profiler error. For each graph kernel, scan forward through capture_events until a dispatch whose args.kernel matches is found, skipping any unmatched @@ -97,7 +98,6 @@ def _align_capture_to_graph(capture_events, graph_events): return None return aligned - def _align_capture_to_graph_by_group(capture_events, graph_events): """ Align capture dispatch events to graph kernel events by grouping on kernel @@ -137,6 +137,89 @@ def _align_capture_to_graph_by_group(capture_events, graph_events): return aligned +def _stream_of(event): + """Return the CUDA stream id a graph kernel executed on, or None.""" + return event.get("args", {}).get("stream") + + +def _names_match(c_event, g_name): + """Pair a capture dispatch to a graph kernel by name (Memcpy/Memset carry no kernel arg).""" + if ("Memcpy" in c_event["name"] and "Memcpy" in g_name) or ( + "Memset" in c_event["name"] and "Memset" in g_name + ): + return True + return _capture_kernel_name(c_event) == g_name + + +def is_multistream(graph_filtered_events): + """True when the graph root's kernels span more than one CUDA stream.""" + streams = set() + for e in graph_filtered_events: + streams.add(_stream_of(e)) + if len(streams) > 1: + return True + return False + + +def capture_has_kernel_names(capture_filtered_events): + """False if any non-Memcpy/Memset capture dispatch lacks args.kernel.""" + for e in capture_filtered_events: + if "Memcpy" in e["name"] or "Memset" in e["name"]: + continue + if "kernel" not in e.get("args", {}): + return False + return True + + +def _best_stream_by_run(candidates, stream_queues, capture_events, ci): + """Tie-break: pick the stream matching the longest forward run of capture dispatches from ci.""" + best_stream = candidates[0] + best_run = -1 + for s in candidates: + q = stream_queues[s] + run = 0 + while ( + run < len(q) + and ci + run < len(capture_events) + and _names_match(capture_events[ci + run], q[run]["name"]) + ): + run += 1 + if run > best_run: + best_run = run + best_stream = s + return best_stream + + +def align_streams(graph_filtered_events, capture_filtered_events): + """Pair capture dispatches (CPU program order) to graph kernels (GPU order across + streams) via per-stream FIFO queues. Returns capture reordered into graph order, or + None if any graph kernel is unmatched.""" + stream_queues = OrderedDict() + for g_event in graph_filtered_events: + stream_queues.setdefault(_stream_of(g_event), deque()).append(g_event) + + mapping = {} + for ci, c_event in enumerate(capture_filtered_events): + candidates = [ + s + for s, q in stream_queues.items() + if q and _names_match(c_event, q[0]["name"]) + ] + if not candidates: + continue + if len(candidates) > 1: + chosen = _best_stream_by_run( + candidates, stream_queues, capture_filtered_events, ci + ) + else: + chosen = candidates[0] + g_event = stream_queues[chosen].popleft() + mapping[id(g_event)] = c_event + + if any(id(g) not in mapping for g in graph_filtered_events): + return None + return [mapping[id(g)] for g in graph_filtered_events] + def verify_subtree_events(capture_events, graph_events): """ @@ -185,7 +268,6 @@ def verify_subtree_events(capture_events, graph_events): ) continue if i["name"] != _capture_kernel_name(j): - # Counts match but order differs. Group by name and match positionally within each group. aligned = _align_capture_to_graph_by_group(capture_events, graph_events) if aligned is not None: print("Group-by-name alignment succeeded.") @@ -599,6 +681,7 @@ def merge_capture_trace_into_graph( capture_map, capture_batch_sizes = load_capture_folder( capture_folder, metadata_json_path ) + merge_failed = False for execution_root, graph_roots in execution_graph_root_map: print("Processing execution root: {}".format(execution_root["name"])) if len(graph_roots) == 0: @@ -661,17 +744,35 @@ def merge_capture_trace_into_graph( ) continue - verify_success, capture_filtered_events = verify_subtree_events( - capture_filtered_events, graph_filtered_events - ) - - if verify_success == 0: - print( - "Warning: subtree events verification failed for capture root {} and graph root {}".format( - c_root["name"], g_root["name"] + if is_multistream(graph_filtered_events): + if not capture_has_kernel_names(capture_filtered_events): + print( + "Graph capture merge failed: multistream graph root {} but " + "capture kernel names are absent".format(g_root["name"]) + ) + merge_failed = True + continue + aligned = align_streams(graph_filtered_events, capture_filtered_events) + if aligned is None: + print( + "Warning: multistream alignment failed for capture root {} and graph root {}".format( + c_root["name"], g_root["name"] + ) ) + continue + capture_filtered_events = aligned + else: + verify_success, capture_filtered_events = verify_subtree_events( + capture_filtered_events, graph_filtered_events ) - continue + + if verify_success == 0: + print( + "Warning: subtree events verification failed for capture root {} and graph root {}".format( + c_root["name"], g_root["name"] + ) + ) + continue start_uid = graph_tree.events[-1][UID] + 1 capture_events, _, cpu_root_nodes = update_subtree_uids_and_timestamps( @@ -693,5 +794,10 @@ def merge_capture_trace_into_graph( graph_tree = make_connections( graph_tree, graph_filtered_events, capture_filtered_events ) + if merge_failed: + print( + "Graph capture merge failed; returning None (report will be unaugmented)." + ) + return None finalize_non_gpu_paths(graph_tree) return graph_tree diff --git a/TraceLens/Trace2Tree/trace_to_tree.py b/TraceLens/Trace2Tree/trace_to_tree.py index 454ce60c7..df26a5e63 100644 --- a/TraceLens/Trace2Tree/trace_to_tree.py +++ b/TraceLens/Trace2Tree/trace_to_tree.py @@ -336,6 +336,8 @@ def __init__( self.linking_key_to_uid_map = defaultdict(list) self.hlo_ops = defaultdict(list) + self.hlo_op_aliases = {} + self._warned_missing_hlo_ops = set() self.metadata = dict def default_categorizer(self): @@ -437,6 +439,9 @@ def build_tree( self._categorize_gpu_kernel_ops() + # Kernel-name FA labels are authoritative; do not replace with TE via hlo_op. + _FA_KERNEL_NAME_CATEGORIES = frozenset({"FA BWD", "FA FWD", "FA V3"}) + def _categorize_gpu_kernel_ops(self) -> None: """ Categorizes GPU kernel operations in the event list based on their names and HLO operation types. @@ -447,6 +452,9 @@ def _categorize_gpu_kernel_ops(self) -> None: predefined category filters in `TraceEventUtils.JaxOpKeys.ClassCategories`. If no category is matched, assigns a default 'Uncategorized/XLA' category. + When the kernel name matches an FA category (FA FWD / FA BWD / FA V3), that label is kept + even if ``hlo_op`` would match TE (e.g. ``te_fused_attn_forward_ffi`` inside Transformer Engine). + Modifies: Each relevant event in `self.events` by adding or updating the 'gpu_kernel_op_cat' key. """ @@ -457,21 +465,24 @@ def _categorize_gpu_kernel_ops(self) -> None: if event.get("cat") != "kernel": continue name = event.get("name", "") - gpu_kernel_op_cat_not_found = True + name_category = None for ( category, filters, ) in TraceEventUtils.JaxOpKeys.ClassCategories.items(): if any(f in name for f in filters): - event["gpu_kernel_op_cat"] = category - gpu_kernel_op_cat_not_found = False + name_category = category break + gpu_kernel_op_cat_not_found = name_category is None + if name_category is not None: + event["gpu_kernel_op_cat"] = name_category + args = event.get("args") if args and "hlo_op" in args: hlo_op = args.get("hlo_op") - if hlo_op: + if hlo_op and name_category not in self._FA_KERNEL_NAME_CATEGORIES: for ( category, filters, @@ -532,6 +543,38 @@ def _set_hlo_ops(self, pb_file_name: str) -> None: pb_file_name, hlo_module ) ) + self._build_hlo_op_alias_maps() + + def _build_hlo_op_alias_maps(self) -> None: + """Build per-module aliases for runtime vs HLO-dump collective names.""" + trace_ops_by_module = defaultdict(set) + for event in self.events: + args = event.get("args") or {} + hlo_module = args.get("hlo_module") + hlo_op = args.get("hlo_op") + if hlo_module and hlo_op: + trace_ops_by_module[hlo_module].add( + JaxProfileProcessor._normalize_hlo_op_key(hlo_op) + ) + + self.hlo_op_aliases = {} + for hlo_module, trace_ops in trace_ops_by_module.items(): + module_ops = self.hlo_ops.get(hlo_module) + if not module_ops: + continue + self.hlo_op_aliases[hlo_module] = ( + JaxProfileProcessor.build_collective_hlo_aliases(module_ops, trace_ops) + ) + + def _lookup_hlo_metadata(self, hlo_module: str, hlo_op: str) -> Optional[dict]: + module_ops = self.hlo_ops.get(hlo_module, {}) + aliases = self.hlo_op_aliases.get(hlo_module, {}) + resolved_key = JaxProfileProcessor.resolve_hlo_op_key( + hlo_op, module_ops, aliases + ) + if resolved_key is None: + return None + return module_ops.get(resolved_key) def _create_linking_key_to_uid_map(self) -> None: """ @@ -589,17 +632,20 @@ def _link_cpu_gpu(self) -> None: if "hlo_op" in GPU_event.get("args").keys(): hlo_op = "%" + GPU_event.get("args").get("hlo_op") hlo_module = GPU_event.get("args").get("hlo_module") - if (hlo_module in self.hlo_ops.keys()) and ( - hlo_op in self.hlo_ops.get(hlo_module).keys() - ): - GPU_event["metadata"] = self.hlo_ops.get( - hlo_module - ).get(hlo_op) + metadata = self._lookup_hlo_metadata( + hlo_module, hlo_op + ) + if metadata is not None: + GPU_event["metadata"] = metadata else: - logger.warning(f"Missing hlo_op: {hlo_op}") - logger.warning( - f"in hlo_module: {GPU_event['args']['hlo_module']}" - ) + warn_key = (hlo_module, hlo_op) + if warn_key not in self._warned_missing_hlo_ops: + self._warned_missing_hlo_ops.add(warn_key) + logger.warning(f"Missing hlo_op: {hlo_op}") + logger.warning( + "in hlo_module: " + f"{GPU_event['args']['hlo_module']}" + ) class TraceToTree(BaseTraceToTree): diff --git a/TraceLens/TraceUtils/split_inference_trace_annotation.py b/TraceLens/TraceUtils/split_inference_trace_annotation.py index 967643f4f..702ba4b2a 100644 --- a/TraceLens/TraceUtils/split_inference_trace_annotation.py +++ b/TraceLens/TraceUtils/split_inference_trace_annotation.py @@ -179,6 +179,7 @@ import csv from statistics import mean from TraceLens.util import DataLoader +from TraceLens.Trace2Tree.trace_to_tree import TraceToTree import pandas as pd # Try to use faster JSON parser (orjson is 2-10x faster than json) @@ -243,8 +244,8 @@ def find_events_by_pattern( def find_iteration_roots(events: List[dict]) -> Optional[List[dict]]: """Return iteration-root events. - Tries the primary annotation pattern first and only falls back to the - backup patterns when the primary matches nothing. + Tries the primary annotation pattern first, then backup patterns, then + falls back to generic call-tree traversal via Trace2Tree. """ roots = find_events_by_pattern( events, ANNOTATION_PATTERN, "execution steps (iteration)", cat="user_annotation" @@ -257,6 +258,155 @@ def find_iteration_roots(events: List[dict]) -> Optional[List[dict]]: "execution steps (iteration, backup)", cat="user_annotation", ) + if roots is None: + print("No annotation patterns found; trying generic call-tree traversal...") + roots = find_iteration_roots_generic(events) + return roots + + +def _find_repeating_period( + names: List[str], min_repeats: int = 3 +) -> Tuple[Optional[int], Optional[List[str]], Optional[int]]: + """Find the shortest repeating name sequence anywhere in ``names``. + + Slides a start offset forward to skip any non-repeating prefix (setup + events before the loop body). Returns ``(period, pattern, start_offset)`` + where ``start_offset`` is the index in ``names`` where the first block + begins. Returns ``(None, None, None)`` if no qualifying period is found. + + Requires at least ``min_repeats`` consecutive repetitions covering more + than half of the suffix starting at ``start_offset``. + """ + n = len(names) + for start in range(n): + suffix = names[start:] + m = len(suffix) + for p in range(1, m // 2 + 1): + pattern = suffix[:p] + count = 0 + i = 0 + while i + p <= m and suffix[i : i + p] == pattern: + count += 1 + i += p + if count >= min_repeats and count * p > m * 0.5: + return p, pattern, start + return None, None, None + + +def _detect_iteration_roots_from_tree(tree: TraceToTree, roots) -> Optional[List[dict]]: + """BFS down the tree from one or more root nodes to find and return synthetic + iteration-root events. + + ``roots`` may be a single event dict or a list of event dicts — all are + seeded into the BFS at depth 0 so they are explored level-by-level together. + + Pattern detection uses all children (not just GPU-path ones) so that + leading CPU-only events (e.g. ``next`` in the OWL pipeline) are included + as part of the iteration anchor. A minimum child count guards against false + positives from short utility-function child lists. + + Returns a list of synthetic root events, one per detected iteration, where + each event's ``dur`` spans from the first to the last child of the block. + """ + from collections import deque + + if isinstance(roots, dict): + roots = [roots] + + queue = deque((node, 0) for node in roots) + while queue: + current, depth = queue.popleft() + children = tree.get_children_events(current) + if not children: + continue + + # Only recurse into GPU-bearing subtrees. + if not any(c.get("gpu_events") for c in children): + continue + + p, _, start = _find_repeating_period([c.get("name", "") for c in children]) + if p is None: + for child in children: + if child.get("gpu_events"): + queue.append((child, depth + 1)) + continue + + print( + f"Generic fallback: repeating pattern found under '{current.get('name')}' at depth {depth}" + ) + print(f"Generic fallback: period={p}") + + # Anchor each iteration between the Nth occurrence of the first and last + # events in the detected pattern. Using all-children anchors means + # CPU-only leading/trailing events are included naturally. + first_anchor_name = children[start]["name"] + last_anchor_name = children[start + p - 1]["name"] + + first_anchors = [ + i + for i, c in enumerate(children) + if i >= start and c.get("name") == first_anchor_name + ] + last_anchors = [ + i + for i, c in enumerate(children) + if i >= start and c.get("name") == last_anchor_name + ] + + iteration_roots = [] + for n in range(min(len(first_anchors), len(last_anchors))): + block_start = first_anchors[n] + block_end = last_anchors[n] + if block_end < block_start: + break + block = children[block_start : block_end + 1] + first, last = block[0], block[-1] + root_event = dict(first) + root_event["dur"] = (last["ts"] + last.get("dur", 0)) - first["ts"] + iteration_roots.append(root_event) + + print(f"Generic fallback: identified {len(iteration_roots)} iterations.") + return iteration_roots if iteration_roots else None + + return None + + +def find_iteration_roots_generic(events: List[dict]) -> Optional[List[dict]]: + """Fallback: detect iteration roots by finding a repeating child pattern in + the call tree, using Trace2Tree for parent/child relationships. + + Works for any workload (diffusion, training, etc.) where the iteration loop + body is a repeating sequence of top-level calls under a common parent. + """ + try: + tree = TraceToTree(events, prune_nongpu_paths=False) + tree.build_tree(add_python_func=True) + except Exception as e: + print(f"Generic fallback: Trace2Tree build failed ({e}), skipping.") + return None + + # Walk every cpu_root_node upward through python_function parents until + # reaching a parentless node — these are the true per-thread entry points. + seen_roots: set = set() + trace_roots = [] + for uid in tree.cpu_root_nodes: + e = tree.get_UID2event(uid) + while True: + parent = tree.get_parent_event(e) + if parent is None: + break + e = parent + if id(e) not in seen_roots: + seen_roots.add(id(e)) + trace_roots.append(e) + + if not trace_roots: + print("Generic fallback: no root nodes found.") + return None + + roots = _detect_iteration_roots_from_tree(tree, trace_roots) + if roots is None: + print("Generic fallback: no repeating child pattern found.") return roots @@ -427,26 +577,47 @@ def get_iter_details_from_name(name: str, prefix: str = "annotation_iteration") } if "annotation_iteration" not in prefix: - return {"batch_size": 0} + # Generic workload (e.g. diffusion): treat every iteration as one + # decode-equivalent step so steady-state detection sees a flat line. + return { + "batch_size": 1, + "num_requests": 1, + "context_requests": 0, + "context_sum": 0, + "generation_requests": 1, + "generation_sum": 1, + } # vLLM execute_..._context_..._generation_... annotations: strip parens and the # sq/sk shape letters to a flat token list, then pick counts by index. - parts = re.sub(r"[sqk]+", "_", name.replace("(", "_").replace(")", "_")).split("_") - if len(parts) < 10: - idx = (2, 3, 6, 7) - elif len(parts) < 12: - idx = (2, 3, 7, 8) - else: - idx = (3, 5, 11, 13) - ctx_req, ctx_sum, gen_req, gen_sum = (int(parts[i]) for i in idx) - return { - "batch_size": ctx_sum + gen_sum, - "num_requests": ctx_req + gen_req, - "context_requests": ctx_req, - "context_sum": ctx_sum, - "generation_requests": gen_req, - "generation_sum": gen_sum, - } + try: + parts = re.sub(r"[sqk]+", "_", name.replace("(", "_").replace(")", "_")).split( + "_" + ) + if len(parts) < 10: + idx = (2, 3, 6, 7) + elif len(parts) < 12: + idx = (2, 3, 7, 8) + else: + idx = (3, 5, 11, 13) + ctx_req, ctx_sum, gen_req, gen_sum = (int(parts[i]) for i in idx) + return { + "batch_size": ctx_sum + gen_sum, + "num_requests": ctx_req + gen_req, + "context_requests": ctx_req, + "context_sum": ctx_sum, + "generation_requests": gen_req, + "generation_sum": gen_sum, + } + except (ValueError, IndexError): + return { + "batch_size": 1, + "num_requests": 1, + "context_requests": 0, + "context_sum": 0, + "generation_requests": 1, + "generation_sum": 1, + } def find_phase_from_window(iter_details: List[dict]) -> dict: @@ -546,7 +717,21 @@ def extract_and_save( f"_bs{phase_details['avg_bs']}_conc{phase_details['avg_conc']}" ) elif is_annotation and len(root) == 1: - name_append = root[0]["name"].replace("(", "_").replace(")", "") + root_name = root[0]["name"] + is_known_annotation = any( + pat.match(root_name) + for pat in ANNOTATION_PATTERN + ANNOTATION_PATTERN_BACKUP + ) + if is_known_annotation: + name_append = ( + root_name.replace("/", "_") + .replace("(", "_") + .replace(")", "") + .replace(":", "") + .replace(" ", "_") + ) + else: + name_append = "" else: if len(batch_list) == len(iter_details): name_append = f"batch{int(sum(batch_list)/len(batch_list))}_gpu{prefix}" @@ -558,8 +743,9 @@ def extract_and_save( output_dir, f"{output_label}_{name_append}_{base_name}.json.gz" ) else: + suffix = f"_{name_append}" if name_append else "" out_path = os.path.join( - output_dir, f"{base_name}_{prefix}_{idx}_{name_append}.json.gz" + output_dir, f"{base_name}_{prefix}_{idx}{suffix}.json.gz" ) with gzip.open(out_path, "wb") as f: f.write(json.dumps(iter_trace).encode("utf-8")) @@ -738,7 +924,7 @@ def identify_steady_state_regions( if len(regions) == 0: delta = min(n, max(8, num_steps - n)) start = max(0, delta // 2) - end = min(n, n - delta // 2) + end = max(start + 1, min(n, n - delta // 2)) regions = [(start, end)] print( "Warning: no steady state region found; discarding initial/final iterations " diff --git a/TraceLens/TreePerf/tree_perf.py b/TraceLens/TreePerf/tree_perf.py index 85fe0dab9..a72a840f6 100644 --- a/TraceLens/TreePerf/tree_perf.py +++ b/TraceLens/TreePerf/tree_perf.py @@ -3444,9 +3444,14 @@ def parse_dtype_shape_layout(operand): for operand in operands: dtype, shape, layout = parse_dtype_shape_layout(operand) if shape and dtype: - total_input_bytes = ( - total_input_bytes + np.prod(shape) * dtype_to_bytes[dtype] + nbytes = dtype_to_bytes.get(dtype, 1 if dtype.startswith(("f8", "s8")) else None ) + if nbytes is None: + logger.warning( + "Unknown dtype '%s' in operand, skipping byte count", dtype + ) + continue + total_input_bytes = total_input_bytes + np.prod(shape) * nbytes total_input_bytes_list.append(total_input_bytes) diff --git a/TraceLens/util.py b/TraceLens/util.py index af945543b..1cf425c25 100644 --- a/TraceLens/util.py +++ b/TraceLens/util.py @@ -4,12 +4,15 @@ # See LICENSE for license information. ############################################################################### +import contextlib import itertools import json import logging import os import re import glob +import sys +import tempfile from collections import defaultdict try: @@ -25,6 +28,47 @@ logger = logging.getLogger(__name__) +# Benign native XLA logs (id > INT_MAX, from packed HLO instruction ids in xprof +# 2.20.1). Emitted to fd 2 before absl init, so only filterable at the fd level. +_NATIVE_LOG_NOISE = re.compile( + r"Instruction with id > INT_MAX" + r"|not intended behavior and might indicate a bug in the HLO proto serialization" + r"|hlo_instruction\.cc" +) + + +@contextlib.contextmanager +def suppress_native_hlo_logs(): + """Filter benign native XLA ``id > INT_MAX`` stderr during a call. + + Set ``TRACELENS_VERBOSE_NATIVE_LOGS=1`` to disable filtering. + """ + if os.environ.get("TRACELENS_VERBOSE_NATIVE_LOGS"): + yield + return + + sys.stderr.flush() + saved_fd = os.dup(2) + tmp = tempfile.TemporaryFile(mode="w+b") + try: + os.dup2(tmp.fileno(), 2) + yield + finally: + sys.stderr.flush() + os.dup2(saved_fd, 2) + os.close(saved_fd) + tmp.seek(0) + for raw in tmp.read().splitlines(keepends=True): + try: + line = raw.decode("utf-8", "replace") + except Exception: + os.write(2, raw) + continue + if not _NATIVE_LOG_NOISE.search(line): + os.write(2, raw) + tmp.close() + + # generic data loader class for json, json.gz, or tensorboard pb files # tensorboard pb files are useful for Jax in particular because the json.gz traces produced by jax can have incorrect timestamps and missing information class DataLoader: @@ -46,7 +90,10 @@ def load_data(filename_path: str, save_preprocessed: bool = False) -> dict: "for trace conversion. Install xprof for JAX 0.8+ support." ) - data, _ = convert.xspace_to_tool_data([filename_path], "trace_viewer@^", {}) + with suppress_native_hlo_logs(): + data, _ = convert.xspace_to_tool_data( + [filename_path], "trace_viewer@^", {} + ) if data is None: raise RuntimeError( f"Trace conversion using '{converter_lib}' returned None for " @@ -88,6 +135,40 @@ def load_data(filename_path: str, save_preprocessed: bool = False) -> dict: class JaxProfileProcessor: gemm_columns = ["Batch", "M", "N", "K", "Beta", "Type"] + # Substrings used to detect parseable HLO graph-viewer text lines. + # The legacy list only covered float types; integer/bool lines were skipped and + # later showed up as "Missing hlo_op" when the profiler trace referenced them. + _HLO_LINE_ELEMENT_TYPE_HINTS_LEGACY = [ + "get-tuple-element", + "bf16", + "f8", + "f16", + "f32", + "f64", + ] + _HLO_LINE_ELEMENT_TYPE_HINTS = _HLO_LINE_ELEMENT_TYPE_HINTS_LEGACY + [ + "s32", + "s64", + "u32", + "u64", + "pred", + ] + + @staticmethod + def _should_parse_hlo_graph_line(line: str) -> bool: + """Return True if a graph-viewer text line should be parsed into hlo_ops.""" + line_processed = line.strip() + if not line_processed or line_processed.startswith("HloModule "): + return False + if line_processed.startswith("ROOT"): + return False + if "metadata" in line_processed and not re.search(r"\)$", line_processed): + return True + return any( + hint in line_processed + for hint in JaxProfileProcessor._HLO_LINE_ELEMENT_TYPE_HINTS + ) + @staticmethod def process_xla_file(xla_file_name): hlo_ops = {} @@ -105,10 +186,11 @@ def process_protobuf_file(protobuf_file_name, module_name): raw_to_tool_data as convert, ) - dir_name = os.path.dirname(protobuf_file_name) + "/" + dir_name = os.path.dirname(os.path.abspath(protobuf_file_name)) + "/" hlo_filename = glob.glob(dir_name + os.path.sep + module_name + "*hlo_proto.pb") if len(hlo_filename) != 1: - convert.xspace_to_tool_names([protobuf_file_name]) + with suppress_native_hlo_logs(): + convert.xspace_to_tool_names([protobuf_file_name]) hlo_filename = glob.glob(dir_name + os.path.sep + module_name + "*hlo_proto.pb") if len(hlo_filename) > 1: logger.warning(f"Multiple matching hlo_filenames: {hlo_filename}") @@ -133,7 +215,8 @@ def process_protobuf_file(protobuf_file_name, module_name): "type": "long_txt", } params = {"graph_viewer_options": graph_viewer_options} - data, _ = convert.xspace_to_tool_data([dir_name], "graph_viewer^", params) + with suppress_native_hlo_logs(): + data, _ = convert.xspace_to_tool_data([dir_name], "graph_viewer^", params) data = data.decode("utf-8").split("\n") for line in data: JaxProfileProcessor.process_line(hlo_ops, line) @@ -172,22 +255,82 @@ def _resolve_operand_references(hlo_ops: dict): @staticmethod def process_line(hlo_ops: dict, line: str): line_processed = line.strip() - if ( - ( - "metadata" in line_processed - and not (re.search(r"\)$", line_processed)) - and not (line_processed.startswith("ROOT")) - ) - or any( - t in line_processed - for t in ["get-tuple-element", "bf16", "f8", "f16", "f32", "f64"] - ) - and not (line_processed.startswith("HloModule ")) - ): - k, v = JaxProfileProcessor.get_dict(hlo_ops, line_processed) - hlo_ops[k] = v - return True - return False + if not JaxProfileProcessor._should_parse_hlo_graph_line(line_processed): + return False + k, v = JaxProfileProcessor.get_dict(hlo_ops, line_processed) + hlo_ops[k] = v + return True + + # Async collectives in HLO text use *-start/*-done names; runtime traces may + # use numbered aliases (e.g. reduce-scatter.12 -> reduce-scatter-start). + _ASYNC_COLLECTIVE_FAMILIES = ("all-to-all", "reduce-scatter", "all-gather") + + @staticmethod + def _normalize_hlo_op_key(hlo_op: str) -> str: + return hlo_op if hlo_op.startswith("%") else f"%{hlo_op}" + + @staticmethod + def _collective_start_keys(module_ops: dict, family: str) -> list: + start_keys = sorted(k for k in module_ops if k.startswith(f"%{family}-start")) + if start_keys: + return start_keys + return sorted(k for k in module_ops if k.startswith(f"%{family}-done")) + + @classmethod + def build_collective_hlo_aliases(cls, module_ops: dict, trace_hlo_ops) -> dict: + """Map numbered runtime collective tags to parsed HLO dump keys.""" + aliases = {} + normalized_ops = {cls._normalize_hlo_op_key(op) for op in trace_hlo_ops} + + for family in cls._ASYNC_COLLECTIVE_FAMILIES: + numbered = [] + for op_key in normalized_ops: + if op_key in module_ops: + continue + bare = op_key.lstrip("%") + prefix = f"{family}." + if not bare.startswith(prefix): + continue + suffix = bare[len(prefix) :] + if suffix.isdigit(): + numbered.append((int(suffix), op_key)) + + if not numbered: + continue + + start_keys = cls._collective_start_keys(module_ops, family) + if not start_keys: + continue + + numbered.sort() + if len(start_keys) == 1: + for _, op_key in numbered: + aliases[op_key] = start_keys[0] + else: + for idx, (_, op_key) in enumerate(numbered): + aliases[op_key] = start_keys[min(idx, len(start_keys) - 1)] + + return aliases + + @classmethod + def resolve_hlo_op_key(cls, hlo_op: str, module_ops: dict, aliases=None): + """Resolve a trace hlo_op to a key present in module_ops.""" + key = cls._normalize_hlo_op_key(hlo_op) + if key in module_ops: + return key + if aliases and key in aliases and aliases[key] in module_ops: + return aliases[key] + + bare = key.lstrip("%") + match = re.match( + r"^(all-to-all|reduce-scatter|all-gather)\.(\d+)$", + bare, + ) + if match: + start_keys = cls._collective_start_keys(module_ops, match.group(1)) + if start_keys: + return start_keys[0] + return None @staticmethod def get_operands(operands): diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..195a58798 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,6 @@ +_build/ +_doxygen/ +_toc.yml +sphinx/_toc.yml +.venv/ +__pycache__/ diff --git a/docs/about/license.md b/docs/about/license.md new file mode 100644 index 000000000..bf0d1523f --- /dev/null +++ b/docs/about/license.md @@ -0,0 +1,34 @@ + + + +# License +```{meta} +:description: Full text of the MIT License under which TraceLens is released by Advanced Micro Devices, Inc. +:keywords: TraceLens, MIT License, open source, AMD, license text +``` + +MIT License + + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/docs/about/release-notes.md b/docs/about/release-notes.md new file mode 100644 index 000000000..467243b7e --- /dev/null +++ b/docs/about/release-notes.md @@ -0,0 +1,103 @@ + + + +# TraceLens release notes +```{meta} +:description: Release notes for TraceLens. Learn what features and SDK modules are available in each version, and see links to the compatibility matrix. +:keywords: TraceLens, release notes, changelog, ROCm, GPU trace analysis, PyTorch, JAX, rocprofv3, SDK, performance report +``` + +This topic summarizes the features available in each TraceLens release. For the +hardware and software versions validated for a release, see the +[Compatibility matrix](../reference/compatibility.md). + +## TraceLens 0.1.0 (initial release) + +The initial release establishes TraceLens as an end-to-end toolkit for +automated GPU trace analysis, available as command-line tools and a Python SDK. + +### Report generation + +- **PyTorch profiler reports** — `TraceLens_generate_perf_report_pytorch` + builds a multi-sheet Excel report from a `torch.profiler` Chrome trace, + including a GPU-timeline breakdown, operator-category and operator summaries, + a unique-argument table, roofline metrics, and an optional short-kernel study. + Compressed traces (`.zip`, `.gz`) are supported. +- **PyTorch inference reports** — `TraceLens_generate_perf_report_pytorch_inference` + adds analysis for LLM-serving traces (vLLM/SGLang). It merges CUDA-graph + capture traces into graph-replay traces (`--capture_folder`) to recover + call-stack and shape information lost in graph mode, and uses per-step request + annotations (prefill/decode counts and token statistics) to drive + inference-specific roofline models for paged attention and fused MoE. +- **JAX reports** — `TraceLens_generate_perf_report_jax` builds reports from JAX + XPlane protobuf traces, with optional kernel-metadata keyword filtering. +- **rocprofv3 JSON reports** — `TraceLens_generate_perf_report_rocprof` builds + reports from rocprofv3 `*_results.json` traces, with kernel summaries, + automatic categorization (GEMM, attention, elementwise, and others), + short-kernel analysis, and optional grid/block detail. +- **rocprofv3 pftrace reports** — for Perfetto-style traces produced with + `rocprofv3 --output-format pftrace`: + - `TraceLens_generate_perf_report_pftrace_hip_activity` — per-GPU category + summary plus kernel/HIP/XLA summaries (NSYS-style), with optional Markdown. + - `TraceLens_generate_perf_report_pftrace_hip_api` — HIP API ↔ kernel + correlation with the latency breakdown `T = A + Q + K`. + - `TraceLens_generate_perf_report_pftrace_memory_copy` — memory-copy counts + per `copy_bytes` with direction (h2d/d2h/d2d) and the GPUs involved. + +### Analysis features + +- **Hierarchical GPU-timeline breakdown** — Splits GPU time into computation, + communication, memory copy, and idle time, with optional micro-idle + classification. +- **Operator categorization** — Groups CPU operations that launch kernels into + categories for a portable, reproducible view. +- **Unique-argument analysis** — Groups operations by name plus input shapes, + dtypes, strides, and concrete inputs to isolate problematic input patterns. +- **Roofline modeling** — Computes arithmetic intensity (FLOPs/byte) and + classifies operations as compute- or memory-bound relative to a target + accelerator's roofline knee point. Optional Origami-based simulated GEMM/SDPA + timings are available when a GPU architecture specification is provided. +- **Activation-recompute detection** and **kernel-overlap** sheets for deeper + PyTorch analysis. + +### Multi-GPU and comparison + +- **Collective communication analysis** — + `TraceLens_generate_multi_rank_collective_report_pytorch` reports time spent + in collectives across ranks, including aggregation metrics, intra- and inter-node + labeling, and an optional all-to-all-v heatmap. +- **Trace comparison** — `TraceLens_compare_perf_reports_pytorch` diffs two + generated reports at the CPU-dispatch level to quantify the impact of a change + across hardware or software versions. +- **Trace diff** — `TraceDiff` provides morphological comparison of two trace + trees to pinpoint structural divergences (also available inline in the + PyTorch report using `--comparison_json_path`). + +### SDK modules + +- **Trace2Tree** — Build and navigate the hierarchical event tree. +- **TreePerf** — GPU-timeline breakdown, per-op performance, and roofline + metrics through the SDK. +- **PerfModel** — Compute and roofline performance models. +- **NcclAnalyser** — Multi-rank collective latency/bandwidth/skew analysis. +- **TraceDiff** — Tree-based trace comparison. +- **EventReplay** — Extract and replay isolated operations. +- **TraceFusion** — Merge multi-rank traces for Perfetto visualization. +- **TraceUtils** — Trace utilities, including inference-trace splitting + (`TraceLens_split_inference_trace`). + +```{note} +Version numbers, dates, and per-release validated configurations should be +updated in this page and in the [Compatibility matrix](../reference/compatibility.md) +with each new TraceLens release. +``` + +## Related topics + +- [What is TraceLens?](../what-is-tracelens.md) +- [Compatibility matrix](../reference/compatibility.md) +- [Install TraceLens](../install/installation.md) diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 000000000..2f80e8280 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,51 @@ +############################################################################### +# Copyright (c) 2024 - 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Configuration file for the Sphinx documentation builder. + +This file only contains a selection of the most common options. For a full +list see the documentation: +https://www.sphinx-doc.org/en/master/usage/configuration.html + +For options specific to rocm-docs-core, see the user guide: +https://rocm.docs.amd.com/projects/rocm-docs-core/en/latest/ +""" + +# project info +project = "TraceLens" +author = "Advanced Micro Devices, Inc." +copyright = "Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved." +version = "0.1.0" +release = "0.1.0" + +# rocm-docs-core provides the ROCm theme, the table-of-contents handling, +# and the shared "external project" cross-references. +extensions = ["rocm_docs"] + +external_toc_path = "./sphinx/_toc.yml" + +html_theme = "rocm_docs_theme" +# fmt: off +html_theme_options = { + "flavor": "generic", + "header_title": f"TraceLens {version}", + "header_link": False, + "version_list_link": False, + "nav_secondary_items": { + "Hyperloom": "https://advanced-micro-devices-demo--660.com.readthedocs.build/projects/hyperloom/en/660/", + "GitHub": "https://github.com/AMD-AGI/TraceLens", + "Community": False, + "Blogs": "https://rocm.blogs.amd.com/", + "ROCm Developer Hub": "https://www.amd.com/en/developer/resources/rocm-hub.html", + "Instinct™ Docs": "https://instinct.docs.amd.com/", + "Infinity Hub": "https://www.amd.com/en/developer/resources/infinity-hub.html", + "Support": "https://github.com/AMD-AGI/TraceLens/issues/new/choose", + }, + "link_main_doc": False, +} +# fmt: on + +html_title = f"{project} {version} documentation" diff --git a/docs/how-to/collective-report.md b/docs/how-to/collective-report.md new file mode 100644 index 000000000..3d4c5546e --- /dev/null +++ b/docs/how-to/collective-report.md @@ -0,0 +1,176 @@ + + + +# Generate a collective-communication report +```{meta} +:description: Learn how to generate a multi-GPU collective-communication report with TraceLens to diagnose scaling issues and separate communication from skew. +:keywords: TraceLens, collective communication, NCCL, multi-GPU, distributed training, AllReduce, AllGather, bandwidth, skew, straggler, ROCm, PyTorch profiler +``` + +This topic shows how to analyze multi-GPU collective operations across ranks to +diagnose scaling issues, separating true communication time from +synchronization skew. + +## Prerequisites + +- TraceLens installed (see [Install TraceLens](../install/installation.md)). +- Per-rank PyTorch profiler traces from a distributed run (one trace per rank). + +## Step 1: Generate the report + +If your traces are in a single directory: + +```bash +TraceLens_generate_multi_rank_collective_report_pytorch \ + --trace_dir /path/to/traces \ + --world_size 8 +``` + +If the per-rank files follow a naming pattern, use `--trace_pattern` with a +single `*` placeholder for the rank: + +```bash +TraceLens_generate_multi_rank_collective_report_pytorch \ + --trace_pattern "/path/to/trace_rank_*_step_3.json" \ + --world_size 8 +``` + +For arbitrarily named files (for example, traces written by +`torch.profiler.tensorboard_trace_handler`, which are not named +`rank0_trace.json`), use `--trace_glob` with `--rank_regex` to extract the rank +from each filename: + +```bash +TraceLens_generate_multi_rank_collective_report_pytorch \ + --trace_glob "/path/to/tensorboard/**/*.pt.trace.json.gz" \ + --rank_regex "rank\[(?P\d+)\]" \ + --world_size 16 +``` + +`--rank_regex` must contain a named group `rank` (or a single capture group). + +**Expected output**: An Excel report summarizing collective operations across +ranks, with aggregation metrics (`mean`, `median`, `min`, `max` by default). If +neither `--output_xlsx_path` nor `--output_csvs_dir` is given, the workbook is +written to `--trace_dir` (or the lowest common directory of the resolved +traces). + +## Step 2: Read the report sheets + +Each collective is assigned a `collective_id` (its Process Group name plus an +`index_in_group` reflecting its order in the trace); this is how the tool +correlates the same collective across ranks. The workbook contains a sheet per +collective type and analysis. The most useful: + +| Sheet | Granularity | What it contains | +|-------|-------------|------------------| +| `nccl_summary_implicit_sync` | One row per (collective name, dtype, message size) | Aggregated latency, skew, and bandwidth (algorithm and bus) for collectives that incur implicit sync (AllReduce, AllGather, ReduceScatter, balanced AllToAll). | +| `nccl_summary_long` | One row per (collective name, dtype, message size) | Duration aggregates (sum/mean/std/min/max) and counts across all ranks. | +| `nccl_implicit_sync` | One row per collective | Per-collective implicit-sync breakdown; per-rank timestamps, durations, and `wait_time` are spread across `rank__*` columns. | +| `nccl_long` | One row per (collective, rank) | Per-event, per-rank NCCL records (timestamps, durations, stream, message sizes) for drilling into specific ops. | +| `nccl_summary_all2allv` / `nccl_all2allv` | Per (process group, dtype) / per (collective, rank) | All-to-all-v metrics (throughput, wall time, size imbalance, skew), aggregated and per-rank. | +| `nccl_all2allv_heatmap` | One row per rank, one column per rank | Per rank-pair send volumes (only with `--all2allv_heatmap`). | +| `straggler_summary` | One row per rank | Aggregated straggler metrics — see [Step 3: Find the straggler rank](#step-3-find-the-straggler-rank). | + +Each sheet is produced only when the corresponding collective type is present in +the trace (for example, the all2allv sheets are skipped if the run has no +all-to-all-v). The detailed per-event sheets (`nccl_long`, `nccl_implicit_sync`, +`nccl_all2allv`) are controlled by `--detailed_analysis`, which is on by default. + +### Interpret communication versus skew + +The implicit-sync sheets separate the time spent in actual data movement from the +time a rank spends waiting for other ranks to arrive. The key metrics: + +| Metric | Meaning | +|--------|---------| +| `comm_latency` | Communication time for the collective, taken as the *minimum duration across ranks* — this strips out per-rank waiting so it reflects real data movement. | +| `algo bw` | Algorithm bandwidth: message size / `comm_latency`. | +| `bus bw` | Bus bandwidth (link utilization). | +| `wait_time`, `skew in start time` | How much later some ranks arrive than the earliest rank — the synchronization cost. | + +High skew points to load imbalance upstream rather than a slow network; high +`comm_latency` with low skew points to a bandwidth or topology limit. + +### Interpret all-to-all-v collectives (MoE / expert parallel) + +All-to-all-v sends a different amount of data per rank, so there's no single +message size and the ring/tree `algo bw` / `bus bw` formulas don't apply. +The all2allv sheets instead report: + +| Metric | Meaning | +|--------|---------| +| `throughput (GB/s)` | Total data moved / wall-clock time. Compare against link bandwidth to gauge efficiency. | +| `wall_time` | End-to-end time from the first rank entering to the last finishing. | +| `size_imbalance` | Max rank's data ÷ mean. `1.0` = balanced; `>> 1.0` = some ranks carry disproportionate load (common when some MoE experts are hotter than others). | +| `skew in start time` | How far apart ranks enter the collective — large skew means some ranks are blocked by upstream compute. | + +To diagnose low throughput, check `size_imbalance`: + +- **`size_imbalance` ≈ 1.0** — all ranks are sending roughly equal amounts of + data, so the slow throughput isn't caused by one rank doing more work than + others. Look for software or driver overhead instead (launch latency, kernel + scheduling). +- **`size_imbalance` >> 1.0** — some ranks are sending more data than + others. This is common in Mixture-of-Experts models where certain experts + attract more tokens. The busiest rank takes the longest, and all other ranks + wait for it to finish before the collective can complete. + +To see which specific rank pairs are exchanging the most data and identify the +overloaded rank, add `--all2allv_heatmap`. + +## Step 3: Find the straggler rank + +A straggler is the rank that consistently arrives last at collectives, forcing +the others to wait in implicit synchronization. Open the `straggler_summary` +sheet: it's sorted so the *straggler is the first row* (lowest total wait +time — it arrives last, so it rarely waits itself). + +| Column | What it tells you | +|--------|-------------------| +| `total_wait_time_us` | Sum of this rank's wait across all collectives. The straggler has the *lowest* value. | +| `times_arrived_last` / `pct_arrived_last` | How often this rank was last. The straggler dominates these. | +| `times_arrived_first` | How often this rank was first; the rank highest here pays the biggest sync penalty. | +| `total_nccl_dur_us` | Time inside NCCL kernels; the straggler is typically *lowest* (others are inflated by wait time). | + +Once you know the straggler, merge its trace with a fast rank using +[trace fusion](./trace-fusion.md) and open the result in Perfetto to see what +compute or memory work delays the straggler before each collective. + +## Command-line options + +| Option | Default | Description | +|--------|---------|-------------| +| `--trace_dir` / `--trace_pattern` / `--trace_glob` | — | Mutually exclusive ways to locate the per-rank traces (directory, `*`-pattern, or glob). Exactly one is required. | +| `--world_size` | required | Number of ranks. | +| `--rank_regex` | `rank[\[\-_/]?(?P\d+)` | With `--trace_glob`, regex (named group `rank` or one capture group) used to extract the rank from each filename. | +| `--output_xlsx_path` | auto | Output Excel path. If omitted, written to the trace directory / lowest common directory of the traces. | +| `--output_csvs_dir` | None | Write each sheet as a separate CSV here instead of (or alongside) Excel. | +| `--detailed_analysis` | on | Emit the per-event detail sheets (`nccl_long`, `nccl_implicit_sync`, `nccl_all2allv`) in addition to the summaries. | +| `--agg_metrics` | `mean median min max` | Aggregation metrics in the summary sheets. | +| `--gpus_per_node` | auto | Adds `node_id` / `node_span` columns and labels each process group `intra_node` or `inter_node`. Auto-detected from trace `deviceProperties` if omitted. | +| `--all2allv_heatmap` | off | Add the `nccl_all2allv_heatmap` sheet (per rank-pair send volumes) — useful for spotting imbalanced all-to-all / MoE routing. | +| `--use_multiprocessing` | off | Load traces in parallel — a significant speedup when processing many large per-rank traces. | +| `--max_workers` | `os.cpu_count()` | Cap on worker processes (requires `--use_multiprocessing`). | + +Example combining topology labeling, the heatmap, and parallel loading: + +```bash +TraceLens_generate_multi_rank_collective_report_pytorch \ + --trace_dir /path/to/traces \ + --world_size 8 \ + --gpus_per_node 8 \ + --all2allv_heatmap \ + --use_multiprocessing +``` + +## Next steps + +- For SDK-level collective analysis, see the + [`nccl_analyser_example.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/nccl_analyser_example.ipynb) + notebook in the repository. +- For JAX collectives, see [Generate a JAX performance report](./generate-perf-report-jax.md). \ No newline at end of file diff --git a/docs/how-to/compare-traces.md b/docs/how-to/compare-traces.md new file mode 100644 index 000000000..5d2ef206e --- /dev/null +++ b/docs/how-to/compare-traces.md @@ -0,0 +1,192 @@ + + + +# Compare two traces in TraceLens +```{meta} +:description: Learn how to compare two TraceLens performance reports side by side to quantify the impact of code, library, or hardware changes on GPU performance. +:keywords: TraceLens, trace comparison, TraceDiff, performance regression, GPU benchmark, ROCm, PyTorch profiler, diff, roofline, GEMM +``` + +This topic shows how to quantify the impact of a change by comparing two +TraceLens reports side by side — for example, a baseline against a candidate +after a code, library, or hardware change. + +TraceLens offers two ways to compare traces, depending on how precise you need +the matching to be: + +- **[Perf-report comparison](#perf-report-comparison)** — compares two finished + reports by **op name**, matching each sheet's rows (per-op aggregates, kernels, + and modelled ops like GEMM/SDPA) across the two reports. CLI-driven, and + produces a side-by-side Excel workbook. +- **[TraceDiff comparison](#tracediff-comparison-morphological)** — an SDK that + compares traces by their *morphological tree structure*, matching ops at the + lowest common node. Use it when op names differ between traces (for example, across + hardware, libraries, or framework versions) or when you need finer-grained, + programmatic analysis. + +## Prerequisites + +- TraceLens installed (see [Install TraceLens](../install/installation.md)). +- Two generated reports (`.xlsx`), one per configuration. Generate them with + [TraceLens_generate_perf_report_pytorch](./generate-perf-report-pytorch.md). + +## Perf-report comparison + +This approach compares two already-generated reports by matching rows on op +**name** within each sheet — per-op aggregates, kernel summaries, and modelled +ops such as GEMM and SDPA in the roofline groups. + +### Step 1: Generate the two reports + +```bash +TraceLens_generate_perf_report_pytorch --profile_json_path traces/baseline.json --output_xlsx_path baseline.xlsx +TraceLens_generate_perf_report_pytorch --profile_json_path traces/candidate.json --output_xlsx_path candidate.xlsx +``` + +### Step 2: Run the comparison + +```bash +TraceLens_compare_perf_reports_pytorch \ + baseline.xlsx candidate.xlsx \ + --names baseline candidate \ + --sheets all \ + -o comparison.xlsx +``` + +- `--names` sets the display tags used in the comparison sheets (the count must + match the number of reports). +- `--sheets` selects sheet groups: `gpu_timeline`, `ops_summary`, + `kernel_summary`, `ops_all`, `roofline`, or `all`. +- `-o` sets the output workbook path; add `--output_csvs_dir` to also emit CSVs. + +**Expected output**: `comparison.xlsx`, a workbook with side-by-side columns for +each report. Rows are matched by op name, so this works best when the two runs +share the same op names (typically the same workload across configurations). When +names diverge — for example across hardware or library versions — use the +[TraceDiff comparison](#tracediff-comparison-morphological) instead. + +You can also pass directories of per-sheet `.csv` files instead of `.xlsx` +reports, and compare more than two reports at once. + +### Step 3: Read the comparison sheets + +The output workbook contains one sheet per group you requested with `--sheets`: + +| Sheet | When you get it | What it shows | +|-------|-----------------|---------------| +| `gpu_timeline` | `gpu_timeline` or `all` | GPU activity by type (compute, memcpy, and so on) with per-report timings plus `time ms___diff` and `time ms___pct`. | +| `ops_summary` | `ops_summary` or `all` | Per-op aggregates keyed on `name`, sorted by the baseline's total kernel time. Generated for PyTorch traces; for rocprof traces without `ops_summary` it falls back to `kernel_summary`. | +| `kernel_summary` | `kernel_summary` or `all` | Kernel-level summary for rocprof reports keyed on `name`, using rocprof columns like `Total Kernel Time (ms)` and `Count`. | +| `ops_all_*` | `ops_all` or `all` | Three sheets per variant tag: `ops_all_intersect_` (ops in both), `ops_all_only_baseline_` (baseline only), `ops_all_only_variant_` (variant only). | +| `_*` | `roofline` or `all` | Same intersect / only-baseline / only-variant breakdown for each roofline group: `GEMM`, `SDPA_fwd`, `SDPA_bwd`, `CONV_fwd`, `CONV_bwd`, `UnaryElementwise` (tab `un_eltwise`), `BinaryElementwise` (tab `bin_eltwise`). | + +For every tracked metric, the comparison adds two columns: + +```text +metric___diff # variant - baseline +metric___pct # 100 * diff / baseline +``` + +Things to know when reading the workbook: + +- **Outer merge, never inner** — if an op exists in only one report it still + appears (in the `only_baseline` / `only_variant` sheets), so you can see ops + that vanished or were newly introduced. +- **Baseline is the first report you pass** — choose its order deliberately. +- **Column prefixing** — every metric is written as `::metric`, so multiple + reports can be compared safely. +- **Noise is hidden, not deleted** — columns like `median`, `std`, `min`, `max`, + and `ex_UID` are hidden in Excel for readability; unhide them if you need them. + +Use these to find operations or categories that regressed or improved, shifts in +the GPU-timeline breakdown (more idle time or exposed communication), and changes +in roofline efficiency. + +## TraceDiff comparison (morphological) + +Where the perf-report comparison matches rows by op name, `TraceDiff` compares +the two traces by their *morphological tree structure*. It is an SDK you call +directly, giving finer-grained, programmatic analysis. + +### Why morphological diffing + +Unlike a leaf-level operation comparison, TraceDiff considers the morphological +structure of each trace to find the *lowest common node* between them. This +matters when the same logical operation lowers to different leaf ops — for +example, `aten::convolution` becomes `aten::miopen_convolution` on ROCm and +`aten::cudnn_convolution` on CUDA. A leaf-level diff would treat these as +unrelated; TraceDiff matches them at the `convolution` level, making it suitable +for comparing across hardware, libraries, or framework versions. + +### Compare two traces with the SDK + +```python +from TraceLens import TreePerfAnalyzer, TraceDiff + +# Build a tree for each trace +tree1 = TreePerfAnalyzer.from_file("/path/to/baseline.json").tree +tree2 = TreePerfAnalyzer.from_file("/path/to/candidate.json").tree + +td = TraceDiff(tree1, tree2) # tree1 is the baseline +td.generate_tracediff_report() # builds DataFrames; writes no files +td.print_tracediff_report_files("rprt_diff", prune_non_gpu=True) # writes files +``` + +`generate_tracediff_report()` populates the result DataFrames in memory; +`print_tracediff_report_files()` writes them to disk (pass `prune_non_gpu=True` +to drop subtrees with no GPU work). + +```{note} +TraceDiff operates on PyTorch profiler JSON traces, which it builds into the +`TraceToTree` objects it compares. +``` + +### Output files + +| File | Contents | +|------|----------| +| `merged_tree_output.txt` | Text visualization of the merged tree, showing matched and unmatched nodes. | +| `diff_stats.csv` | Detailed per-op-instance statistics: input shapes, types, kernel times, and kernel names. | +| `diff_stats_unique_args_summary.csv` | Statistics aggregated per op name plus unique argument combination. | +| `cpu_op_map_trace1.json` / `cpu_op_map_trace2.json` | Per-trace map from each CPU op to its kernels. | + +### Access DataFrames and UID mapping + +After `generate_tracediff_report()`, the same data is available as DataFrames, +and `merged_uid_map` cross-references events between the two trees: + +```python +df_stats = td.diff_stats_df # detailed per-op +df_args = td.diff_stats_unique_args_summary_df # per op name + unique args + +# Find the tree2 UID corresponding to a tree1 UID (-1 if no match) +uid1 = next(iter(td.baseline.cpu_root_nodes)) +uid2 = td.get_corresponding_uid(1, uid1) +``` + +### Inline diff during report generation + +To run TraceDiff automatically while generating the primary PyTorch report, pass +`--comparison_json_path`. This adds speedup, delta, and lowest common ancestor (LCA) columns to +`unified_perf_summary`, plus a `diff_stats` sheet: + +```bash +TraceLens_generate_perf_report_pytorch \ + --profile_json_path traces/candidate.json \ + --comparison_json_path traces/baseline.json +``` + +See the +[`trace_diff_example.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/trace_diff_example.ipynb) +notebook for a worked example. + +## Related topics + +- [What is TraceLens?](../what-is-tracelens.md) +- [Install TraceLens](../install/installation.md) +- [Generate a report](generate-reports.md) +- [API reference](../reference/api-reference.md) diff --git a/docs/how-to/event-replay.md b/docs/how-to/event-replay.md new file mode 100644 index 000000000..d4ff2a797 --- /dev/null +++ b/docs/how-to/event-replay.md @@ -0,0 +1,112 @@ + + + +# Replay a single operation in TraceLens +```{meta} +:description: Learn how to isolate a single GPU operation into a minimal, self-contained replay script using TraceLens EventReplay for focused debugging. +:keywords: TraceLens, EventReplay, GPU debugging, reproducer, operator replay, PyTorch profiler, ROCm, kernel isolation, IP-safe +``` + +This topic shows how to isolate an operation from a trace into a minimal, +self-contained replay — useful for focused debugging and for sharing IP-safe +reproducers with kernel or framework developers. + +## Prerequisites + +- TraceLens installed (see [Install TraceLens](../install/installation.md)). +- A PyTorch profiler trace containing the operation you want to isolate. + +## How it works + +`EventReplay` extracts each operation's essential attributes — name, input +shapes, strides, dtypes, and other arguments — into a lightweight, portable JSON +intermediate representation (IR), then reconstructs and re-runs the operation +from that IR. Because the IR is built from trace metadata rather than your model +code, the artifacts can be shared without exposing model IP. + +```{note} +EventReplay allocates inputs with randomized data matching the recorded tensor +shapes, so replay timings approximate — but do not exactly reproduce — the +original run. +``` + +## Step 1: Identify the operation + +Generate a PyTorch report (see +[Generate a PyTorch performance report](./generate-perf-report-pytorch.md)) and use the +`ops_unique_args` sheet to find the operation and input shape you want to +isolate, noting its UID. + +## Step 2: Replay a single event (SDK) + +```python +from TraceLens import TreePerfAnalyzer, EventReplayer + +perf_analyzer = TreePerfAnalyzer.from_file("/path/to/profile.json") +uid = 12345 # UID of the target op (from the ops_unique_args sheet) +event = perf_analyzer.tree.get_UID2event(uid) + +replayer = EventReplayer(event, device="cuda") +replayer.replay() +``` + +The `examples/event_replayer_example.ipynb` notebook walks through the same flow +interactively, including selecting the target event from the tree. + +## Batch replay and benchmark + +Extract a portable IR for many events at once, then replay and benchmark them +with the bundled `batched_replay.py` script: + +```python +import json +from TraceLens import EventReplayer + +repro_data = [ + EventReplayer(event, lazy=True).get_repro_info() + for event in events_of_interest +] +with open("event_replay_ir.json", "w") as f: + json.dump(repro_data, f, indent=4) +``` + +```bash +python batched_replay.py event_replay_ir.json +``` + +`batched_replay.py` accepts: + +- `--device {cuda,cpu}` — device to run on (default `cuda`). +- `--op-filter ` — only replay ops whose name contains the substring + (for example, `aten::convolution`). +- `--op-limit ` — replay at most `N` ops. +- `--stop-on-error` — abort on the first failure instead of continuing. +- `--verbose` / `-v` — print reconstructed arguments and per-op detail. + +Each replayed op prints its reconstructed arguments, average time, and result +tensor, followed by a summary of attempted, successful, and failed replays. + +## Package standalone artifacts + +The IR plus the replay scripts can be zipped into a self-contained bundle that +runs without TraceLens or the original model. The bundle contains: + +- `event_replay_ir.json` — serialized operator replay instructions. +- `utils.py` — tensor-creation and helper utilities. +- `batched_replay.py` — batch replay and benchmark script. +- `batched_replay_readme.md` — run instructions. + +See the +[`event_replayer_example.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/event_replayer_example.ipynb) +notebook for end-to-end IR extraction and packaging. + +## Related topics + +- [What is TraceLens?](../what-is-tracelens.md) +- [Install TraceLens](../install/installation.md) +- [Generate a PyTorch performance report](./generate-perf-report-pytorch.md) +- [API reference](../reference/api-reference.md) diff --git a/docs/how-to/generate-perf-report-jax.md b/docs/how-to/generate-perf-report-jax.md new file mode 100644 index 000000000..2c1ce1ea9 --- /dev/null +++ b/docs/how-to/generate-perf-report-jax.md @@ -0,0 +1,104 @@ + + + +# Generate a JAX performance report +```{meta} +:description: Learn how to generate a TraceLens performance report from a JAX XPlane protobuf trace, including GPU-event and GEMM analysis. +:keywords: TraceLens, JAX, XPlane, protobuf, GPU trace, GEMM, performance report, roofline, ROCm, AMD Instinct, xprof +``` + +TraceLens offers two JAX reports from an XPlane protobuf trace: the *standard +report* (operator and roofline analysis, like the PyTorch report) and a +*GPU-event and GEMM analysis* focused on event-type breakdowns and GEMM +performance. + +## Prerequisites + +- TraceLens installed (see [Install TraceLens](../install/installation.md)). +- A JAX XPlane protobuf trace (`xplane.pb`). JAX parsing uses the `xprof` + dependency, installed automatically with TraceLens. + +```{note} +JAX protobuf parsing has been validated with `tensorboard` 2.19.0, +`tensorboard-plugin-profile` 2.19.0, and `protobuf` 5.29.2. Other versions might +not work. +``` + +## Standard report + +Generate a report from a JAX XPlane protobuf trace (`xplane.pb`): + +```bash +TraceLens_generate_perf_report_jax --profile_path path/to/xplane.pb +``` + +The same `--profile_path` argument also accepts a PyTorch `trace.json`. + +**Expected output**: An Excel report analogous to the +[PyTorch report](./generate-perf-report-pytorch.md), with the operator and +roofline analysis derived from the XPlane trace (the operator sheets are named +`kernel_launchers*`, alongside `xla_summary` and `df_xla_perf`). JAX output does +*not* include the `short_kernels_summary` / `short_kernel_histogram` sheets — +those are PyTorch-only. + +Options: + +- `--kernel_metadata_keyword_filters ...` restricts the analysis to events + whose metadata contains the given keywords (for example, `remat checkpoint` to + focus on rematerialization/checkpointing scopes). +- `--enable-origami` uses Origami-simulated GEMM/SDPA times when a GPU arch JSON + is available. +- `--output_xlsx_path` and `--output_csvs_dir` control output paths. (JAX + currently supports only these output options.) + +For bandwidth analysis of JAX collective operations from XPlane traces, see the +[`jax_nccl_analyser_example.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/jax_nccl_analyser_example.ipynb) +notebook. + +## GPU-event and GEMM analysis + +For a JAX-specific breakdown of GPU event statistics and GEMM performance, use +the analysis report. It has no console entry point, so run it as a module: + +```bash +python -m TraceLens.Reporting.generate_perf_report_jax_analysis \ + --profile_xplane_pb_path path/to/xplane.pb \ + --output_path ./jax_analysis \ + --num_cus 304 +``` + +This writes one file per table into `--output_path`, named +`` (default `output_filename` is +`trace_analysis_results`), in both `.xlsx` and `.csv` by default: + +| File suffix | Contents | +|-------------|----------| +| `_gpu_events_averages` | Average time and percentage per GPU event type, including total/exposed/overlapped communication time. | +| `_gpu_events_categorized_mean` | GPU event statistics grouped by category. | +| `_xla_grouped` | XLA computations grouped by base name (digits/trailing underscores stripped), sorted by percentage of total time. | +| `_gemms` | Summary of GEMM events. | +| `_gemms_detailed` | Detailed GEMM performance metrics, computed against the GPU compute units (`--num_cus`). | + +Options: + +- `--profile_xplane_pb_path PATH` (required) — the JAX XPlane protobuf trace. +- `--output_path DIR` (required) — output directory. +- `--num_cus N` — GPU compute units for the GEMM model (default `304` for MI300X; + use `104` for MI210). `--name` sets the architecture label (default `mi300x`). +- `--output_table_formats {.xlsx,.csv} ...` — one or both output formats (default + both). +- `--output_filename NAME` — base name for the output files (default + `trace_analysis_results`). + +## Next steps + +- Quantify the effect of a change by [comparing two traces](./compare-traces.md). +- Analyze multi-GPU collectives with a + [collective-communication report](./collective-report.md). +- Analyze [PyTorch](./generate-perf-report-pytorch.md) or + [rocprof](./generate-perf-report-rocprof.md) traces. + diff --git a/docs/how-to/generate-perf-report-pytorch-inference.md b/docs/how-to/generate-perf-report-pytorch-inference.md new file mode 100644 index 000000000..b46dc6029 --- /dev/null +++ b/docs/how-to/generate-perf-report-pytorch-inference.md @@ -0,0 +1,93 @@ + + + +# Generate a PyTorch inference performance report +```{meta} +:description: Learn how to generate a TraceLens performance report from a PyTorch LLM-serving (vLLM/SGLang) trace captured in graph mode, including capture-trace merging. +:keywords: TraceLens, PyTorch profiler, inference, vLLM, SGLang, CUDA graph, HIP graph, graph capture, LLM serving, FusedMoE, roofline, ROCm +``` + +`TraceLens_generate_perf_report_pytorch_inference` is the inference-oriented +variant of the PyTorch report. It targets LLM-serving traces (for example, from +vLLM or SGLang) that run in CUDA/HIP graph mode, and can merge the graph-capture +traces back into the graph-replay trace to recover the call-stack and input-shape +metadata that graph execution drops. + +For training or single-run PyTorch traces, use +[Generate a PyTorch performance report](./generate-perf-report-pytorch.md) +instead. + +## Prerequisites + +Before generating a report, confirm you have the following: + +- TraceLens installed (see [Install TraceLens](../install/installation.md)). +- A graph-replay `torch.profiler` trace (`.json` or `.json.gz`). +- (Optional) The folder of graph-capture traces from the same run, if you want to + recover shapes and call stacks (see [Merge capture traces](#merge-capture-traces)). + +## Generate the report + +Pass the graph-replay trace to generate the default Excel report: + +```bash +TraceLens_generate_perf_report_pytorch_inference \ + --profile_json_path tests/traces/inference/graph_full/graph_execution.json.gz +``` + +Output behavior matches the PyTorch report: a single Excel workbook is written +next to the trace by default; use `--output_xlsx_path` or `--output_csvs_dir` to +change the destination. + +## Merge capture traces + +In graph mode, the replay trace records kernel launches but loses the CPU +call-stack and input-shape metadata attached to the original operations. If you +captured the graphs, point `--capture_folder` at that folder to merge the capture +traces back into the replay trace and restore that metadata for richer operator +and roofline analysis: + +```bash +TraceLens_generate_perf_report_pytorch_inference \ + --profile_json_path tests/traces/inference/graph_full/graph_execution.json.gz \ + --capture_folder tests/traces/inference/graph_full/capture_traces +``` + +When `--capture_folder` is set, TraceLens first classifies the capture traces +(writing an `execution_details.json` in the folder if one isn't already present), +then merges the matching subtrees into the graph tree before running the standard +analysis. + +```{note} +`--capture_folder` and `--comparison_json_path` can't be used together: the +TraceDiff comparison doesn't support graph-capture traces. +``` + +## Inference-oriented options + +The inference report shares most options with the PyTorch report (output paths, +short-kernel study, roofline and Origami, collective analysis). The options most +relevant to serving traces: + +| Argument | Default | Description | +|----------|---------|-------------| +| `--profile_json_path` | required | Path to the graph-replay `torch.profiler` trace (`.json` or `.json.gz`). | +| `--capture_folder PATH` | `None` | Folder of graph-capture traces to merge into the replay trace (recovers shapes and call stacks). Mutually exclusive with `--comparison_json_path`. | +| `--group_by_parent_module` | `False` | Group kernel-launcher summaries by parent `nn.Module` in addition to operation name. | +| `--group_by_num_kernels` | `False` | Group summary rows by the number of kernels. | +| `--include_call_stack` | `False` | Add the CPU call stack to the report. | +| `--include_overlap_info` | `False` | Add kernel-overlap sheets (`*_kl_overlap`) when overlap data exists. | +| `--enable_pseudo_ops` | `False` | Augment the tree with pseudo-ops to isolate kernels (for example, `FusedMoE`). | + +Run the tool with `--help` for the complete, version-specific argument list. + +## Related topics + +- [Generate a PyTorch performance report](./generate-perf-report-pytorch.md) +- [Generate TraceLens reports](./generate-reports.md) +- [Compare two traces](./compare-traces.md) +- [API reference](../reference/api-reference.md) diff --git a/docs/how-to/generate-perf-report-pytorch.md b/docs/how-to/generate-perf-report-pytorch.md new file mode 100644 index 000000000..79e12e9ae --- /dev/null +++ b/docs/how-to/generate-perf-report-pytorch.md @@ -0,0 +1,207 @@ + + + +# Generate a PyTorch performance report +```{meta} +:description: Learn how to generate a multi-sheet Excel performance report from a PyTorch torch.profiler trace using TraceLens, including roofline analysis. +:keywords: TraceLens, PyTorch profiler, torch.profiler, GPU trace, performance report, roofline, GEMM, ROCm, AMD Instinct, activation recompute, CUDA migration +``` + +Turn a `torch.profiler` Chrome trace into a multi-sheet Excel (or CSV) +performance report, then read the sheets to find what dominates GPU time. + +## Prerequisites + +Before generating a report, confirm you have the following: + +- TraceLens installed (see [Install TraceLens](../install/installation.md)). +- A `torch.profiler` Chrome trace (`.json` or `.json.gz`). + +## Generate the report + +Pass the trace path to generate the default Excel report: + +```bash +TraceLens_generate_perf_report_pytorch --profile_json_path path/to/trace.json +``` + +Set a custom Excel path, or write per-sheet CSVs instead: + +```bash +# Custom Excel path +TraceLens_generate_perf_report_pytorch \ + --profile_json_path path/to/trace.json \ + --output_xlsx_path report.xlsx + +# Per-sheet CSVs instead of Excel +TraceLens_generate_perf_report_pytorch \ + --profile_json_path path/to/trace.json \ + --output_csvs_dir ./report_csvs +``` + +**Output behavior**: By default a single Excel workbook is written next to the +trace, with the name inferred from the trace (`profile.json` → +`profile_perf_report.xlsx`). `--output_xlsx_path` changes that location. +`--output_csvs_dir` writes one CSV per sheet; passing it alone replaces the Excel +output, while passing it together with `--output_xlsx_path` produces both. The +`openpyxl` package is only needed for Excel output and is auto-installed if +missing. + +## The report sheets + +The generated workbook contains the following sheets: + +| Sheet | Description | +|-------|-------------| +| `gpu_timeline` | End-to-end GPU activity: computation, communication, memory copy, and idle time. | +| `ops_summary_by_category` | Compute time grouped by operation category (GEMM, SDPA_fwd, elementwise, and so on) — the most aggregated view. | +| `ops_summary` | Per-operation aggregate; one row per unique operation name. | +| `ops_unique_args` | Most detailed view; one row per unique (operation name, argument) combination. | +| `unified_perf_summary` | Unified perf metrics for ops with perf models or leaf ops that launch kernels — `GFLOPS`, `TFLOPS/s`, `Data Moved (MB)`, `FLOPS/Byte`, `TB/s`, aggregated by unique args. | +| `coll_analysis` | Collective-communication analysis (enabled by default; disable with `--disable_coll_analysis`). | +| Roofline sheets | One per operation category (`GEMM`, `CONV_fwd`, `SDPA_fwd`, and so on) with the intensity/roofline metrics described below. | +| `kernel_summary` | Per-kernel summary — added with `--enable_kernel_summary`. | +| `short_kernels_summary`, `short_kernel_histogram` | Short-kernel table and duration histogram — added with `--short_kernel_study`. | + +For the GPU timeline, a low computation percentage with significant idle time +indicates poor compute/communication overlap; use `--micro_idle_thresh_us` to +split very short idle gaps into their own category. + +See [Performance report column definitions](https://github.com/AMD-AGI/TraceLens/blob/main/docs_original/perf_report_columns.md) +for what each column means. + +## Roofline classification + +Every per-category roofline sheet includes operation-intensity columns by +default: `GFLOPS`, `Data Moved (MB)`, `FLOPS/Byte`, `TFLOPS/s`, and `TB/s`. + +To add the roofline *bound classification*, supply a GPU architecture spec. +This adds: + +- `Compute Spec` — combined compute type and precision (for example, `matrix_bf16`, + `vector_fp32`). +- `Roofline Time (µs)` — theoretical minimum time from the GPU's peak + capabilities. +- `Roofline Bound` — `COMPUTE_BOUND` or `MEMORY_BOUND`. +- `Pct Roofline` — how close the measured kernel time runs to the roofline. + + ```bash + TraceLens_generate_perf_report_pytorch \ + --profile_json_path path/to/trace.json \ + --gpu_arch_platform MI300X + ``` + +- `--gpu_arch_platform` takes a bundled platform name (`MI300X`, `MI325X`, under + `TraceLens/Agent/Analysis/utils/arch/`); use `--gpu_arch_json_path` to supply + your own spec. The two flags are mutually exclusive. +- An operation is classified by comparing its compute time (`FLOPs / peak FLOPS`) + against its memory time (`bytes / peak bandwidth`): the larger term wins. + Equivalently, operations whose arithmetic intensity (FLOPs/byte) sits below the + roofline knee point (peak FLOPS / peak bandwidth) are memory-bound; those above + it are compute-bound. +- Add `--enable-origami` to use Origami-simulated GEMM/SDPA times when a GPU arch + spec is provided. + +The arch JSON specifies Max Achievable FLOPS (MAF) per compute type and +precision; see the +[GPU architecture example](https://github.com/AMD-AGI/TraceLens/blob/main/examples/gpu_arch_example.md) +for the format and the +[AMD MAF measurements](https://rocm.blogs.amd.com/software-tools-optimization/measuring-max-achievable-flops-part2/README.html#amd-maf-results) +for reference values. To plot roofline charts for specific operators through the +SDK, see the +[`roofline_plots_example.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/roofline_plots_example.ipynb) +notebook. + +## Detect activation recompute + +When training with activation checkpointing (`torch.utils.checkpoint`), some +forward-pass ops are recomputed during the backward pass to save memory. +`--detect_recompute` identifies these and adds an `is_recompute` column so you +can see how much GPU time and compute is spent on recomputation: + +```bash +TraceLens_generate_perf_report_pytorch \ + --profile_json_path path/to/trace.json \ + --detect_recompute +``` + +TraceLens walks the CPU call-stack tree and marks all ops under +`recompute_fn` subtrees (`python_function` events from `torch/utils/checkpoint.py`) +as `is_recompute=True`. This requires `python_function` events in the trace, +which the flag enables automatically. The `is_recompute` column is added to the +`gpu_timeline`, `ops_summary_by_category`, `ops_summary`, `ops_unique_args`, and +`unified_perf_summary` sheets, splitting rows into recompute vs non-recompute. +Use it to answer questions like what percentage of GPU time is +recomputation, which layers are recomputed and at what cost, and whether the +overhead is acceptable for the memory saved. When the flag is not set there is +zero overhead — no extra columns and no `python_function` parsing. + +The same split is available through the SDK: + +```python +from TraceLens.TreePerf import TreePerfAnalyzer + +analyzer = TreePerfAnalyzer.from_file("trace.json", detect_recompute=True) +df = analyzer.get_df_kernel_launchers(include_kernel_details=True) +print(df["is_recompute"].value_counts()) +``` + +## Extend the report (custom hooks) + +`--extension_file` injects custom logic into the report pipeline — useful for +pseudo-op injection, custom perf models, or new op categories. The Python file +can define any of: + +| Symbol | Type | Purpose | +|--------|------|---------| +| `tree_postprocess_extension` | `Callable` | Called with `perf_analyzer.tree`; update the tree post-construction. | +| `perf_model_extension` | `dict` | Map op name → custom perf-model class; overrides or extends built-in models. | +| `op_category_extension` | `dict` | Map category-only op names to final categories, so an op appears in unified reports without a perf model. | + +```bash +TraceLens_generate_perf_report_pytorch \ + --profile_json_path path/to/trace.json \ + --extension_file my_extension.py +``` + +See the example extension file for MegatronLM in the +[`examples/`](https://github.com/AMD-AGI/TraceLens/tree/main/examples) directory. + +## Optional arguments + +| Argument | Default | Description | +|----------|---------|-------------| +| `--output_xlsx_path PATH` | auto-inferred | Excel output path (see output behavior above). | +| `--output_csvs_dir DIR` | `None` | Write each sheet as a CSV in this directory. | +| `--gpu_arch_platform NAME` | `None` | Bundled GPU arch for roofline classification (`MI300X`, `MI325X`). | +| `--gpu_arch_json_path PATH` | `None` | Custom GPU arch JSON (mutually exclusive with `--gpu_arch_platform`). | +| `--enable-origami` | `False` | Use Origami-simulated GEMM/SDPA times when an arch is provided. | +| `--detect_recompute` | `False` | Add an `is_recompute` column for activation checkpointing (see above). | +| `--extension_file PATH` | `None` | Custom tree / perf-model / op-category hooks (see above). | +| `--enable_kernel_summary` | `False` | Add the `kernel_summary` sheet. | +| `--short_kernel_study` | `False` | Add the short-kernel study sheets. | +| `--short_kernel_threshold_us X` | `10` | Threshold (µs) to classify a kernel as "short". | +| `--short_kernel_histogram_bins B` | `100` | Number of bins for the short-kernel histogram. | +| `--enable_pseudo_ops` | `False` | Augment the tree with pseudo-ops to isolate kernels (for example, `FusedMoE`). | +| `--include_overlap_info` | `False` | Add kernel-overlap sheets. | +| `--include_unlinked_kernels` | `False` | Include kernels not linked to a host call stack in the GPU timeline. | +| `--micro_idle_thresh_us X` | `None` | Split idle gaps shorter than this into a separate micro-idle category. | +| `--disable_coll_analysis` | (on) | Disable the `coll_analysis` sheet (collective analysis is on by default). | +| `--topk_ops N` | `None` | Cap rows in the unique-args (`ops_unique_args`) table. | +| `--topk_short_kernels N` | `None` | Cap rows in the short-kernel table. | +| `--topk_roofline_ops N` | `None` | Cap rows in the roofline sheets. | + +## Next steps + +- Quantify the effect of a change by [comparing two traces](./compare-traces.md). +- Analyze multi-GPU collectives with a + [collective-communication report](./collective-report.md). +- Isolate a single operation into a reproducer with + [EventReplay](./event-replay.md). +- Analyze [JAX](./generate-perf-report-jax.md) or + [rocprof](./generate-perf-report-rocprof.md) traces. + diff --git a/docs/how-to/generate-perf-report-rocprof.md b/docs/how-to/generate-perf-report-rocprof.md new file mode 100644 index 000000000..630fab5b2 --- /dev/null +++ b/docs/how-to/generate-perf-report-rocprof.md @@ -0,0 +1,143 @@ + + + +# Generate a rocprof performance report +```{meta} +:description: Learn how to build a performance report from AMD ROCm rocprofiler-sdk traces (rocprofv3 JSON and Perfetto pftrace) using TraceLens. +:keywords: TraceLens, rocprofv3, rocprofiler-sdk, ROCm, pftrace, Perfetto, GPU trace, kernel summary, performance report, AMD Instinct, HIP +``` + +Build a performance report from AMD ROCm rocprofiler-sdk traces. TraceLens +supports both `rocprofv3` JSON results and Perfetto-style `.pftrace` files. + +## Prerequisites + +- TraceLens installed (see [Install TraceLens](../install/installation.md)). +- A `rocprofv3` trace — either a `*_results.json` file or a `.pftrace` file. + +## rocprofv3 JSON + +Generate a report from a rocprofv3 `*_results.json` trace captured with the AMD +ROCm rocprofiler-sdk: + +```bash +TraceLens_generate_perf_report_rocprof \ + --profile_json_path trace_results.json \ + --short_kernel_study \ + --kernel_details +``` + +The report sheets are: + +| Sheet | Description | +|-------|-------------| +| `gpu_timeline` | GPU activity: kernel execution, memory operations, and idle time. | +| `kernel_summary` | Per-kernel statistics — count, total/mean/median/std/min/max duration, and percentage of total kernel time. | +| `kernel_summary_by_category` | Kernel time grouped by category (GEMM, elementwise, attention, …). | +| `kernel_details` | Per-dispatch grid/block dimensions — added with `--kernel_details`. | +| `short_kernels_summary`, `short_kernel_histogram` | Short-kernel table and histogram — added with `--short_kernel_study`. | + +Options: + +- `--kernel_details` includes per-kernel grid/block dimensions; pair with + `--topk_kernels N` to limit to the top N kernels by time. +- `--short_kernel_study` adds short-kernel analysis (tune with + `--short_kernel_threshold_us` and `--short_kernel_histogram_bins`). +- Kernel-summary sheets are on by default; disable with `--disable_kernel_summary`. +- `--output_xlsx_path` / `--output_csvs_dir` control output. + +Kernels are categorized from name patterns (GEMM, elementwise, reduction, +convolution, normalization, attention, memory, and other). + +Because rocprofv3 captures GPU activity directly, it has no CPU call stack or +operator hierarchy, categorization is name-based rather than semantic, and +PyTorch-specific metadata (input shapes, op args) isn't available. For +operator-level shape analysis, use a PyTorch trace instead. The two sources +compare as follows: + +| Feature | rocprofv3 | PyTorch profiler | +|---------|-----------|------------------| +| Format | rocprofiler-sdk JSON | Chrome Trace Event | +| Kernel names | Direct from ROCm | Via PyTorch ops | +| Grid/block dims | Available | Available | +| CPU operations | Limited | Full trace | +| API calls | HIP / HSA | CUDA runtime | +| CPU call-stack tree | Not available | Available | + +**Troubleshooting**: + +- `"Not a valid rocprofv3 file"` — ensure the input is a `*_results.json` file + from rocprofv3, not another format. +- `"No kernel events found"` — the trace captured no GPU activity; check that the GPU + work ran during profiling and that rocprofv3 recorded kernel dispatches. +- `openpyxl not installed` — install it for the Excel output (`pip install openpyxl`) + or use `--output_csvs_dir` for CSV output instead. + +## rocprofv3 pftrace + +For Perfetto-style `.pftrace` files produced by +`rocprofv3 --output-format pftrace`, TraceLens provides three complementary +reports. Each takes `--trace_path` and writes an Excel workbook (or CSVs with +`--output_csvs_dir`) next to the trace. Accepted inputs are `.pftrace` (Perfetto +binary), `.json` (Perfetto-style JSON with a `traceEvents` array), and `.json.gz`. + +```{note} +`.pftrace` input requires `traceconv` to convert the trace to JSON. You don't +need to install it manually: TraceLens uses it from `PATH` if present, otherwise +downloads it into the trace's directory. You can also pass +`--traceconv /path/to/traceconv`. +``` + +**Activity report** — an NSYS-style per-GPU category summary plus kernel/HIP/XLA +summaries, with optional Markdown output: + +```bash +TraceLens_generate_perf_report_pftrace_hip_activity \ + --trace_path sample.pftrace \ + --write_md +``` + +- `--write_md` (or `--output_md_path`) writes a Markdown report. +- `--merge_kernels` merges kernel names by stripping digits. +- `--min_event_ns` drops events shorter than the given nanosecond threshold + (default 5000). +- `--kernel_summary_include_rccl` includes RCCL kernels in the kernel summary. + +**API↔kernel report** — correlates HIP API calls with the kernels they launch +and reports the latency breakdown `T = A + Q + K` (total = API duration + queue +delay + kernel duration): + +```bash +TraceLens_generate_perf_report_pftrace_hip_api --trace_path sample.pftrace +``` + +- `--allow_multi_kernel_per_api` allows multiple kernels per API correlation ID. +- `--include_nonlaunch_apis` includes API rows that did not launch a kernel. +- `--exclude_kernel_regex` excludes kernel names matching a regex (defaults to + the redzone checker kernel). + +A large queue-delay (`Q`) relative to kernel duration (`K`) points to launch +overhead or host-side bottlenecks rather than slow kernels. + +**Memory-copy report** — summarizes memory copies grouped by `copy_bytes`, with +direction (`h2d`, `d2h`, `d2d`) and the GPUs involved: + +```bash +TraceLens_generate_perf_report_pftrace_memory_copy --trace_path sample.pftrace +``` + +Each pftrace generator can also be imported and called with a trace path, +returning a dictionary of pandas DataFrames (for example `api_kernel_summary`, +`category_summary`, `kernel_summary`, `hip_summary`). + +## Next steps + +- Quantify the effect of a change by [comparing two traces](./compare-traces.md). +- Analyze multi-GPU collectives with a + [collective-communication report](./collective-report.md). +- Analyze [PyTorch](./generate-perf-report-pytorch.md) or + [JAX](./generate-perf-report-jax.md) traces. \ No newline at end of file diff --git a/docs/how-to/generate-reports.md b/docs/how-to/generate-reports.md new file mode 100644 index 000000000..c85ab3730 --- /dev/null +++ b/docs/how-to/generate-reports.md @@ -0,0 +1,26 @@ + + + +# Generate TraceLens reports +```{meta} +:description: Learn how to generate TraceLens performance reports from PyTorch, JAX, rocprofv3, and collective-communication traces. +:keywords: TraceLens, performance report, PyTorch profiler, JAX, rocprofv3, collective communication, ROCm, GPU trace analysis +``` + +TraceLens generates structured performance reports from GPU trace files produced by PyTorch, JAX, and the AMD ROCm profiler. Choose the guide for your trace format: + +- [Generate a PyTorch performance report](./generate-perf-report-pytorch.md) +- [Generate a PyTorch inference performance report](./generate-perf-report-pytorch-inference.md) +- [Generate a JAX performance report](./generate-perf-report-jax.md) +- [Generate a rocprof performance report](./generate-perf-report-rocprof.md) +- [Generate a collective-communication report](./collective-report.md) + +## Related topics + +- [What is TraceLens?](../what-is-tracelens.md) +- [Installation instructions](../install/installation.md) +- [API reference](../reference/api-reference.md) diff --git a/docs/how-to/trace-fusion.md b/docs/how-to/trace-fusion.md new file mode 100644 index 000000000..c60ae56dd --- /dev/null +++ b/docs/how-to/trace-fusion.md @@ -0,0 +1,133 @@ + + + +# Fuse multi-rank traces in TraceLens +```{meta} +:description: Learn how to merge per-rank PyTorch traces from a distributed run into a single file for cross-rank visualization in Perfetto using TraceLens. +:keywords: TraceLens, TraceFuse, trace fusion, multi-rank, distributed training, Perfetto, PyTorch profiler, ROCm, visualization, straggler +``` + +This topic shows how to merge per-rank PyTorch traces from a distributed run into +a single file that can be visualized together in Perfetto, using the `TraceFuse` +SDK. + +## Prerequisites + +- TraceLens installed (see [Install TraceLens](../install/installation.md)). +- Per-rank PyTorch profiler traces (one trace per rank). + +## Why fuse traces + +By default, each rank in a distributed run produces its own trace. Inspecting +them separately makes it hard to diagnose cross-rank issues — straggling ranks, +load imbalance, or a rank stalling on a collective — because you can't see how +ranks line up on a common timeline. `TraceFuse` merges the per-rank traces into a +single file so all ranks render together in Perfetto, with clear per-rank CPU/GPU +separation and correct flow linking. + +`TraceFuse` is *for visual analysis in the Perfetto UI only* — not for +automated analysis. For quantitative cross-rank metrics, use a +[collective-communication report](./collective-report.md) instead. + +## Step 1: Fuse the traces + +Pass `TraceFuse` the per-rank trace files (a list ordered by rank, or a +`{rank: filepath}` dict), then call `merge_and_save`: + +```python +import os +from TraceLens import TraceFuse + +profiles_root_dir = "path/to/your/profiles" +world_size = 8 +list_profile_filepaths = [ + os.path.join(profiles_root_dir, f"rank_{i}.json") for i in range(world_size) +] + +fuser = TraceFuse(list_profile_filepaths) + +output_file = os.path.join(profiles_root_dir, "merged_trace.json") +fuser.merge_and_save(output_file) +``` + +A ready-to-edit version of this script is at +[`examples/trace_fusion_example.py`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/trace_fusion_example.py). + +**Expected output**: A single merged trace file containing the events from all +ranks, aligned on a common timeline with per-rank `RANK N - CPU` / `RANK N - GPU` +process labels. + +```{note} +Python-function category events (`python_function`) are skipped by default to +save memory. To keep them, pass `include_pyfunc=True` to `merge_and_save`. +``` + +### Speed up loading with multiprocessing + +Loading many large per-rank traces is the slow part. Enable parallel loading +(speedup is system-dependent): + +```python +# Defaults to os.cpu_count() workers +fuser = TraceFuse(list_profile_filepaths, use_multiprocessing=True) + +# Or cap the worker count +fuser = TraceFuse(list_profile_filepaths, use_multiprocessing=True, max_workers=32) +``` + +### Filter the events you merge + +For large runs, merging every event from every rank is heavy. Pass a `filter_fn` +to `merge_and_save` to keep only the events you care about — for example, NCCL +kernels: + +```python +def filter_nccl_kernels(event): + return ( + event.get("cat") in ["kernel", "gpu_user_annotation"] + and "nccl" in event.get("name", "").lower() + ) + +fuser.merge_and_save(output_file, filter_fn=filter_nccl_kernels) +``` + +You can also narrow the run itself — pass a dict to merge only a subset of ranks +(for instance, rank 0 of each node on a 64-rank job): + +```python +profile_files = { + i: os.path.join(profiles_root_dir, f"rank_{i}.json") + for i in range(0, 64, 8) +} +fuser = TraceFuse(profile_files) +``` + +## Step 2: Visualize in Perfetto + +Open the merged trace in the [Perfetto UI](https://ui.perfetto.dev/) (or the +Chrome trace viewer) to inspect cross-rank behavior, such as exposed +communication and synchronization gaps. Each rank appears as separate +`RANK N - CPU` and `RANK N - GPU` tracks. + +## What the merge does + +`TraceFuse` combines the `traceEvents` from each rank into one list and adjusts +them so they render correctly together: + +- **Process IDs** (`pid`) are offset per rank so ranks don't collide in the UI, + and `process_name` metadata is added to label each track `RANK N - CPU` / + `RANK N - GPU`. +- **Flow linking** is preserved by offsetting the linking key (`correlation` or + `External id`) and the `ac2g` flow `id`s per rank, so CPU→GPU launch arrows + stay correct. + +## Next steps + +- For quantitative collective analysis instead of visualization, see + [Generate a collective-communication report](./collective-report.md). +- Profile a single rank's operations with a + [PyTorch performance report](./generate-perf-report-pytorch.md). \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 000000000..5a50eb7d2 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,44 @@ +.. + Copyright (c) 2024 - 2026 Advanced Micro Devices, Inc. All rights reserved. + +.. meta:: + :description: TraceLens is an open-source Python library for automated GPU trace analysis. Generate performance reports from PyTorch, JAX, and rocprofv3 traces. + :keywords: TraceLens, GPU trace analysis, ROCm, AMD Instinct, PyTorch profiler, JAX, rocprofv3, roofline analysis, performance report, distributed training, CUDA migration + +*********************** +TraceLens documentation +*********************** + +TraceLens is an open-source Python library developed by AMD that automates +performance analysis from GPU trace files. Instead of manually inspecting raw +profiling data in tools such as Perfetto or Chrome Trace Viewer, TraceLens +parses traces from PyTorch, JAX, and ``rocprofv3`` and produces structured +performance reports — including hierarchical GPU-timeline breakdowns, +per-operator roofline analysis (TFLOP/s, TB/s), and multi-GPU communication +diagnostics. + +The TraceLens source code is hosted at `github.com/AMD-AGI/TraceLens `_. + +.. grid:: 2 + :gutter: 3 + + .. grid-item-card:: Install + + * :doc:`Install TraceLens ` + + .. grid-item-card:: How to + + * :doc:`Generate TraceLens reports ` + * :doc:`Compare two traces ` + * :doc:`Replay a single operation ` + * :doc:`Fuse multi-rank traces ` + + .. grid-item-card:: Reference + + * :doc:`API reference ` + +For information on contributing to TraceLens, see the +`Contributing guide `_. + +TraceLens is released under the MIT License. For details, see the +:doc:`License ` page. diff --git a/docs/install/installation.md b/docs/install/installation.md new file mode 100644 index 000000000..091c2b853 --- /dev/null +++ b/docs/install/installation.md @@ -0,0 +1,115 @@ + + + +# Install TraceLens +```{meta} +:description: Step-by-step instructions to install TraceLens from GitHub or source, verify the installation, and set up traceconv for Perfetto pftrace input. +:keywords: TraceLens, install, pip, Python, ROCm, GPU trace analysis, traceconv, pftrace, virtual environment, open source +``` + +This topic provides step-by-step instructions to install TraceLens and verify +the installation. TraceLens is distributed as a Python package; install it with +`pip` either directly from the public GitHub repository (recommended) or from a +local source checkout for development. + +## Prerequisites + +- Python 3.6 or later (3.10 recommended). Confirm your version: + + ```bash + python3 --version + ``` + +- A recent `pip`. Upgrade it inside your environment: + + ```bash + python3 -m pip install --upgrade pip + ``` + +- (Recommended) An isolated virtual environment: + + ```bash + python3 -m venv .venv + source .venv/bin/activate + ``` + +## Method 1: Install from GitHub (recommended) + +Install the latest TraceLens directly from the public repository: + +```bash +pip install git+https://github.com/AMD-AGI/TraceLens.git +``` + +This installs TraceLens and its dependencies and places the `TraceLens_*` +command-line tools on your `PATH`. + +## Method 2: Install from source (development) + +Use an editable install when you want to modify TraceLens or run its test +suite. The `[dev]` extra installs the development and test dependencies: + +```bash +git clone https://github.com/AMD-AGI/TraceLens.git && cd TraceLens +pip install -e .[dev] +python -m pytest tests/ -v +``` + +## Optional: `traceconv` for `.pftrace` input + +`traceconv` is needed only when you pass a Perfetto-style `.pftrace` trace +(produced by `rocprofv3 --output-format pftrace`) to one of the pftrace report +tools (`TraceLens_generate_perf_report_pftrace_hip_activity`, `..._hip_api`, or +`..._memory_copy`); it converts the `.pftrace` to JSON. The other report tools +(PyTorch, JAX, rocprofv3 JSON) don't use it. You don't need to install it +manually: + +- If `traceconv` is on your `PATH`, TraceLens uses it. +- Otherwise, TraceLens downloads it automatically (from + `https://get.perfetto.dev`) into the trace file's directory, so this step + needs network access. +- You can also point a pftrace tool at a specific binary with + `--traceconv /path/to/traceconv`. + +## Verify the installation + +Run the following checks to confirm TraceLens is installed correctly: + +1. Confirm the package imports: + + ```bash + python3 -c "import TraceLens; print('TraceLens import OK')" + ``` + +2. Confirm the command-line tools are available: + + ```bash + TraceLens_generate_perf_report_pytorch --help + ``` + + Expected output: the tool prints its usage and the list of accepted + arguments (for example, `--profile_json_path`) and exits without error. + +3. (Optional) Generate a report from a bundled demo trace to confirm end-to-end + operation. The repository ships sample traces under `tests/traces/`, so run + this from a source checkout (see Method 2): + + ```bash + TraceLens_generate_perf_report_pytorch \ + --profile_json_path tests/traces/mi300/Qwen_Qwen1.5-0.5B-Chat__1016005.json.gz + ``` + + Expected output: an Excel report (`.xlsx`) is written next to the trace, + containing the GPU-timeline and operator-summary sheets. + +## Related topics + +- [What is TraceLens?](../what-is-tracelens.md) +- [Generate TraceLens reports](../how-to/generate-reports.md) +- [Compare two traces](../how-to/compare-traces.md) +- [Replay a single operation](../how-to/event-replay.md) +- [Fuse multi-rank traces](../how-to/trace-fusion.md) diff --git a/docs/reference/api-reference.md b/docs/reference/api-reference.md new file mode 100644 index 000000000..52531811e --- /dev/null +++ b/docs/reference/api-reference.md @@ -0,0 +1,212 @@ + + + +# TraceLens API reference +```{meta} +:description: Complete reference for TraceLens command-line tools and Python SDK modules, including arguments and output descriptions for all report generators. +:keywords: TraceLens, API reference, command-line tools, Python SDK, ROCm, GPU trace, performance report, PyTorch, JAX, rocprofv3, roofline, CLI +``` + + +TraceLens exposes two complementary interfaces: + +- A set of command-line tools (installed as `console_scripts`) for + generating and comparing reports. +- A Python SDK for building custom analysis workflows. + +This topic documents the command-line tools and their main arguments, and +summarizes the SDK modules. Run any tool with `--help` for the complete, +version-specific argument list. + +## Command-line tools + +The following sections document each tool's main arguments and expected output. + +### TraceLens_generate_perf_report_pytorch + +Generate a multi-sheet Excel report from a PyTorch (`torch.profiler`) trace. + +| Argument | Default | Description | +|----------|---------|-------------| +| `--profile_json_path` | required | Path to the `profile.json` or `.json.gz` trace. | +| `--output_xlsx_path` | auto | Path to the output Excel file. | +| `--output_csvs_dir` | None | Directory to write per-sheet CSV files instead of/with Excel. | +| `--enable_kernel_summary` | off | Add a kernel-summary sheet. | +| `--short_kernel_study` | off | Add a short-kernel study; tune with `--short_kernel_threshold_us`, `--short_kernel_histogram_bins`, `--topk_short_kernels`. | +| `--disable_coll_analysis` | on | Disable the collective-analysis section (enabled by default). | +| `--include_unlinked_kernels` | off | Include kernels with no linked CPU op in the GPU-timeline analysis. | +| `--micro_idle_thresh_us` | None | Threshold (µs) to classify an idle interval as micro-idle. | +| `--comparison_json_path` | None | Second trace to compare against; runs TraceDiff and adds speedup/delta/LCA columns plus a `diff_stats` sheet. | +| `--enable-origami` | off | Use Origami for simulated GEMM/SDPA times when a GPU arch JSON is provided. | +| `--detect_recompute` | off | Detect activation recomputation and add an `is_recompute` column. | +| `--include_overlap_info` | off | Add kernel-overlap sheets. | +| `--topk_ops`, `--topk_roofline_ops` | None | Limit rows in the unique-args and roofline tables. | +| `--extension_file` | None | Custom extensions for `TraceTree` and `PerfModel`. | + +**Output:** an `.xlsx` workbook with the GPU-timeline, operator-category, +operator, unique-argument, and roofline sheets. + +### TraceLens_generate_perf_report_pytorch_inference + +Inference-oriented variant of the PyTorch report. + +| Argument | Default | Description | +|----------|---------|-------------| +| `--profile_json_path` | required | Path to the trace. | +| `--group_by_parent_module` | off | Group kernel-launcher summaries by parent `nn.Module`. | +| `--capture_folder` | None | Path to the capture-trace folder. | +| `--include_overlap_info` | off | Add `*_kl_overlap` sheets when data exists. | + +Shares most options with `TraceLens_generate_perf_report_pytorch` (output +paths, short-kernel study, roofline/Origami, comparison, call stack). Run with +`--help` for the full list. + +### TraceLens_generate_perf_report_jax + +Generate a report from a JAX XPlane protobuf trace (also accepts a PyTorch +trace). + +| Argument | Default | Description | +|----------|---------|-------------| +| `--profile_path` | required | Path to the trace (`trace.json` or JAX `xplane.pb`). | +| `--output_xlsx_path` | auto | Output Excel file. | +| `--output_csvs_dir` | None | Directory for CSV output. | +| `--kernel_metadata_keyword_filters` | None | Only analyze events whose metadata contains the given keyword(s), for example `remat checkpoint`. | +| `--enable-origami` | off | Use Origami simulated GEMM/SDPA times when a GPU arch JSON is provided. | + +### TraceLens_generate_perf_report_rocprof + +Generate a report from a rocprofv3 `*_results.json` trace. + +| Argument | Default | Description | +|----------|---------|-------------| +| `--profile_json_path` | required | Path to the rocprofv3 `*_results.json` trace. | +| `--output_xlsx_path` / `--output_csvs_dir` | auto / None | Output destinations. | +| `--kernel_details` | off | Include per-kernel detail with grid/block dimensions. | +| `--disable_kernel_summary` | on | Disable kernel-summary sheets (enabled by default). | +| `--short_kernel_study` | off | Add short-kernel analysis; tune with `--short_kernel_threshold_us`, `--short_kernel_histogram_bins`. | +| `--topk_kernels` | all | Limit kernel details to the top K kernels by time. | + +### TraceLens_compare_perf_reports_pytorch + +Compare two or more previously generated reports. + +| Argument | Default | Description | +|----------|---------|-------------| +| `reports` | required | One or more TraceLens reports: `.xlsx` files or directories of per-sheet `.csv` files. | +| `--names` | None | Optional display tags for each report (count must match). | +| `--sheets` | `all` | Sheet groups to compare: `gpu_timeline`, `ops_summary`, `kernel_summary`, `ops_all`, `roofline`, or `all`. | +| `-o`, `--output` | `comparison.xlsx` | Output Excel file. | +| `--output_csvs_dir` | None | Also write each comparison sheet as a CSV here. | + +### TraceLens_generate_multi_rank_collective_report_pytorch + +Generate a collective-communication report across ranks. + +| Argument | Default | Description | +|----------|---------|-------------| +| `--trace_dir` | — | Directory containing per-rank trace files. | +| `--trace_pattern` | — | Template path with a single `*` placeholder for rank. | +| `--trace_glob` | — | Glob for arbitrarily named trace files (requires `--world_size`, uses `--rank_regex`). | +| `--world_size` | required | Number of ranks. | +| `--agg_metrics` | `mean median min max` | Aggregation metrics in the summary. | +| `--gpus_per_node` | auto | Adds `node_id`/`node_span` columns and labels each process group `intra_node` or `inter_node`. | +| `--all2allv_heatmap` | off | Add an `nccl_all2allv_heatmap` sheet with per rank-pair send volumes. | +| `--use_multiprocessing` / `--max_workers` | off / `cpu_count` | Parallel trace loading. | + +`--trace_dir`, `--trace_pattern`, and `--trace_glob` are mutually exclusive +ways to locate the per-rank traces. + +### TraceLens_generate_perf_report_pftrace_hip_activity + +Per-GPU category and kernel/HIP/XLA activity report from a Perfetto-style +trace. + +| Argument | Default | Description | +|----------|---------|-------------| +| `--trace_path` | required | Path to `.json`, `.json.gz`, or `.pftrace`. | +| `--write_md` / `--output_md_path` | off / None | Write a Markdown report. | +| `--merge_kernels` | off | Merge kernel names by stripping digits. | +| `--min_event_ns` | 5000 | Drop events shorter than this (ns). | +| `--kernel_summary_baseline` | `total` | Baseline for the kernel summary. | +| `--kernel_summary_group` | `config` | Grouping key for the kernel summary. | +| `--kernel_summary_include_rccl` | off | Include RCCL kernels in the kernel summary. | +| `--traceconv` | auto | Path to `traceconv` (auto-resolved or downloaded for `.pftrace`). | + +### TraceLens_generate_perf_report_pftrace_hip_api + +HIP API ↔ kernel correlation with the latency breakdown `T = A + Q + K` (API +duration, queue delay, kernel duration). + +| Argument | Default | Description | +|----------|---------|-------------| +| `--trace_path` | required | Path to `.json`, `.json.gz`, or `.pftrace`. | +| `--output_xlsx_path` / `--output_csvs_dir` | auto / None | Output destinations. | +| `--exclude_kernel_regex` | redzone checker | Regex of kernel names to exclude. | +| `--allow_multi_kernel_per_api` | off | Allow multiple kernels per API correlation ID. | +| `--include_nonlaunch_apis` | off | Include API rows that have no linked kernel. | +| `--traceconv` | auto | Path to `traceconv`. | + +### TraceLens_generate_perf_report_pftrace_memory_copy + +Memory-copy report grouped by `copy_bytes` with direction and the GPUs +involved. + +| Argument | Default | Description | +|----------|---------|-------------| +| `--trace_path` | required | Path to `.json`, `.json.gz`, or `.pftrace`. | +| `--output_xlsx_path` | auto | Custom Excel output path. | +| `--output_csvs_dir` | None | Directory for CSV output. | +| `--traceconv` | auto | Path to `traceconv`. | + +### TraceLens_split_inference_trace + +Split an inference trace into per-iteration or per-phase sub-traces. + +| Argument | Default | Description | +|----------|---------|-------------| +| `trace_path` | required | Path to the trace (`.json` or `.json.gz`). | +| `-o`, `--output-dir` | required | Output directory. | +| `-i`, `--iterations` | `all` | Iteration range: `all`, a single index (`50`), or a range (`10:20`). | +| `-d`, `--dummy` | `all` | Dummy-run range. | +| `--find-steady-state` / `--num-steps` | off / 32 | Extract a steady-state region of N iterations. | +| `--divide-phases` | off | Store steady-state steps into `prefilldecodemix/` and `decode_only/` sub-folders. | +| `--CONC`, `--OSL`, `--R` | None | Expected concurrency and output-sequence-length window parameters. | + +## Python SDK + +The SDK modules live under the `TraceLens` package and can be imported to build +custom workflows. Each module has a dedicated guide in the repository `docs_original/` +directory and an example notebook under `examples/`. + +| Module | Purpose | Reference | +|--------|---------|-----------| +| `Trace2Tree` | Build and navigate the hierarchical event tree (Python ops → CPU dispatch → GPU kernels). | `docs_original/Trace2Tree.md`, `examples/trace2tree_example.ipynb` | +| `TreePerf` | GPU-timeline breakdown, per-op performance, and roofline metrics. | `docs_original/TreePerf.md`, `examples/tree_perf_example.ipynb` | +| `PerfModel` | Compute and roofline performance models for operators. | `docs_original/gemm_dim_eff.md`, `docs_original/triton_perf_model_walkthrough.md` | +| `NcclAnalyser` | Multi-rank collective latency/bandwidth/skew analysis. | `docs_original/NcclAnalyser.md`, `examples/nccl_analyser_example.ipynb` | +| `TraceDiff` | Morphological comparison of two trace trees. | `docs_original/TraceDiff.md`, `examples/trace_diff_example.ipynb` | +| `EventReplay` | Extract and replay isolated operations. | `docs_original/EventReplay.md`, `examples/event_replayer_example.ipynb` | +| `TraceFusion` | Merge multi-rank traces for Perfetto visualization. | `docs_original/TraceFusion.md`, `examples/trace_fusion_example.py` | +| `Reporting` | The report generators behind the CLI tools; importable to return pandas data frames. | `docs_original/generate_perf_report.md` | +| `TraceUtils` | Trace utilities, including inference-trace splitting. | — | + +For report-column definitions across all sheets, see +`docs_original/perf_report_columns.md` in the repository. + +```{note} +For a class- and function-level SDK reference generated directly from +docstrings, build the documentation against the TraceLens source with a Sphinx +autodoc/autosummary extension. +``` + +## Related topics + +- [What is TraceLens?](../what-is-tracelens.md) +- [Install TraceLens](../install/installation.md) +- [Compatibility matrix](../reference/compatibility.md) +- [Release notes](../about/release-notes.md) diff --git a/docs/reference/compatibility.md b/docs/reference/compatibility.md new file mode 100644 index 000000000..255516c9c --- /dev/null +++ b/docs/reference/compatibility.md @@ -0,0 +1,95 @@ + + + +# TraceLens compatibility matrix +```{meta} +:description: TraceLens compatibility matrix: supported Python versions, operating systems, trace formats, and validated GPU accelerators for roofline analysis. +:keywords: TraceLens, compatibility, Python, ROCm, AMD Instinct, MI300X, PyTorch profiler, JAX, rocprofv3, pftrace, GPU, Linux +``` + +This topic lists the hardware and software configurations for TraceLens. Only +configurations that have been verified and tested should appear in the +validated tables below. + +```{note} +TraceLens analyzes trace files and does not execute GPU kernels itself, so its +core report generation runs on any host with a supported Python version. GPU +and ROCm requirements apply to the *profiling tools* that produce the traces +(for example, `rocprofv3`) and to the roofline specifications used for a given +accelerator. +``` + +## Software requirements + +| Component | Requirement | Notes | +|-----------|-------------|-------| +| Python | 3.6 or later (3.10 recommended) | `python_requires>=3.6`; the 3.10 toolchain is used for documentation and CI builds. | +| Operating system | Linux (OS-independent core) | Report generation is not OS-specific; ROCm-based trace capture requires Linux. | +| TraceLens package | 0.1.0 | Installed from [github.com/AMD-AGI/TraceLens](https://github.com/AMD-AGI/TraceLens). | + +### Python dependencies + +These are installed automatically with the package: + +| Dependency | Purpose | +|------------|---------| +| `pandas` | Tabular analysis and report data frames. | +| `openpyxl` | Excel (`.xlsx`) report output. | +| `tqdm` | Progress bars for long-running analyses. | +| `orjson` | Fast JSON parsing of large traces. | +| `tabulate` | Text/Markdown table rendering. | +| `matplotlib` | Roofline and other plots. | +| `xprof==2.20.1` | JAX XPlane parsing (HLO sidecar generation; supports JAX 0.8+). | +| `protobuf>=6.31.1,<7.0.0` | Required by `xprof`'s `grpcio-status` dependency. | +| `backports.strenum`, `StrEnum` | `StrEnum` backport for Python < 3.11. | +| `office365-rest-python-client`, `msal` | Optional SharePoint/365 integrations. | +| `traceconv` | Optional; required only for `.pftrace` input. Resolved from `PATH` or downloaded automatically if not provided with `--traceconv`. | + +## Supported trace formats + +| Format | Producing tool | Validated | +|--------|----------------|-----------| +| PyTorch Chrome trace (`.json`, `.json.gz`, `.zip`) | `torch.profiler` | Yes | +| JAX XPlane protobuf (`.pb`) | JAX profiler / `xprof` | Yes | +| rocprofv3 JSON (`*_results.json`) | AMD ROCm rocprofiler-sdk | Yes | +| rocprofv3 pftrace / Perfetto-style | `rocprofv3 --output-format pftrace` | Yes | + +## Accelerators (roofline analysis) + +Roofline classification requires a GPU architecture specification that provides +the peak FLOPS and peak bandwidth for the target accelerator (for example, +`mi300.json`). Architecture specifications are bundled under +`TraceLens/Agent/Analysis/utils/arch/`; supply your own JSON with +`--gpu_arch_json_path` for accelerators not listed. + +| Accelerator | Notes | +|-------------|-------| +| AMD Instinct™ MI300X | Used for the roofline knee point (for example, FP16 ≈ 1300 TFLOPS / 5.3 TB/s ≈ 245 FLOPs/byte). | + +```{note} +Add validated accelerators to this table as they are tested for each release. +``` + +## ROCm and CUDA compatibility + +TraceLens analyzes trace files rather than talking to the GPU or runtime +directly, so it isn't tied to a specific ROCm version. `rocprofv3`-based capture +(JSON and pftrace) only requires a ROCm installation that provides `rocprofv3` +and, for `.pftrace` conversion, `traceconv`; any ROCm version that emits +well-formed traces should work. If a particular ROCm build produces malformed +traces (for example, missing required fields), TraceLens reports the problem and +stops rather than silently producing misleading results. + +The PyTorch report workflow works on any `torch.profiler` trace regardless of +the GPU backend, and is well tested on both AMD ROCm and NVIDIA CUDA traces. + +## Related topics + +- [What is TraceLens?](../what-is-tracelens.md) +- [Install TraceLens](../install/installation.md) +- [Release notes](../about/release-notes.md) +- [API reference](../reference/api-reference.md) diff --git a/docs/sphinx/_toc.yml.in b/docs/sphinx/_toc.yml.in new file mode 100644 index 000000000..e407b0a9a --- /dev/null +++ b/docs/sphinx/_toc.yml.in @@ -0,0 +1,52 @@ +# Anywhere {branch} is used, the branch name will be substituted. +# These comments will also be removed. +defaults: + numbered: False + maxdepth: 6 +root: index + +subtrees: +- entries: + - file: what-is-tracelens + title: What is TraceLens? + - file: about/release-notes + title: Release notes + - file: reference/compatibility + title: Compatibility matrix + +- caption: Install + entries: + - file: install/installation + title: Install TraceLens + +- caption: How to + entries: + - file: how-to/generate-reports + title: Generate reports + entries: + - file: how-to/generate-perf-report-pytorch + title: PyTorch performance report + - file: how-to/generate-perf-report-pytorch-inference + title: PyTorch inference performance report + - file: how-to/generate-perf-report-jax + title: JAX performance report + - file: how-to/generate-perf-report-rocprof + title: rocprof performance report + - file: how-to/collective-report + title: Collective-communication report + - file: how-to/compare-traces + title: Compare two traces + - file: how-to/event-replay + title: Replay a single operation + - file: how-to/trace-fusion + title: Fuse multi-rank traces + +- caption: Reference + entries: + - file: reference/api-reference + title: API reference + +- caption: About + entries: + - file: about/license + title: License diff --git a/docs/sphinx/requirements.txt b/docs/sphinx/requirements.txt new file mode 100644 index 000000000..f40e2d3af --- /dev/null +++ b/docs/sphinx/requirements.txt @@ -0,0 +1 @@ +rocm-docs-core==1.22.0 diff --git a/docs/what-is-tracelens.md b/docs/what-is-tracelens.md new file mode 100644 index 000000000..66fb480d0 --- /dev/null +++ b/docs/what-is-tracelens.md @@ -0,0 +1,104 @@ + + + +# What is TraceLens? +```{meta} +:description: Learn what TraceLens is and what it does — an open-source Python library from AMD for automated GPU trace analysis, roofline modeling, and distributed workload profiling. +:keywords: TraceLens, GPU trace analysis, ROCm, AMD, PyTorch profiler, JAX, rocprofv3, roofline, distributed training, performance report, open source +``` + +TraceLens is an open-source Python library developed by AMD that automates +performance analysis from GPU trace files. Instead of manually inspecting raw +profiling data in tools such as Perfetto or Chrome Trace Viewer, TraceLens +parses traces from PyTorch, JAX, and `rocprofv3` and produces structured +performance reports — including hierarchical GPU-timeline breakdowns, +per-operator roofline analysis (TFLOP/s, TB/s), and multi-GPU communication +diagnostics. + +TraceLens can pinpoint whether a kernel is compute-bound or memory-bound, +separate true communication time from synchronization skew in distributed +workloads, and compare traces side-by-side to quantify the impact of code or +configuration changes. It's available as a set of command-line tools for +quick report generation and as a Python SDK for building custom analysis +workflows, making it useful for one-off debugging and repeatable performance +regression testing alike. + +The TraceLens source code is hosted at +[github.com/AMD-AGI/TraceLens](https://github.com/AMD-AGI/TraceLens). + +## What TraceLens does + +TraceLens provides these capabilities: + +- **Hierarchical performance breakdowns** — Pinpoint bottlenecks with a + top-down view, moving from the overall GPU timeline (idle/busy) to operator + categories, individual operators, and right down to unique argument shapes. +- **Compute and roofline modeling** — Translate raw timings into efficiency + metrics such as TFLOP/s and TB/s. Determine whether an operation is compute- + or memory-bound and see how effectively your code uses the hardware. +- **Multi-GPU communication analysis** — Diagnose scaling issues by dissecting + collective operations. TraceLens separates pure communication time from + synchronization skew and calculates effective bandwidth on your real + workload. +- **Trace comparison** — Quantify the impact of changes with trace diffing at + the CPU-dispatch level, enabling meaningful side-by-side comparisons across + hardware and software versions. +- **Event replay** — Isolate any operation for focused debugging. TraceLens + generates minimal, self-contained replay scripts from trace metadata, making + it straightforward to share IP-safe reproducers with kernel developers. +- **Extensible SDK** — Start with ready-to-use scripts, then build custom + workflows with a flexible Python API. + +## Use cases + +TraceLens is suited to these scenarios: + +- **Performance debugging** — Find the operators and kernels responsible for low + GPU utilization in a training or inference workload. +- **Roofline efficiency analysis** — Measure how close each operator runs to the + hardware's compute and memory-bandwidth limits on a given accelerator. +- **Distributed scaling analysis** — Quantify exposed communication and + synchronization skew across ranks in multi-GPU and multi-node runs. +- **Regression testing** — Compare a baseline trace against a candidate to + quantify the effect of a code, library, or hardware change. +- **Reproducer generation** — Extract a single operator into a standalone replay + script to share with kernel or framework developers. + +## Supported profile formats + +TraceLens supports these trace formats: + +| Format | Source tool | Report CLI | +|--------|-------------|------------| +| PyTorch | `torch.profiler` | `TraceLens_generate_perf_report_pytorch` | +| PyTorch (inference) | `torch.profiler` | `TraceLens_generate_perf_report_pytorch_inference` | +| JAX | XPlane protobuf | `TraceLens_generate_perf_report_jax` | +| rocprofv3 JSON | AMD ROCm rocprofiler-sdk | `TraceLens_generate_perf_report_rocprof` | +| rocprofv3 pftrace (Perfetto-style) | `rocprofv3 --output-format pftrace` | `TraceLens_generate_perf_report_pftrace_hip_activity`, `..._pftrace_hip_api`, `..._pftrace_memory_copy` | + +## Example notebooks + +Hands-on notebooks in the repository walk through the core features: + +| Example | What it covers | +|---------|----------------| +| [`examples/trace2tree_example.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/trace2tree_example.ipynb) | Navigate the hierarchical event tree — link Python ops, CPU dispatches, and GPU kernels | +| [`examples/tree_perf_example.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/tree_perf_example.ipynb) | GPU-timeline breakdown, per-op performance, and roofline metrics using the SDK | +| [`examples/nn_module_view.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/nn_module_view.ipynb) | GPU time broken down by `nn.Module` | +| [`examples/nccl_analyser_example.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/nccl_analyser_example.ipynb) | Multi-rank collective analysis: latency, bandwidth, skew | +| [`examples/trace_diff_example.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/trace_diff_example.ipynb) | Morphological comparison of two trace trees | +| [`examples/event_replayer_example.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/event_replayer_example.ipynb) | Extract and replay operations for isolated debugging | +| [`examples/trace_fusion_example.py`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/trace_fusion_example.py) | Merge multi-rank PyTorch traces for Perfetto visualization | +| [`examples/roofline_plots_example.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/roofline_plots_example.ipynb) | Roofline-style visualizations for specific operators | +| [`examples/jax_nccl_analyser_example.ipynb`](https://github.com/AMD-AGI/TraceLens/blob/main/examples/jax_nccl_analyser_example.ipynb) | Bandwidth analysis for JAX collectives from XPlane traces | + +## Related topics + +- [Install TraceLens](./install/installation.md) +- [API reference](./reference/api-reference.md) +- [Compatibility matrix](./reference/compatibility.md) +- [Release notes](./about/release-notes.md) diff --git a/docs/Agentic_Mode.md b/docs_original/Agentic_Mode.md similarity index 100% rename from docs/Agentic_Mode.md rename to docs_original/Agentic_Mode.md diff --git a/docs/EventReplay.md b/docs_original/EventReplay.md similarity index 100% rename from docs/EventReplay.md rename to docs_original/EventReplay.md diff --git a/docs/Inference_analysis.md b/docs_original/Inference_analysis.md similarity index 98% rename from docs/Inference_analysis.md rename to docs_original/Inference_analysis.md index 1ae4c4539..52d6c1db9 100644 --- a/docs/Inference_analysis.md +++ b/docs_original/Inference_analysis.md @@ -69,7 +69,7 @@ The remainder of Step 2 covers manual trace collection — building or patching ###### vLLM Script -A unified build script is provided that supports multiple vLLM versions. It takes a version tag (`v14`, `v15`, `v16`, `v17`, `v18`, `v19`, `v20`, or `v21`) as the first argument, followed by the path to your local TraceLens clone and any standard `docker build` flags. The script selects the correct base image and patch file automatically. +A unified build script is provided that supports multiple vLLM versions. It takes a version tag (`v14`, `v15`, `v16`, `v17`, `v18`, `v19`, `v20`, `v21`, `v22`, `v23`, or `v24`) as the first argument, followed by the path to your local TraceLens clone and any standard `docker build` flags. The script selects the correct base image and patch file automatically. | Version | Base Image | vLLM Version | Patch File | @@ -82,6 +82,9 @@ A unified build script is provided that supports multiple vLLM versions. It take | `v19` | `vllm/vllm-openai-rocm:v0.19.0` | v0.19.0 | `config_vllm_v0.19.0.patch` | | `v20` | `rocm/vllm-dev:preview_v0.20.0_20260429` | v0.20.0 | `config_vllm_v0.20.0.patch` | | `v21` | `vllm/vllm-openai-rocm:v0.21.0` | v0.21.0 | `config_vllm_v0.21.0.patch` | +| `v22` | `vllm/vllm-openai-rocm:v0.22.0` | v0.22.0 | `config_vllm_v0.22.0.patch` | +| `v23` | `vllm/vllm-openai-rocm:v0.23.0` | v0.23.0 | `config_vllm_v0.23.0.patch` | +| `v24` | `vllm/vllm-openai-rocm:v0.24.0` | v0.24.0 | `config_vllm_v0.24.0.patch` | ```bash @@ -163,7 +166,7 @@ If you prefer to patch an existing environment instead of building a new image, ###### vLLM -The `config_vllm_v*.patch` patches add two `ProfilerConfig` flags that control graph-capture profiling and trace annotation detail. These patches are available for v0.14–v0.20. Pass the flags as server arguments: +The `config_vllm_v*.patch` patches add two `ProfilerConfig` flags that control graph-capture profiling and trace annotation detail. These patches are available for v0.14–v0.24. Pass the flags as server arguments: | Flag | Type | Default | Description | @@ -196,7 +199,7 @@ The `config_vllm_v*.patch` patches add two `ProfilerConfig` flags that control g This optional step reads the collected trace and splits it into smaller trace files or execution‑phase‑specific trace files. -Option 1: Find steady-state region of execution (highest concurrency) and separate prefill-decode and decode-only execution steps (supports vLLM v0.14–v0.20 and SGLang v0.5.9; using the patchfile is recommended). This is recommended if the tracefile is large and the user wants to extract a few representative steps automatically. +Option 1: Find steady-state region of execution (highest concurrency) and separate prefill-decode and decode-only execution steps (supports vLLM v0.14–v0.24 and SGLang v0.5.9; using the patchfile is recommended). This is recommended if the tracefile is large and the user wants to extract a few representative steps automatically. ```python python -m TraceLens.TraceUtils.split_inference_trace_annotation trace.json.gz -o ./steady_state_analysis \ @@ -708,7 +711,7 @@ delay_iters = ( ((R+1)/2) * 5 * OSL ) - (max_iters/2) # The execution step where #### Trace Splitting -The trace splitting workflow provides three key features. Note that trace splitting assumes vLLM v0.14 or higher (tested through v0.20), or use of our provided patches, to ensure that relevant annotations (batch size, request counts, etc.) are included in execution step metadata. +The trace splitting workflow provides three key features. Note that trace splitting assumes vLLM v0.14 or higher (tested through v0.24), or use of our provided patches, to ensure that relevant annotations (batch size, request counts, etc.) are included in execution step metadata. 1. **Split into individual execution steps:** Decompose the entire trace into per-step files, extracting batch size from annotations or kernels for shape-focused analysis and comparison. 2. **Identify steady-state region:** Detect execution steps with near-maximum concurrency. The algorithm identifies large windows with concurrency close to peak levels and selects a representative steady-state region based on prefill-decode and decode-only step composition. When benchmark parameters are known, pass `--CONC`, `--OSL`, and `--R` to `split_inference_trace_annotation` to override the empirical reference ratio with the analytically derived ideal PD ratio — see [Step 3](#step-3-trace-preparation-optional) for details. diff --git a/docs/NcclAnalyser.md b/docs_original/NcclAnalyser.md similarity index 100% rename from docs/NcclAnalyser.md rename to docs_original/NcclAnalyser.md diff --git a/docs/Trace2Tree.md b/docs_original/Trace2Tree.md similarity index 100% rename from docs/Trace2Tree.md rename to docs_original/Trace2Tree.md diff --git a/docs/TraceDiff.md b/docs_original/TraceDiff.md similarity index 100% rename from docs/TraceDiff.md rename to docs_original/TraceDiff.md diff --git a/docs/TraceFusion.md b/docs_original/TraceFusion.md similarity index 100% rename from docs/TraceFusion.md rename to docs_original/TraceFusion.md diff --git a/docs/TraceLens - Democratizing AI Performance Analysis - Adeem Jassani, AMD.pdf b/docs_original/TraceLens - Democratizing AI Performance Analysis - Adeem Jassani, AMD.pdf similarity index 100% rename from docs/TraceLens - Democratizing AI Performance Analysis - Adeem Jassani, AMD.pdf rename to docs_original/TraceLens - Democratizing AI Performance Analysis - Adeem Jassani, AMD.pdf diff --git a/docs/TreePerf.md b/docs_original/TreePerf.md similarity index 100% rename from docs/TreePerf.md rename to docs_original/TreePerf.md diff --git a/docs/compare_perf_reports_pytorch.md b/docs_original/compare_perf_reports_pytorch.md similarity index 100% rename from docs/compare_perf_reports_pytorch.md rename to docs_original/compare_perf_reports_pytorch.md diff --git a/docs/conceptual/aimodels_gemms.md b/docs_original/conceptual/aimodels_gemms.md similarity index 100% rename from docs/conceptual/aimodels_gemms.md rename to docs_original/conceptual/aimodels_gemms.md diff --git a/docs/conceptual/anomaly_detection_guide.ipynb b/docs_original/conceptual/anomaly_detection_guide.ipynb similarity index 100% rename from docs/conceptual/anomaly_detection_guide.ipynb rename to docs_original/conceptual/anomaly_detection_guide.ipynb diff --git a/docs/conceptual/distributed_profiling_guide.ipynb b/docs_original/conceptual/distributed_profiling_guide.ipynb similarity index 100% rename from docs/conceptual/distributed_profiling_guide.ipynb rename to docs_original/conceptual/distributed_profiling_guide.ipynb diff --git a/docs/conceptual/imgs/profiling_analysis_fig1.png b/docs_original/conceptual/imgs/profiling_analysis_fig1.png similarity index 100% rename from docs/conceptual/imgs/profiling_analysis_fig1.png rename to docs_original/conceptual/imgs/profiling_analysis_fig1.png diff --git a/docs/conceptual/imgs/profiling_analysis_fig2.png b/docs_original/conceptual/imgs/profiling_analysis_fig2.png similarity index 100% rename from docs/conceptual/imgs/profiling_analysis_fig2.png rename to docs_original/conceptual/imgs/profiling_analysis_fig2.png diff --git a/docs/conceptual/imgs/profiling_analysis_fig3.png b/docs_original/conceptual/imgs/profiling_analysis_fig3.png similarity index 100% rename from docs/conceptual/imgs/profiling_analysis_fig3.png rename to docs_original/conceptual/imgs/profiling_analysis_fig3.png diff --git a/docs/conceptual/imgs/profiling_analysis_fig4.png b/docs_original/conceptual/imgs/profiling_analysis_fig4.png similarity index 100% rename from docs/conceptual/imgs/profiling_analysis_fig4.png rename to docs_original/conceptual/imgs/profiling_analysis_fig4.png diff --git a/docs/conceptual/imgs/profiling_analysis_fig5.png b/docs_original/conceptual/imgs/profiling_analysis_fig5.png similarity index 100% rename from docs/conceptual/imgs/profiling_analysis_fig5.png rename to docs_original/conceptual/imgs/profiling_analysis_fig5.png diff --git a/docs/conceptual/imgs/profiling_analysis_fig6.png b/docs_original/conceptual/imgs/profiling_analysis_fig6.png similarity index 100% rename from docs/conceptual/imgs/profiling_analysis_fig6.png rename to docs_original/conceptual/imgs/profiling_analysis_fig6.png diff --git a/docs/conceptual/shape_metadata_guide.md b/docs_original/conceptual/shape_metadata_guide.md similarity index 100% rename from docs/conceptual/shape_metadata_guide.md rename to docs_original/conceptual/shape_metadata_guide.md diff --git a/docs/conceptual/torch_profiling_analysis.md b/docs_original/conceptual/torch_profiling_analysis.md similarity index 100% rename from docs/conceptual/torch_profiling_analysis.md rename to docs_original/conceptual/torch_profiling_analysis.md diff --git a/docs/conceptual/torch_profiling_guide.ipynb b/docs_original/conceptual/torch_profiling_guide.ipynb similarity index 100% rename from docs/conceptual/torch_profiling_guide.ipynb rename to docs_original/conceptual/torch_profiling_guide.ipynb diff --git a/docs/conceptual/trace2tree_motivation.md b/docs_original/conceptual/trace2tree_motivation.md similarity index 100% rename from docs/conceptual/trace2tree_motivation.md rename to docs_original/conceptual/trace2tree_motivation.md diff --git a/docs/gemm_dim_eff.md b/docs_original/gemm_dim_eff.md similarity index 100% rename from docs/gemm_dim_eff.md rename to docs_original/gemm_dim_eff.md diff --git a/docs/generate_multi_rank_collective_report_pytorch.md b/docs_original/generate_multi_rank_collective_report_pytorch.md similarity index 100% rename from docs/generate_multi_rank_collective_report_pytorch.md rename to docs_original/generate_multi_rank_collective_report_pytorch.md diff --git a/docs/generate_perf_report.md b/docs_original/generate_perf_report.md similarity index 100% rename from docs/generate_perf_report.md rename to docs_original/generate_perf_report.md diff --git a/docs/generate_perf_report_rocprof.md b/docs_original/generate_perf_report_rocprof.md similarity index 100% rename from docs/generate_perf_report_rocprof.md rename to docs_original/generate_perf_report_rocprof.md diff --git a/docs/generate_perf_report_rocprof_pftrace.md b/docs_original/generate_perf_report_rocprof_pftrace.md similarity index 100% rename from docs/generate_perf_report_rocprof_pftrace.md rename to docs_original/generate_perf_report_rocprof_pftrace.md diff --git a/docs/gpu_event_analyser.md b/docs_original/gpu_event_analyser.md similarity index 100% rename from docs/gpu_event_analyser.md rename to docs_original/gpu_event_analyser.md diff --git a/docs/jax_analyses.md b/docs_original/jax_analyses.md similarity index 100% rename from docs/jax_analyses.md rename to docs_original/jax_analyses.md diff --git a/docs/locate_node.PNG b/docs_original/locate_node.PNG similarity index 100% rename from docs/locate_node.PNG rename to docs_original/locate_node.PNG diff --git a/docs/origami_with_tracelens.md b/docs_original/origami_with_tracelens.md similarity index 100% rename from docs/origami_with_tracelens.md rename to docs_original/origami_with_tracelens.md diff --git a/docs/perf_report_columns.md b/docs_original/perf_report_columns.md similarity index 100% rename from docs/perf_report_columns.md rename to docs_original/perf_report_columns.md diff --git a/docs/triton_perf_model_walkthrough.md b/docs_original/triton_perf_model_walkthrough.md similarity index 100% rename from docs/triton_perf_model_walkthrough.md rename to docs_original/triton_perf_model_walkthrough.md diff --git a/examples/custom_workflows/inference_analysis/build_docker_vllm.sh b/examples/custom_workflows/inference_analysis/build_docker_vllm.sh index 6bd5d64b0..9f137c67e 100644 --- a/examples/custom_workflows/inference_analysis/build_docker_vllm.sh +++ b/examples/custom_workflows/inference_analysis/build_docker_vllm.sh @@ -10,7 +10,7 @@ set -e usage() { echo "Usage: $0 [--base-image ] [docker build args...]" echo "" - echo " vllm-version One of: v14, v15, v16, v17, v18, v19, v20, v21 (shorthand for v0.14.0, v0.15.0, v0.16.0, v0.17.0, v0.18.0, v0.19.0, v0.20.0, v0.21.0)" + echo " vllm-version One of: v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24 (shorthand for v0.14.0, v0.15.0, v0.16.0, v0.17.0, v0.18.0, v0.19.0, v0.20.0, v0.21.0, v0.22.0, v0.23.0, v0.24.0)" echo " --base-image Override the default base Docker image for the selected vllm version" echo "" echo "Examples:" @@ -60,9 +60,21 @@ case "${VLLM_VERSION}" in BASE_IMAGE="vllm/vllm-openai-rocm:v0.21.0" PATCH_FILE="config_vllm_v0.21.0.patch" ;; + v22) + BASE_IMAGE="vllm/vllm-openai-rocm:v0.22.0" + PATCH_FILE="config_vllm_v0.22.0.patch" + ;; + v23) + BASE_IMAGE="vllm/vllm-openai-rocm:v0.23.0" + PATCH_FILE="config_vllm_v0.23.0.patch" + ;; + v24) + BASE_IMAGE="vllm/vllm-openai-rocm:v0.24.0" + PATCH_FILE="config_vllm_v0.24.0.patch" + ;; *) echo "Error: unsupported vllm version '${VLLM_VERSION}'" - echo "Supported versions: v14, v15, v16, v17, v18, v19, v20, v21" + echo "Supported versions: v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24" exit 1 ;; esac diff --git a/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/eagle_draft_cuda_graph_runner.patch b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/eagle_draft_cuda_graph_runner.patch new file mode 100644 index 000000000..812251681 --- /dev/null +++ b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/eagle_draft_cuda_graph_runner.patch @@ -0,0 +1,61 @@ +diff --git a/python/sglang/srt/speculative/eagle_draft_cuda_graph_runner.py b/python/sglang/srt/speculative/eagle_draft_cuda_graph_runner.py +index a5fc8523b..106cbd3e7 100644 +--- a/python/sglang/srt/speculative/eagle_draft_cuda_graph_runner.py ++++ b/python/sglang/srt/speculative/eagle_draft_cuda_graph_runner.py +@@ -27,6 +27,7 @@ from sglang.srt.model_executor.forward_batch_info import ( + from sglang.srt.model_executor.input_buffers import ForwardInputBuffers + from sglang.srt.speculative.eagle_info import EagleDraftInput + from sglang.srt.speculative.spec_utils import maybe_detect_nan, maybe_detect_oob ++from sglang.srt.utils.kernel_shape_profiler import enable, is_enabled + from sglang.srt.utils import ( + require_attn_tp_gather, + require_gathered_buffer, +@@ -90,6 +91,9 @@ class EAGLEDraftCudaGraphRunner: + self.enable_profile_cuda_graph = ( + model_runner.server_args.enable_profile_cuda_graph + ) ++ self.enable_shape_discovery_for_cuda_graph_profile = ( ++ model_runner.server_args.enable_shape_discovery_for_cuda_graph_profile ++ ) + self.enable_pdmux = False + self.deepep_adapter = DeepEPCudaGraphRunnerAdapter() + +@@ -211,6 +215,16 @@ class EAGLEDraftCudaGraphRunner: + torch.cuda.synchronize() + self.model_runner.tp_group.barrier() + run_once_fn() ++ if self.enable_profile_cuda_graph: ++ # Activate kernel shape profiler AFTER warmup runs so that all ++ # lazily-imported modules (e.g. tilelang_kernel) are in sys.modules ++ # and auto-discovery can find them. ++ if ( ++ self.enable_shape_discovery_for_cuda_graph_profile ++ and not is_enabled() ++ ): ++ enable() ++ self._profiler.step() + + def _capture_graph(self, graph, pool, stream, run_once_fn): + with torch.cuda.graph(graph, pool=pool, stream=stream): +@@ -229,6 +243,11 @@ class EAGLEDraftCudaGraphRunner: + def capture(self): + CudaGraphRunner.capture(self) + ++ _init_profile_context_and_memory_record = ( ++ CudaGraphRunner._init_profile_context_and_memory_record ++ ) ++ _post_process_after_profile = CudaGraphRunner._post_process_after_profile ++ + def capture_one_batch_size( + self, num_seqs: int, forward: Callable, stream_idx: int = 0 + ): +@@ -358,6 +377,9 @@ class EAGLEDraftCudaGraphRunner: + graph, get_global_graph_memory_pool(), stream, run_once + ) + ++ if self.enable_profile_cuda_graph: ++ self._profiler.step() ++ + set_global_graph_memory_pool(graph.pool()) + return graph, out + diff --git a/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/eagle_draft_extend_cuda_graph_runner.patch b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/eagle_draft_extend_cuda_graph_runner.patch new file mode 100644 index 000000000..70b9a3a2a --- /dev/null +++ b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/eagle_draft_extend_cuda_graph_runner.patch @@ -0,0 +1,61 @@ +diff --git a/python/sglang/srt/speculative/eagle_draft_extend_cuda_graph_runner.py b/python/sglang/srt/speculative/eagle_draft_extend_cuda_graph_runner.py +index a5ae5b5b3..add252bba 100644 +--- a/python/sglang/srt/speculative/eagle_draft_extend_cuda_graph_runner.py ++++ b/python/sglang/srt/speculative/eagle_draft_extend_cuda_graph_runner.py +@@ -28,6 +28,7 @@ from sglang.srt.model_executor.forward_batch_info import ( + from sglang.srt.model_executor.input_buffers import ForwardInputBuffers + from sglang.srt.speculative.eagle_info import EagleDraftInput + from sglang.srt.speculative.spec_utils import fast_topk ++from sglang.srt.utils.kernel_shape_profiler import enable, is_enabled + from sglang.srt.utils import ( + require_attn_tp_gather, + require_gathered_buffer, +@@ -97,6 +98,9 @@ class EAGLEDraftExtendCudaGraphRunner: + self.enable_profile_cuda_graph = ( + model_runner.server_args.enable_profile_cuda_graph + ) ++ self.enable_shape_discovery_for_cuda_graph_profile = ( ++ model_runner.server_args.enable_shape_discovery_for_cuda_graph_profile ++ ) + self.enable_pdmux = False + self.deepep_adapter = DeepEPCudaGraphRunnerAdapter() + +@@ -276,6 +280,16 @@ class EAGLEDraftExtendCudaGraphRunner: + torch.cuda.synchronize() + self.model_runner.tp_group.barrier() + run_once_fn() ++ if self.enable_profile_cuda_graph: ++ # Activate kernel shape profiler AFTER warmup runs so that all ++ # lazily-imported modules (e.g. tilelang_kernel) are in sys.modules ++ # and auto-discovery can find them. ++ if ( ++ self.enable_shape_discovery_for_cuda_graph_profile ++ and not is_enabled() ++ ): ++ enable() ++ self._profiler.step() + + def _capture_graph(self, graph, pool, stream, run_once_fn): + with torch.cuda.graph(graph, pool=pool, stream=stream): +@@ -296,6 +310,11 @@ class EAGLEDraftExtendCudaGraphRunner: + def capture(self): + CudaGraphRunner.capture(self) + ++ _init_profile_context_and_memory_record = ( ++ CudaGraphRunner._init_profile_context_and_memory_record ++ ) ++ _post_process_after_profile = CudaGraphRunner._post_process_after_profile ++ + def capture_one_batch_size(self, bs: int, forward: Callable, stream_idx: int = 0): + buffers = self.buffers + graph = self._create_graph() +@@ -441,6 +460,9 @@ class EAGLEDraftExtendCudaGraphRunner: + graph, get_global_graph_memory_pool(), stream, run_once + ) + ++ if self.enable_profile_cuda_graph: ++ self._profiler.step() ++ + set_global_graph_memory_pool(graph.pool()) + return graph, out + diff --git a/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/kernel_shape_profiler.patch b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/kernel_shape_profiler.patch index 0e85b92b5..0bf9a8593 100644 --- a/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/kernel_shape_profiler.patch +++ b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/kernel_shape_profiler.patch @@ -1,9 +1,9 @@ diff --git a/python/sglang/srt/utils/kernel_shape_profiler.py b/python/sglang/srt/utils/kernel_shape_profiler.py new file mode 100644 -index 000000000..6d8563b29 +index 000000000..468dfd101 --- /dev/null +++ b/python/sglang/srt/utils/kernel_shape_profiler.py -@@ -0,0 +1,746 @@ +@@ -0,0 +1,871 @@ +""" +Automatic tensor shape metadata for Triton / FlashInfer / aiter kernels +in PyTorch profiler traces. @@ -33,6 +33,7 @@ index 000000000..6d8563b29 + ``aiter_w8a8_block_fp8_linear``). +""" + ++import contextlib +import functools +import importlib +import inspect @@ -47,15 +48,77 @@ index 000000000..6d8563b29 + +logger = logging.getLogger(__name__) + ++ ++@contextlib.contextmanager ++def _preserve_global_torch_state(): ++ """Snapshot and restore process-global torch defaults. ++ ++ ``enable()`` imports a large number of modules (both the explicit ++ registry via ``_resolve_target`` and the auto-discovery ++ ``_force_import_submodules``). Some of those modules mutate ++ process-global torch state at import time — most notably ++ ``torch.set_default_device("cuda")`` — and that mutation is NOT undone ++ by ``disable()`` (which only restores patched *function references*). ++ ++ A leaked default device corrupts downstream CPU tensor creation: e.g. ++ a buffer such as ``seq_lens_cpu`` is suddenly allocated on cuda, which ++ surfaces as ``Buffer seq_lens_cpu has different device than before`` in ++ the input-buffer pool and, later, as out-of-bounds GPU memory access ++ faults in index kernels (e.g. ``write_req_to_token_pool_triton``). ++ ++ Restoring the default device and dtype around the import-heavy regions ++ keeps these side effects from escaping into the serving path. In the ++ healthy case (nothing mutates the defaults) this is a no-op. ++ """ ++ get_default_device = getattr(torch, "get_default_device", None) ++ saved_device = get_default_device() if get_default_device is not None else None ++ saved_dtype = torch.get_default_dtype() ++ try: ++ yield ++ finally: ++ if saved_device is not None: ++ try: ++ torch.set_default_device(saved_device) ++ except Exception: ++ pass ++ try: ++ torch.set_default_dtype(saved_dtype) ++ except Exception: ++ pass ++ +# --------------------------------------------------------------------------- +# State +# --------------------------------------------------------------------------- +_lock = threading.Lock() +_enabled = False ++# The torch.library.Library is created once and kept alive for the whole ++# process lifetime. It is intentionally NEVER torn down: dropping it destroys ++# the registered custom ops (freeing their OperatorName / schema). A wrapper ++# reference can outlive a disable() — e.g. a module imported lazily *during* a ++# profiling window captured the wrapper via ``from X import Y`` and is not in ++# ``_patches`` to be restored. If the backing op were freed, that leaked ++# wrapper would later dispatch into freed memory and segfault. Keeping the ++# Library (and the monotonic op counter) alive makes such a stale dispatch ++# safe; the ``if not _enabled`` guard in each wrapper then routes it straight ++# to the original function. +_lib: Optional[Library] = None ++# Monotonic — NEVER reset, so op names from earlier enable() cycles stay valid. +_op_counter = 0 +# Each entry: (module_obj, attr_name, original_fn) +_patches: List[Tuple[Any, str, Callable]] = [] ++# Persistent cache of built wrappers keyed by qualified function name. ++# Value: (wrapper_fn, original_fn). Reused across enable()/disable() cycles so ++# each op is defined exactly once and a given function maps to a stable wrapper ++# object (so references that leaked across cycles still point at a live op). ++_built_wrappers: dict = {} ++ ++ ++def _get_or_create_lib() -> Library: ++ """Return the process-wide custom-op Library, creating it on first use.""" ++ global _lib ++ if _lib is None: ++ _lib = Library("sglang_profiler", "FRAGMENT") ++ return _lib + +# --------------------------------------------------------------------------- +# Registry of kernel entry points to wrap. @@ -303,7 +366,8 @@ index 000000000..6d8563b29 + Returns None if registration fails. + """ + try: -+ _lib.define(op_name + schema_str) ++ lib = _get_or_create_lib() ++ lib.define(op_name + schema_str) + + def impl(*tensor_args): + nt_args = _pop_non_tensor_args(op_name) @@ -325,12 +389,19 @@ index 000000000..6d8563b29 + # through the dispatcher. Stash it for the caller. + _stash_return_value(op_name, result) + -+ _lib.impl(op_name, impl, dispatch_key="CompositeExplicitAutograd") ++ lib.impl(op_name, impl, dispatch_key="CompositeExplicitAutograd") + + torch_op = getattr(torch.ops.sglang_profiler, op_name) + + @functools.wraps(original_fn) + def dispatch_wrapper(*args, **kwargs): ++ # When profiling is not active, never route through the custom op. ++ # A wrapper reference may outlive disable() (captured by a module ++ # imported lazily while profiling was on, so _patch_all_references ++ # could not restore it). Falling back to the original keeps such ++ # leaked bindings correct and crash-free. ++ if not _enabled: ++ return original_fn(*args, **kwargs) + try: + bound = sig.bind(*args, **kwargs) + bound.apply_defaults() @@ -453,6 +524,10 @@ index 000000000..6d8563b29 + + @functools.wraps(original_fn) + def wrapper(*args, **kwargs): ++ # See dispatch_wrapper: a leaked reference must be a no-op when ++ # profiling is inactive. ++ if not _enabled: ++ return original_fn(*args, **kwargs) + shape_parts: List[str] = [] + for i, arg in enumerate(args): + if isinstance(arg, torch.Tensor): @@ -530,6 +605,27 @@ index 000000000..6d8563b29 + if pkg_path is None: + return + ++ # Snapshot the global defaults once; restore them after *every* import so ++ # a module that calls torch.set_default_device("cuda") at import time ++ # cannot taint subsequently imported modules during discovery (nor leak ++ # into the serving path). The leaf-name skip list below catches the known ++ # offenders, but this restore makes the discovery robust to any other ++ # module with the same import-time side effect. ++ get_default_device = getattr(torch, "get_default_device", None) ++ saved_device = get_default_device() if get_default_device is not None else None ++ saved_dtype = torch.get_default_dtype() ++ ++ def _restore_defaults(): ++ if saved_device is not None: ++ try: ++ torch.set_default_device(saved_device) ++ except Exception: ++ pass ++ try: ++ torch.set_default_dtype(saved_dtype) ++ except Exception: ++ pass ++ + for _importer, mod_name, _is_pkg in pkgutil.walk_packages( + pkg_path, prefix=prefix + "." + ): @@ -554,6 +650,8 @@ index 000000000..6d8563b29 + except Exception: + # Optional modules may fail to import depending on environment. + pass ++ finally: ++ _restore_defaults() + + +def _discover_kernel_entry_points() -> List[Tuple[str, str]]: @@ -638,94 +736,116 @@ index 000000000..6d8563b29 + +def enable(): + """Patch registered kernel entry points to appear as cpu_op.""" -+ global _enabled, _lib, _op_counter ++ global _enabled + with _lock: + if _enabled: + return + -+ _lib = Library("sglang_profiler", "FRAGMENT") -+ _op_counter = 0 ++ # NOTE: the Library and op counter are process-persistent (see the ++ # _lib / _op_counter docs). We do NOT recreate or reset them here so ++ # ops registered in earlier cycles stay valid. Only the per-cycle ++ # reference patches are rebuilt. + _patches.clear() + _wrapped_ids: set = set() # track function ids to avoid double-wrapping + -+ # Merge explicit registry with filtered auto-discovered functions. -+ # Duplicates are harmless — _wrapped_ids prevents double-wrapping. -+ all_entry_points = ( -+ list(_KERNEL_ENTRY_POINTS) -+ + -+ _discover_kernel_entry_points() -+ ) -+ -+ for module_path, attr_name in all_entry_points: -+ resolved = _resolve_target(module_path, attr_name) -+ if resolved is None: -+ continue -+ -+ container, name, original_fn, is_method = resolved -+ is_plain_function = not is_method -+ -+ # Skip if this exact function object was already wrapped -+ fn_id = id(original_fn) -+ if fn_id in _wrapped_ids: -+ logger.debug("Skipping duplicate %s.%s", module_path, attr_name) -+ continue -+ _wrapped_ids.add(fn_id) -+ -+ qualified_name = f"{module_path}.{name}" ++ # Backstop guard around the import-heavy region. Both the explicit ++ # registry (_resolve_target -> importlib.import_module) and the ++ # auto-discovery (_discover_kernel_entry_points -> _force_import_*) ++ # import modules that may mutate process-global torch defaults at ++ # import time; restore them on exit so the leak cannot escape into ++ # the serving path. (No-op when nothing mutates the defaults.) ++ with _preserve_global_torch_state(): ++ # Merge explicit registry with filtered auto-discovered functions. ++ # Duplicates are harmless — _wrapped_ids prevents double-wrapping. ++ all_entry_points = ( ++ list(_KERNEL_ENTRY_POINTS) ++ + ++ _discover_kernel_entry_points() ++ ) ++ ++ for module_path, attr_name in all_entry_points: ++ resolved = _resolve_target(module_path, attr_name) ++ if resolved is None: ++ continue + -+ # ── Regular functions ── -+ try: -+ sig = inspect.signature(original_fn) -+ except (ValueError, TypeError): -+ logger.debug( -+ "Cannot inspect signature of %s — skipping", -+ qualified_name, -+ ) -+ continue ++ container, name, original_fn, is_method = resolved ++ is_plain_function = not is_method + -+ base = f"{module_path.split('.')[-1]}_{name}" -+ schema_info = _build_schema_from_sig(sig, skip_self=is_method) -+ -+ wrapper = None -+ if schema_info is not None: -+ # Full tensor annotations → use torch.library custom op -+ schema_str, t_names, nt_names = schema_info -+ op_name = _next_op_name(base) -+ wrapper = _register_op( -+ op_name, schema_str, original_fn, -+ t_names, nt_names, sig, skip_self=is_method, -+ ) -+ if wrapper is not None: -+ logger.debug("Registered %s as custom op %s", -+ qualified_name, op_name) -+ -+ if wrapper is None: -+ # Fallback: no annotations or schema registration failed -+ # → use record_function wrapper (shapes in event name) -+ wrapper = _make_record_function_wrapper( -+ qualified_name, original_fn, -+ ) -+ logger.debug("Registered %s via record_function", -+ qualified_name) -+ -+ # --- Apply patches --- -+ if is_plain_function: -+ ref_patches = _patch_all_references(original_fn, wrapper) -+ _patches.extend(ref_patches) -+ if not ref_patches: ++ # Skip if this exact function object was already wrapped ++ fn_id = id(original_fn) ++ if fn_id in _wrapped_ids: ++ logger.debug("Skipping duplicate %s.%s", module_path, attr_name) ++ continue ++ _wrapped_ids.add(fn_id) ++ ++ qualified_name = f"{module_path}.{name}" ++ ++ # Reuse a wrapper built in a previous cycle if the underlying ++ # function object is unchanged. This keeps each op defined ++ # exactly once and ensures a given function maps to a stable ++ # wrapper, so a reference that leaked across cycles still ++ # targets a live op. ++ wrapper = None ++ cached = _built_wrappers.get(qualified_name) ++ if cached is not None and cached[1] is original_fn: ++ wrapper = cached[0] ++ ++ if wrapper is None: ++ # ── Regular functions ── ++ try: ++ sig = inspect.signature(original_fn) ++ except (ValueError, TypeError): ++ logger.debug( ++ "Cannot inspect signature of %s — skipping", ++ qualified_name, ++ ) ++ continue ++ ++ base = f"{module_path.split('.')[-1]}_{name}" ++ schema_info = _build_schema_from_sig(sig, skip_self=is_method) ++ ++ if schema_info is not None: ++ # Full tensor annotations → use torch.library custom op ++ schema_str, t_names, nt_names = schema_info ++ op_name = _next_op_name(base) ++ wrapper = _register_op( ++ op_name, schema_str, original_fn, ++ t_names, nt_names, sig, skip_self=is_method, ++ ) ++ if wrapper is not None: ++ logger.debug("Registered %s as custom op %s", ++ qualified_name, op_name) ++ ++ if wrapper is None: ++ # Fallback: no annotations or schema registration failed ++ # → use record_function wrapper (shapes in event name) ++ wrapper = _make_record_function_wrapper( ++ qualified_name, original_fn, ++ ) ++ logger.debug("Registered %s via record_function", ++ qualified_name) ++ ++ _built_wrappers[qualified_name] = (wrapper, original_fn) ++ ++ # --- Apply patches --- ++ if is_plain_function: ++ ref_patches = _patch_all_references(original_fn, wrapper) ++ _patches.extend(ref_patches) ++ if not ref_patches: ++ setattr(container, name, wrapper) ++ _patches.append((container, name, original_fn)) ++ else: + setattr(container, name, wrapper) + _patches.append((container, name, original_fn)) -+ else: -+ setattr(container, name, wrapper) -+ _patches.append((container, name, original_fn)) + -+ n_discovered = len(all_entry_points) - len(_KERNEL_ENTRY_POINTS) ++ n_discovered = len(all_entry_points) - len(_KERNEL_ENTRY_POINTS) ++ + _enabled = True + logger.info( + "kernel_shape_profiler enabled: %d references patched across " + "%d entry points (%d explicit + %d auto-discovered)", + len(_patches), -+ len(all_entry_points), ++ len(_KERNEL_ENTRY_POINTS) + n_discovered, + len(_KERNEL_ENTRY_POINTS), + n_discovered, + ) @@ -733,18 +853,23 @@ index 000000000..6d8563b29 + +def disable(): + """Restore all patched functions to originals.""" -+ global _enabled, _lib ++ global _enabled + with _lock: + if not _enabled: + return ++ # Flip the flag first so any wrapper invoked concurrently — or one that ++ # leaked past restoration — short-circuits to the original instead of ++ # dispatching into a custom op. ++ _enabled = False + for container, name, original_fn in reversed(_patches): + try: + setattr(container, name, original_fn) + except Exception: + pass + _patches.clear() -+ _lib = None -+ _enabled = False ++ # Intentionally keep _lib, _op_counter and _built_wrappers alive: the ++ # registered ops must outlive any wrapper reference that may have ++ # leaked (see module-level _lib docs). + logger.info("kernel_shape_profiler disabled: all patches restored") + + diff --git a/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/multi_layer_eagle_draft_extend_cuda_graph_runner.patch b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/multi_layer_eagle_draft_extend_cuda_graph_runner.patch new file mode 100644 index 000000000..1e4625f08 --- /dev/null +++ b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_11/multi_layer_eagle_draft_extend_cuda_graph_runner.patch @@ -0,0 +1,61 @@ +diff --git a/python/sglang/srt/speculative/multi_layer_eagle_draft_extend_cuda_graph_runner.py b/python/sglang/srt/speculative/multi_layer_eagle_draft_extend_cuda_graph_runner.py +index 295c1009b..3460bce13 100644 +--- a/python/sglang/srt/speculative/multi_layer_eagle_draft_extend_cuda_graph_runner.py ++++ b/python/sglang/srt/speculative/multi_layer_eagle_draft_extend_cuda_graph_runner.py +@@ -44,6 +44,7 @@ from sglang.srt.model_executor.input_buffers import ForwardInputBuffers + from sglang.srt.speculative.eagle_info import EagleDraftInput + from sglang.srt.speculative.multi_layer_eagle_utils import assign_new_state_triton + from sglang.srt.speculative.spec_utils import fast_topk ++from sglang.srt.utils.kernel_shape_profiler import enable, is_enabled + from sglang.srt.utils import ( + get_available_gpu_memory, + require_attn_tp_gather, +@@ -111,6 +112,9 @@ class MultiLayerEagleDraftExtendCudaGraphRunner: + self.enable_profile_cuda_graph = ( + model_runner.server_args.enable_profile_cuda_graph + ) ++ self.enable_shape_discovery_for_cuda_graph_profile = ( ++ model_runner.server_args.enable_shape_discovery_for_cuda_graph_profile ++ ) + self.capture_bs, self.compile_bs = get_batch_sizes_to_capture(model_runner) + self.padded_static_len = -1 + self.deepep_adapter = DeepEPCudaGraphRunnerAdapter() +@@ -280,6 +284,16 @@ class MultiLayerEagleDraftExtendCudaGraphRunner: + torch.cuda.synchronize() + self.model_runner.tp_group.barrier() + run_once_fn() ++ if self.enable_profile_cuda_graph: ++ # Activate kernel shape profiler AFTER warmup runs so that all ++ # lazily-imported modules (e.g. tilelang_kernel) are in sys.modules ++ # and auto-discovery can find them. ++ if ( ++ self.enable_shape_discovery_for_cuda_graph_profile ++ and not is_enabled() ++ ): ++ enable() ++ self._profiler.step() + + def _capture_graph(self, graph, pool, stream, run_once_fn): + with torch.cuda.graph(graph, pool=pool, stream=stream): +@@ -292,6 +306,11 @@ class MultiLayerEagleDraftExtendCudaGraphRunner: + def capture(self): + CudaGraphRunner.capture(self) + ++ _init_profile_context_and_memory_record = ( ++ CudaGraphRunner._init_profile_context_and_memory_record ++ ) ++ _post_process_after_profile = CudaGraphRunner._post_process_after_profile ++ + def get_forward_batch(self, bs: int) -> ForwardBatch: + buffers = self.buffers + num_tokens = bs * self.num_tokens_per_bs +@@ -501,6 +520,9 @@ class MultiLayerEagleDraftExtendCudaGraphRunner: + graph, get_global_graph_memory_pool(), stream, run_once + ) + ++ if self.enable_profile_cuda_graph: ++ self._profiler.step() ++ + set_global_graph_memory_pool(graph.pool()) + return graph, out + diff --git a/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/eagle_draft_cuda_graph_runner.patch b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/eagle_draft_cuda_graph_runner.patch new file mode 100644 index 000000000..812251681 --- /dev/null +++ b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/eagle_draft_cuda_graph_runner.patch @@ -0,0 +1,61 @@ +diff --git a/python/sglang/srt/speculative/eagle_draft_cuda_graph_runner.py b/python/sglang/srt/speculative/eagle_draft_cuda_graph_runner.py +index a5fc8523b..106cbd3e7 100644 +--- a/python/sglang/srt/speculative/eagle_draft_cuda_graph_runner.py ++++ b/python/sglang/srt/speculative/eagle_draft_cuda_graph_runner.py +@@ -27,6 +27,7 @@ from sglang.srt.model_executor.forward_batch_info import ( + from sglang.srt.model_executor.input_buffers import ForwardInputBuffers + from sglang.srt.speculative.eagle_info import EagleDraftInput + from sglang.srt.speculative.spec_utils import maybe_detect_nan, maybe_detect_oob ++from sglang.srt.utils.kernel_shape_profiler import enable, is_enabled + from sglang.srt.utils import ( + require_attn_tp_gather, + require_gathered_buffer, +@@ -90,6 +91,9 @@ class EAGLEDraftCudaGraphRunner: + self.enable_profile_cuda_graph = ( + model_runner.server_args.enable_profile_cuda_graph + ) ++ self.enable_shape_discovery_for_cuda_graph_profile = ( ++ model_runner.server_args.enable_shape_discovery_for_cuda_graph_profile ++ ) + self.enable_pdmux = False + self.deepep_adapter = DeepEPCudaGraphRunnerAdapter() + +@@ -211,6 +215,16 @@ class EAGLEDraftCudaGraphRunner: + torch.cuda.synchronize() + self.model_runner.tp_group.barrier() + run_once_fn() ++ if self.enable_profile_cuda_graph: ++ # Activate kernel shape profiler AFTER warmup runs so that all ++ # lazily-imported modules (e.g. tilelang_kernel) are in sys.modules ++ # and auto-discovery can find them. ++ if ( ++ self.enable_shape_discovery_for_cuda_graph_profile ++ and not is_enabled() ++ ): ++ enable() ++ self._profiler.step() + + def _capture_graph(self, graph, pool, stream, run_once_fn): + with torch.cuda.graph(graph, pool=pool, stream=stream): +@@ -229,6 +243,11 @@ class EAGLEDraftCudaGraphRunner: + def capture(self): + CudaGraphRunner.capture(self) + ++ _init_profile_context_and_memory_record = ( ++ CudaGraphRunner._init_profile_context_and_memory_record ++ ) ++ _post_process_after_profile = CudaGraphRunner._post_process_after_profile ++ + def capture_one_batch_size( + self, num_seqs: int, forward: Callable, stream_idx: int = 0 + ): +@@ -358,6 +377,9 @@ class EAGLEDraftCudaGraphRunner: + graph, get_global_graph_memory_pool(), stream, run_once + ) + ++ if self.enable_profile_cuda_graph: ++ self._profiler.step() ++ + set_global_graph_memory_pool(graph.pool()) + return graph, out + diff --git a/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/eagle_draft_extend_cuda_graph_runner.patch b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/eagle_draft_extend_cuda_graph_runner.patch new file mode 100644 index 000000000..70b9a3a2a --- /dev/null +++ b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/eagle_draft_extend_cuda_graph_runner.patch @@ -0,0 +1,61 @@ +diff --git a/python/sglang/srt/speculative/eagle_draft_extend_cuda_graph_runner.py b/python/sglang/srt/speculative/eagle_draft_extend_cuda_graph_runner.py +index a5ae5b5b3..add252bba 100644 +--- a/python/sglang/srt/speculative/eagle_draft_extend_cuda_graph_runner.py ++++ b/python/sglang/srt/speculative/eagle_draft_extend_cuda_graph_runner.py +@@ -28,6 +28,7 @@ from sglang.srt.model_executor.forward_batch_info import ( + from sglang.srt.model_executor.input_buffers import ForwardInputBuffers + from sglang.srt.speculative.eagle_info import EagleDraftInput + from sglang.srt.speculative.spec_utils import fast_topk ++from sglang.srt.utils.kernel_shape_profiler import enable, is_enabled + from sglang.srt.utils import ( + require_attn_tp_gather, + require_gathered_buffer, +@@ -97,6 +98,9 @@ class EAGLEDraftExtendCudaGraphRunner: + self.enable_profile_cuda_graph = ( + model_runner.server_args.enable_profile_cuda_graph + ) ++ self.enable_shape_discovery_for_cuda_graph_profile = ( ++ model_runner.server_args.enable_shape_discovery_for_cuda_graph_profile ++ ) + self.enable_pdmux = False + self.deepep_adapter = DeepEPCudaGraphRunnerAdapter() + +@@ -276,6 +280,16 @@ class EAGLEDraftExtendCudaGraphRunner: + torch.cuda.synchronize() + self.model_runner.tp_group.barrier() + run_once_fn() ++ if self.enable_profile_cuda_graph: ++ # Activate kernel shape profiler AFTER warmup runs so that all ++ # lazily-imported modules (e.g. tilelang_kernel) are in sys.modules ++ # and auto-discovery can find them. ++ if ( ++ self.enable_shape_discovery_for_cuda_graph_profile ++ and not is_enabled() ++ ): ++ enable() ++ self._profiler.step() + + def _capture_graph(self, graph, pool, stream, run_once_fn): + with torch.cuda.graph(graph, pool=pool, stream=stream): +@@ -296,6 +310,11 @@ class EAGLEDraftExtendCudaGraphRunner: + def capture(self): + CudaGraphRunner.capture(self) + ++ _init_profile_context_and_memory_record = ( ++ CudaGraphRunner._init_profile_context_and_memory_record ++ ) ++ _post_process_after_profile = CudaGraphRunner._post_process_after_profile ++ + def capture_one_batch_size(self, bs: int, forward: Callable, stream_idx: int = 0): + buffers = self.buffers + graph = self._create_graph() +@@ -441,6 +460,9 @@ class EAGLEDraftExtendCudaGraphRunner: + graph, get_global_graph_memory_pool(), stream, run_once + ) + ++ if self.enable_profile_cuda_graph: ++ self._profiler.step() ++ + set_global_graph_memory_pool(graph.pool()) + return graph, out + diff --git a/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/kernel_shape_profiler.patch b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/kernel_shape_profiler.patch index 0e85b92b5..0bf9a8593 100644 --- a/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/kernel_shape_profiler.patch +++ b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/kernel_shape_profiler.patch @@ -1,9 +1,9 @@ diff --git a/python/sglang/srt/utils/kernel_shape_profiler.py b/python/sglang/srt/utils/kernel_shape_profiler.py new file mode 100644 -index 000000000..6d8563b29 +index 000000000..468dfd101 --- /dev/null +++ b/python/sglang/srt/utils/kernel_shape_profiler.py -@@ -0,0 +1,746 @@ +@@ -0,0 +1,871 @@ +""" +Automatic tensor shape metadata for Triton / FlashInfer / aiter kernels +in PyTorch profiler traces. @@ -33,6 +33,7 @@ index 000000000..6d8563b29 + ``aiter_w8a8_block_fp8_linear``). +""" + ++import contextlib +import functools +import importlib +import inspect @@ -47,15 +48,77 @@ index 000000000..6d8563b29 + +logger = logging.getLogger(__name__) + ++ ++@contextlib.contextmanager ++def _preserve_global_torch_state(): ++ """Snapshot and restore process-global torch defaults. ++ ++ ``enable()`` imports a large number of modules (both the explicit ++ registry via ``_resolve_target`` and the auto-discovery ++ ``_force_import_submodules``). Some of those modules mutate ++ process-global torch state at import time — most notably ++ ``torch.set_default_device("cuda")`` — and that mutation is NOT undone ++ by ``disable()`` (which only restores patched *function references*). ++ ++ A leaked default device corrupts downstream CPU tensor creation: e.g. ++ a buffer such as ``seq_lens_cpu`` is suddenly allocated on cuda, which ++ surfaces as ``Buffer seq_lens_cpu has different device than before`` in ++ the input-buffer pool and, later, as out-of-bounds GPU memory access ++ faults in index kernels (e.g. ``write_req_to_token_pool_triton``). ++ ++ Restoring the default device and dtype around the import-heavy regions ++ keeps these side effects from escaping into the serving path. In the ++ healthy case (nothing mutates the defaults) this is a no-op. ++ """ ++ get_default_device = getattr(torch, "get_default_device", None) ++ saved_device = get_default_device() if get_default_device is not None else None ++ saved_dtype = torch.get_default_dtype() ++ try: ++ yield ++ finally: ++ if saved_device is not None: ++ try: ++ torch.set_default_device(saved_device) ++ except Exception: ++ pass ++ try: ++ torch.set_default_dtype(saved_dtype) ++ except Exception: ++ pass ++ +# --------------------------------------------------------------------------- +# State +# --------------------------------------------------------------------------- +_lock = threading.Lock() +_enabled = False ++# The torch.library.Library is created once and kept alive for the whole ++# process lifetime. It is intentionally NEVER torn down: dropping it destroys ++# the registered custom ops (freeing their OperatorName / schema). A wrapper ++# reference can outlive a disable() — e.g. a module imported lazily *during* a ++# profiling window captured the wrapper via ``from X import Y`` and is not in ++# ``_patches`` to be restored. If the backing op were freed, that leaked ++# wrapper would later dispatch into freed memory and segfault. Keeping the ++# Library (and the monotonic op counter) alive makes such a stale dispatch ++# safe; the ``if not _enabled`` guard in each wrapper then routes it straight ++# to the original function. +_lib: Optional[Library] = None ++# Monotonic — NEVER reset, so op names from earlier enable() cycles stay valid. +_op_counter = 0 +# Each entry: (module_obj, attr_name, original_fn) +_patches: List[Tuple[Any, str, Callable]] = [] ++# Persistent cache of built wrappers keyed by qualified function name. ++# Value: (wrapper_fn, original_fn). Reused across enable()/disable() cycles so ++# each op is defined exactly once and a given function maps to a stable wrapper ++# object (so references that leaked across cycles still point at a live op). ++_built_wrappers: dict = {} ++ ++ ++def _get_or_create_lib() -> Library: ++ """Return the process-wide custom-op Library, creating it on first use.""" ++ global _lib ++ if _lib is None: ++ _lib = Library("sglang_profiler", "FRAGMENT") ++ return _lib + +# --------------------------------------------------------------------------- +# Registry of kernel entry points to wrap. @@ -303,7 +366,8 @@ index 000000000..6d8563b29 + Returns None if registration fails. + """ + try: -+ _lib.define(op_name + schema_str) ++ lib = _get_or_create_lib() ++ lib.define(op_name + schema_str) + + def impl(*tensor_args): + nt_args = _pop_non_tensor_args(op_name) @@ -325,12 +389,19 @@ index 000000000..6d8563b29 + # through the dispatcher. Stash it for the caller. + _stash_return_value(op_name, result) + -+ _lib.impl(op_name, impl, dispatch_key="CompositeExplicitAutograd") ++ lib.impl(op_name, impl, dispatch_key="CompositeExplicitAutograd") + + torch_op = getattr(torch.ops.sglang_profiler, op_name) + + @functools.wraps(original_fn) + def dispatch_wrapper(*args, **kwargs): ++ # When profiling is not active, never route through the custom op. ++ # A wrapper reference may outlive disable() (captured by a module ++ # imported lazily while profiling was on, so _patch_all_references ++ # could not restore it). Falling back to the original keeps such ++ # leaked bindings correct and crash-free. ++ if not _enabled: ++ return original_fn(*args, **kwargs) + try: + bound = sig.bind(*args, **kwargs) + bound.apply_defaults() @@ -453,6 +524,10 @@ index 000000000..6d8563b29 + + @functools.wraps(original_fn) + def wrapper(*args, **kwargs): ++ # See dispatch_wrapper: a leaked reference must be a no-op when ++ # profiling is inactive. ++ if not _enabled: ++ return original_fn(*args, **kwargs) + shape_parts: List[str] = [] + for i, arg in enumerate(args): + if isinstance(arg, torch.Tensor): @@ -530,6 +605,27 @@ index 000000000..6d8563b29 + if pkg_path is None: + return + ++ # Snapshot the global defaults once; restore them after *every* import so ++ # a module that calls torch.set_default_device("cuda") at import time ++ # cannot taint subsequently imported modules during discovery (nor leak ++ # into the serving path). The leaf-name skip list below catches the known ++ # offenders, but this restore makes the discovery robust to any other ++ # module with the same import-time side effect. ++ get_default_device = getattr(torch, "get_default_device", None) ++ saved_device = get_default_device() if get_default_device is not None else None ++ saved_dtype = torch.get_default_dtype() ++ ++ def _restore_defaults(): ++ if saved_device is not None: ++ try: ++ torch.set_default_device(saved_device) ++ except Exception: ++ pass ++ try: ++ torch.set_default_dtype(saved_dtype) ++ except Exception: ++ pass ++ + for _importer, mod_name, _is_pkg in pkgutil.walk_packages( + pkg_path, prefix=prefix + "." + ): @@ -554,6 +650,8 @@ index 000000000..6d8563b29 + except Exception: + # Optional modules may fail to import depending on environment. + pass ++ finally: ++ _restore_defaults() + + +def _discover_kernel_entry_points() -> List[Tuple[str, str]]: @@ -638,94 +736,116 @@ index 000000000..6d8563b29 + +def enable(): + """Patch registered kernel entry points to appear as cpu_op.""" -+ global _enabled, _lib, _op_counter ++ global _enabled + with _lock: + if _enabled: + return + -+ _lib = Library("sglang_profiler", "FRAGMENT") -+ _op_counter = 0 ++ # NOTE: the Library and op counter are process-persistent (see the ++ # _lib / _op_counter docs). We do NOT recreate or reset them here so ++ # ops registered in earlier cycles stay valid. Only the per-cycle ++ # reference patches are rebuilt. + _patches.clear() + _wrapped_ids: set = set() # track function ids to avoid double-wrapping + -+ # Merge explicit registry with filtered auto-discovered functions. -+ # Duplicates are harmless — _wrapped_ids prevents double-wrapping. -+ all_entry_points = ( -+ list(_KERNEL_ENTRY_POINTS) -+ + -+ _discover_kernel_entry_points() -+ ) -+ -+ for module_path, attr_name in all_entry_points: -+ resolved = _resolve_target(module_path, attr_name) -+ if resolved is None: -+ continue -+ -+ container, name, original_fn, is_method = resolved -+ is_plain_function = not is_method -+ -+ # Skip if this exact function object was already wrapped -+ fn_id = id(original_fn) -+ if fn_id in _wrapped_ids: -+ logger.debug("Skipping duplicate %s.%s", module_path, attr_name) -+ continue -+ _wrapped_ids.add(fn_id) -+ -+ qualified_name = f"{module_path}.{name}" ++ # Backstop guard around the import-heavy region. Both the explicit ++ # registry (_resolve_target -> importlib.import_module) and the ++ # auto-discovery (_discover_kernel_entry_points -> _force_import_*) ++ # import modules that may mutate process-global torch defaults at ++ # import time; restore them on exit so the leak cannot escape into ++ # the serving path. (No-op when nothing mutates the defaults.) ++ with _preserve_global_torch_state(): ++ # Merge explicit registry with filtered auto-discovered functions. ++ # Duplicates are harmless — _wrapped_ids prevents double-wrapping. ++ all_entry_points = ( ++ list(_KERNEL_ENTRY_POINTS) ++ + ++ _discover_kernel_entry_points() ++ ) ++ ++ for module_path, attr_name in all_entry_points: ++ resolved = _resolve_target(module_path, attr_name) ++ if resolved is None: ++ continue + -+ # ── Regular functions ── -+ try: -+ sig = inspect.signature(original_fn) -+ except (ValueError, TypeError): -+ logger.debug( -+ "Cannot inspect signature of %s — skipping", -+ qualified_name, -+ ) -+ continue ++ container, name, original_fn, is_method = resolved ++ is_plain_function = not is_method + -+ base = f"{module_path.split('.')[-1]}_{name}" -+ schema_info = _build_schema_from_sig(sig, skip_self=is_method) -+ -+ wrapper = None -+ if schema_info is not None: -+ # Full tensor annotations → use torch.library custom op -+ schema_str, t_names, nt_names = schema_info -+ op_name = _next_op_name(base) -+ wrapper = _register_op( -+ op_name, schema_str, original_fn, -+ t_names, nt_names, sig, skip_self=is_method, -+ ) -+ if wrapper is not None: -+ logger.debug("Registered %s as custom op %s", -+ qualified_name, op_name) -+ -+ if wrapper is None: -+ # Fallback: no annotations or schema registration failed -+ # → use record_function wrapper (shapes in event name) -+ wrapper = _make_record_function_wrapper( -+ qualified_name, original_fn, -+ ) -+ logger.debug("Registered %s via record_function", -+ qualified_name) -+ -+ # --- Apply patches --- -+ if is_plain_function: -+ ref_patches = _patch_all_references(original_fn, wrapper) -+ _patches.extend(ref_patches) -+ if not ref_patches: ++ # Skip if this exact function object was already wrapped ++ fn_id = id(original_fn) ++ if fn_id in _wrapped_ids: ++ logger.debug("Skipping duplicate %s.%s", module_path, attr_name) ++ continue ++ _wrapped_ids.add(fn_id) ++ ++ qualified_name = f"{module_path}.{name}" ++ ++ # Reuse a wrapper built in a previous cycle if the underlying ++ # function object is unchanged. This keeps each op defined ++ # exactly once and ensures a given function maps to a stable ++ # wrapper, so a reference that leaked across cycles still ++ # targets a live op. ++ wrapper = None ++ cached = _built_wrappers.get(qualified_name) ++ if cached is not None and cached[1] is original_fn: ++ wrapper = cached[0] ++ ++ if wrapper is None: ++ # ── Regular functions ── ++ try: ++ sig = inspect.signature(original_fn) ++ except (ValueError, TypeError): ++ logger.debug( ++ "Cannot inspect signature of %s — skipping", ++ qualified_name, ++ ) ++ continue ++ ++ base = f"{module_path.split('.')[-1]}_{name}" ++ schema_info = _build_schema_from_sig(sig, skip_self=is_method) ++ ++ if schema_info is not None: ++ # Full tensor annotations → use torch.library custom op ++ schema_str, t_names, nt_names = schema_info ++ op_name = _next_op_name(base) ++ wrapper = _register_op( ++ op_name, schema_str, original_fn, ++ t_names, nt_names, sig, skip_self=is_method, ++ ) ++ if wrapper is not None: ++ logger.debug("Registered %s as custom op %s", ++ qualified_name, op_name) ++ ++ if wrapper is None: ++ # Fallback: no annotations or schema registration failed ++ # → use record_function wrapper (shapes in event name) ++ wrapper = _make_record_function_wrapper( ++ qualified_name, original_fn, ++ ) ++ logger.debug("Registered %s via record_function", ++ qualified_name) ++ ++ _built_wrappers[qualified_name] = (wrapper, original_fn) ++ ++ # --- Apply patches --- ++ if is_plain_function: ++ ref_patches = _patch_all_references(original_fn, wrapper) ++ _patches.extend(ref_patches) ++ if not ref_patches: ++ setattr(container, name, wrapper) ++ _patches.append((container, name, original_fn)) ++ else: + setattr(container, name, wrapper) + _patches.append((container, name, original_fn)) -+ else: -+ setattr(container, name, wrapper) -+ _patches.append((container, name, original_fn)) + -+ n_discovered = len(all_entry_points) - len(_KERNEL_ENTRY_POINTS) ++ n_discovered = len(all_entry_points) - len(_KERNEL_ENTRY_POINTS) ++ + _enabled = True + logger.info( + "kernel_shape_profiler enabled: %d references patched across " + "%d entry points (%d explicit + %d auto-discovered)", + len(_patches), -+ len(all_entry_points), ++ len(_KERNEL_ENTRY_POINTS) + n_discovered, + len(_KERNEL_ENTRY_POINTS), + n_discovered, + ) @@ -733,18 +853,23 @@ index 000000000..6d8563b29 + +def disable(): + """Restore all patched functions to originals.""" -+ global _enabled, _lib ++ global _enabled + with _lock: + if not _enabled: + return ++ # Flip the flag first so any wrapper invoked concurrently — or one that ++ # leaked past restoration — short-circuits to the original instead of ++ # dispatching into a custom op. ++ _enabled = False + for container, name, original_fn in reversed(_patches): + try: + setattr(container, name, original_fn) + except Exception: + pass + _patches.clear() -+ _lib = None -+ _enabled = False ++ # Intentionally keep _lib, _op_counter and _built_wrappers alive: the ++ # registered ops must outlive any wrapper reference that may have ++ # leaked (see module-level _lib docs). + logger.info("kernel_shape_profiler disabled: all patches restored") + + diff --git a/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/multi_layer_eagle_draft_extend_cuda_graph_runner.patch b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/multi_layer_eagle_draft_extend_cuda_graph_runner.patch new file mode 100644 index 000000000..1e4625f08 --- /dev/null +++ b/examples/custom_workflows/inference_analysis/sglang_roofline_patches/sglang_0_5_12/multi_layer_eagle_draft_extend_cuda_graph_runner.patch @@ -0,0 +1,61 @@ +diff --git a/python/sglang/srt/speculative/multi_layer_eagle_draft_extend_cuda_graph_runner.py b/python/sglang/srt/speculative/multi_layer_eagle_draft_extend_cuda_graph_runner.py +index 295c1009b..3460bce13 100644 +--- a/python/sglang/srt/speculative/multi_layer_eagle_draft_extend_cuda_graph_runner.py ++++ b/python/sglang/srt/speculative/multi_layer_eagle_draft_extend_cuda_graph_runner.py +@@ -44,6 +44,7 @@ from sglang.srt.model_executor.input_buffers import ForwardInputBuffers + from sglang.srt.speculative.eagle_info import EagleDraftInput + from sglang.srt.speculative.multi_layer_eagle_utils import assign_new_state_triton + from sglang.srt.speculative.spec_utils import fast_topk ++from sglang.srt.utils.kernel_shape_profiler import enable, is_enabled + from sglang.srt.utils import ( + get_available_gpu_memory, + require_attn_tp_gather, +@@ -111,6 +112,9 @@ class MultiLayerEagleDraftExtendCudaGraphRunner: + self.enable_profile_cuda_graph = ( + model_runner.server_args.enable_profile_cuda_graph + ) ++ self.enable_shape_discovery_for_cuda_graph_profile = ( ++ model_runner.server_args.enable_shape_discovery_for_cuda_graph_profile ++ ) + self.capture_bs, self.compile_bs = get_batch_sizes_to_capture(model_runner) + self.padded_static_len = -1 + self.deepep_adapter = DeepEPCudaGraphRunnerAdapter() +@@ -280,6 +284,16 @@ class MultiLayerEagleDraftExtendCudaGraphRunner: + torch.cuda.synchronize() + self.model_runner.tp_group.barrier() + run_once_fn() ++ if self.enable_profile_cuda_graph: ++ # Activate kernel shape profiler AFTER warmup runs so that all ++ # lazily-imported modules (e.g. tilelang_kernel) are in sys.modules ++ # and auto-discovery can find them. ++ if ( ++ self.enable_shape_discovery_for_cuda_graph_profile ++ and not is_enabled() ++ ): ++ enable() ++ self._profiler.step() + + def _capture_graph(self, graph, pool, stream, run_once_fn): + with torch.cuda.graph(graph, pool=pool, stream=stream): +@@ -292,6 +306,11 @@ class MultiLayerEagleDraftExtendCudaGraphRunner: + def capture(self): + CudaGraphRunner.capture(self) + ++ _init_profile_context_and_memory_record = ( ++ CudaGraphRunner._init_profile_context_and_memory_record ++ ) ++ _post_process_after_profile = CudaGraphRunner._post_process_after_profile ++ + def get_forward_batch(self, bs: int) -> ForwardBatch: + buffers = self.buffers + num_tokens = bs * self.num_tokens_per_bs +@@ -501,6 +520,9 @@ class MultiLayerEagleDraftExtendCudaGraphRunner: + graph, get_global_graph_memory_pool(), stream, run_once + ) + ++ if self.enable_profile_cuda_graph: ++ self._profiler.step() ++ + set_global_graph_memory_pool(graph.pool()) + return graph, out + diff --git a/examples/custom_workflows/inference_analysis/vllm_patches/config_vllm_v0.22.0.patch b/examples/custom_workflows/inference_analysis/vllm_patches/config_vllm_v0.22.0.patch new file mode 100644 index 000000000..89505779a --- /dev/null +++ b/examples/custom_workflows/inference_analysis/vllm_patches/config_vllm_v0.22.0.patch @@ -0,0 +1,245 @@ +diff --git a/vllm/config/profiler.py b/vllm/config/profiler.py +index 68fa78854..eb8d6c264 100644 +--- a/vllm/config/profiler.py ++++ b/vllm/config/profiler.py +@@ -66,6 +66,17 @@ class ProfilerConfig: + """If `True`, enables memory profiling in the torch profiler. + Disabled by default.""" + ++ capture_torch_profiler_dir: str = "" ++ """Directory to save profiler traces captured during CUDA graph capture. ++ If set and non-empty, a torch profiler will be enabled during graph capture ++ on rank 0. Must be an absolute path.""" ++ ++ detailed_trace_annotation: bool = False ++ """If `True`, uses detailed annotations with roofline metrics (sk, sqsq, ++ sqsk) in profiler trace events. If `False`, uses simple annotations with ++ only context/generation request counts and token counts. ++ Disabled by default.""" ++ + ignore_frontend: bool = False + """If `True`, disables the front-end profiling of AsyncLLM when using the + 'torch' profiler. This is needed to reduce overhead when using delay/limit options, +@@ -144,4 +155,14 @@ class ProfilerConfig: + if profiler_dir and not _is_uri_path(profiler_dir): + self.torch_profiler_dir = os.path.abspath(os.path.expanduser(profiler_dir)) + ++ capture_dir = self.capture_torch_profiler_dir ++ if capture_dir and self.profiler != "torch": ++ raise ValueError( ++ "capture_torch_profiler_dir is only applicable when profiler is set to 'torch'" ++ ) ++ if capture_dir and not _is_uri_path(capture_dir): ++ self.capture_torch_profiler_dir = os.path.abspath( ++ os.path.expanduser(capture_dir) ++ ) ++ + return self +diff --git a/vllm/v1/worker/gpu_model_runner.py b/vllm/v1/worker/gpu_model_runner.py +index d51bf2284..c53faa282 100644 +--- a/vllm/v1/worker/gpu_model_runner.py ++++ b/vllm/v1/worker/gpu_model_runner.py +@@ -8,7 +8,7 @@ import threading + import time + from collections import defaultdict + from collections.abc import Callable, Iterable, Iterator, Sequence +-from contextlib import contextmanager ++from contextlib import contextmanager, nullcontext + from copy import copy, deepcopy + from dataclasses import dataclass, replace + from functools import reduce +@@ -6413,6 +6413,30 @@ class GPUModelRunner( + # Capture the large shapes first so that the smaller shapes + # can reuse the memory pool allocated for the large shapes. + set_cudagraph_capturing_enabled(True) ++ ++ # Setup torch profiler for graph capture traces (conditional) ++ from vllm.distributed.parallel_state import get_world_group ++ local_rank = get_world_group().local_rank ++ enable_profiler = (local_rank == 0) and self.vllm_config.profiler_config.capture_torch_profiler_dir ++ if enable_profiler: ++ trace_dir = self.vllm_config.profiler_config.torch_profiler_dir + "/capture_traces" ++ profiler = torch.profiler.profile( ++ activities=[ ++ torch.profiler.ProfilerActivity.CPU, ++ torch.profiler.ProfilerActivity.CUDA, ++ ], ++ record_shapes=True, ++ profile_memory=True, ++ with_stack=True, ++ on_trace_ready=torch.profiler.tensorboard_trace_handler( ++ trace_dir, worker_name=f"graph_capture_rank_{local_rank}",use_gzip=True ++ ), ++ ) ++ logger.info("Rank %d: Torch profiler enabled for CUDA graph capture, traces will be saved to: %s", local_rank, trace_dir) ++ else: ++ profiler = nullcontext() ++ logger.info("Rank %d: Torch profiler disabled for CUDA graph capture", local_rank) ++ + with self._freeze_gc(), graph_capture(device=self.device): + torch.accelerator.synchronize() + torch.accelerator.empty_cache() +@@ -6425,6 +6449,7 @@ class GPUModelRunner( + self._capture_cudagraphs( + batch_descriptors=batch_descs, + cudagraph_runtime_mode=runtime_mode, ++ profiler=profiler, + ) + torch.accelerator.synchronize() + +@@ -6467,6 +6492,7 @@ class GPUModelRunner( + profile_seq_lens: int | None = None, + allow_microbatching: bool = False, + num_warmups: int | None = None, ++ profiler: "ContextManager[Any]" = nullcontext(), + ): + if num_warmups is None: + num_warmups = self.compilation_config.cudagraph_num_of_warmups +@@ -6483,22 +6509,27 @@ class GPUModelRunner( + num_active_loras=desc.num_active_loras, + profile_seq_lens=profile_seq_lens, + ) +- self._dummy_run( +- desc.num_tokens, +- cudagraph_runtime_mode=cudagraph_runtime_mode, +- uniform_decode=desc.uniform, +- allow_microbatching=allow_microbatching, +- skip_eplb=True, +- remove_lora=False, +- num_active_loras=desc.num_active_loras, +- is_graph_capturing=True, +- profile_seq_lens=profile_seq_lens, +- ) ++ with profiler: ++ with torch.profiler.record_function( ++ f"capture_{desc.num_tokens}_{cudagraph_runtime_mode.name}" ++ ): ++ self._dummy_run( ++ desc.num_tokens, ++ cudagraph_runtime_mode=cudagraph_runtime_mode, ++ uniform_decode=desc.uniform, ++ allow_microbatching=allow_microbatching, ++ skip_eplb=True, ++ remove_lora=False, ++ num_active_loras=desc.num_active_loras, ++ is_graph_capturing=True, ++ profile_seq_lens=profile_seq_lens, ++ ) + + def _capture_cudagraphs( + self, + batch_descriptors: list[BatchDescriptor], + cudagraph_runtime_mode: CUDAGraphMode, ++ profiler: "ContextManager[Any]" = nullcontext(), + ): + assert ( + cudagraph_runtime_mode != CUDAGraphMode.NONE +@@ -6541,6 +6572,7 @@ class GPUModelRunner( + batch_desc, + cudagraph_runtime_mode=cudagraph_runtime_mode, + allow_microbatching=allow_microbatching, ++ profiler=profiler, + ) + torch.accelerator.synchronize() + self.maybe_remove_all_loras(self.lora_config) +diff --git a/vllm/v1/worker/gpu_worker.py b/vllm/v1/worker/gpu_worker.py +index 582c6a17c..6b8b6dfd8 100644 +--- a/vllm/v1/worker/gpu_worker.py ++++ b/vllm/v1/worker/gpu_worker.py +@@ -756,19 +756,87 @@ class Worker(WorkerBase): + + iteration_details = compute_iteration_details(scheduler_output) + +- annotation = "".join( +- [ +- "execute_context_", ++ if self.vllm_config.profiler_config.detailed_trace_annotation: ++ # Compute roofline-model metrics per request, split by phase ++ # (context vs generation). These help estimate compute and ++ # memory intensity from the trace. ++ # ++ # Per-request quantities: ++ # sq = number of scheduled (new) tokens for this request ++ # sk = total sequence length (computed + scheduled tokens) ++ # ++ # Aggregated across requests in each phase (c_=context, g_=gen): ++ # sk = sum of sk (total KV length) ++ # sqsq = sum of sq*sq (proxy for QK^T compute cost) ++ # sqsk = sum of sq*sk (proxy for QK^T compute cost for decode and chunked prefill) ++ # bs = total scheduled tokens across all requests ++ c_sk = 0 ++ c_sqsq = 0 ++ c_sqsk = 0 ++ g_sk = 0 ++ g_sqsq = 0 ++ g_sqsk = 0 ++ bs = 0 ++ ++ # Build a map of req_id -> num_computed_tokens for all requests ++ new_req_ids = { ++ new_req.req_id ++ for new_req in scheduler_output.scheduled_new_reqs ++ } ++ num_computed_tokens_ids = { ++ new_req.req_id: new_req.num_computed_tokens ++ for new_req in scheduler_output.scheduled_new_reqs ++ } ++ for req_id, num_computed_tokens in zip( ++ scheduler_output.scheduled_cached_reqs.req_ids, ++ scheduler_output.scheduled_cached_reqs.num_computed_tokens, ++ ): ++ num_computed_tokens_ids[req_id] = num_computed_tokens ++ ++ # Accumulate per-phase metrics ++ for req_id, num_tokens in ( ++ scheduler_output.num_scheduled_tokens.items() ++ ): ++ sq = num_tokens ++ bs += sq ++ sk = num_computed_tokens_ids.get(req_id, 0) + sq ++ if ( ++ scheduler_output.scheduled_cached_reqs.is_context_phase( ++ req_id ++ ) ++ or req_id in new_req_ids ++ ): ++ c_sk += sk ++ c_sqsq += sq * sq ++ c_sqsk += sq * sk ++ else: ++ g_sk += sk ++ g_sqsq += sq * sq ++ g_sqsk += sq * sk ++ annotation = "".join([ ++ "execute_", str(bs), "_context_", + str(iteration_details.num_ctx_requests), +- "(", +- str(iteration_details.num_ctx_tokens), ++ "(sq", str(iteration_details.num_ctx_tokens), ++ "sk", str(c_sk), ++ "sqsq", str(c_sqsq), ++ "sqsk", str(c_sqsk), + ")_generation_", + str(iteration_details.num_generation_requests), +- "(", +- str(iteration_details.num_generation_tokens), ++ "(sq", str(iteration_details.num_generation_tokens), ++ "sk", str(g_sk), ++ "sqsq", str(g_sqsq), ++ "sqsk", str(g_sqsk), + ")", +- ] +- ) ++ ]) ++ else: ++ annotation = "".join([ ++ "execute_context_", ++ str(iteration_details.num_ctx_requests), ++ "(", str(iteration_details.num_ctx_tokens), ")", ++ "_generation_", ++ str(iteration_details.num_generation_requests), ++ "(", str(iteration_details.num_generation_tokens), ")", ++ ]) + return self.profiler.annotate_context_manager(annotation) + + @torch.inference_mode() diff --git a/examples/custom_workflows/inference_analysis/vllm_patches/config_vllm_v0.23.0.patch b/examples/custom_workflows/inference_analysis/vllm_patches/config_vllm_v0.23.0.patch new file mode 100644 index 000000000..fcfcfabf3 --- /dev/null +++ b/examples/custom_workflows/inference_analysis/vllm_patches/config_vllm_v0.23.0.patch @@ -0,0 +1,245 @@ +diff --git a/vllm/config/profiler.py b/vllm/config/profiler.py +index 68fa78854..eb8d6c264 100644 +--- a/vllm/config/profiler.py ++++ b/vllm/config/profiler.py +@@ -66,6 +66,17 @@ class ProfilerConfig: + """If `True`, enables memory profiling in the torch profiler. + Disabled by default.""" + ++ capture_torch_profiler_dir: str = "" ++ """Directory to save profiler traces captured during CUDA graph capture. ++ If set and non-empty, a torch profiler will be enabled during graph capture ++ on rank 0. Must be an absolute path.""" ++ ++ detailed_trace_annotation: bool = False ++ """If `True`, uses detailed annotations with roofline metrics (sk, sqsq, ++ sqsk) in profiler trace events. If `False`, uses simple annotations with ++ only context/generation request counts and token counts. ++ Disabled by default.""" ++ + ignore_frontend: bool = False + """If `True`, disables the front-end profiling of AsyncLLM when using the + 'torch' profiler. This is needed to reduce overhead when using delay/limit options, +@@ -144,4 +155,14 @@ class ProfilerConfig: + if profiler_dir and not _is_uri_path(profiler_dir): + self.torch_profiler_dir = os.path.abspath(os.path.expanduser(profiler_dir)) + ++ capture_dir = self.capture_torch_profiler_dir ++ if capture_dir and self.profiler != "torch": ++ raise ValueError( ++ "capture_torch_profiler_dir is only applicable when profiler is set to 'torch'" ++ ) ++ if capture_dir and not _is_uri_path(capture_dir): ++ self.capture_torch_profiler_dir = os.path.abspath( ++ os.path.expanduser(capture_dir) ++ ) ++ + return self +diff --git a/vllm/v1/worker/gpu_model_runner.py b/vllm/v1/worker/gpu_model_runner.py +index 801a8574a..cd158b535 100644 +--- a/vllm/v1/worker/gpu_model_runner.py ++++ b/vllm/v1/worker/gpu_model_runner.py +@@ -8,7 +8,7 @@ import threading + import time + from collections import defaultdict + from collections.abc import Callable, Iterable, Iterator, Sequence +-from contextlib import contextmanager ++from contextlib import contextmanager, nullcontext + from copy import copy, deepcopy + from dataclasses import dataclass, replace + from functools import reduce +@@ -6541,6 +6541,30 @@ class GPUModelRunner( + # Capture the large shapes first so that the smaller shapes + # can reuse the memory pool allocated for the large shapes. + set_cudagraph_capturing_enabled(True) ++ ++ # Setup torch profiler for graph capture traces (conditional) ++ from vllm.distributed.parallel_state import get_world_group ++ local_rank = get_world_group().local_rank ++ enable_profiler = (local_rank == 0) and self.vllm_config.profiler_config.capture_torch_profiler_dir ++ if enable_profiler: ++ trace_dir = self.vllm_config.profiler_config.torch_profiler_dir + "/capture_traces" ++ profiler = torch.profiler.profile( ++ activities=[ ++ torch.profiler.ProfilerActivity.CPU, ++ torch.profiler.ProfilerActivity.CUDA, ++ ], ++ record_shapes=True, ++ profile_memory=True, ++ with_stack=True, ++ on_trace_ready=torch.profiler.tensorboard_trace_handler( ++ trace_dir, worker_name=f"graph_capture_rank_{local_rank}",use_gzip=True ++ ), ++ ) ++ logger.info("Rank %d: Torch profiler enabled for CUDA graph capture, traces will be saved to: %s", local_rank, trace_dir) ++ else: ++ profiler = nullcontext() ++ logger.info("Rank %d: Torch profiler disabled for CUDA graph capture", local_rank) ++ + with self._freeze_gc(), graph_capture(device=self.device): + torch.accelerator.synchronize() + torch.accelerator.empty_cache() +@@ -6553,6 +6577,7 @@ class GPUModelRunner( + self._capture_cudagraphs( + batch_descriptors=batch_descs, + cudagraph_runtime_mode=runtime_mode, ++ profiler=profiler, + ) + torch.accelerator.synchronize() + +@@ -6596,6 +6621,7 @@ class GPUModelRunner( + profile_seq_lens: int | None = None, + allow_microbatching: bool = False, + num_warmups: int | None = None, ++ profiler: "ContextManager[Any]" = nullcontext(), + ): + if num_warmups is None: + num_warmups = self.compilation_config.cudagraph_num_of_warmups +@@ -6612,22 +6638,27 @@ class GPUModelRunner( + num_active_loras=desc.num_active_loras, + profile_seq_lens=profile_seq_lens, + ) +- self._dummy_run( +- desc.num_tokens, +- cudagraph_runtime_mode=cudagraph_runtime_mode, +- uniform_decode=desc.uniform, +- allow_microbatching=allow_microbatching, +- skip_eplb=True, +- remove_lora=False, +- num_active_loras=desc.num_active_loras, +- is_graph_capturing=True, +- profile_seq_lens=profile_seq_lens, +- ) ++ with profiler: ++ with torch.profiler.record_function( ++ f"capture_{desc.num_tokens}_{cudagraph_runtime_mode.name}" ++ ): ++ self._dummy_run( ++ desc.num_tokens, ++ cudagraph_runtime_mode=cudagraph_runtime_mode, ++ uniform_decode=desc.uniform, ++ allow_microbatching=allow_microbatching, ++ skip_eplb=True, ++ remove_lora=False, ++ num_active_loras=desc.num_active_loras, ++ is_graph_capturing=True, ++ profile_seq_lens=profile_seq_lens, ++ ) + + def _capture_cudagraphs( + self, + batch_descriptors: list[BatchDescriptor], + cudagraph_runtime_mode: CUDAGraphMode, ++ profiler: "ContextManager[Any]" = nullcontext(), + ): + assert ( + cudagraph_runtime_mode != CUDAGraphMode.NONE +@@ -6670,6 +6701,7 @@ class GPUModelRunner( + batch_desc, + cudagraph_runtime_mode=cudagraph_runtime_mode, + allow_microbatching=allow_microbatching, ++ profiler=profiler, + ) + torch.accelerator.synchronize() + self.maybe_remove_all_loras(self.lora_config) +diff --git a/vllm/v1/worker/gpu_worker.py b/vllm/v1/worker/gpu_worker.py +index 052e1fe76..7ea4d8b14 100644 +--- a/vllm/v1/worker/gpu_worker.py ++++ b/vllm/v1/worker/gpu_worker.py +@@ -781,19 +781,87 @@ class Worker(WorkerBase): + + iteration_details = compute_iteration_details(scheduler_output) + +- annotation = "".join( +- [ +- "execute_context_", ++ if self.vllm_config.profiler_config.detailed_trace_annotation: ++ # Compute roofline-model metrics per request, split by phase ++ # (context vs generation). These help estimate compute and ++ # memory intensity from the trace. ++ # ++ # Per-request quantities: ++ # sq = number of scheduled (new) tokens for this request ++ # sk = total sequence length (computed + scheduled tokens) ++ # ++ # Aggregated across requests in each phase (c_=context, g_=gen): ++ # sk = sum of sk (total KV length) ++ # sqsq = sum of sq*sq (proxy for QK^T compute cost) ++ # sqsk = sum of sq*sk (proxy for QK^T compute cost for decode and chunked prefill) ++ # bs = total scheduled tokens across all requests ++ c_sk = 0 ++ c_sqsq = 0 ++ c_sqsk = 0 ++ g_sk = 0 ++ g_sqsq = 0 ++ g_sqsk = 0 ++ bs = 0 ++ ++ # Build a map of req_id -> num_computed_tokens for all requests ++ new_req_ids = { ++ new_req.req_id ++ for new_req in scheduler_output.scheduled_new_reqs ++ } ++ num_computed_tokens_ids = { ++ new_req.req_id: new_req.num_computed_tokens ++ for new_req in scheduler_output.scheduled_new_reqs ++ } ++ for req_id, num_computed_tokens in zip( ++ scheduler_output.scheduled_cached_reqs.req_ids, ++ scheduler_output.scheduled_cached_reqs.num_computed_tokens, ++ ): ++ num_computed_tokens_ids[req_id] = num_computed_tokens ++ ++ # Accumulate per-phase metrics ++ for req_id, num_tokens in ( ++ scheduler_output.num_scheduled_tokens.items() ++ ): ++ sq = num_tokens ++ bs += sq ++ sk = num_computed_tokens_ids.get(req_id, 0) + sq ++ if ( ++ scheduler_output.scheduled_cached_reqs.is_context_phase( ++ req_id ++ ) ++ or req_id in new_req_ids ++ ): ++ c_sk += sk ++ c_sqsq += sq * sq ++ c_sqsk += sq * sk ++ else: ++ g_sk += sk ++ g_sqsq += sq * sq ++ g_sqsk += sq * sk ++ annotation = "".join([ ++ "execute_", str(bs), "_context_", + str(iteration_details.num_ctx_requests), +- "(", +- str(iteration_details.num_ctx_tokens), ++ "(sq", str(iteration_details.num_ctx_tokens), ++ "sk", str(c_sk), ++ "sqsq", str(c_sqsq), ++ "sqsk", str(c_sqsk), + ")_generation_", + str(iteration_details.num_generation_requests), +- "(", +- str(iteration_details.num_generation_tokens), ++ "(sq", str(iteration_details.num_generation_tokens), ++ "sk", str(g_sk), ++ "sqsq", str(g_sqsq), ++ "sqsk", str(g_sqsk), + ")", +- ] +- ) ++ ]) ++ else: ++ annotation = "".join([ ++ "execute_context_", ++ str(iteration_details.num_ctx_requests), ++ "(", str(iteration_details.num_ctx_tokens), ")", ++ "_generation_", ++ str(iteration_details.num_generation_requests), ++ "(", str(iteration_details.num_generation_tokens), ")", ++ ]) + return self.profiler.annotate_context_manager(annotation) + + @torch.inference_mode() diff --git a/examples/custom_workflows/inference_analysis/vllm_patches/config_vllm_v0.24.0.patch b/examples/custom_workflows/inference_analysis/vllm_patches/config_vllm_v0.24.0.patch new file mode 100644 index 000000000..161b52816 --- /dev/null +++ b/examples/custom_workflows/inference_analysis/vllm_patches/config_vllm_v0.24.0.patch @@ -0,0 +1,245 @@ +diff --git a/vllm/config/profiler.py b/vllm/config/profiler.py +index 68fa78854..eb8d6c264 100644 +--- a/vllm/config/profiler.py ++++ b/vllm/config/profiler.py +@@ -66,6 +66,17 @@ class ProfilerConfig: + """If `True`, enables memory profiling in the torch profiler. + Disabled by default.""" + ++ capture_torch_profiler_dir: str = "" ++ """Directory to save profiler traces captured during CUDA graph capture. ++ If set and non-empty, a torch profiler will be enabled during graph capture ++ on rank 0. Must be an absolute path.""" ++ ++ detailed_trace_annotation: bool = False ++ """If `True`, uses detailed annotations with roofline metrics (sk, sqsq, ++ sqsk) in profiler trace events. If `False`, uses simple annotations with ++ only context/generation request counts and token counts. ++ Disabled by default.""" ++ + ignore_frontend: bool = False + """If `True`, disables the front-end profiling of AsyncLLM when using the + 'torch' profiler. This is needed to reduce overhead when using delay/limit options, +@@ -144,4 +155,14 @@ class ProfilerConfig: + if profiler_dir and not _is_uri_path(profiler_dir): + self.torch_profiler_dir = os.path.abspath(os.path.expanduser(profiler_dir)) + ++ capture_dir = self.capture_torch_profiler_dir ++ if capture_dir and self.profiler != "torch": ++ raise ValueError( ++ "capture_torch_profiler_dir is only applicable when profiler is set to 'torch'" ++ ) ++ if capture_dir and not _is_uri_path(capture_dir): ++ self.capture_torch_profiler_dir = os.path.abspath( ++ os.path.expanduser(capture_dir) ++ ) ++ + return self +diff --git a/vllm/v1/worker/gpu_model_runner.py b/vllm/v1/worker/gpu_model_runner.py +index 74938a823..af48209fc 100644 +--- a/vllm/v1/worker/gpu_model_runner.py ++++ b/vllm/v1/worker/gpu_model_runner.py +@@ -8,7 +8,7 @@ import threading + import time + from collections import defaultdict + from collections.abc import Callable, Iterable, Iterator, Sequence +-from contextlib import contextmanager ++from contextlib import contextmanager, nullcontext + from copy import copy, deepcopy + from dataclasses import dataclass, replace + from functools import reduce +@@ -6612,6 +6612,30 @@ class GPUModelRunner( + # Capture the large shapes first so that the smaller shapes + # can reuse the memory pool allocated for the large shapes. + set_cudagraph_capturing_enabled(True) ++ ++ # Setup torch profiler for graph capture traces (conditional) ++ from vllm.distributed.parallel_state import get_world_group ++ local_rank = get_world_group().local_rank ++ enable_profiler = (local_rank == 0) and self.vllm_config.profiler_config.capture_torch_profiler_dir ++ if enable_profiler: ++ trace_dir = self.vllm_config.profiler_config.torch_profiler_dir + "/capture_traces" ++ profiler = torch.profiler.profile( ++ activities=[ ++ torch.profiler.ProfilerActivity.CPU, ++ torch.profiler.ProfilerActivity.CUDA, ++ ], ++ record_shapes=True, ++ profile_memory=True, ++ with_stack=True, ++ on_trace_ready=torch.profiler.tensorboard_trace_handler( ++ trace_dir, worker_name=f"graph_capture_rank_{local_rank}",use_gzip=True ++ ), ++ ) ++ logger.info("Rank %d: Torch profiler enabled for CUDA graph capture, traces will be saved to: %s", local_rank, trace_dir) ++ else: ++ profiler = nullcontext() ++ logger.info("Rank %d: Torch profiler disabled for CUDA graph capture", local_rank) ++ + with self._freeze_gc(), graph_capture(device=self.device): + torch.accelerator.synchronize() + torch.accelerator.empty_cache() +@@ -6624,6 +6648,7 @@ class GPUModelRunner( + self._capture_cudagraphs( + batch_descriptors=batch_descs, + cudagraph_runtime_mode=runtime_mode, ++ profiler=profiler, + ) + torch.accelerator.synchronize() + +@@ -6667,6 +6692,7 @@ class GPUModelRunner( + profile_seq_lens: int | None = None, + allow_microbatching: bool = False, + num_warmups: int | None = None, ++ profiler: "ContextManager[Any]" = nullcontext(), + ): + if num_warmups is None: + num_warmups = self.compilation_config.cudagraph_num_of_warmups +@@ -6683,22 +6709,27 @@ class GPUModelRunner( + num_active_loras=desc.num_active_loras, + profile_seq_lens=profile_seq_lens, + ) +- self._dummy_run( +- desc.num_tokens, +- cudagraph_runtime_mode=cudagraph_runtime_mode, +- uniform_decode=desc.uniform, +- allow_microbatching=allow_microbatching, +- skip_eplb=True, +- remove_lora=False, +- num_active_loras=desc.num_active_loras, +- is_graph_capturing=True, +- profile_seq_lens=profile_seq_lens, +- ) ++ with profiler: ++ with torch.profiler.record_function( ++ f"capture_{desc.num_tokens}_{cudagraph_runtime_mode.name}" ++ ): ++ self._dummy_run( ++ desc.num_tokens, ++ cudagraph_runtime_mode=cudagraph_runtime_mode, ++ uniform_decode=desc.uniform, ++ allow_microbatching=allow_microbatching, ++ skip_eplb=True, ++ remove_lora=False, ++ num_active_loras=desc.num_active_loras, ++ is_graph_capturing=True, ++ profile_seq_lens=profile_seq_lens, ++ ) + + def _capture_cudagraphs( + self, + batch_descriptors: list[BatchDescriptor], + cudagraph_runtime_mode: CUDAGraphMode, ++ profiler: "ContextManager[Any]" = nullcontext(), + ): + assert ( + cudagraph_runtime_mode != CUDAGraphMode.NONE +@@ -6741,6 +6772,7 @@ class GPUModelRunner( + batch_desc, + cudagraph_runtime_mode=cudagraph_runtime_mode, + allow_microbatching=allow_microbatching, ++ profiler=profiler, + ) + torch.accelerator.synchronize() + self.maybe_remove_all_loras(self.lora_config) +diff --git a/vllm/v1/worker/gpu_worker.py b/vllm/v1/worker/gpu_worker.py +index 5e266a313..2344a6405 100644 +--- a/vllm/v1/worker/gpu_worker.py ++++ b/vllm/v1/worker/gpu_worker.py +@@ -811,19 +811,87 @@ class Worker(WorkerBase): + + iteration_details = compute_iteration_details(scheduler_output) + +- annotation = "".join( +- [ +- "execute_context_", ++ if self.vllm_config.profiler_config.detailed_trace_annotation: ++ # Compute roofline-model metrics per request, split by phase ++ # (context vs generation). These help estimate compute and ++ # memory intensity from the trace. ++ # ++ # Per-request quantities: ++ # sq = number of scheduled (new) tokens for this request ++ # sk = total sequence length (computed + scheduled tokens) ++ # ++ # Aggregated across requests in each phase (c_=context, g_=gen): ++ # sk = sum of sk (total KV length) ++ # sqsq = sum of sq*sq (proxy for QK^T compute cost) ++ # sqsk = sum of sq*sk (proxy for QK^T compute cost for decode and chunked prefill) ++ # bs = total scheduled tokens across all requests ++ c_sk = 0 ++ c_sqsq = 0 ++ c_sqsk = 0 ++ g_sk = 0 ++ g_sqsq = 0 ++ g_sqsk = 0 ++ bs = 0 ++ ++ # Build a map of req_id -> num_computed_tokens for all requests ++ new_req_ids = { ++ new_req.req_id ++ for new_req in scheduler_output.scheduled_new_reqs ++ } ++ num_computed_tokens_ids = { ++ new_req.req_id: new_req.num_computed_tokens ++ for new_req in scheduler_output.scheduled_new_reqs ++ } ++ for req_id, num_computed_tokens in zip( ++ scheduler_output.scheduled_cached_reqs.req_ids, ++ scheduler_output.scheduled_cached_reqs.num_computed_tokens, ++ ): ++ num_computed_tokens_ids[req_id] = num_computed_tokens ++ ++ # Accumulate per-phase metrics ++ for req_id, num_tokens in ( ++ scheduler_output.num_scheduled_tokens.items() ++ ): ++ sq = num_tokens ++ bs += sq ++ sk = num_computed_tokens_ids.get(req_id, 0) + sq ++ if ( ++ scheduler_output.scheduled_cached_reqs.is_context_phase( ++ req_id ++ ) ++ or req_id in new_req_ids ++ ): ++ c_sk += sk ++ c_sqsq += sq * sq ++ c_sqsk += sq * sk ++ else: ++ g_sk += sk ++ g_sqsq += sq * sq ++ g_sqsk += sq * sk ++ annotation = "".join([ ++ "execute_", str(bs), "_context_", + str(iteration_details.num_ctx_requests), +- "(", +- str(iteration_details.num_ctx_tokens), ++ "(sq", str(iteration_details.num_ctx_tokens), ++ "sk", str(c_sk), ++ "sqsq", str(c_sqsq), ++ "sqsk", str(c_sqsk), + ")_generation_", + str(iteration_details.num_generation_requests), +- "(", +- str(iteration_details.num_generation_tokens), ++ "(sq", str(iteration_details.num_generation_tokens), ++ "sk", str(g_sk), ++ "sqsq", str(g_sqsq), ++ "sqsk", str(g_sqsk), + ")", +- ] +- ) ++ ]) ++ else: ++ annotation = "".join([ ++ "execute_context_", ++ str(iteration_details.num_ctx_requests), ++ "(", str(iteration_details.num_ctx_tokens), ")", ++ "_generation_", ++ str(iteration_details.num_generation_requests), ++ "(", str(iteration_details.num_generation_tokens), ")", ++ ]) + return self.profiler.annotate_context_manager(annotation) + + @torch.inference_mode() diff --git a/examples/custom_workflows/trace_checker.py b/examples/custom_workflows/trace_checker.py new file mode 100644 index 000000000..ab9b808fd --- /dev/null +++ b/examples/custom_workflows/trace_checker.py @@ -0,0 +1,1528 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Trace quality checks for PyTorch and JAX profiler traces. + +Given a trace path and a framework (``"pytorch"`` or ``"jax"``), returns a +:class:`QualityReport`. + +* Phase 1 -- kernel presence, drop detection, runtime variability, GPU + busy/idle, kernel-count structure and metadata richness, off the raw JSON. +* Phase 2 -- checks derived from TraceLens perf reports, plus (JAX) an optional + attention-kernel-count sanity check when the model config is supplied. + +CLI (runs both phases by default):: + + python examples/custom_workflows/trace_checker.py TRACE.trace.json.gz --framework pytorch --phase all + + python examples/custom_workflows/trace_checker.py --json_trace TRACE.trace.json.gz --framework jax --phase all --xplane-pb-path TRACE.xplane.pb + +Optional outputs and the JAX attention-kernel-count check +(expected = num_gpus * num_steps * num_layers * calls * unique_kernels; num_gpus +and unique_kernels are inferred, --num-layers and --num-steps enable the check):: + + python examples/custom_workflows/trace_checker.py --json_trace TRACE.trace.json.gz --framework jax --xplane-pb-path TRACE.xplane.pb \\ + --output-dir ./perf_csvs --json ./report.json \\ + --num-layers 4 --num-steps 3 --fwd-attn-calls 2 --bwd-attn-calls 1 + +Set ``TRACELENS_VERBOSE_NATIVE_LOGS=1`` to keep the raw native XLA/xprof logs. +""" + +from __future__ import annotations + +import argparse +import enum +import functools +import json +import math +import os +import statistics +import sys +import tempfile +from collections import Counter, defaultdict +from dataclasses import dataclass, field +from typing import Any, Dict, Iterable, List, Optional, Sequence + +from TraceLens import GPUEventAnalyser +from TraceLens.util import DataLoader + +FRAMEWORK_PYTORCH = "pytorch" +FRAMEWORK_JAX = "jax" +VALID_FRAMEWORKS = (FRAMEWORK_PYTORCH, FRAMEWORK_JAX) + +# Categories treated as GPU work in a PyTorch trace. +PT_GPU_CATS = {"kernel", "gpu_memcpy", "gpu_memset"} + + +# =========================================================================== +# Result data model +# =========================================================================== +class Status(enum.Enum): + """Outcome of a single quality check (ordered PASS < SKIP < WARN < FAIL).""" + + PASS = "PASS" + SKIP = "SKIP" + WARN = "WARN" + FAIL = "FAIL" + + @property + def severity(self) -> int: + return {"PASS": 0, "SKIP": 1, "WARN": 2, "FAIL": 3}[self.value] + + +@dataclass +class QualityResult: + check_id: str + name: str + status: Status + message: str = "" + metrics: Dict[str, Any] = field(default_factory=dict) + + def to_dict(self) -> Dict[str, Any]: + return { + "check_id": self.check_id, + "name": self.name, + "status": self.status.value, + "message": self.message, + "metrics": self.metrics, + } + + +@dataclass +class QualityReport: + trace_path: str + framework: str + results: List[QualityResult] = field(default_factory=list) + + def add(self, result: QualityResult) -> QualityResult: + self.results.append(result) + return result + + def extend(self, results: List[QualityResult]) -> None: + self.results.extend(results) + + @property + def worst_status(self) -> Status: + if not self.results: + return Status.SKIP + return max((r.status for r in self.results), key=lambda s: s.severity) + + @property + def ok(self) -> bool: + """True when no check FAILED (WARN/SKIP are tolerated).""" + return all(r.status is not Status.FAIL for r in self.results) + + def get(self, check_id: str) -> Optional[QualityResult]: + for r in self.results: + if r.check_id == check_id: + return r + return None + + def counts(self) -> Dict[str, int]: + out = {s.value: 0 for s in Status} + for r in self.results: + out[r.status.value] += 1 + return out + + def to_dict(self) -> Dict[str, Any]: + return { + "trace_path": self.trace_path, + "framework": self.framework, + "ok": self.ok, + "worst_status": self.worst_status.value, + "counts": self.counts(), + "results": [r.to_dict() for r in self.results], + } + + def __str__(self) -> str: # pragma: no cover - cosmetic + lines = [ + f"Trace quality report: {self.trace_path}", + f" framework={self.framework} worst={self.worst_status.value} " + f"ok={self.ok} counts={self.counts()}", + "", + ] + width = max((len(r.check_id) for r in self.results), default=10) + for r in self.results: + lines.append(f" [{r.status.value:<4}] {r.check_id:<{width}} {r.message}") + return "\n".join(lines) + + +# =========================================================================== +# Tunable thresholds +# =========================================================================== +@dataclass +class QualityThresholds: + # kernel presence + min_kernels: int = 100 + + # dropped-kernel detection + drop_num_windows: int = 20 + drop_empty_window_frac: float = 0.5 + drop_fail_frac: float = 0.15 + + # runtime variability (spurious events) + runtime_cv_warn: float = 0.25 + runtime_cv_fail: float = 0.75 + runtime_min_samples: int = 5 + runtime_min_dur_us: float = 2.0 + runtime_max_flagged_frac: float = 0.10 + + # GPU busy / idle + idle_pct_warn: float = 30.0 + idle_pct_fail: float = 60.0 + + # shape / metadata coverage + shape_coverage_warn: float = 0.80 + shape_coverage_fail: float = 0.40 + + # CPU:GPU event ratio (PyTorch) + cpu_gpu_ratio_min: float = 0.2 + cpu_gpu_ratio_max: float = 50.0 + + # attention / SDPA detection + attn_name_patterns: List[str] = field( + default_factory=lambda: [ + "fmha", + "flash_attn", + "flash_fwd", + "flash_bwd", + "fused_attn", + "sdpa", + "scaled_dot_product", + "attention", + "_attn", + ] + ) + + # phase 2: high-idle ops + op_high_idle_pct: float = 40.0 + + +@dataclass +class AttnCountConfig: + """Config for the attention-kernel-count check. + + expected = num_gpus * num_steps * num_layers * calls * unique_kernels (per + pass). num_gpus and unique_kernels are inferred; num_layers and num_steps + must be supplied (else the check SKIPs and just reports observed counts). + """ + + num_layers: Optional[int] = None + num_steps: Optional[int] = None + num_gpus: Optional[int] = None + fwd_attn_calls: int = 1 + bwd_attn_calls: int = 1 + tol: float = 0.0 # relative tolerance; 0.0 == exact + + @property + def enabled(self) -> bool: + return self.num_layers is not None and self.num_steps is not None + + +def coefficient_of_variation(values: Sequence[float]) -> float: + """std / mean (population std). 0.0 if empty or mean is 0.""" + n = len(values) + if n == 0: + return 0.0 + mean = sum(values) / n + if mean == 0: + return 0.0 + return statistics.pstdev(values) / abs(mean) + + +def gcd_of_counts(counts: Iterable[int]) -> int: + """GCD ("largest common denominator") of positive counts.""" + positives = [int(c) for c in counts if c and int(c) > 0] + if not positives: + return 0 + return functools.reduce(math.gcd, positives) + + +def merge_intervals(intervals): + """Merge overlapping ``(start, end)`` intervals.""" + if not intervals: + return [] + return GPUEventAnalyser.merge_intervals(list(intervals)) + + +def busy_idle_from_events(events: Sequence[dict]) -> Dict[str, float]: + """Compute busy/idle/total time (us) from events with ``ts``/``dur``.""" + intervals = [ + (float(e["ts"]), float(e["ts"]) + float(e["dur"])) + for e in events + if e.get("ts") is not None and e.get("dur") is not None + ] + if not intervals: + return {"busy_time": 0.0, "idle_time": 0.0, "total_time": 0.0, "idle_pct": 0.0} + merged = merge_intervals(intervals) + total_time = merged[-1][1] - merged[0][0] + busy_time = sum(e - s for s, e in merged) + idle_time = max(0.0, total_time - busy_time) + idle_pct = (100.0 * idle_time / total_time) if total_time > 0 else 0.0 + return { + "busy_time": busy_time, + "idle_time": idle_time, + "total_time": total_time, + "idle_pct": idle_pct, + } + + +def matches_any(name: str, patterns: Iterable[str]) -> bool: + low = (name or "").lower() + return any(p.lower() in low for p in patterns) + + +def _round_metric(value): + if isinstance(value, (int, float)) and not isinstance(value, bool): + return round(value, 3) + return value + + +@dataclass +class PytorchTrace: + path: str + raw_events: List[dict] + by_cat: Dict[str, List[dict]] = field(default_factory=dict) + + @property + def kernels(self) -> List[dict]: + return self.by_cat.get("kernel", []) + + @property + def cpu_ops(self) -> List[dict]: + return self.by_cat.get("cpu_op", []) + + @property + def gpu_events(self) -> List[dict]: + out: List[dict] = [] + for cat in PT_GPU_CATS: + out.extend(self.by_cat.get(cat, [])) + return out + + +@dataclass +class JaxJsonTrace: + path: str + raw_events: List[dict] + pid_name: Dict[str, str] = field(default_factory=dict) + gpu_events: List[dict] = field(default_factory=list) + gpu_events_by_device: Dict[str, List[dict]] = field(default_factory=dict) + host_events: List[dict] = field(default_factory=list) + + +def load_pytorch(path: str) -> PytorchTrace: + """Load a PyTorch trace, bucket events by ``cat`` and assign each a ``UID``.""" + data = DataLoader.load_data(path) + events = data.get("traceEvents", []) + by_cat: Dict[str, List[dict]] = defaultdict(list) + for i, e in enumerate(events): + if "UID" not in e: + e["UID"] = i + by_cat[e.get("cat", "unknown")].append(e) + return PytorchTrace(path=path, raw_events=events, by_cat=dict(by_cat)) + + +def load_jax_json(path: str) -> JaxJsonTrace: + """Load a JAX xprof JSON export. + + GPU events are ``ph == "X"`` events on a ``/device:GPU:*`` process. + """ + data = DataLoader.load_data(path) + events = data.get("traceEvents", []) + + pid_name: Dict[str, str] = {} + for e in events: + if e.get("ph") == "M" and e.get("name") == "process_name": + pid = e.get("pid") + if pid is not None: + pid_name[pid] = (e.get("args") or {}).get("name", "") + + gpu_events: List[dict] = [] + gpu_by_dev: Dict[str, List[dict]] = defaultdict(list) + host_events: List[dict] = [] + for e in events: + if e.get("ph") != "X": + continue + _coerce_numeric(e) # xprof exports ts/dur as strings + proc = pid_name.get(e.get("pid"), "") + if proc.startswith("/device:GPU"): + gpu_events.append(e) + gpu_by_dev[proc].append(e) + elif proc.startswith("/host"): + host_events.append(e) + return JaxJsonTrace( + path=path, + raw_events=events, + pid_name=pid_name, + gpu_events=gpu_events, + gpu_events_by_device=dict(gpu_by_dev), + host_events=host_events, + ) + + +def _coerce_numeric(event: dict) -> None: + for key in ("ts", "dur"): + val = event.get(key) + if isinstance(val, str): + try: + event[key] = float(val) + except ValueError: + pass + + +def make_jax_analyzer(xplane_path: str): + """Build a ``JaxTreePerfAnalyzer`` from an ``*.xplane.pb`` file.""" + from TraceLens.TreePerf.tree_perf import JaxTreePerfAnalyzer + + return JaxTreePerfAnalyzer.from_file(profile_filepath=xplane_path) + + +# Phase 1 checks (no external tooling) + + +def _check_kernels_present( + kernels: Sequence[dict], thr: QualityThresholds +) -> QualityResult: + n = len(kernels) + if n == 0: + status, msg = Status.FAIL, "no GPU kernel events found in trace" + elif n < thr.min_kernels: + status = Status.WARN + msg = f"only {n} GPU kernels (< min_kernels={thr.min_kernels})" + else: + status, msg = Status.PASS, f"{n} GPU kernel events present" + return QualityResult( + "kernels_present", "GPU kernels present", status, msg, {"num_kernels": n} + ) + + +def _check_kernels_not_dropped( + kernels: Sequence[dict], thr: QualityThresholds +) -> QualityResult: + """Detect intermittent kernel dropping. + + Buckets the timeline into windows; an interior window that is nearly empty + while its neighbors are busy indicates dropped kernels. + """ + times = sorted( + float(k["ts"]) for k in kernels if k.get("ts") is not None and k.get("dur") + ) + if len(times) < thr.drop_num_windows: + return QualityResult( + "kernels_not_dropped", + "Kernels not intermittently dropped", + Status.SKIP, + "too few kernels to bucket reliably", + {"num_kernels": len(times)}, + ) + t0, t1 = times[0], times[-1] + span = t1 - t0 + if span <= 0: + return QualityResult( + "kernels_not_dropped", + "Kernels not intermittently dropped", + Status.SKIP, + "zero time span across kernels", + {}, + ) + nbins = thr.drop_num_windows + width = span / nbins + counts = [0] * nbins + for t in times: + counts[min(int((t - t0) / width), nbins - 1)] += 1 + nonzero = [c for c in counts if c > 0] + median = statistics.median(nonzero) if nonzero else 0 + floor = thr.drop_empty_window_frac * median + # Only interior windows count as "drops" (ramp-up/tear-down live at edges). + starved = [i for i in range(1, nbins - 1) if counts[i] < floor] + num_interior = max(1, nbins - 2) + starved_frac = len(starved) / num_interior + metrics = { + "num_windows": nbins, + "window_counts": counts, + "median_window_count": median, + "starved_windows": starved, + "starved_frac": round(starved_frac, 3), + } + if not starved: + status = Status.PASS + msg = f"kernel density even across {nbins} windows (median={median})" + elif starved_frac > thr.drop_fail_frac: + status = Status.FAIL + msg = ( + f"{len(starved)}/{num_interior} interior windows starved of kernels " + f"(idx={starved}); kernels likely dropped intermittently" + ) + else: + status = Status.WARN + msg = ( + f"{len(starved)}/{num_interior} interior window(s) sparse " + f"(idx={starved}); likely a phase boundary, verify not dropped kernels" + ) + return QualityResult( + "kernels_not_dropped", + "Kernels not intermittently dropped", + status, + msg, + metrics, + ) + + +def _check_runtime_variability( + groups: Dict[str, List[float]], thr: QualityThresholds +) -> QualityResult: + """Flag kernel groups whose per-invocation duration varies too much.""" + eligible = 0 + warned: List[Dict[str, Any]] = [] + failed: List[Dict[str, Any]] = [] + worst_cv = 0.0 + worst_name = None + for key, durs in groups.items(): + if len(durs) < thr.runtime_min_samples: + continue + if sum(durs) / len(durs) < thr.runtime_min_dur_us: + continue + eligible += 1 + cv = coefficient_of_variation(durs) + if cv > worst_cv: + worst_cv, worst_name = cv, key + if cv >= thr.runtime_cv_warn: + stats = { + "group": key, + "cv": round(cv, 3), + "count": len(durs), + "min_us": round(min(durs), 3), + "median_us": round(statistics.median(durs), 3), + "max_us": round(max(durs), 3), + "mean_us": round(sum(durs) / len(durs), 3), + } + (failed if cv >= thr.runtime_cv_fail else warned).append(stats) + + failed.sort(key=lambda s: -s["cv"]) + warned.sort(key=lambda s: -s["cv"]) + metrics = { + "eligible_groups": eligible, + "num_warn": len(warned), + "num_fail": len(failed), + "worst_cv": round(worst_cv, 3), + "worst_group": worst_name, + "failed_groups": failed, + "warned_groups": warned, + "top_offenders": [ + {"group": s["group"], "cv": s["cv"]} for s in (failed + warned)[:10] + ], + } + if eligible == 0: + return QualityResult( + "runtime_variability", + "No spurious kernel-time variability", + Status.SKIP, + "no eligible kernel groups to assess", + metrics, + ) + fail_frac = len(failed) / eligible + if fail_frac > thr.runtime_max_flagged_frac: + status = Status.FAIL + msg = ( + f"{len(failed)}/{eligible} groups exceed CV>={thr.runtime_cv_fail} " + f"(worst={worst_cv:.2f} '{worst_name}')" + ) + msg += _format_variability_detail( + failed, "failed (CV>=%.2f)" % thr.runtime_cv_fail + ) + elif failed or warned: + status = Status.WARN + msg = ( + f"{len(failed)} high / {len(warned)} moderate variability groups " + f"(worst CV={worst_cv:.2f} '{worst_name}')" + ) + if failed: + msg += _format_variability_detail( + failed, "failed (CV>=%.2f)" % thr.runtime_cv_fail + ) + else: + status = Status.PASS + msg = f"kernel durations stable across {eligible} groups (worst CV={worst_cv:.2f})" + return QualityResult( + "runtime_variability", + "No spurious kernel-time variability", + status, + msg, + metrics, + ) + + +def _format_variability_detail(groups: List[Dict[str, Any]], header: str) -> str: + """Multi-line listing of every flagged kernel group with duration stats.""" + if not groups: + return "" + lines = [ + f"\n {len(groups)} kernel group(s) {header} " + "[us: count / CV / min / median / max]:" + ] + for s in groups: + lines.append( + f" - {s['group']}\n" + f" count={s['count']} CV={s['cv']} " + f"min={s['min_us']} median={s['median_us']} max={s['max_us']} " + f"mean={s['mean_us']}" + ) + return "\n".join(lines) + + +def _check_busy_idle( + metrics: Dict[str, float], thr: QualityThresholds +) -> QualityResult: + idle_pct = metrics.get("idle_pct", 0.0) + out = {k: _round_metric(v) for k, v in metrics.items()} + if idle_pct >= thr.idle_pct_fail: + status = Status.FAIL + msg = f"GPU idle {idle_pct:.1f}% (>= {thr.idle_pct_fail}%)" + elif idle_pct >= thr.idle_pct_warn: + status = Status.WARN + msg = f"GPU idle {idle_pct:.1f}% (>= {thr.idle_pct_warn}%)" + else: + status = Status.PASS + msg = f"GPU idle {idle_pct:.1f}%, busy {100 - idle_pct:.1f}%" + return QualityResult("gpu_busy_idle", "GPU busy/idle time", status, msg, out) + + +def _check_kernel_counts(name_counts: Counter, thr: QualityThresholds) -> QualityResult: + """Report kernel-count structure: common divisor + attention kernel count.""" + if not name_counts: + return QualityResult( + "kernel_counts", + "Kernel counts / attention presence", + Status.FAIL, + "no kernels to count", + {}, + ) + divisor = gcd_of_counts(name_counts.values()) + attn = { + name: c + for name, c in name_counts.items() + if matches_any(name, thr.attn_name_patterns) + } + attn_total = sum(attn.values()) + top_attn = sorted(attn.items(), key=lambda x: -x[1])[:5] + metrics = { + "num_unique_kernels": len(name_counts), + "count_gcd": divisor, + "attention_kernel_count": attn_total, + "attention_kernels": [{"name": n, "count": c} for n, c in top_attn], + "top_kernels": [{"name": n, "count": c} for n, c in name_counts.most_common(5)], + } + if attn_total == 0: + status = Status.WARN + msg = ( + f"{len(name_counts)} unique kernels (count gcd={divisor}); " + "no attention/FMHA kernel detected" + ) + else: + status = Status.PASS + msg = ( + f"{len(name_counts)} unique kernels (count gcd={divisor}); " + f"attention kernels={attn_total}" + ) + return QualityResult( + "kernel_counts", "Kernel counts / attention presence", status, msg, metrics + ) + + +def run_pytorch_phase1( + trace: PytorchTrace, thr: Optional[QualityThresholds] = None +) -> List[QualityResult]: + thr = thr or QualityThresholds() + kernels = trace.kernels + results = [ + _check_kernels_present(kernels, thr), + _check_kernels_not_dropped(kernels, thr), + ] + + # Runtime variability grouped by (name, grid, block): GPU kernel events lack + # tensor shapes, but grid/block launch dims disambiguate problem sizes so + # only genuinely identical launches are compared. + groups: Dict[str, List[float]] = defaultdict(list) + for k in kernels: + if k.get("dur") is None: + continue + args = k.get("args") or {} + sig = ( + f"{k.get('name')}|grid={args.get('grid', '')}|block={args.get('block', '')}" + ) + groups[sig].append(float(k["dur"])) + results.append(_check_runtime_variability(groups, thr)) + + results.append(_pytorch_busy_idle(trace, thr)) + results.append( + _check_kernel_counts(Counter(k.get("name", "") for k in kernels), thr) + ) + results.append(_check_cpu_op_shapes(trace, thr)) + results.append(_check_cpu_call_stack(trace, thr)) + return results + + +def _pytorch_busy_idle(trace: PytorchTrace, thr: QualityThresholds) -> QualityResult: + gpu_events = trace.gpu_events + if not gpu_events: + return QualityResult( + "gpu_busy_idle", "GPU busy/idle time", Status.FAIL, "no GPU events", {} + ) + try: + m = dict(GPUEventAnalyser(gpu_events).compute_metrics()) + total = m.get("total_time", 0.0) + m["idle_pct"] = (100.0 * m.get("idle_time", 0.0) / total) if total else 0.0 + except Exception as exc: # noqa: BLE001 - fall back to manual interval merge + m = busy_idle_from_events(gpu_events) + m["fallback_reason"] = f"GPUEventAnalyser failed: {exc}" + return _check_busy_idle(m, thr) + + +def _check_cpu_op_shapes(trace: PytorchTrace, thr: QualityThresholds) -> QualityResult: + cpu_ops = trace.cpu_ops + if not cpu_ops: + return QualityResult( + "cpu_op_shapes", + "CPU ops carry shapes (PyTorch, optional)", + Status.WARN, + "no cpu_op events in trace", + {"num_cpu_ops": 0}, + ) + with_shapes = 0 + for op in cpu_ops: + dims = (op.get("args") or {}).get("Input Dims") + if dims and any(d for d in dims): + with_shapes += 1 + coverage = with_shapes / len(cpu_ops) + num_gpu = len(trace.gpu_events) + cpu_gpu_ratio = (len(cpu_ops) / num_gpu) if num_gpu else float("inf") + metrics = { + "num_cpu_ops": len(cpu_ops), + "cpu_ops_with_shapes": with_shapes, + "shape_coverage": round(coverage, 3), + "num_gpu_events": num_gpu, + "cpu_gpu_ratio": round(cpu_gpu_ratio, 3), + } + msgs = [] + status = Status.PASS + if coverage < thr.shape_coverage_fail: + status = Status.FAIL + msgs.append(f"only {coverage:.0%} of cpu_ops have shapes") + elif coverage < thr.shape_coverage_warn: + status = Status.WARN + msgs.append(f"{coverage:.0%} of cpu_ops have shapes") + else: + msgs.append(f"{coverage:.0%} of cpu_ops have shapes") + if not (thr.cpu_gpu_ratio_min <= cpu_gpu_ratio <= thr.cpu_gpu_ratio_max): + status = max(status, Status.WARN, key=lambda s: s.severity) + msgs.append(f"suspicious CPU:GPU ratio {cpu_gpu_ratio:.2f}") + return QualityResult( + "cpu_op_shapes", + "CPU ops carry shapes (PyTorch, optional)", + status, + "; ".join(msgs), + metrics, + ) + + +def _check_cpu_call_stack(trace: PytorchTrace, thr: QualityThresholds) -> QualityResult: + py_funcs = trace.by_cat.get("python_function", []) + metrics = {"num_python_function_events": len(py_funcs)} + if py_funcs: + status = Status.PASS + msg = f"CPU call stack present ({len(py_funcs)} python_function events)" + else: + status = Status.WARN + msg = "no python_function events (call stack not captured; with_stack=False)" + return QualityResult( + "cpu_call_stack", + "CPU call stack present (PyTorch, optional)", + status, + msg, + metrics, + ) + + +def run_jax_phase1( + trace: JaxJsonTrace, thr: Optional[QualityThresholds] = None +) -> List[QualityResult]: + thr = thr or QualityThresholds() + gpu_events = trace.gpu_events + results = [ + _check_kernels_present(gpu_events, thr), + _check_kernels_not_dropped(gpu_events, thr), + ] + + # Runtime variability grouped by (name, hlo_op). + groups: Dict[str, List[float]] = defaultdict(list) + for e in gpu_events: + if e.get("dur") is None: + continue + hlo = (e.get("args") or {}).get("hlo_op", "") + groups[f"{e.get('name')}|{hlo}"].append(float(e["dur"])) + results.append(_check_runtime_variability(groups, thr)) + + results.append(_jax_busy_idle(trace, thr)) + results.append( + _check_kernel_counts(Counter(e.get("name", "") for e in gpu_events), thr) + ) + results.append(_check_jax_metadata_richness(gpu_events, thr)) + return results + + +def _jax_busy_idle(trace: JaxJsonTrace, thr: QualityThresholds) -> QualityResult: + by_dev = trace.gpu_events_by_device or {"all": trace.gpu_events} + per_dev = {} + worst = None + for dev, evs in by_dev.items(): + m = busy_idle_from_events(evs) + per_dev[dev] = round(m["idle_pct"], 3) + if worst is None or m["idle_pct"] > worst[1]["idle_pct"]: + worst = (dev, m) + if worst is None: + return QualityResult( + "gpu_busy_idle", "GPU busy/idle time", Status.FAIL, "no GPU events", {} + ) + dev, m = worst + m = dict(m) + m["worst_device"] = dev + m["idle_pct_per_device"] = per_dev + result = _check_busy_idle(m, thr) + result.message = f"[{dev}] " + result.message + return result + + +def _check_jax_metadata_richness( + gpu_events: Sequence[dict], thr: QualityThresholds +) -> QualityResult: + """Fraction of GPU events carrying rich HLO metadata.""" + n = len(gpu_events) + if n == 0: + return QualityResult( + "jax_metadata_richness", + "JAX GPU metadata richness (optional)", + Status.FAIL, + "no GPU events", + {}, + ) + fields = ("hlo_op", "hlo_module", "tf_op") + field_counts = {f: 0 for f in fields} + for e in gpu_events: + args = e.get("args") or {} + for f in fields: + if args.get(f): + field_counts[f] += 1 + coverage = {f: round(c / n, 3) for f, c in field_counts.items()} + min_cov = min(coverage.values()) + metrics = {"num_gpu_events": n, "coverage": coverage} + if min_cov < thr.shape_coverage_fail: + status = Status.FAIL + msg = f"sparse HLO metadata (min coverage {min_cov:.0%}): {coverage}" + elif min_cov < thr.shape_coverage_warn: + status = Status.WARN + msg = f"partial HLO metadata (min coverage {min_cov:.0%}): {coverage}" + else: + status = Status.PASS + msg = f"rich HLO metadata: {coverage}" + return QualityResult( + "jax_metadata_richness", + "JAX GPU metadata richness (optional)", + status, + msg, + metrics, + ) + + +# Phase 2 checks (TraceLens perf reports) + +# Map a logical sheet role to the concrete perf-report sheet per framework. +_SHEETS = { + "pytorch": { + "timeline": "gpu_timeline", + "op_summary": "ops_summary", + "op_category": "ops_summary_by_category", + "unique_args": "ops_unique_args", + "count_col": "Count", + "category_col": "op category", + }, + "jax": { + "timeline": "gpu_timeline", + "op_summary": "kernel_launchers_summary", + "op_category": "kernel_launchers_summary_by_category", + "unique_args": "kernel_launchers_unique_args", + "count_col": "Count", + "category_col": "op category", + }, +} + + +def find_megatron_extension() -> Optional[str]: + """Locate the Megatron/TE extension (override via ``TRACE_QUALITY_MEGATRON_EXTENSION``).""" + override = os.environ.get("TRACE_QUALITY_MEGATRON_EXTENSION") + if override and os.path.exists(override): + return override + try: + import TraceLens + + base = os.path.dirname(os.path.dirname(os.path.abspath(TraceLens.__file__))) + candidate = os.path.join(base, "examples", "example_megatron_extension.py") + if os.path.exists(candidate): + return candidate + except Exception: # noqa: BLE001 + pass + return None + + +def generate_report( + path: str, framework: str, output_dir: Optional[str] = None +) -> Dict: + """Generate the TraceLens perf report. PyTorch gets the Megatron extension.""" + out = output_dir or tempfile.mkdtemp(prefix="trace_quality_") + if framework == FRAMEWORK_PYTORCH: + from TraceLens.Reporting.generate_perf_report_pytorch import ( + generate_perf_report_pytorch, + ) + + return generate_perf_report_pytorch( + profile_json_path=path, + output_csvs_dir=out, + collective_analysis=True, + extension_file=find_megatron_extension(), + ) + if framework == FRAMEWORK_JAX: + from TraceLens.Reporting.generate_perf_report_jax import ( + generate_perf_report_jax, + ) + + return generate_perf_report_jax(profile_path=path, output_csvs_dir=out) + raise ValueError(f"unknown framework: {framework}") + + +def _check_report_generated(dfs: Dict, sheets: Dict) -> QualityResult: + present = sorted(dfs.keys()) + expected = {sheets["timeline"], sheets["op_summary"], sheets["unique_args"]} + missing = sorted(expected - set(present)) + metrics = {"sheets": present, "missing_expected": missing} + if missing: + status = Status.FAIL + msg = f"perf report missing expected sheets: {missing}" + else: + status = Status.PASS + msg = f"perf report generated with {len(present)} sheets" + return QualityResult( + "perf_report_generated", "Perf report generated", status, msg, metrics + ) + + +def _check_idle_timeline( + dfs: Dict, sheets: Dict, thr: QualityThresholds +) -> QualityResult: + tl = dfs.get(sheets["timeline"]) + if tl is None or "type" not in getattr(tl, "columns", []): + return QualityResult( + "gpu_idle_timeline", + "GPU idle timeline (perf report)", + Status.SKIP, + "no gpu_timeline sheet", + {}, + ) + idle_rows = tl[tl["type"] == "idle_time"] + if idle_rows.empty: + return QualityResult( + "gpu_idle_timeline", + "GPU idle timeline (perf report)", + Status.SKIP, + "no idle_time row in timeline", + {}, + ) + idle_pct = float(idle_rows["percent"].mean()) + metrics = {"idle_pct": round(idle_pct, 3), "num_devices": int(len(idle_rows))} + if idle_pct >= thr.idle_pct_fail: + status = Status.FAIL + msg = f"GPU idle {idle_pct:.1f}% (>= {thr.idle_pct_fail}%)" + elif idle_pct >= thr.idle_pct_warn: + status = Status.WARN + msg = f"GPU idle {idle_pct:.1f}% (>= {thr.idle_pct_warn}%)" + else: + status = Status.PASS + msg = f"GPU idle {idle_pct:.1f}%" + return QualityResult( + "gpu_idle_timeline", "GPU idle timeline (perf report)", status, msg, metrics + ) + + +def _check_op_count_consistency(dfs: Dict, sheets: Dict) -> QualityResult: + summary = dfs.get(sheets["op_summary"]) + col = sheets["count_col"] + if summary is None or col not in getattr(summary, "columns", []): + return QualityResult( + "op_count_consistency", + "Op-count consistency (perf report)", + Status.SKIP, + "no op-count column available", + {}, + ) + counts = [int(c) for c in summary[col].tolist() if c and int(c) > 0] + if not counts: + return QualityResult( + "op_count_consistency", + "Op-count consistency (perf report)", + Status.WARN, + "no positive op counts", + {}, + ) + divisor = gcd_of_counts(counts) + metrics = { + "num_ops": len(counts), + "count_gcd": divisor, + "min_count": min(counts), + "max_count": max(counts), + } + if divisor > 1: + status = Status.PASS + msg = f"{len(counts)} ops share count gcd={divisor} (consistent per-step multiplicity)" + else: + status = Status.WARN + msg = f"{len(counts)} ops have gcd=1 (no common per-step multiple)" + return QualityResult( + "op_count_consistency", + "Op-count consistency (perf report)", + status, + msg, + metrics, + ) + + +def _check_ops_have_shapes( + dfs: Dict, sheets: Dict, thr: QualityThresholds +) -> QualityResult: + df = dfs.get(sheets["unique_args"]) + if df is None or "Input Dims" not in getattr(df, "columns", []): + return QualityResult( + "ops_have_shapes", + "Ops carry shapes (perf report)", + Status.SKIP, + "no Input Dims column", + {}, + ) + total = len(df) + if total == 0: + return QualityResult( + "ops_have_shapes", + "Ops carry shapes (perf report)", + Status.WARN, + "no ops in unique_args sheet", + {}, + ) + + def _has_shape(v) -> bool: + if v is None: + return False + return str(v).strip() not in ("", "[]", "[[]]", "nan", "None", "()") + + with_shape = int(df["Input Dims"].apply(_has_shape).sum()) + coverage = with_shape / total + metrics = { + "num_ops": total, + "ops_with_shapes": with_shape, + "shape_coverage": round(coverage, 3), + } + if coverage < thr.shape_coverage_fail: + status = Status.FAIL + msg = f"only {coverage:.0%} of ops have shapes" + elif coverage < thr.shape_coverage_warn: + status = Status.WARN + msg = f"{coverage:.0%} of ops have shapes" + else: + status = Status.PASS + msg = f"{coverage:.0%} of ops have shapes" + return QualityResult( + "ops_have_shapes", "Ops carry shapes (perf report)", status, msg, metrics + ) + + +def _check_high_idle_ops( + dfs: Dict, sheets: Dict, thr: QualityThresholds +) -> QualityResult: + """Flag ops with a large gap between subtree wall time and kernel time.""" + df = dfs.get(sheets["unique_args"]) + cols = set(df.columns) if df is not None else set() + need = {"total_subtree_kernel_time_sum", "total_direct_kernel_time_sum"} + if df is None or not need.issubset(cols): + return QualityResult( + "high_idle_ops", + "High-idle ops (perf report)", + Status.SKIP, + "no subtree/direct kernel-time columns to estimate idle", + {}, + ) + offenders = [] + for _, row in df.iterrows(): + subtree = float(row["total_subtree_kernel_time_sum"] or 0) + direct = float(row["total_direct_kernel_time_sum"] or 0) + if subtree <= 0: + continue + gap_pct = 100.0 * max(0.0, subtree - direct) / subtree + if gap_pct >= thr.op_high_idle_pct: + offenders.append({"name": row.get("name"), "gap_pct": round(gap_pct, 1)}) + offenders.sort(key=lambda x: -x["gap_pct"]) + metrics = {"num_high_idle_ops": len(offenders), "top": offenders[:10]} + if offenders: + status = Status.WARN + msg = f"{len(offenders)} op(s) with >= {thr.op_high_idle_pct}% non-kernel time" + else: + status = Status.PASS + msg = "no ops with excessive non-kernel (idle) time" + return QualityResult( + "high_idle_ops", "High-idle ops (perf report)", status, msg, metrics + ) + + +def _check_sdpa_count(dfs: Dict, sheets: Dict, thr: QualityThresholds) -> QualityResult: + """Count SDPA / attention ops across category and dedicated op sheets.""" + counts: Dict[str, int] = {} + cat_df = dfs.get(sheets["op_category"]) + cat_col = sheets["category_col"] + total = 0 + if cat_df is not None and cat_col in getattr(cat_df, "columns", []): + count_col = ( + sheets["count_col"] if sheets["count_col"] in cat_df.columns else None + ) + for _, row in cat_df.iterrows(): + cat = str(row.get(cat_col, "")) + if matches_any(cat, thr.attn_name_patterns): + c = int(row[count_col]) if count_col else 1 + counts[cat] = counts.get(cat, 0) + c + total += c + # Additional signal: dedicated TE / attention op sheets (e.g. JAX op_te). + for sheet_name, df in dfs.items(): + if sheet_name.startswith("op_") and ( + "te" in sheet_name.lower() + or matches_any(sheet_name, thr.attn_name_patterns) + ): + counts[sheet_name] = max(counts.get(sheet_name, 0), len(df)) + metrics = {"attention_breakdown": counts, "total_attention_ops": total} + if total == 0 and not counts: + status = Status.WARN + msg = "no SDPA / attention ops found in perf report" + else: + status = Status.PASS + msg = f"attention ops present: {counts}" + return QualityResult( + "sdpa_count", "SDPA / attention op count (perf report)", status, msg, metrics + ) + + +# Perf-report sheets that hold forward / backward attention kernels. +_ATTN_FWD_SHEETS = ("op_fa_fwd",) +_ATTN_BWD_SHEETS = ("op_fa_bwd",) + + +def _infer_num_gpus(dfs: Dict) -> Optional[int]: + """Number of GPU devices, from the perf-report ``gpu_timeline`` sheet.""" + tl = dfs.get("gpu_timeline") + if tl is None or "gpu_pid" not in getattr(tl, "columns", []): + return None + try: + n = int(tl["gpu_pid"].nunique()) + except Exception: # noqa: BLE001 + return None + return n or None + + +def _attention_observed(dfs: Dict, sheet_names: Sequence[str]) -> Dict[str, Any]: + """Sum observed launches, count unique kernels, and list per-kernel counts.""" + launches = 0 + unique = 0 + found = [] + kernels: List[Dict[str, Any]] = [] + for name in sheet_names: + df = dfs.get(name) + if df is None or "name_count" not in getattr(df, "columns", []): + continue + found.append(name) + unique += int(len(df)) + launches += int(df["name_count"].fillna(0).astype(int).sum()) + names = df["name"] if "name" in df.columns else [None] * len(df) + for kname, kcount in zip(names, df["name_count"].fillna(0).astype(int)): + kernels.append({"name": kname, "count": int(kcount)}) + kernels.sort(key=lambda k: -k["count"]) + return { + "launches": launches, + "unique_kernels": unique, + "sheets": found, + "kernels": kernels, + } + + +def _format_attn_failure( + label: str, + obs: Dict[str, Any], + num_gpus: int, + num_steps: int, + num_layers: int, + calls: int, + expected: int, +) -> str: + """FAIL detail: substituted formula and per-kernel counts.""" + lines = [ + f"\n {label}: expected {expected} != observed {obs['launches']}", + " formula: num_gpus * num_steps * num_layers * calls * unique_kernels", + f" = {num_gpus} * {num_steps} * {num_layers} * {calls} " + f"* {obs['unique_kernels']} = {expected}", + f" observed launches = {obs['launches']} " + f"across {obs['unique_kernels']} unique kernel(s):", + ] + for k in obs["kernels"]: + lines.append(f" - count={k['count']:<8} {k['name']}") + return "\n".join(lines) + + +def _check_attention_kernel_count( + dfs: Dict, + cfg: AttnCountConfig, +) -> QualityResult: + """Sanity-check observed attention launches against the model config. + + expected = num_gpus * num_steps * num_layers * calls * unique_kernels, + computed separately for the forward and backward passes. + """ + check_id = "attention_kernel_count" + name = "Attention kernel count matches config" + + fwd = _attention_observed(dfs, _ATTN_FWD_SHEETS) + bwd = _attention_observed(dfs, _ATTN_BWD_SHEETS) + if not fwd["sheets"] and not bwd["sheets"]: + return QualityResult( + check_id, + name, + Status.SKIP, + "no attention (op_fa_fwd/op_fa_bwd) sheets in perf report", + {}, + ) + + num_gpus = cfg.num_gpus or _infer_num_gpus(dfs) + num_steps = cfg.num_steps + + def _per_pass(obs: Dict[str, Any], calls: int) -> Dict[str, Any]: + info: Dict[str, Any] = { + "observed_launches": obs["launches"], + "unique_kernels": obs["unique_kernels"], + "calls": calls, + "kernels": obs["kernels"], + } + # layers*calls implied by the trace (independent of config). + denom = (num_gpus or 0) * (num_steps or 0) * (obs["unique_kernels"] or 0) + if denom: + info["implied_layers_x_calls"] = round(obs["launches"] / denom, 4) + return info + + metrics: Dict[str, Any] = { + "num_gpus": num_gpus, + "num_steps": num_steps, + "num_layers": cfg.num_layers, + "forward": _per_pass(fwd, cfg.fwd_attn_calls), + "backward": _per_pass(bwd, cfg.bwd_attn_calls), + } + + if not cfg.enabled: + return QualityResult( + check_id, + name, + Status.SKIP, + "num_layers and/or num_steps not provided; reporting observed counts " + f"only (fwd={fwd['launches']}, bwd={bwd['launches']}, " + f"num_gpus={num_gpus})", + metrics, + ) + if not num_gpus: + return QualityResult( + check_id, + name, + Status.SKIP, + "could not infer num_gpus; pass --num-gpus to enable the check", + metrics, + ) + + problems = [] + for label, obs, calls in ( + ("forward", fwd, cfg.fwd_attn_calls), + ("backward", bwd, cfg.bwd_attn_calls), + ): + if not obs["sheets"]: + continue + expected = num_gpus * num_steps * cfg.num_layers * calls * obs["unique_kernels"] + metrics[label]["expected_launches"] = expected + observed = obs["launches"] + tol_abs = cfg.tol * expected + ok = abs(observed - expected) <= tol_abs + if not ok: + problems.append( + _format_attn_failure( + label, obs, num_gpus, num_steps, cfg.num_layers, calls, expected + ) + ) + + if problems: + summary = ( + f"attention launches do not match config " + f"(num_gpus={num_gpus}, num_steps={num_steps}, num_layers={cfg.num_layers})" + ) + return QualityResult( + check_id, name, Status.FAIL, summary + "".join(problems), metrics + ) + return QualityResult( + check_id, + name, + Status.PASS, + f"attention launches match config " + f"(num_gpus={num_gpus}, num_steps={num_steps}, num_layers={cfg.num_layers}; " + f"fwd={fwd['launches']}, bwd={bwd['launches']})", + metrics, + ) + + +def run_phase2( + path: str, + framework: str, + thr: Optional[QualityThresholds] = None, + output_dir: Optional[str] = None, + attn_cfg: Optional[AttnCountConfig] = None, +) -> List[QualityResult]: + thr = thr or QualityThresholds() + sheets = _SHEETS[framework] + try: + dfs = generate_report(path, framework, output_dir=output_dir) + except Exception as exc: # noqa: BLE001 + return [ + QualityResult( + "perf_report_generated", + "Perf report generated", + Status.FAIL, + f"perf report generation failed: {exc}", + {}, + ) + ] + results = [ + _check_report_generated(dfs, sheets), + _check_idle_timeline(dfs, sheets, thr), + _check_op_count_consistency(dfs, sheets), + _check_ops_have_shapes(dfs, sheets, thr), + _check_high_idle_ops(dfs, sheets, thr), + _check_sdpa_count(dfs, sheets, thr), + ] + if framework == FRAMEWORK_JAX: + results.append( + _check_attention_kernel_count(dfs, attn_cfg or AttnCountConfig()) + ) + return results + + +# =========================================================================== +# Runner +# =========================================================================== +def run_quality_checks( + path: str, + framework: str, + phases: Iterable[str] = ("1", "2"), + thresholds: Optional[QualityThresholds] = None, + xplane_pb_path: Optional[str] = None, + output_dir: Optional[str] = None, + attn_cfg: Optional[AttnCountConfig] = None, +) -> QualityReport: + """Run trace quality checks for a single trace. + + Args: + path: Trace path. For phase 1 JAX, the xprof JSON export. + framework: ``"pytorch"`` or ``"jax"``. + phases: Subset of ``{"1", "2"}``. + thresholds: Optional :class:`QualityThresholds` overrides. + xplane_pb_path: For JAX, the ``*.xplane.pb`` used by phase 2; defaults to + ``path`` (PyTorch) or a ``.xplane.pb`` sibling guess (JAX). + output_dir: Optional directory for perf-report CSV output (phase 2). + attn_cfg: Optional model config for the attention-kernel-count check. + """ + framework = framework.lower() + if framework not in VALID_FRAMEWORKS: + raise ValueError( + f"framework must be one of {VALID_FRAMEWORKS}, got {framework!r}" + ) + thr = thresholds or QualityThresholds() + phases = {str(p) for p in phases} + report = QualityReport(trace_path=path, framework=framework) + + if "1" in phases: + try: + if framework == FRAMEWORK_PYTORCH: + report.extend(run_pytorch_phase1(load_pytorch(path), thr)) + else: + report.extend(run_jax_phase1(load_jax_json(path), thr)) + except Exception as exc: # noqa: BLE001 + report.add( + QualityResult( + "phase1_load", + "Phase 1 load/parse", + Status.FAIL, + f"failed to load/parse trace for phase 1: {exc}", + {}, + ) + ) + + if "2" in phases: + p2_path = xplane_pb_path or _default_xplane_pb_path(path, framework) + report.extend( + run_phase2( + p2_path, + framework, + thr, + output_dir=output_dir, + attn_cfg=attn_cfg, + ) + ) + + return report + + +def _default_xplane_pb_path(path: str, framework: str) -> str: + if framework == FRAMEWORK_JAX and not path.endswith(".xplane.pb"): + for suffix in (".trace.json.gz", ".trace.json", ".json.gz", ".json"): + if path.endswith(suffix): + return path[: -len(suffix)] + ".xplane.pb" + return path + + +# =========================================================================== +# CLI +# =========================================================================== +def _build_parser() -> argparse.ArgumentParser: + p = argparse.ArgumentParser( + prog="trace_quality.py", + description="Check the quality of a PyTorch or JAX profiler trace.", + ) + p.add_argument( + "trace", + nargs="?", + default=None, + help="Path to the trace file (can also be passed via --json_trace)", + ) + p.add_argument( + "--json_trace", + default=None, + help="Path to the trace file (alternative to the positional argument)", + ) + p.add_argument( + "--framework", + required=True, + choices=VALID_FRAMEWORKS, + help="Trace framework (explicit; not auto-detected)", + ) + p.add_argument( + "--phase", + default="all", + choices=["1", "2", "all"], + help="Which phase(s) of checks to run (default: all)", + ) + p.add_argument( + "--xplane-pb-path", + default=None, + help="JAX only: path to the .xplane.pb used for phase 2 perf report", + ) + p.add_argument( + "--output-dir", + default=None, + help="Directory to write perf-report CSVs (phase 2)", + ) + p.add_argument("--json", default=None, help="Write the full report as JSON here") + + attn = p.add_argument_group( + "attention kernel count (JAX phase 2)", + "Sanity-check observed attention launches against the model config: " + "expected = num_gpus * num_steps * num_layers * calls * unique_kernels " + "(forward and backward computed separately). num_gpus and the " + "unique-kernel counts are inferred from the trace; --num-layers and " + "--num-steps are both required to enable the check (else it SKIPs and " + "just reports counts).", + ) + attn.add_argument( + "--num-layers", + type=int, + default=None, + help="Number of transformer/attention layers (required to enable the check)", + ) + attn.add_argument( + "--num-steps", + type=int, + default=None, + help="Training steps in the trace (required to enable the check)", + ) + attn.add_argument( + "--num-gpus", + type=int, + default=None, + help="Number of GPUs (default: inferred from the trace)", + ) + attn.add_argument( + "--fwd-attn-calls", + type=int, + default=1, + help="Attention invocations per layer in the forward pass (default: 1; " + "use 2 when forward attention is recomputed during backward)", + ) + attn.add_argument( + "--bwd-attn-calls", + type=int, + default=1, + help="Attention invocations per layer in the backward pass (default: 1)", + ) + attn.add_argument( + "--attn-count-tol", + type=float, + default=0.0, + help="Relative tolerance for the attention-count comparison (default: 0.0)", + ) + return p + + +def main(argv=None) -> int: + parser = _build_parser() + args = parser.parse_args(argv) + trace_path = args.trace or args.json_trace + if not trace_path: + parser.error("a trace path is required (positional argument or --json_trace)") + phases = ("1", "2") if args.phase == "all" else (args.phase,) + + attn_cfg = AttnCountConfig( + num_layers=args.num_layers, + num_steps=args.num_steps, + num_gpus=args.num_gpus, + fwd_attn_calls=args.fwd_attn_calls, + bwd_attn_calls=args.bwd_attn_calls, + tol=args.attn_count_tol, + ) + + report = run_quality_checks( + path=trace_path, + framework=args.framework, + phases=phases, + thresholds=QualityThresholds(), + xplane_pb_path=args.xplane_pb_path, + output_dir=args.output_dir, + attn_cfg=attn_cfg, + ) + + print(report) + + if args.json: + with open(args.json, "w", encoding="utf-8") as f: + json.dump(report.to_dict(), f, indent=2) + print(f"\nWrote JSON report to {args.json}") + + # Non-zero exit when any check FAILed, so CI can gate on it. + return 1 if report.worst_status is Status.FAIL else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tests/test_inference_perf_report.py b/tests/test_inference_perf_report.py index b26853e49..6af52ce29 100644 --- a/tests/test_inference_perf_report.py +++ b/tests/test_inference_perf_report.py @@ -24,6 +24,7 @@ generate_perf_report_pytorch, classify_graph_capture_trace, ) +import TraceLens.Trace2Tree.trace_capture_merge_experimental as _merge_mod from TraceLens.Trace2Tree.trace_capture_merge_experimental import ( merge_capture_trace_into_graph, ) @@ -207,6 +208,15 @@ def find_inference_test_cases(): # --------------------------------------------------------------------------- +@pytest.fixture(autouse=True) +def _clear_capture_tree_cache(): + # Reproduce per-process isolation: the capture-tree cache is keyed by + # {batch_size}_{mode}, which collides across fixtures sharing a key. + _merge_mod._capture_tree_cache.clear() + yield + _merge_mod._capture_tree_cache.clear() + + @pytest.mark.parametrize( "dirpath,trace_gz,capture_folder,gpu_arch_path", find_inference_test_cases(), diff --git a/tests/traces/inference/sglang_decode/capture_traces/bs_32_rank0.json.gz b/tests/traces/inference/sglang_decode/capture_traces/bs_32_rank0.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..184c82b6dc39bdd84e01991306fa131c226c1349 GIT binary patch literal 1217245 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
Qol9% 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�FGXDrKVqwy>fETe4O4CvR^<5xuR&+G@ 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

T@CD#xTt@(#G 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

{k5&sU)j6 z=>amJ-)PpvU$Vuf+}OC|WP&HL$dQniSh5?mEr6iJ{y24)GoZT$wXF802!c!CAwxo@ zC~B))86M_d6n3tEHPD5aki_dUhKOn_HawTpigGqZGeNH9F6v729jZ7xeB~k$bVV5B`ZUWUFlK z>zKpyWa-$3k*QyTR8#iPVgf*5@&bsqs*EeNJ2X`jdYLho@ey}*@va}z$B1bqA4=8_ ziED{__W36*X&qROoT-&cTU#H*zF0?%vvdC%G(@a?ts8*9KM}_bZhJ;9Dg|NL3;ZD9 zDHRJ5K?e^Vk<#ty*GlCu+(EwN-Uq_!yMj{mT{d;xE{SZ&pczyp;mS7@9a|FbhQ|Uc zmg!4AAtu0X$x$SaW9F82JZ^jhj@E?QU)`PK;zSa=uo?5(|6hCB%&Abf?-TLNq($e$ z!lH=nCha%>siX^1ECvj}HoN!XF|ANWy8ha5q7Q5XE10wFq%tKR>T0idOaFijMkC7< zp1XG)R#!8yABfBD%DhV_&mB!7Y9y}&H)HrSw|4yE!div0V$M6yiSB&veO8YZ^{cRhqx&7`r|*sXPo z$!@ilsi&1N`TzCOA5^n3J*i}^h6kMx!y|Df8>^#Gcu=}ND4S1M+@5iwR7^7N z-qR4Q`ztVFac5;M;j0}IV0p_9m~dA|&XF2~TaKAr*wh2s_iOFmGVA)StM|u>^cfR& zIyA>fS2DIO>@NDV--SsDDxv~pAB)lNh(j=4m<0+38}?n;iCShLbvs(`b≰D-bZn8a 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 A@7fW#_{?u&f|s@ErQNX>slVY;k9iJ0#>U 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⋙IXn@XORBb~%dPQs(1v zOBP#>7`|iV-ZCvq&Xk^Ka=gq)IL|Y2$dH*M9RC6CUTv07Tb-~Q_LU$y_|euz4N-q) zI~YrzpN(2``iiKX{4Ne zin;T_*_%JmgG{+{>sIE^D#2eBGG$VRq-&oGig9=8U8CgJoC-P*Q+GuE=E)-aJVDfZ z#sWXUy!+-K<2|3Tafz74@$p0|ZleNGJPO7dw$V$8n0X9}K2Ie%XKD9?iX{fq@LaC& zAF9g?r=DXI;xuQ0(&RaIV~moRR%T|MHAYu*1yVG9xx8cYk}-1_6s?~ybw+Bn6msp= z8Oxfrw&Jer8h*Ct{h(P8rK6P9D)!18MKm)Xjt~DR+VJn+%-J>e?u+n!m0Aj^N~T^7 ziMZSm;J;cm*jbNX>{|qi5sLS$-8=BMRWe2XYCb6+aj1T53YKHSo zBBRG7zLoPz2@GMC!m`R?tFcmclJp7SJH}%2IzPp$3f)qiFD2vnH0{up{3J27s8)2r zz$FcQM%|2}hX44CysAwtTBX>=CWm0E$~O3uBbC1263ZXFT( z)Z74KXfHv0MiwFsXCR!-@@1Ky;6H%@)Pc}^vT0MP9^4$hUqWWOYK7*V)~&&zP+$ht z*)xMo_n7`T`D*7rSBJGVwcA;!67)QD9o{OVgVGC|2h?f9YyoQMJYWQLm;8to_MsUVU@~kKfvdr80=uc`evIWd&g4eHUHl;R>h&oMuk4zL(n}E7{ z391-#dR?B}y%6>^oj*0%V}}wROK1jfa;m>fkC__hda*ujqgPy{--BEBXZfVfnyyEX z8~zKRRNI%R^3hWUahU-#X!qBm5u0A0&T4o_Lq>iA;=k^h7b0vN=Vu!h`%`UcZ0nw1DQ5yxeKQ(TIM-@YG8#AHg3kzEvmJ*&p1 z+423m73q~97fA#$^E*%{qU<2_RpyU91O`|mR3tavR{fm{X-MPj7&SBKkp^OUKmt9F zuD`1mh^|aa^3jjPwL-75K(_n7_A$}zS#oJG1Z2qNT)Xv;$-ct0w)XARAn^A9UGXvap7V)q@!}4TFbXfqbd4A2aV`C zG%#j!SO$5G_b6j(Umd|qqgSN+=m)VPdZA0~2c6*eEd>YF!{-)dB^qJ7yunY#_|5^! z)=tQjcD<}9{m8OOh%r>Ij#fy^W}4vo7>+Mw8>&4v{SZuWcN9&xZ<#K<;~_K|LTzH( zT`#SUdXvq8I{RnSku8~kA~-32kzWmK5dM_UO%bxp{W2`RZt6v5PHik`!`1_4v_-)= z8QG$S8@z@&7X%(c9hY>jUW*(y<0*;sg1vyO9wgE>#KUR732B9Fw~V2<_z)_}=Ytb) zuXf{zwe$Ae&`{V_(xJjMl|WvM9jgWfvJ!Ig+(EoAx$G_FS}#jgI}(% zU?Jl0w{P~}i(z-uoEU=hi|y376Y@h%a$ZJ>S*LR$p^@{Y!UPKrXcu{$VIQi6@szCH z+HJ9L%)fp8`DmDS*LZ6vuGPihutB>}(G2@il@PS=zq<$Arx7@oo3~)?QVrhO*OvWP z+ifvcyF;VhxLuIb$_bp;(Hi3G;Jd+_od09{-R(7an3hG_JP)}+j~H-McXr89{8wI>216aT@7O6xPfqL6MwFd4pfF zRI8nP+9Sq)UtG0a9c{B;x>@TnEQc{u@?7eV% zXihu%D3(955UvOaWC$GV3S3!1*|VPNjHiVTw2Yhc{cUzNNPnYe#Y?OxtR^ytPl8Tn zu57$qhBhsK{bVP)a@rf7GL!rg9z2IT9Zv8uqC6YZiwsRZ-@Q6ay0*PI`V3~q{Yoka zdp`kH(dETsf9y|OQj656Gw@&z1*`==q6@%KeCSN~14*sPUU7d@J&?dk;QK}-#RsGe zKft>GHEpkwQm{Fb8_>&$rX7gkrJxpf>)EZ44~@aDD+L8z0elmK)NhV1W(7Yoj-McJ z^@j6R@k}Mf<(^^lU^Rdg*#jaJ*Jf#;F3kfV>!Fv%Qlo^w5gHk!*aRprXcQN+1E6^* zkZ8uhtoR3KDK;e`@WC*RzC?MJ>{oQK@cH=WrN6r<6%0A>?D1YBOh1+z^2 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 z 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

d0s10ItYGVqS&s?ssJ0w4?m%$m2L&Ln^8?z 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 $wkD3`OWZ?mcN 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%0Ag%0JCDkj^Jn_J%cO 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 B#G(KI literal 0 HcmV?d00001 diff --git a/tests/traces/inference/sglang_decode/capture_traces/execution_details.json b/tests/traces/inference/sglang_decode/capture_traces/execution_details.json new file mode 100644 index 000000000..34f91c16a --- /dev/null +++ b/tests/traces/inference/sglang_decode/capture_traces/execution_details.json @@ -0,0 +1,7 @@ +[ + { + "file": "bs_32_rank0.json.gz", + "batch_size": 32, + "mode": "FULL" + } +] \ No newline at end of file diff --git a/tests/traces/inference/sglang_decode/perf_csvs/GEMM.csv b/tests/traces/inference/sglang_decode/perf_csvs/GEMM.csv new file mode 100644 index 000000000..5f769439f --- /dev/null +++ b/tests/traces/inference/sglang_decode/perf_csvs/GEMM.csv @@ -0,0 +1,10 @@ +name,param: B,param: M,param: N,param: K,param: bias,param: dtype_A_B,param: transpose,param: stride_A,param: stride_B,num_kernels,GFLOPS_first,Data Moved (MB)_first,FLOPS/Byte_first,TB/s_mean,TB/s_median,TB/s_std,TB/s_min,TB/s_max,TFLOPS/s_mean,TFLOPS/s_median,TFLOPS/s_std,TFLOPS/s_min,TFLOPS/s_max,process_name_first,process_label_first,thread_name_first,Compute Spec,kernel_details__summarize_kernel_stats,trunc_kernel_details,Input Dims_first,Input type_first,Input Strides_first,Concrete Inputs_first,Kernel Time (µs)_mean,Kernel Time (µs)_median,Kernel Time (µs)_std,Kernel Time (µs)_min,Kernel Time (µs)_max,Kernel Time (µs)_sum,name_count,UID_first +aiter::gemm_a16w16,1,32,24576,4096,False,"('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16')","(True, False)",nan,nan,1,6.442450944,193.75,31.710967741935484,3.0281005673551444,3.0523747073479246,0.09384870781134186,2.759264130723115,3.1382935344697542,96.02399941073553,96.7937558810098,2.9760333460278057,87.49893584084036,99.51832503629507,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x32x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB256_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB2_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(2417.659), 'mean_duration_us': np.float64(67.15719444444444), 'median_duration_us': np.float64(66.55850000000001), 'std_dev_duration_us': np.float64(2.1321042529681073), 'min_duration_us': np.float64(64.736), 'max_duration_us': np.float64(73.629)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x32x64_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(67.16)}]","[[32, 4096], [24576, 4096], [], [], [], [], []]","['c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '']","[[4096, 1], [4096, 1], [], [], [], [], []]","['', '', '', '15', '', '', '']",67.15719943576389,66.55859375,2.162312900832966,64.736328125,73.62890625,2417.6591796875,36,3603 +aten::mm,1,32,24576,4096,False,"('c10::BFloat16', 'c10::BFloat16')","(True, False)","(4096, 1)","(1, 4096)",1,6.442450944,193.75,31.710967741935484,3.0281005673551444,3.0523747073479246,0.09384870781134186,2.759264130723115,3.1382935344697542,96.02399941073553,96.7937558810098,2.9760333460278057,87.49893584084036,99.51832503629507,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x32x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB256_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB2_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(2417.659), 'mean_duration_us': np.float64(67.15719444444444), 'median_duration_us': np.float64(66.55850000000001), 'std_dev_duration_us': np.float64(2.1321042529681073), 'min_duration_us': np.float64(64.736), 'max_duration_us': np.float64(73.629)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x32x64_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(67.16)}]","[[32, 4096], [4096, 24576]]","['c10::BFloat16', 'c10::BFloat16']","[[4096, 1], [1, 4096]]","['', '']",67.15719943576389,66.55859375,2.162312900832966,64.736328125,73.62890625,2417.6591796875,36,3618 +aiter::gemm_a16w16,1,32,4096,12288,False,"('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16')","(True, False)",nan,nan,1,3.221225472,97.0,31.670103092783506,2.5179118357004993,2.48711682149981,0.18476128484204382,2.1481037191766696,2.7963528144767222,79.74252741517458,78.76724614069502,5.851408938502671,68.03066624031679,88.56078191827311,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT32x32x256_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA1024_LBSPPB1024_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT2_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW2_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO1_USL1_UIOFGRO0_USFGROn1_VSn1_VWA2_VWB2_WSGRA0_WSGRB0_WS64_WG16_4_4', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(1461.9070000000002), 'mean_duration_us': np.float64(40.60852777777778), 'median_duration_us': np.float64(40.8995), 'std_dev_duration_us': np.float64(2.950849194969241), 'min_duration_us': np.float64(36.373), 'max_duration_us': np.float64(47.35)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT32x32x256_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(40.61)}]","[[32, 12288], [4096, 12288], [], [], [], [], []]","['c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '']","[[12288, 1], [12288, 1], [], [], [], [], []]","['', '', '', '15', '', '', '']",40.608425564236114,40.8994140625,2.9926972240857443,36.373046875,47.349609375,1461.9033203125,36,3698 +aten::mm,1,32,4096,12288,False,"('c10::BFloat16', 'c10::BFloat16')","(True, False)","(12288, 1)","(1, 12288)",1,3.221225472,97.0,31.670103092783506,2.5179118357004993,2.48711682149981,0.18476128484204382,2.1481037191766696,2.7963528144767222,79.74252741517458,78.76724614069502,5.851408938502671,68.03066624031679,88.56078191827311,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT32x32x256_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA1024_LBSPPB1024_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT2_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW2_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO1_USL1_UIOFGRO0_USFGROn1_VSn1_VWA2_VWB2_WSGRA0_WSGRB0_WS64_WG16_4_4', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(1461.9070000000002), 'mean_duration_us': np.float64(40.60852777777778), 'median_duration_us': np.float64(40.8995), 'std_dev_duration_us': np.float64(2.950849194969241), 'min_duration_us': np.float64(36.373), 'max_duration_us': np.float64(47.35)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT32x32x256_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(40.61)}]","[[32, 12288], [12288, 4096]]","['c10::BFloat16', 'c10::BFloat16']","[[12288, 1], [1, 12288]]","['', '']",40.608425564236114,40.8994140625,2.9926972240857443,36.373046875,47.349609375,1461.9033203125,36,3713 +aiter::gemm_a16w16,1,32,6144,4096,False,"('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16')","(True, False)",nan,nan,1,1.610612736,48.625,31.588688946015424,2.3118616016609934,2.401485497079251,0.3492055932142782,0.34269780634320524,2.461955778375065,73.02867702110615,75.8597783756037,11.030946862254629,10.825374407057343,77.76995528193521,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT64x32x256_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA2048_LBSPPB1024_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB2_WSGRA0_WSGRB0_WS64_WG16_4_4', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(903.515), 'mean_duration_us': np.float64(25.097638888888888), 'median_duration_us': np.float64(21.231), 'std_dev_duration_us': np.float64(20.9245116153716), 'min_duration_us': np.float64(20.71), 'max_duration_us': np.float64(148.781)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT64x32x256_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(25.1)}]","[[32, 4096], [6144, 4096], [], [], [], [], []]","['c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '']","[[4096, 1], [4096, 1], [], [], [], [], []]","['', '', '', '15', '', '', '']",25.097737630208332,21.2314453125,21.22134930970088,20.7099609375,148.78125,903.5185546875,36,2306 +aten::mm,1,32,6144,4096,False,"('c10::BFloat16', 'c10::BFloat16')","(True, False)","(4096, 1)","(1, 4096)",1,1.610612736,48.625,31.588688946015424,2.3118616016609934,2.401485497079251,0.3492055932142782,0.34269780634320524,2.461955778375065,73.02867702110615,75.8597783756037,11.030946862254629,10.825374407057343,77.76995528193521,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT64x32x256_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA2048_LBSPPB1024_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB2_WSGRA0_WSGRB0_WS64_WG16_4_4', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(903.515), 'mean_duration_us': np.float64(25.097638888888888), 'median_duration_us': np.float64(21.231), 'std_dev_duration_us': np.float64(20.9245116153716), 'min_duration_us': np.float64(20.71), 'max_duration_us': np.float64(148.781)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT64x32x256_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(25.1)}]","[[32, 4096], [4096, 6144]]","['c10::BFloat16', 'c10::BFloat16']","[[4096, 1], [1, 4096]]","['', '']",25.097737630208332,21.2314453125,21.22134930970088,20.7099609375,148.78125,903.5185546875,36,2321 +aiter::gemm_a16w16,1,32,4096,4096,False,"('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16')","(True, False)",nan,nan,1,1.073741824,32.5,31.50769230769231,2.045055758676163,2.0135627422757225,0.13064427853186372,1.7048516918266645,2.2566353647180546,64.4349875964428,63.44271532585662,4.116299729742416,53.71594253632322,71.10137272219347,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT16x32x512_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA1024_LBSPPB2048_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT1_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW1_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA1_VWB2_WSGRA0_WSGRB0_WS64_WG16_4_4', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(602.3440000000002), 'mean_duration_us': np.float64(16.731777777777783), 'median_duration_us': np.float64(16.924500000000002), 'std_dev_duration_us': np.float64(1.079763299964681), 'min_duration_us': np.float64(15.102), 'max_duration_us': np.float64(19.989)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT16x32x512_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(16.73)}]","[[32, 4096], [4096, 4096], [], [], [], [], []]","['c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '']","[[4096, 1], [4096, 1], [], [], [], [], []]","['', '', '', '15', '', '', '']",16.731689453125,16.9248046875,1.0951818785939924,15.1015625,19.9892578125,602.3408203125,36,3402 +aten::mm,1,32,4096,4096,False,"('c10::BFloat16', 'c10::BFloat16')","(True, False)","(4096, 1)","(1, 4096)",1,1.073741824,32.5,31.50769230769231,2.045055758676163,2.0135627422757225,0.13064427853186372,1.7048516918266645,2.2566353647180546,64.4349875964428,63.44271532585662,4.116299729742416,53.71594253632322,71.10137272219347,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT16x32x512_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA1024_LBSPPB2048_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT1_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW1_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA1_VWB2_WSGRA0_WSGRB0_WS64_WG16_4_4', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(602.3440000000002), 'mean_duration_us': np.float64(16.731777777777783), 'median_duration_us': np.float64(16.924500000000002), 'std_dev_duration_us': np.float64(1.079763299964681), 'min_duration_us': np.float64(15.102), 'max_duration_us': np.float64(19.989)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT16x32x512_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(16.73)}]","[[32, 4096], [4096, 4096]]","['c10::BFloat16', 'c10::BFloat16']","[[4096, 1], [1, 4096]]","['', '']",16.731689453125,16.9248046875,1.0951818785939924,15.1015625,19.9892578125,602.3408203125,36,3417 +aten::mm,1,32,151936,4096,False,"('c10::BFloat16', 'c10::BFloat16')","(True, False)","(4096, 1)","(1, 4096)",1,39.829110784,1196.5234375,31.745303777219156,3.161654456289559,3.161654456289559,,3.161654456289559,3.161654456289559,100.36768115351072,100.36768115351072,,100.36768115351072,100.36768115351072,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x48x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB4_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB128_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_3_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB1_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(396.832), 'mean_duration_us': np.float64(396.832), 'median_duration_us': np.float64(396.832), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(396.832), 'max_duration_us': np.float64(396.832)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x48x64_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(396.83)}]","[[32, 4096], [4096, 151936]]","['c10::BFloat16', 'c10::BFloat16']","[[4096, 1], [1, 4096]]","['', '']",396.83203125,396.83203125,,396.83203125,396.83203125,396.83203125,1,60441 diff --git a/tests/traces/inference/sglang_decode/perf_csvs/InferenceAttention_fwd.csv b/tests/traces/inference/sglang_decode/perf_csvs/InferenceAttention_fwd.csv new file mode 100644 index 000000000..0ccba759a --- /dev/null +++ b/tests/traces/inference/sglang_decode/perf_csvs/InferenceAttention_fwd.csv @@ -0,0 +1,3 @@ +name,param: op_shape,param: nelems,param: dtype,param: B,param: N_Q,param: H_Q,param: H_V,param: H_K,param: N_KV,param: H_KV,param: d_h_qk,param: d_h_v,param: dropout,param: causal,param: flash_impl,param: c_sq,param: c_sk,param: c_sqsq,param: c_sqsk,param: g_sq,param: g_sk,param: g_sqsq,param: g_sqsk,param: dtype_Q,num_kernels,GFLOPS_first,Data Moved (MB)_first,FLOPS/Byte_first,TB/s_mean,TB/s_median,TB/s_std,TB/s_min,TB/s_max,TFLOPS/s_mean,TFLOPS/s_median,TFLOPS/s_std,TFLOPS/s_min,TFLOPS/s_max,process_name_first,process_label_first,thread_name_first,Compute Spec,kernel_details__summarize_kernel_stats,trunc_kernel_details,Input Dims_first,Input type_first,Input Strides_first,Concrete Inputs_first,Kernel Time (µs)_mean,Kernel Time (µs)_median,Kernel Time (µs)_std,Kernel Time (µs)_min,Kernel Time (µs)_max,Kernel Time (µs)_sum,name_count,UID_first +sglang_profiler::attention_paged_attention_ragged,nan,nan,nan,1.0,32.0,32.0,8.0,8.0,32785.0,8.0,128.0,128.0,0.0,False,True,0.0,0.0,0.0,0.0,32.0,32785.0,32.0,32785.0,c10::BFloat16,2,0.53714944,128.56640625,3.9844438367818187,2.283041251375341,2.29091646674352,0.07122734658138916,2.055832961801367,2.3901781209225015,9.096649643161127,9.128027996498199,0.28380136209653906,8.191350974102368,9.523530482720409,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'void paged_attention_ll4mi_reduce_kernel<__hip_bfloat16, __hip_bfloat16, 128, 128, 256, 3, false>(__hip_bfloat16*, float const*, float const*, __hip_bfloat16 const*, int const*, int const*, int, int, float const*)', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(178.31300000000002), 'mean_duration_us': np.float64(4.95313888888889), 'median_duration_us': np.float64(4.926), 'std_dev_duration_us': np.float64(0.2737306211078672), 'min_duration_us': np.float64(4.526), 'max_duration_us': np.float64(5.848)}, {'name': 'void paged_attention_ll4mi_QKV_mfma16_kernel<0, __hip_bfloat16, __hip_bfloat16, (vllm::Fp8KVCacheDataType)0, 1, 128, 256, false, 4, 1, ck_tile::ComposedAttention<0u, false> >(__hip_bfloat16 const*, __hip_bfloat16 const*, __hip_bfloat16 const*, float, int const*, int const*, int const*, float const*, int, int, int, int, float*, float*, __hip_bfloat16*, float, float, float const*, float const*, float const*, ck_tile::ComposedAttention<0u, false> const*)', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(1949.556), 'mean_duration_us': np.float64(54.154333333333334), 'median_duration_us': np.float64(53.9595), 'std_dev_duration_us': np.float64(1.6962556804129898), 'min_duration_us': np.float64(51.596), 'max_duration_us': np.float64(59.728)}]","[{'name': 'void paged_attention_ll4mi_reduce_kernel<__hip_bfloat16, __hip_b...', 'stream': 3, 'mean_duration_us': np.float64(4.95)}, {'name': 'void paged_attention_ll4mi_QKV_mfma16_kernel<0, __hip_bfloat16, ...', 'stream': 3, 'mean_duration_us': np.float64(54.15)}]","[[32, 32, 128], [10905190400], [32, 32, 128], [835874, 1, 8, 128], [835874, 1, 8, 128], [33], [20971520], [4096], [], [1], [1], []]","['c10::BFloat16', 'unsigned char', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'int', 'int', 'int', '', 'float', 'float', '']","[[4096, 128, 1], [1], [4096, 128, 1], [1024, 1024, 128, 1], [1024, 1024, 128, 1], [1], [1], [1], [], [1], [1], []]","['', '', '', '', '', '', '', '', '', '', '', '']",59.10731336805556,58.84619140625,1.9199264842925137,56.40234375,65.5751953125,2127.86328125,36,3205 +sglang::store_cache,"(32, 1024)",32768.0,c10::BFloat16,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,1,0.0,0.25,0.0,0.05458750456658629,0.05594736473530638,0.003229331743270655,0.045137961325037834,0.05895793015594114,0.0,0.0,0.0,0.0,0.0,Unknown,Unknown,Unknown,vector_bf16,"[{'name': 'void (anonymous namespace)::store_kvcache<2048l, 4, false, long>((anonymous namespace)::StoreKVCacheParams)', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(173.545), 'mean_duration_us': np.float64(4.820694444444444), 'median_duration_us': np.float64(4.686), 'std_dev_duration_us': np.float64(0.31601018087014254), 'min_duration_us': np.float64(4.446), 'max_duration_us': np.float64(5.808)}]","[{'name': 'void (anonymous namespace)::store_kvcache<2048l, 4, false, long>...', 'stream': 3, 'mean_duration_us': np.float64(4.82)}]","[[32, 1024], [32, 1024], [835874, 1024], [835874, 1024], [32], [], []]","['c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'long int', 'Scalar', 'Scalar']","[[1024, 1], [6144, 1], [1024, 1], [1024, 1], [1], [], []]","['', '', '', '', '', '2048', '0']",4.820638020833333,4.685546875,0.3202933594836537,4.4462890625,5.8076171875,173.54296875,36,2982 diff --git a/tests/traces/inference/sglang_decode/perf_csvs/RMSNorm_fwd.csv b/tests/traces/inference/sglang_decode/perf_csvs/RMSNorm_fwd.csv new file mode 100644 index 000000000..e33ab0b86 --- /dev/null +++ b/tests/traces/inference/sglang_decode/perf_csvs/RMSNorm_fwd.csv @@ -0,0 +1,5 @@ +name,param: op_shape,param: dtype_in_out,param: stride_input,param: stride_output,param: num_channels,param: has_bias,param: is_affine,param: is_training,num_kernels,GFLOPS_first,Data Moved (MB)_first,FLOPS/Byte_first,TB/s_mean,TB/s_median,TB/s_std,TB/s_min,TB/s_max,TFLOPS/s_mean,TFLOPS/s_median,TFLOPS/s_std,TFLOPS/s_min,TFLOPS/s_max,process_name_first,process_label_first,thread_name_first,Compute Spec,kernel_details__summarize_kernel_stats,trunc_kernel_details,Input Dims_first,Input type_first,Input Strides_first,Concrete Inputs_first,Kernel Time (µs)_mean,Kernel Time (µs)_median,Kernel Time (µs)_std,Kernel Time (µs)_min,Kernel Time (µs)_max,Kernel Time (µs)_sum,name_count,UID_first +aiter::add_rmsnorm,"(32, 4096)","('c10::BFloat16', None)","(4096, 1)",None,4096,False,True,False,1,0.000655424,1.0078125,0.6202156007751938,0.22039436068874996,0.2236268716676999,0.013737918655783806,0.15077754382053782,0.2398338723404255,0.1366920208220378,0.1386968745608597,0.008520471472497716,0.09351458492406298,0.14874870921985814,Unknown,Unknown,Unknown,vector_bf16,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb1ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 72, 'total_duration_us': np.float64(346.84399999999994), 'mean_duration_us': np.float64(4.817277777777777), 'median_duration_us': np.float64(4.726), 'std_dev_duration_us': np.float64(0.36565459651236065), 'min_duration_us': np.float64(4.406), 'max_duration_us': np.float64(7.009)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb1ELb0...', 'stream': 3, 'mean_duration_us': np.float64(4.82)}]","[[32, 4096], [32, 4096], [32, 4096], [32, 4096], [4096], []]","['c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar']","[[4096, 1], [4096, 1], [4096, 1], [4096, 1], [1], []]","['', '', '', '', '', '9.9999999999999995e-07']",4.817247178819445,4.7255859375,0.36813716584561973,4.40625,7.0087890625,346.841796875,72,3557 +aiter::rmsnorm,"(256, 128)","('c10::BFloat16', None)","(128, 1)",None,128,False,True,False,1,0.000131584,0.125244140625,1.0019493177387915,0.02859908185566152,0.029017126672840253,0.0017242386549007672,0.02293312960436562,0.030363484307970198,0.028654830553235908,0.02907369027259238,0.001727599743896673,0.022977833560709413,0.03042267238654324,Unknown,Unknown,Unknown,vector_bf16,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(165.97099999999998), 'mean_duration_us': np.float64(4.610305555555555), 'median_duration_us': np.float64(4.5255), 'std_dev_duration_us': np.float64(0.31204271604349704), 'min_duration_us': np.float64(4.325), 'max_duration_us': np.float64(5.727)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0EL...', 'stream': 3, 'mean_duration_us': np.float64(4.61)}]","[[256, 128], [256, 128], [128], []]","['c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar']","[[128, 1], [128, 1], [1], []]","['', '', '', '9.9999999999999995e-07']",4.610514322916667,4.52587890625,0.3163628873091587,4.3251953125,5.7265625,165.978515625,36,2753 +aiter::rmsnorm,"(1024, 128)","('c10::BFloat16', None)","(128, 1)",None,128,False,True,False,1,0.000526336,0.500244140625,1.0034163006344559,0.11448449128883594,0.11640343635274938,0.00615180258908413,0.0955922861719167,0.12127637299616166,0.11487560472906136,0.11680110548621413,0.0061728189961722645,0.09591885815981491,0.12169068954617296,Unknown,Unknown,Unknown,vector_bf16,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(165.44999999999996), 'mean_duration_us': np.float64(4.595833333333332), 'median_duration_us': np.float64(4.506), 'std_dev_duration_us': np.float64(0.26861222566699716), 'min_duration_us': np.float64(4.325), 'max_duration_us': np.float64(5.487)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0EL...', 'stream': 3, 'mean_duration_us': np.float64(4.6)}]","[[1024, 128], [1024, 128], [128], []]","['c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar']","[[128, 1], [128, 1], [1], []]","['', '', '', '9.9999999999999995e-07']",4.595974392361111,4.50634765625,0.2723561217428755,4.3251953125,5.4873046875,165.455078125,36,2594 +aiter::rmsnorm,"(32, 4096)","('c10::BFloat16', None)","(4096, 1)",None,4096,False,True,False,1,0.000524352,0.5078125,0.9847355769230769,0.09360678454935621,0.09360678454935621,,0.09360678454935621,0.09360678454935621,0.09217793098712446,0.09217793098712446,,0.09217793098712446,0.09217793098712446,Unknown,Unknown,Unknown,vector_bf16,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.688), 'mean_duration_us': np.float64(5.688), 'median_duration_us': np.float64(5.688), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.688), 'max_duration_us': np.float64(5.688)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb0ELb0...', 'stream': 3, 'mean_duration_us': np.float64(5.69)}]","[[32, 4096], [32, 4096], [4096], []]","['c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar']","[[4096, 1], [4096, 1], [1], []]","['', '', '', '9.9999999999999995e-07']",5.6884765625,5.6884765625,,5.6884765625,5.6884765625,5.6884765625,1,2255 diff --git a/tests/traces/inference/sglang_decode/perf_csvs/Reduce_fwd.csv b/tests/traces/inference/sglang_decode/perf_csvs/Reduce_fwd.csv new file mode 100644 index 000000000..107ef79b1 --- /dev/null +++ b/tests/traces/inference/sglang_decode/perf_csvs/Reduce_fwd.csv @@ -0,0 +1,3 @@ +name,param: num_input_elems,param: num_output_elems,param: dtype_in_out,param: reduce_type,num_kernels,GFLOPS_first,Data Moved (MB)_first,FLOPS/Byte_first,TB/s_mean,TB/s_median,TB/s_std,TB/s_min,TB/s_max,TFLOPS/s_mean,TFLOPS/s_median,TFLOPS/s_std,TFLOPS/s_min,TFLOPS/s_max,process_name_first,process_label_first,thread_name_first,Compute Spec,kernel_details__summarize_kernel_stats,trunc_kernel_details,Input Dims_first,Input type_first,Input Strides_first,Concrete Inputs_first,Kernel Time (µs)_mean,Kernel Time (µs)_median,Kernel Time (µs)_std,Kernel Time (µs)_min,Kernel Time (µs)_max,Kernel Time (µs)_sum,name_count,UID_first +aten::cumsum,32,32,"('int', None)",sum,2,3.2e-08,0.000244140625,0.125,2.3937905214135693e-05,2.3937905214135693e-05,,2.3937905214135693e-05,2.3937905214135693e-05,2.9922381517669616e-06,2.9922381517669616e-06,,2.9922381517669616e-06,2.9922381517669616e-06,Unknown,Unknown,Unknown,,"[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel, (rocprim::ROCPRIM_400200_NS::detail::target_arch)942, rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2}, rocprim::ROCPRIM_400200_NS::detail::default_config_selector>(rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.247), 'mean_duration_us': np.float64(5.247), 'median_duration_us': np.float64(5.247), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.247), 'max_duration_us': np.float64(5.247)}, {'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.447), 'mean_duration_us': np.float64(5.447), 'median_duration_us': np.float64(5.447), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.447), 'max_duration_us': np.float64(5.447)}]","[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel(long const*, c10::BFloat16*, c10::BFloat16*, c10::BFloat16 const*, int, long, long, long, int, int, int)', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(195.81500000000003), 'mean_duration_us': np.float64(5.439305555555556), 'median_duration_us': np.float64(5.2865), 'std_dev_duration_us': np.float64(0.4970839309549045), 'min_duration_us': np.float64(4.886), 'max_duration_us': np.float64(6.969)}]","[{'name': 'void rotary_embedding_kernel(long const*, c...', 'stream': 3, 'mean_duration_us': np.float64(5.44)}]","[[32], [32, 4096], [32, 1024], [], [41216, 128], []]","['long int', 'c10::BFloat16', 'c10::BFloat16', 'Scalar', 'c10::BFloat16', 'Scalar']","[[1], [4096, 1], [1024, 1], [], [128, 1], []]","['', '', '', '128', '', 'True']",5.439317491319445,5.28662109375,0.5040695329554886,4.8857421875,6.96875,195.8154296875,36,2833 diff --git a/tests/traces/inference/sglang_decode/perf_csvs/UnaryElementwise.csv b/tests/traces/inference/sglang_decode/perf_csvs/UnaryElementwise.csv new file mode 100644 index 000000000..914a334f4 --- /dev/null +++ b/tests/traces/inference/sglang_decode/perf_csvs/UnaryElementwise.csv @@ -0,0 +1,10 @@ +name,param: op_shape,param: dtype_in_out,param: stride_input,param: stride_output,num_kernels,GFLOPS_first,Data Moved (MB)_first,FLOPS/Byte_first,TB/s_mean,TB/s_median,TB/s_std,TB/s_min,TB/s_max,TFLOPS/s_mean,TFLOPS/s_median,TFLOPS/s_std,TFLOPS/s_min,TFLOPS/s_max,process_name_first,process_label_first,thread_name_first,Compute Spec,kernel_details__summarize_kernel_stats,trunc_kernel_details,Input Dims_first,Input type_first,Input Strides_first,Concrete Inputs_first,Kernel Time (µs)_mean,Kernel Time (µs)_median,Kernel Time (µs)_std,Kernel Time (µs)_min,Kernel Time (µs)_max,Kernel Time (µs)_sum,name_count,UID_first +sgl_kernel::silu_and_mul,"(32, 12288)","('c10::BFloat16', 'c10::BFloat16')","(24576, 1)","(12288, 1)",1,0.00196608,2.25,0.8333333333333333,0.26418305580074875,0.2665469053155024,0.02341910845805231,0.19248817655963668,0.29599596961529034,0.22015254650062394,0.22212242109625202,0.019515923715043605,0.16040681379969723,0.24666330801274194,Unknown,Unknown,Unknown,vector_bf16,"[{'name': '_ZN7sgl_hip10activation18act_and_mul_kernelI14__hip_bfloat16TnPFT_RKS3_EXadL_Z4siluIS2_ES3_S5_EEEEvPS3_PS4_i', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(324.367), 'mean_duration_us': np.float64(9.010194444444444), 'median_duration_us': np.float64(8.852), 'std_dev_duration_us': np.float64(0.9225923566970422), 'min_duration_us': np.float64(7.971), 'max_duration_us': np.float64(12.257)}]","[{'name': '_ZN7sgl_hip10activation18act_and_mul_kernelI14__hip_bfloat16TnPF...', 'stream': 3, 'mean_duration_us': np.float64(9.01)}]","[[32, 12288], [32, 24576]]","['c10::BFloat16', 'c10::BFloat16']","[[12288, 1], [24576, 1]]","['', '']",9.010199652777779,8.85205078125,0.9356385690682965,7.970703125,12.2568359375,324.3671875,36,3664 +aten::copy_,"(32, 4096)","('c10::BFloat16', 'c10::BFloat16')","(4096, 1)","(6144, 1)",1,0.000131072,0.5,0.25,0.10746729184423291,0.10817467499496271,0.007018556900696719,0.08500172767574414,0.11582975447680689,0.026866822961058228,0.027043668748740677,0.0017546392251741798,0.021250431918936035,0.028957438619201723,Unknown,Unknown,Unknown,vector_bf16,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(176.46699999999996), 'mean_duration_us': np.float64(4.90186111111111), 'median_duration_us': np.float64(4.847), 'std_dev_duration_us': np.float64(0.36145071531090583), 'min_duration_us': np.float64(4.526), 'max_duration_us': np.float64(6.168)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::na...', 'stream': 3, 'mean_duration_us': np.float64(4.9)}]","[[32, 4096], [32, 4096], []]","['c10::BFloat16', 'c10::BFloat16', 'Scalar']","[[4096, 1], [6144, 1], []]","['', '', 'False']",4.901746961805555,4.8466796875,0.36648663563973427,4.5263671875,6.16796875,176.462890625,36,2504 +aten::copy_,"(32, 1024)","('c10::BFloat16', 'c10::BFloat16')","(1024, 1)","(6144, 1)",1,3.2768e-05,0.125,0.25,0.027821325069313372,0.028208854140395125,0.0015746796670120893,0.023041670042918454,0.029753431168255372,0.006955331267328343,0.007052213535098781,0.0003936699167530223,0.005760417510729613,0.007438357792063843,Unknown,Unknown,Unknown,vector_bf16,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(170.181), 'mean_duration_us': np.float64(4.727250000000001), 'median_duration_us': np.float64(4.646), 'std_dev_duration_us': np.float64(0.2908131678777821), 'min_duration_us': np.float64(4.405), 'max_duration_us': np.float64(5.688)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::na...', 'stream': 3, 'mean_duration_us': np.float64(4.73)}]","[[32, 1024], [32, 1024], []]","['c10::BFloat16', 'c10::BFloat16', 'Scalar']","[[1024, 1], [6144, 1], []]","['', '', 'False']",4.727376302083333,4.646484375,0.29486444901236286,4.4052734375,5.6884765625,170.185546875,36,2663 +aten::copy_,"(32,)","('long int', 'long int')","(1,)","(1,)",1,3.2e-08,0.00048828125,0.0625,0.00011730456616320462,0.00011311499460625673,1.1633278896224444e-05,0.0001083463525521802,0.0001304523513311769,7.3315353852002885e-06,7.069687162891046e-06,7.270799310140277e-07,6.771647034511262e-06,8.153271958198557e-06,Unknown,Unknown,Unknown,,"[{'name': 'Memcpy DtoH (Device -> Host)', 'stream': 3, 'count': 3, 'total_duration_us': np.float64(13.177), 'mean_duration_us': np.float64(4.392333333333333), 'median_duration_us': np.float64(4.526), 'std_dev_duration_us': np.float64(0.3403922573868109), 'min_duration_us': np.float64(3.925), 'max_duration_us': np.float64(4.726)}]","[{'name': 'Memcpy DtoH (Device -> Host)', 'stream': 3, 'mean_duration_us': np.float64(4.39)}]","[[32], [32], []]","['long int', 'long int', 'Scalar']","[[1], [1], []]","['', '', 'False']",4.392252604166667,4.5263671875,0.4168965023658701,3.9248046875,4.7255859375,13.1767578125,3,28 +aten::copy_,"(32,)","('int', 'long int')","(1,)","(1,)",1,3.2e-08,0.0003662109375,0.08333333333333333,8.171614416463391e-05,8.171614416463391e-05,4.412490267485512e-06,7.859604237457526e-05,8.483624595469255e-05,6.809678680386159e-06,6.809678680386159e-06,3.6770752229045947e-07,6.549670197881271e-06,7.069687162891046e-06,Unknown,Unknown,Unknown,,"[{'name': 'Memcpy DtoH (Device -> Host)', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(9.411999999999999), 'mean_duration_us': np.float64(4.7059999999999995), 'median_duration_us': np.float64(4.7059999999999995), 'std_dev_duration_us': np.float64(0.18000000000000016), 'min_duration_us': np.float64(4.526), 'max_duration_us': np.float64(4.886)}]","[{'name': 'Memcpy DtoH (Device -> Host)', 'stream': 3, 'mean_duration_us': np.float64(4.71)}]","[[32], [32], []]","['int', 'long int', 'Scalar']","[[1], [1], []]","['', '', 'False']",4.7060546875,4.7060546875,0.2541164994889155,4.5263671875,4.8857421875,9.412109375,2,22 +aten::copy_,"(32, 151936)","('float', 'c10::BFloat16')","(151936, 1)","(151936, 1)",1,0.004861952,27.8203125,0.16666666666666666,3.451794902703952,3.451794902703952,,3.451794902703952,3.451794902703952,0.5752991504506586,0.5752991504506586,,0.5752991504506586,0.5752991504506586,Unknown,Unknown,Unknown,vector_fp32,"[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::bfloat16tofloat32_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda(c10::BFloat16)#1}, std::array >(int, at::native::bfloat16tofloat32_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda(c10::BFloat16)#1}, std::array)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(8.451), 'mean_duration_us': np.float64(8.451), 'median_duration_us': np.float64(8.451), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(8.451), 'max_duration_us': np.float64(8.451)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::bf...', 'stream': 3, 'mean_duration_us': np.float64(8.45)}]","[[32, 151936], [32, 151936], []]","['float', 'c10::BFloat16', 'Scalar']","[[151936, 1], [151936, 1], []]","['', '', 'False']",8.451171875,8.451171875,,8.451171875,8.451171875,8.451171875,1,60455 +aten::neg,"(32,)","('long int', None)","(1,)",None,1,3.2e-08,0.00048828125,0.0625,9.000652360515021e-05,9.000652360515021e-05,,9.000652360515021e-05,9.000652360515021e-05,5.625407725321888e-06,5.625407725321888e-06,,5.625407725321888e-06,5.625407725321888e-06,Unknown,Unknown,Unknown,,"[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::neg_kernel_cuda(at::TensorIteratorBase&)::{lambda()#2}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, std::array >(int, at::native::neg_kernel_cuda(at::TensorIteratorBase&)::{lambda()#2}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, std::array)', 'stream': 2, 'count': 1, 'total_duration_us': np.float64(5.688), 'mean_duration_us': np.float64(5.688), 'median_duration_us': np.float64(5.688), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.688), 'max_duration_us': np.float64(5.688)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::ne...', 'stream': 2, 'mean_duration_us': np.float64(5.69)}]",[[32]],['long int'],[[1]],[''],5.6884765625,5.6884765625,,5.6884765625,5.6884765625,5.6884765625,1,62 +aten::copy_,"(32,)","('long int', 'int')","(1,)","(1,)",1,3.2e-08,0.0003662109375,0.08333333333333333,7.049408390103981e-05,7.049408390103981e-05,,7.049408390103981e-05,7.049408390103981e-05,5.874506991753317e-06,5.874506991753317e-06,,5.874506991753317e-06,5.874506991753317e-06,Unknown,Unknown,Unknown,,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.447), 'mean_duration_us': np.float64(5.447), 'median_duration_us': np.float64(5.447), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.447), 'max_duration_us': np.float64(5.447)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(5.45)}]","[[32], [32], []]","['long int', 'int', 'Scalar']","[[1], [1], []]","['', '', 'False']",5.447265625,5.447265625,,5.447265625,5.447265625,5.447265625,1,45 +aten::copy_,"(32,)","('int', 'long int')","(1,)","(1,)",0,3.2e-08,0.0003662109375,0.08333333333333333,,,,,,,,,,,Unknown,Unknown,Unknown,,[],,"[[32], [32], []]","['int', 'long int', 'Scalar']","[[1], [1], []]","['', '', 'False']",0.0,0.0,,0.0,0.0,0.0,1,29 diff --git a/tests/traces/inference/sglang_decode/perf_csvs/gpu_timeline.csv b/tests/traces/inference/sglang_decode/perf_csvs/gpu_timeline.csv new file mode 100644 index 000000000..739304b3d --- /dev/null +++ b/tests/traces/inference/sglang_decode/perf_csvs/gpu_timeline.csv @@ -0,0 +1,9 @@ +type,time ms,percent +computation_time,9.759751953125,2.060106199468502 +exposed_comm_time,0.0,0.0 +exposed_memcpy_time,0.0131767578125,0.002781374013274433 +busy_time,9.7729287109375,2.062887573481776 +idle_time,463.9770146484375,97.93711242651823 +total_time,473.749943359375,100.0 +total_comm_time,0.0,0.0 +total_memcpy_time,0.0131767578125,0.002781374013274433 diff --git a/tests/traces/inference/sglang_decode/perf_csvs/ops_summary.csv b/tests/traces/inference/sglang_decode/perf_csvs/ops_summary.csv new file mode 100644 index 000000000..df0383c5c --- /dev/null +++ b/tests/traces/inference/sglang_decode/perf_csvs/ops_summary.csv @@ -0,0 +1,22 @@ +name,parent_module,total_direct_kernel_time_sum,total_subtree_kernel_time_sum,total_subtree_kernel_time_count,total_direct_kernel_time_ms,Count,Categories,call_stack_first,Percentage (%),Cumulative Percentage (%) +aten::mm,nn.Module: MergedColumnParallelLinear,2417.6591796875,2417.6591796875,36,2.4176591796875,36,['GEMM'],"['aten::mm', 'nn.Module: MergedColumnParallelLinear_0', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",24.72393727385087,24.72393727385087 +sglang_profiler::attention_paged_attention_ragged,nn.Module: RadixAttention,2127.86328125,2127.86328125,36,2.12786328125,36,['InferenceAttention'],"['sglang_profiler::attention_paged_attention_ragged', 'nn.Module: RadixAttention_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",21.760370003747013,46.48430727759788 +aten::mm,nn.Module: RowParallelLinear,2064.244140625,2064.244140625,72,2.064244140625,72,['GEMM'],"['aten::mm', 'nn.Module: RowParallelLinear_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",21.10977555460216,67.59408283220003 +aten::mm,nn.Module: QKVParallelLinear,903.5185546875,903.5185546875,36,0.9035185546875,36,['GEMM'],"['aten::mm', 'nn.Module: QKVParallelLinear_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",9.23973745329214,76.83382028549217 +aten::mm,nn.Module: LogitsProcessor,396.83203125,396.83203125,1,0.39683203125,1,['GEMM'],"['aten::mm', 'nn.Module: LogitsProcessor_0']",4.0581610225755655,80.89198130806773 +aiter::add_rmsnorm,nn.Module: RMSNorm,346.841796875,346.841796875,72,0.346841796875,72,['RMSNorm'],"['aiter::add_rmsnorm', 'nn.Module: RMSNorm_3', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",3.5469411494947125,84.43892245756244 +aten::copy_,nn.Module: Qwen3Attention,346.6484375,346.6484375,72,0.3466484375,72,['elementwise'],"['aten::copy_', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",3.5449637801868397,87.98388623774927 +aiter::rmsnorm,nn.Module: RMSNorm,337.1220703125,337.1220703125,73,0.3371220703125,73,['RMSNorm'],"['aiter::rmsnorm', 'nn.Module: RMSNorm_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",3.447543388276238,91.43142962602552 +sgl_kernel::silu_and_mul,nn.Module: SiluAndMul,324.3671875,324.3671875,36,0.3243671875,36,['elementwise'],"['sgl_kernel::silu_and_mul', 'nn.Module: SiluAndMul_0', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",3.3171069209523645,94.74853654697789 +sgl_kernel::rotary_embedding,nn.Module: RotaryEmbedding,195.8154296875,195.8154296875,36,0.1958154296875,36,['RoPE_fwd'],"['sgl_kernel::rotary_embedding', 'nn.Module: RotaryEmbedding_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",2.002485892768261,96.75102243974615 +sglang::store_cache,nn.Module: RadixAttention,173.54296875,173.54296875,36,0.17354296875,36,['InferenceAttention'],"['sglang::store_cache', 'nn.Module: RadixAttention_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",1.7747189139568718,98.52574135370303 +aten::argmax,nn.Module: Sampler,53.83984375,53.83984375,1,0.05383984375,1,['reduce'],"['aten::argmax', 'nn.Module: Sampler_0']",0.550587498392139,99.07632885209516 +aten::copy_,NA,23.509765625,23.509765625,5,0.023509765625,5,['elementwise'],['aten::copy_'],0.24042014503904008,99.3167489971342 +aten::gather,nn.Module: VocabParallelEmbedding,13.4990234375,13.4990234375,1,0.0134990234375,1,['other'],"['aten::gather', 'nn.Module: VocabParallelEmbedding_0', 'nn.Module: Qwen3Model_0']",0.13804634314507977,99.45479534027928 +hipLaunchKernel,NA,12.1767578125,12.1767578125,2,0.0121767578125,2,['other'],['hipLaunchKernel'],0.12452433282760615,99.57931967310688 +aten::_foreach_copy_,NA,12.0966796875,12.0966796875,2,0.0120966796875,2,['multi_tensor_apply'],['aten::_foreach_copy_'],0.12370542230616388,99.70302509541304 +aten::copy_,nn.Module: LogitsProcessor,8.451171875,8.451171875,1,0.008451171875,1,['elementwise'],"['aten::copy_', 'nn.Module: LogitsProcessor_0']",0.0864250201531882,99.78945011556623 +aten::neg,NA,5.6884765625,5.6884765625,1,0.0056884765625,1,['elementwise'],['aten::neg'],0.05817260716342977,99.84762272272965 +hipModuleLaunchKernel,NA,5.4072265625,5.4072265625,1,0.0054072265625,1,['other'],['hipModuleLaunchKernel'],0.05529643362470569,99.90291915635436 +aten::cumsum,NA,5.2470703125,10.6943359375,1,0.0052470703125,1,['reduce'],['aten::cumsum'],0.05365861258182115,99.95657776893619 +aten::arange,NA,4.24609375,4.24609375,1,0.00424609375,1,['other'],['aten::arange'],0.04342223106379273,99.99999999999997 diff --git a/tests/traces/inference/sglang_decode/perf_csvs/ops_summary_by_category.csv b/tests/traces/inference/sglang_decode/perf_csvs/ops_summary_by_category.csv new file mode 100644 index 000000000..b77618b66 --- /dev/null +++ b/tests/traces/inference/sglang_decode/perf_csvs/ops_summary_by_category.csv @@ -0,0 +1,17 @@ +op category,parent_module,Count,call_stack_first,total_direct_kernel_time_ms,Percentage (%),Cumulative Percentage (%) +GEMM,nn.Module: MergedColumnParallelLinear,36,"['aten::mm', 'nn.Module: MergedColumnParallelLinear_0', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",2.4176591796875,24.72393727385087,24.72393727385087 +InferenceAttention,nn.Module: RadixAttention,72,"['sglang::store_cache', 'nn.Module: RadixAttention_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",2.30140625,23.535088917703888,48.25902619155475 +GEMM,nn.Module: RowParallelLinear,72,"['aten::mm', 'nn.Module: RowParallelLinear_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",2.064244140625,21.10977555460216,69.36880174615692 +GEMM,nn.Module: QKVParallelLinear,36,"['aten::mm', 'nn.Module: QKVParallelLinear_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",0.9035185546875,9.23973745329214,78.60853919944905 +RMSNorm,nn.Module: RMSNorm,145,"['aiter::rmsnorm', 'nn.Module: RMSNorm_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",0.6839638671875,6.9944845377709495,85.60302373722 +GEMM,nn.Module: LogitsProcessor,1,"['aten::mm', 'nn.Module: LogitsProcessor_0']",0.39683203125,4.0581610225755655,89.66118475979556 +elementwise,nn.Module: Qwen3Attention,72,"['aten::copy_', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",0.3466484375,3.5449637801868397,93.2061485399824 +elementwise,nn.Module: SiluAndMul,36,"['sgl_kernel::silu_and_mul', 'nn.Module: SiluAndMul_0', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",0.3243671875,3.3171069209523645,96.52325546093476 +RoPE_fwd,nn.Module: RotaryEmbedding,36,"['sgl_kernel::rotary_embedding', 'nn.Module: RotaryEmbedding_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",0.1958154296875,2.002485892768261,98.52574135370303 +reduce,nn.Module: Sampler,1,"['aten::argmax', 'nn.Module: Sampler_0']",0.05383984375,0.550587498392139,99.07632885209516 +elementwise,NA,6,['aten::copy_'],0.0291982421875,0.29859275220246984,99.37492160429763 +other,NA,4,['aten::arange'],0.021830078125,0.22324299751610457,99.59816460181374 +other,nn.Module: VocabParallelEmbedding,1,"['aten::gather', 'nn.Module: VocabParallelEmbedding_0', 'nn.Module: Qwen3Model_0']",0.0134990234375,0.13804634314507977,99.73621094495881 +multi_tensor_apply,NA,2,['aten::_foreach_copy_'],0.0120966796875,0.12370542230616388,99.85991636726497 +elementwise,nn.Module: LogitsProcessor,1,"['aten::copy_', 'nn.Module: LogitsProcessor_0']",0.008451171875,0.0864250201531882,99.94634138741816 +reduce,NA,1,['aten::cumsum'],0.0052470703125,0.05365861258182115,99.99999999999999 diff --git a/tests/traces/inference/sglang_decode/perf_csvs/ops_unique_args.csv b/tests/traces/inference/sglang_decode/perf_csvs/ops_unique_args.csv new file mode 100644 index 000000000..e74583984 --- /dev/null +++ b/tests/traces/inference/sglang_decode/perf_csvs/ops_unique_args.csv @@ -0,0 +1,30 @@ +name,op category,parent_module,process_name,process_label,thread_name,Input Dims,Input type,Input Strides,Concrete Inputs,num_kernels,operation_count,total_direct_kernel_time_mean,total_subtree_kernel_time_mean,total_direct_kernel_time_median,total_subtree_kernel_time_median,total_direct_kernel_time_std,total_subtree_kernel_time_std,total_direct_kernel_time_min,total_subtree_kernel_time_min,total_direct_kernel_time_max,total_subtree_kernel_time_max,total_direct_kernel_time_sum,total_subtree_kernel_time_sum,ex_UID,call_stack,kernel_details_summary,trunc_kernel_details,Percentage (%),Cumulative Percentage (%) +aten::mm,GEMM,nn.Module: MergedColumnParallelLinear,Unknown,Unknown,Unknown,"((32, 4096), (4096, 24576))","('c10::BFloat16', 'c10::BFloat16')","((4096, 1), (1, 4096))","('', '')",1,36,67.15719943576389,67.15719943576389,66.55859375,66.55859375,2.162312900832966,2.162312900832966,64.736328125,64.736328125,73.62890625,73.62890625,2417.6591796875,2417.6591796875,3618,"['aten::mm', 'nn.Module: MergedColumnParallelLinear_0', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x32x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB256_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB2_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(2417.659), 'mean_duration_us': np.float64(67.15719444444444), 'median_duration_us': np.float64(66.55850000000001), 'std_dev_duration_us': np.float64(2.1321042529681073), 'min_duration_us': np.float64(64.736), 'max_duration_us': np.float64(73.629)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x32x64_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(67.16)}]",24.72393727385087,24.72393727385087 +sglang_profiler::attention_paged_attention_ragged,InferenceAttention,nn.Module: RadixAttention,Unknown,Unknown,Unknown,"((32, 32, 128), (10905190400,), (32, 32, 128), (835874, 1, 8, 128), (835874, 1, 8, 128), (33,), (20971520,), (4096,), (), (1,), (1,), ())","('c10::BFloat16', 'unsigned char', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'int', 'int', 'int', '', 'float', 'float', '')","((4096, 128, 1), (1,), (4096, 128, 1), (1024, 1024, 128, 1), (1024, 1024, 128, 1), (1,), (1,), (1,), (), (1,), (1,), ())","('', '', '', '', '', '', '', '', '', '', '', '')",2,36,59.10731336805556,59.10731336805556,58.84619140625,58.84619140625,1.9199264842925137,1.9199264842925137,56.40234375,56.40234375,65.5751953125,65.5751953125,2127.86328125,2127.86328125,3205,"['sglang_profiler::attention_paged_attention_ragged', 'nn.Module: RadixAttention_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'void paged_attention_ll4mi_reduce_kernel<__hip_bfloat16, __hip_bfloat16, 128, 128, 256, 3, false>(__hip_bfloat16*, float const*, float const*, __hip_bfloat16 const*, int const*, int const*, int, int, float const*)', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(178.31300000000002), 'mean_duration_us': np.float64(4.95313888888889), 'median_duration_us': np.float64(4.926), 'std_dev_duration_us': np.float64(0.2737306211078672), 'min_duration_us': np.float64(4.526), 'max_duration_us': np.float64(5.848)}, {'name': 'void paged_attention_ll4mi_QKV_mfma16_kernel<0, __hip_bfloat16, __hip_bfloat16, (vllm::Fp8KVCacheDataType)0, 1, 128, 256, false, 4, 1, ck_tile::ComposedAttention<0u, false> >(__hip_bfloat16 const*, __hip_bfloat16 const*, __hip_bfloat16 const*, float, int const*, int const*, int const*, float const*, int, int, int, int, float*, float*, __hip_bfloat16*, float, float, float const*, float const*, float const*, ck_tile::ComposedAttention<0u, false> const*)', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(1949.556), 'mean_duration_us': np.float64(54.154333333333334), 'median_duration_us': np.float64(53.9595), 'std_dev_duration_us': np.float64(1.6962556804129898), 'min_duration_us': np.float64(51.596), 'max_duration_us': np.float64(59.728)}]","[{'name': 'void paged_attention_ll4mi_reduce_kernel<__hip_bfloat16, __hip_b...', 'stream': 3, 'mean_duration_us': np.float64(4.95)}, {'name': 'void paged_attention_ll4mi_QKV_mfma16_kernel<0, __hip_bfloat16, ...', 'stream': 3, 'mean_duration_us': np.float64(54.15)}]",21.760370003747013,46.48430727759788 +aten::mm,GEMM,nn.Module: RowParallelLinear,Unknown,Unknown,Unknown,"((32, 12288), (12288, 4096))","('c10::BFloat16', 'c10::BFloat16')","((12288, 1), (1, 12288))","('', '')",1,36,40.608425564236114,40.608425564236114,40.8994140625,40.8994140625,2.9926972240857443,2.9926972240857443,36.373046875,36.373046875,47.349609375,47.349609375,1461.9033203125,1461.9033203125,3713,"['aten::mm', 'nn.Module: RowParallelLinear_1', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT32x32x256_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA1024_LBSPPB1024_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT2_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW2_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO1_USL1_UIOFGRO0_USFGROn1_VSn1_VWA2_VWB2_WSGRA0_WSGRB0_WS64_WG16_4_4', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(1461.9070000000002), 'mean_duration_us': np.float64(40.60852777777778), 'median_duration_us': np.float64(40.8995), 'std_dev_duration_us': np.float64(2.950849194969241), 'min_duration_us': np.float64(36.373), 'max_duration_us': np.float64(47.35)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT32x32x256_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(40.61)}]",14.950000519309112,61.43430779690699 +aten::mm,GEMM,nn.Module: QKVParallelLinear,Unknown,Unknown,Unknown,"((32, 4096), (4096, 6144))","('c10::BFloat16', 'c10::BFloat16')","((4096, 1), (1, 4096))","('', '')",1,36,25.097737630208332,25.097737630208332,21.2314453125,21.2314453125,21.22134930970088,21.22134930970088,20.7099609375,20.7099609375,148.78125,148.78125,903.5185546875,903.5185546875,2321,"['aten::mm', 'nn.Module: QKVParallelLinear_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT64x32x256_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA2048_LBSPPB1024_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB2_WSGRA0_WSGRB0_WS64_WG16_4_4', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(903.515), 'mean_duration_us': np.float64(25.097638888888888), 'median_duration_us': np.float64(21.231), 'std_dev_duration_us': np.float64(20.9245116153716), 'min_duration_us': np.float64(20.71), 'max_duration_us': np.float64(148.781)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT64x32x256_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(25.1)}]",9.23973745329214,70.67404525019913 +aten::mm,GEMM,nn.Module: RowParallelLinear,Unknown,Unknown,Unknown,"((32, 4096), (4096, 4096))","('c10::BFloat16', 'c10::BFloat16')","((4096, 1), (1, 4096))","('', '')",1,36,16.731689453125,16.731689453125,16.9248046875,16.9248046875,1.0951818785939924,1.0951818785939924,15.1015625,15.1015625,19.9892578125,19.9892578125,602.3408203125,602.3408203125,3417,"['aten::mm', 'nn.Module: RowParallelLinear_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT16x32x512_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA1024_LBSPPB2048_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT1_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW1_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA1_VWB2_WSGRA0_WSGRB0_WS64_WG16_4_4', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(602.3440000000002), 'mean_duration_us': np.float64(16.731777777777783), 'median_duration_us': np.float64(16.924500000000002), 'std_dev_duration_us': np.float64(1.079763299964681), 'min_duration_us': np.float64(15.102), 'max_duration_us': np.float64(19.989)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT16x32x512_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(16.73)}]",6.1597750352930465,76.83382028549218 +aten::mm,GEMM,nn.Module: LogitsProcessor,Unknown,Unknown,Unknown,"((32, 4096), (4096, 151936))","('c10::BFloat16', 'c10::BFloat16')","((4096, 1), (1, 4096))","('', '')",1,1,396.83203125,396.83203125,396.83203125,396.83203125,,,396.83203125,396.83203125,396.83203125,396.83203125,396.83203125,396.83203125,60441,"['aten::mm', 'nn.Module: LogitsProcessor_0']","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x48x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB4_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB128_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_3_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB1_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(396.832), 'mean_duration_us': np.float64(396.832), 'median_duration_us': np.float64(396.832), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(396.832), 'max_duration_us': np.float64(396.832)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x48x64_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(396.83)}]",4.0581610225755655,80.89198130806774 +aiter::add_rmsnorm,RMSNorm,nn.Module: RMSNorm,Unknown,Unknown,Unknown,"((32, 4096), (32, 4096), (32, 4096), (32, 4096), (4096,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((4096, 1), (4096, 1), (4096, 1), (4096, 1), (1,), ())","('', '', '', '', '', '9.9999999999999995e-07')",1,72,4.817247178819445,4.817247178819445,4.7255859375,4.7255859375,0.36813716584561973,0.36813716584561973,4.40625,4.40625,7.0087890625,7.0087890625,346.841796875,346.841796875,3557,"['aiter::add_rmsnorm', 'nn.Module: RMSNorm_3', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb1ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 72, 'total_duration_us': np.float64(346.84399999999994), 'mean_duration_us': np.float64(4.817277777777777), 'median_duration_us': np.float64(4.726), 'std_dev_duration_us': np.float64(0.36565459651236065), 'min_duration_us': np.float64(4.406), 'max_duration_us': np.float64(7.009)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb1ELb0...', 'stream': 3, 'mean_duration_us': np.float64(4.82)}]",3.5469411494947125,84.43892245756246 +sgl_kernel::silu_and_mul,elementwise,nn.Module: SiluAndMul,Unknown,Unknown,Unknown,"((32, 12288), (32, 24576))","('c10::BFloat16', 'c10::BFloat16')","((12288, 1), (24576, 1))","('', '')",1,36,9.010199652777779,9.010199652777779,8.85205078125,8.85205078125,0.9356385690682965,0.9356385690682965,7.970703125,7.970703125,12.2568359375,12.2568359375,324.3671875,324.3671875,3664,"['sgl_kernel::silu_and_mul', 'nn.Module: SiluAndMul_0', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': '_ZN7sgl_hip10activation18act_and_mul_kernelI14__hip_bfloat16TnPFT_RKS3_EXadL_Z4siluIS2_ES3_S5_EEEEvPS3_PS4_i', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(324.367), 'mean_duration_us': np.float64(9.010194444444444), 'median_duration_us': np.float64(8.852), 'std_dev_duration_us': np.float64(0.9225923566970422), 'min_duration_us': np.float64(7.971), 'max_duration_us': np.float64(12.257)}]","[{'name': '_ZN7sgl_hip10activation18act_and_mul_kernelI14__hip_bfloat16TnPF...', 'stream': 3, 'mean_duration_us': np.float64(9.01)}]",3.3171069209523654,87.75602937851482 +sgl_kernel::rotary_embedding,RoPE_fwd,nn.Module: RotaryEmbedding,Unknown,Unknown,Unknown,"((32,), (32, 4096), (32, 1024), (), (41216, 128), ())","('long int', 'c10::BFloat16', 'c10::BFloat16', 'Scalar', 'c10::BFloat16', 'Scalar')","((1,), (4096, 1), (1024, 1), (), (128, 1), ())","('', '', '', '128', '', 'True')",1,36,5.439317491319445,5.439317491319445,5.28662109375,5.28662109375,0.5040695329554886,0.5040695329554886,4.8857421875,4.8857421875,6.96875,6.96875,195.8154296875,195.8154296875,2833,"['sgl_kernel::rotary_embedding', 'nn.Module: RotaryEmbedding_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'void rotary_embedding_kernel(long const*, c10::BFloat16*, c10::BFloat16*, c10::BFloat16 const*, int, long, long, long, int, int, int)', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(195.81500000000003), 'mean_duration_us': np.float64(5.439305555555556), 'median_duration_us': np.float64(5.2865), 'std_dev_duration_us': np.float64(0.4970839309549045), 'min_duration_us': np.float64(4.886), 'max_duration_us': np.float64(6.969)}]","[{'name': 'void rotary_embedding_kernel(long const*, c...', 'stream': 3, 'mean_duration_us': np.float64(5.44)}]",2.002485892768261,89.75851527128309 +aten::copy_,elementwise,nn.Module: Qwen3Attention,Unknown,Unknown,Unknown,"((32, 4096), (32, 4096), ())","('c10::BFloat16', 'c10::BFloat16', 'Scalar')","((4096, 1), (6144, 1), ())","('', '', 'False')",1,36,4.901746961805555,4.901746961805555,4.8466796875,4.8466796875,0.36648663563973427,0.36648663563973427,4.5263671875,4.5263671875,6.16796875,6.16796875,176.462890625,176.462890625,2504,"['aten::copy_', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(176.46699999999996), 'mean_duration_us': np.float64(4.90186111111111), 'median_duration_us': np.float64(4.847), 'std_dev_duration_us': np.float64(0.36145071531090583), 'min_duration_us': np.float64(4.526), 'max_duration_us': np.float64(6.168)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::na...', 'stream': 3, 'mean_duration_us': np.float64(4.9)}]",1.8045791878484863,91.56309445913158 +sglang::store_cache,InferenceAttention,nn.Module: RadixAttention,Unknown,Unknown,Unknown,"((32, 1024), (32, 1024), (835874, 1024), (835874, 1024), (32,), (), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'long int', 'Scalar', 'Scalar')","((1024, 1), (6144, 1), (1024, 1), (1024, 1), (1,), (), ())","('', '', '', '', '', '2048', '0')",1,36,4.820638020833333,4.820638020833333,4.685546875,4.685546875,0.3202933594836537,0.3202933594836537,4.4462890625,4.4462890625,5.8076171875,5.8076171875,173.54296875,173.54296875,2982,"['sglang::store_cache', 'nn.Module: RadixAttention_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'void (anonymous namespace)::store_kvcache<2048l, 4, false, long>((anonymous namespace)::StoreKVCacheParams)', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(173.545), 'mean_duration_us': np.float64(4.820694444444444), 'median_duration_us': np.float64(4.686), 'std_dev_duration_us': np.float64(0.31601018087014254), 'min_duration_us': np.float64(4.446), 'max_duration_us': np.float64(5.808)}]","[{'name': 'void (anonymous namespace)::store_kvcache<2048l, 4, false, long>...', 'stream': 3, 'mean_duration_us': np.float64(4.82)}]",1.7747189139568718,93.33781337308845 +aten::copy_,elementwise,nn.Module: Qwen3Attention,Unknown,Unknown,Unknown,"((32, 1024), (32, 1024), ())","('c10::BFloat16', 'c10::BFloat16', 'Scalar')","((1024, 1), (6144, 1), ())","('', '', 'False')",1,36,4.727376302083333,4.727376302083333,4.646484375,4.646484375,0.29486444901236286,0.29486444901236286,4.4052734375,4.4052734375,5.6884765625,5.6884765625,170.185546875,170.185546875,2663,"['aten::copy_', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(170.181), 'mean_duration_us': np.float64(4.727250000000001), 'median_duration_us': np.float64(4.646), 'std_dev_duration_us': np.float64(0.2908131678777821), 'min_duration_us': np.float64(4.405), 'max_duration_us': np.float64(5.688)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::na...', 'stream': 3, 'mean_duration_us': np.float64(4.73)}]",1.740384592338353,95.07819796542681 +aiter::rmsnorm,RMSNorm,nn.Module: RMSNorm,Unknown,Unknown,Unknown,"((256, 128), (256, 128), (128,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((128, 1), (128, 1), (1,), ())","('', '', '', '9.9999999999999995e-07')",1,36,4.610514322916667,4.610514322916667,4.52587890625,4.52587890625,0.3163628873091587,0.3163628873091587,4.3251953125,4.3251953125,5.7265625,5.7265625,165.978515625,165.978515625,2753,"['aiter::rmsnorm', 'nn.Module: RMSNorm_2', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(165.97099999999998), 'mean_duration_us': np.float64(4.610305555555555), 'median_duration_us': np.float64(4.5255), 'std_dev_duration_us': np.float64(0.31204271604349704), 'min_duration_us': np.float64(4.325), 'max_duration_us': np.float64(5.727)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0EL...', 'stream': 3, 'mean_duration_us': np.float64(4.61)}]",1.697361829821605,96.77555979524841 +aiter::rmsnorm,RMSNorm,nn.Module: RMSNorm,Unknown,Unknown,Unknown,"((1024, 128), (1024, 128), (128,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((128, 1), (128, 1), (1,), ())","('', '', '', '9.9999999999999995e-07')",1,36,4.595974392361111,4.595974392361111,4.50634765625,4.50634765625,0.2723561217428755,0.2723561217428755,4.3251953125,4.3251953125,5.4873046875,5.4873046875,165.455078125,165.455078125,2594,"['aiter::rmsnorm', 'nn.Module: RMSNorm_1', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(165.44999999999996), 'mean_duration_us': np.float64(4.595833333333332), 'median_duration_us': np.float64(4.506), 'std_dev_duration_us': np.float64(0.26861222566699716), 'min_duration_us': np.float64(4.325), 'max_duration_us': np.float64(5.487)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0EL...', 'stream': 3, 'mean_duration_us': np.float64(4.6)}]",1.6920089512912022,98.46756874653961 +aten::argmax,reduce,nn.Module: Sampler,Unknown,Unknown,Unknown,"((32, 151936), (), ())","('float', 'Scalar', 'Scalar')","((151936, 1), (), ())","('', '-1', 'False')",1,1,53.83984375,53.83984375,53.83984375,53.83984375,,,53.83984375,53.83984375,53.83984375,53.83984375,53.83984375,53.83984375,53,"['aten::argmax', 'nn.Module: Sampler_0']","[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp, unsigned int, long, 4, 4> >(at::native::ReduceOp, unsigned int, long, 4, 4>)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(53.84), 'mean_duration_us': np.float64(53.84), 'median_duration_us': np.float64(53.84), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(53.84), 'max_duration_us': np.float64(53.84)}]","[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp(char*, char*, long*, int, long, long, long, long, bool)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(13.499), 'mean_duration_us': np.float64(13.499), 'median_duration_us': np.float64(13.499), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(13.499), 'max_duration_us': np.float64(13.499)}]","[{'name': 'void at::native::vectorized_gather_kernel<16, long>(char*, char*...', 'stream': 3, 'mean_duration_us': np.float64(13.5)}]",0.13804634314507977,99.15620258807682 +hipLaunchKernel,other,NA,Unknown,Unknown,Unknown,,,,,1,2,6.08837890625,6.08837890625,6.08837890625,6.08837890625,0.7934235269368585,0.7934235269368585,5.52734375,5.52734375,6.6494140625,6.6494140625,12.1767578125,12.1767578125,887,['hipLaunchKernel'],"[{'name': 'void (anonymous namespace)::resolve_future_token_ids_kernel(long*, long const*, unsigned long)', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(12.176), 'mean_duration_us': np.float64(6.088), 'median_duration_us': np.float64(6.088), 'std_dev_duration_us': np.float64(0.5609999999999999), 'min_duration_us': np.float64(5.527), 'max_duration_us': np.float64(6.649)}]","[{'name': 'void (anonymous namespace)::resolve_future_token_ids_kernel Host)', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(9.251999999999999), 'mean_duration_us': np.float64(4.6259999999999994), 'median_duration_us': np.float64(4.6259999999999994), 'std_dev_duration_us': np.float64(0.10000000000000009), 'min_duration_us': np.float64(4.526), 'max_duration_us': np.float64(4.726)}]","[{'name': 'Memcpy DtoH (Device -> Host)', 'stream': 3, 'mean_duration_us': np.float64(4.63)}]",0.09461412536761092,99.37534104627204 +aten::copy_,elementwise,nn.Module: LogitsProcessor,Unknown,Unknown,Unknown,"((32, 151936), (32, 151936), ())","('float', 'c10::BFloat16', 'Scalar')","((151936, 1), (151936, 1), ())","('', '', 'False')",1,1,8.451171875,8.451171875,8.451171875,8.451171875,,,8.451171875,8.451171875,8.451171875,8.451171875,8.451171875,8.451171875,60455,"['aten::copy_', 'nn.Module: LogitsProcessor_0']","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::bfloat16tofloat32_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda(c10::BFloat16)#1}, std::array >(int, at::native::bfloat16tofloat32_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda(c10::BFloat16)#1}, std::array)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(8.451), 'mean_duration_us': np.float64(8.451), 'median_duration_us': np.float64(8.451), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(8.451), 'max_duration_us': np.float64(8.451)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::bf...', 'stream': 3, 'mean_duration_us': np.float64(8.45)}]",0.0864250201531882,99.46176606642523 +aten::_foreach_copy_,multi_tensor_apply,NA,Unknown,Unknown,Unknown,"(((32,),), ((32,),), ())","('TensorList', 'TensorList', 'Scalar')","(((1,),), ((1,),), ())","('', '', 'False')",1,1,6.5283203125,6.5283203125,6.5283203125,6.5283203125,,,6.5283203125,6.5283203125,6.5283203125,6.5283203125,6.5283203125,6.5283203125,19,['aten::_foreach_copy_'],"[{'name': 'void at::native::(anonymous namespace)::multi_tensor_apply_kernel, at::native::(anonymous namespace)::CopyFunctor, at::native::Copy >(at::native::(anonymous namespace)::TensorListMetadata<2>, at::native::(anonymous namespace)::CopyFunctor, at::native::Copy)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(6.528), 'mean_duration_us': np.float64(6.528), 'median_duration_us': np.float64(6.528), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(6.528), 'max_duration_us': np.float64(6.528)}]","[{'name': 'void at::native::(anonymous namespace)::multi_tensor_apply_kerne...', 'stream': 3, 'mean_duration_us': np.float64(6.53)}]",0.06676118092489751,99.52852724735013 +aten::neg,elementwise,NA,Unknown,Unknown,Unknown,"((32,),)","('long int',)","((1,),)","('',)",1,1,5.6884765625,5.6884765625,5.6884765625,5.6884765625,,,5.6884765625,5.6884765625,5.6884765625,5.6884765625,5.6884765625,5.6884765625,62,['aten::neg'],"[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::neg_kernel_cuda(at::TensorIteratorBase&)::{lambda()#2}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, std::array >(int, at::native::neg_kernel_cuda(at::TensorIteratorBase&)::{lambda()#2}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, std::array)', 'stream': 2, 'count': 1, 'total_duration_us': np.float64(5.688), 'mean_duration_us': np.float64(5.688), 'median_duration_us': np.float64(5.688), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.688), 'max_duration_us': np.float64(5.688)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::ne...', 'stream': 2, 'mean_duration_us': np.float64(5.69)}]",0.05817260716342977,99.58669985451355 +aiter::rmsnorm,RMSNorm,nn.Module: RMSNorm,Unknown,Unknown,Unknown,"((32, 4096), (32, 4096), (4096,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((4096, 1), (4096, 1), (1,), ())","('', '', '', '9.9999999999999995e-07')",1,1,5.6884765625,5.6884765625,5.6884765625,5.6884765625,,,5.6884765625,5.6884765625,5.6884765625,5.6884765625,5.6884765625,5.6884765625,2255,"['aiter::rmsnorm', 'nn.Module: RMSNorm_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.688), 'mean_duration_us': np.float64(5.688), 'median_duration_us': np.float64(5.688), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.688), 'max_duration_us': np.float64(5.688)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb0ELb0...', 'stream': 3, 'mean_duration_us': np.float64(5.69)}]",0.05817260716342977,99.64487246167698 +aten::_foreach_copy_,multi_tensor_apply,NA,Unknown,Unknown,Unknown,"(((32,), (32,), (32,), (32,)), ((32,), (32,), (32,), (32,)), ())","('TensorList', 'TensorList', 'Scalar')","(((1,), (1,), (1,), (1,)), ((1,), (1,), (1,), (1,)), ())","('', '', 'False')",1,1,5.568359375,5.568359375,5.568359375,5.568359375,,,5.568359375,5.568359375,5.568359375,5.568359375,5.568359375,5.568359375,18,['aten::_foreach_copy_'],"[{'name': 'void at::native::(anonymous namespace)::multi_tensor_apply_kernel, at::native::(anonymous namespace)::UnaryOpFunctor, at::native::Copy >(at::native::(anonymous namespace)::TensorListMetadata<2>, at::native::(anonymous namespace)::UnaryOpFunctor, at::native::Copy)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.568), 'mean_duration_us': np.float64(5.568), 'median_duration_us': np.float64(5.568), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.568), 'max_duration_us': np.float64(5.568)}]","[{'name': 'void at::native::(anonymous namespace)::multi_tensor_apply_kerne...', 'stream': 3, 'mean_duration_us': np.float64(5.57)}]",0.05694424138126636,99.70181670305824 +aten::copy_,elementwise,NA,Unknown,Unknown,Unknown,"((32,), (32,), ())","('long int', 'int', 'Scalar')","((1,), (1,), ())","('', '', 'False')",1,1,5.447265625,5.447265625,5.447265625,5.447265625,,,5.447265625,5.447265625,5.447265625,5.447265625,5.447265625,5.447265625,45,['aten::copy_'],"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.447), 'mean_duration_us': np.float64(5.447), 'median_duration_us': np.float64(5.447), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.447), 'max_duration_us': np.float64(5.447)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(5.45)}]",0.05570588888542683,99.75752259194367 +hipModuleLaunchKernel,other,NA,Unknown,Unknown,Unknown,,,,,1,1,5.4072265625,5.4072265625,5.4072265625,5.4072265625,,,5.4072265625,5.4072265625,5.4072265625,5.4072265625,5.4072265625,5.4072265625,905,['hipModuleLaunchKernel'],"[{'name': 'create_flashinfer_kv_indices_triton', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.407), 'mean_duration_us': np.float64(5.407), 'median_duration_us': np.float64(5.407), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.407), 'max_duration_us': np.float64(5.407)}]","[{'name': 'create_flashinfer_kv_indices_triton', 'stream': 3, 'mean_duration_us': np.float64(5.41)}]",0.05529643362470569,99.81281902556837 +aten::cumsum,reduce,NA,Unknown,Unknown,Unknown,"((32,), (), ())","('int', 'Scalar', '')","((1,), (), ())","('', '0', '')",1,1,5.2470703125,10.6943359375,5.2470703125,10.6943359375,,,5.2470703125,10.6943359375,5.2470703125,10.6943359375,5.2470703125,10.6943359375,41,['aten::cumsum'],"[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel, (rocprim::ROCPRIM_400200_NS::detail::target_arch)942, rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2}, rocprim::ROCPRIM_400200_NS::detail::default_config_selector>(rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.247), 'mean_duration_us': np.float64(5.247), 'median_duration_us': np.float64(5.247), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.247), 'max_duration_us': np.float64(5.247)}]","[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(4.886), 'mean_duration_us': np.float64(4.886), 'median_duration_us': np.float64(4.886), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(4.886), 'max_duration_us': np.float64(4.886)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(4.89)}]",0.04996352852165479,99.91644116667186 +aten::arange,other,NA,Unknown,Unknown,Unknown,"((), (), (), (0,))","('Scalar', 'Scalar', 'Scalar', 'long int')","((), (), (), (1,))","('238', '270', '1', '')",1,1,4.24609375,4.24609375,4.24609375,4.24609375,,,4.24609375,4.24609375,4.24609375,4.24609375,4.24609375,4.24609375,3,['aten::arange'],"[{'name': 'void (anonymous namespace)::elementwise_kernel_with_index(int, at::native::arange_cuda_out(c10::Scalar const&, c10::Scalar const&, c10::Scalar const&, at::Tensor&)::{lambda()#1}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, function_traits::result_type*)', 'stream': 2, 'count': 1, 'total_duration_us': np.float64(4.246), 'mean_duration_us': np.float64(4.246), 'median_duration_us': np.float64(4.246), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(4.246), 'max_duration_us': np.float64(4.246)}]","[{'name': 'void (anonymous namespace)::elementwise_kernel_with_index Device)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(3.925), 'mean_duration_us': np.float64(3.925), 'median_duration_us': np.float64(3.925), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(3.925), 'max_duration_us': np.float64(3.925)}]","[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'mean_duration_us': np.float64(3.92)}]",0.04013660226434751,100.0 diff --git a/tests/traces/inference/sglang_decode/perf_csvs/unified_perf_summary.csv b/tests/traces/inference/sglang_decode/perf_csvs/unified_perf_summary.csv new file mode 100644 index 000000000..06f2c1347 --- /dev/null +++ b/tests/traces/inference/sglang_decode/perf_csvs/unified_perf_summary.csv @@ -0,0 +1,30 @@ +name,op category,process_name,process_label,thread_name,Input Dims,Input type,Input Strides,Concrete Inputs,ex_UID,operation_count,total_duration_us,mean_duration_us,std_duration_us,GFLOPS,Data Moved (MB),FLOPS/Byte,Compute Spec,TB/s_mean,TB/s_std,TFLOPS/s_mean,TFLOPS/s_std,Kernel Time (µs)_mean,Kernel Time (µs)_std,Kernel Time (µs)_sum,duration_us_median,duration_us_min,duration_us_max,TB/s_median,TB/s_min,TB/s_max,TFLOPS/s_median,TFLOPS/s_min,TFLOPS/s_max,Kernel Time (µs)_median,Kernel Time (µs)_min,Kernel Time (µs)_max,kernel_details_summary,trunc_kernel_details,perf_params,has_perf_model,Percentage (%),Cumulative Percentage (%) +aiter::gemm_a16w16,GEMM,Unknown,Unknown,Unknown,"((32, 4096), (24576, 4096), (), (), (), (), ())","('c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '')","((4096, 1), (4096, 1), (), (), (), (), ())","('', '', '', '15', '', '', '')",3603,36,56613.924,1572.609,0.0,6.442450944,193.75,31.710967741935484,matrix_bf16,3.0281005673551444,0.09384870781134186,96.02399941073553,2.9760333460278057,67.15719943576389,2.162312900832966,2417.6591796875,1572.609,1572.609,1572.609,3.0523747073479246,2.759264130723115,3.1382935344697542,96.7937558810098,87.49893584084036,99.51832503629507,66.55859375,64.736328125,73.62890625,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x32x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB256_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB2_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen2MLP', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(94): forward', 'nn.Module: MergedColumnParallelLinear', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/linear.py(461): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/quantization/unquant.py(136): apply', 'aiter/tuned_gemm.py(552): mm', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'aiter::gemm_a16w16', 'aiter/tuned_gemm.py(246): gemm_a16w16', 'aiter/tuned_gemm.py(395): torch_gemm', 'aten::linear', 'aten::matmul', 'aten::mm'], 'count': 36, 'total_duration_us': np.float64(2417.659), 'mean_duration_us': np.float64(67.15719444444444), 'median_duration_us': np.float64(66.55850000000001), 'std_dev_duration_us': np.float64(2.1321042529681073), 'min_duration_us': np.float64(64.736), 'max_duration_us': np.float64(73.629)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x32x64_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(67.16)}]","{'B': 1, 'M': 32, 'N': 24576, 'K': 4096, 'bias': False, 'dtype_A_B': ('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16'), 'transpose': (True, False)}",True,24.72393727385087,24.72393727385087 +sglang_profiler::attention_paged_attention_ragged,InferenceAttention,Unknown,Unknown,Unknown,"((32, 32, 128), (10905190400,), (32, 32, 128), (835874, 1, 8, 128), (835874, 1, 8, 128), (33,), (20971520,), (4096,), (), (1,), (1,), ())","('c10::BFloat16', 'unsigned char', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'int', 'int', 'int', '', 'float', 'float', '')","((4096, 128, 1), (1,), (4096, 128, 1), (1024, 1024, 128, 1), (1024, 1024, 128, 1), (1,), (1,), (1,), (), (1,), (1,), ())","('', '', '', '', '', '', '', '', '', '', '', '')",3205,36,56613.924,1572.609,0.0,0.53714944,128.56640625,3.9844438367818187,matrix_bf16,2.283041251375341,0.07122734658138916,9.096649643161127,0.28380136209653906,59.10731336805556,1.9199264842925137,2127.86328125,1572.609,1572.609,1572.609,2.29091646674352,2.055832961801367,2.3901781209225015,9.128027996498199,8.191350974102368,9.523530482720409,58.84619140625,56.40234375,65.5751953125,"[{'name': 'void paged_attention_ll4mi_reduce_kernel<__hip_bfloat16, __hip_bfloat16, 128, 128, 256, 3, false>(__hip_bfloat16*, float const*, float const*, __hip_bfloat16 const*, int const*, int const*, int, int, float const*)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', 'nn.Module: RadixAttention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/radix_attention.py(105): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/base_attn_backend.py(80): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(2435): forward_decode', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::attention_paged_attention_ragged', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', 'aiter/ops/attention.py(598): paged_attention_ragged', 'csrc/cpp_itfs/pa/pa_ragged.py(65): paged_attention_ragged'], 'count': 36, 'total_duration_us': np.float64(178.31300000000002), 'mean_duration_us': np.float64(4.95313888888889), 'median_duration_us': np.float64(4.926), 'std_dev_duration_us': np.float64(0.2737306211078672), 'min_duration_us': np.float64(4.526), 'max_duration_us': np.float64(5.848)}, {'name': 'void paged_attention_ll4mi_QKV_mfma16_kernel<0, __hip_bfloat16, __hip_bfloat16, (vllm::Fp8KVCacheDataType)0, 1, 128, 256, false, 4, 1, ck_tile::ComposedAttention<0u, false> >(__hip_bfloat16 const*, __hip_bfloat16 const*, __hip_bfloat16 const*, float, int const*, int const*, int const*, float const*, int, int, int, int, float*, float*, __hip_bfloat16*, float, float, float const*, float const*, float const*, ck_tile::ComposedAttention<0u, false> const*)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', 'nn.Module: RadixAttention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/radix_attention.py(105): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/base_attn_backend.py(80): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(2435): forward_decode', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::attention_paged_attention_ragged', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', 'aiter/ops/attention.py(598): paged_attention_ragged', 'csrc/cpp_itfs/pa/pa_ragged.py(65): paged_attention_ragged'], 'count': 36, 'total_duration_us': np.float64(1949.556), 'mean_duration_us': np.float64(54.154333333333334), 'median_duration_us': np.float64(53.9595), 'std_dev_duration_us': np.float64(1.6962556804129898), 'min_duration_us': np.float64(51.596), 'max_duration_us': np.float64(59.728)}]","[{'name': 'void paged_attention_ll4mi_reduce_kernel<__hip_bfloat16, __hip_b...', 'stream': 3, 'mean_duration_us': np.float64(4.95)}, {'name': 'void paged_attention_ll4mi_QKV_mfma16_kernel<0, __hip_bfloat16, ...', 'stream': 3, 'mean_duration_us': np.float64(54.15)}]","{'B': 1, 'N_Q': 32, 'H_Q': 32, 'H_V': 8, 'H_K': 8, 'N_KV': 32785, 'H_KV': 8, 'd_h_qk': 128, 'd_h_v': 128, 'dropout': 0.0, 'causal': False, 'flash_impl': True, 'c_sq': 0, 'c_sk': 0, 'c_sqsq': 0, 'c_sqsk': 0, 'g_sq': 32, 'g_sk': 32785, 'g_sqsq': 32, 'g_sqsk': 32785, 'dtype_Q': 'c10::BFloat16'}",True,21.760370003747013,46.48430727759788 +aiter::gemm_a16w16,GEMM,Unknown,Unknown,Unknown,"((32, 12288), (4096, 12288), (), (), (), (), ())","('c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '')","((12288, 1), (12288, 1), (), (), (), (), ())","('', '', '', '15', '', '', '')",3698,36,56613.924,1572.609,0.0,3.221225472,97.0,31.670103092783506,matrix_bf16,2.5179118357004993,0.18476128484204382,79.74252741517458,5.851408938502671,40.608425564236114,2.9926972240857443,1461.9033203125,1572.609,1572.609,1572.609,2.48711682149981,2.1481037191766696,2.7963528144767222,78.76724614069502,68.03066624031679,88.56078191827311,40.8994140625,36.373046875,47.349609375,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT32x32x256_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA1024_LBSPPB1024_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT2_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW2_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO1_USL1_UIOFGRO0_USFGROn1_VSn1_VWA2_VWB2_WSGRA0_WSGRB0_WS64_WG16_4_4', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen2MLP', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(94): forward', 'nn.Module: RowParallelLinear', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/linear.py(1514): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/quantization/unquant.py(136): apply', 'aiter/tuned_gemm.py(552): mm', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'aiter::gemm_a16w16', 'aiter/tuned_gemm.py(246): gemm_a16w16', 'aiter/tuned_gemm.py(395): torch_gemm', 'aten::linear', 'aten::matmul', 'aten::mm'], 'count': 36, 'total_duration_us': np.float64(1461.9070000000002), 'mean_duration_us': np.float64(40.60852777777778), 'median_duration_us': np.float64(40.8995), 'std_dev_duration_us': np.float64(2.950849194969241), 'min_duration_us': np.float64(36.373), 'max_duration_us': np.float64(47.35)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT32x32x256_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(40.61)}]","{'B': 1, 'M': 32, 'N': 4096, 'K': 12288, 'bias': False, 'dtype_A_B': ('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16'), 'transpose': (True, False)}",True,14.950000519309112,61.43430779690699 +aiter::gemm_a16w16,GEMM,Unknown,Unknown,Unknown,"((32, 4096), (6144, 4096), (), (), (), (), ())","('c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '')","((4096, 1), (4096, 1), (), (), (), (), ())","('', '', '', '15', '', '', '')",2306,36,56613.924,1572.609,0.0,1.610612736,48.625,31.588688946015424,matrix_bf16,2.3118616016609934,0.3492055932142782,73.02867702110615,11.030946862254629,25.097737630208332,21.22134930970088,903.5185546875,1572.609,1572.609,1572.609,2.401485497079251,0.34269780634320524,2.461955778375065,75.8597783756037,10.825374407057343,77.76995528193521,21.2314453125,20.7099609375,148.78125,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT64x32x256_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA2048_LBSPPB1024_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB2_WSGRA0_WSGRB0_WS64_WG16_4_4', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(167): forward_prepare_native', 'nn.Module: QKVParallelLinear', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/linear.py(461): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/quantization/unquant.py(136): apply', 'aiter/tuned_gemm.py(552): mm', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'aiter::gemm_a16w16', 'aiter/tuned_gemm.py(246): gemm_a16w16', 'aiter/tuned_gemm.py(395): torch_gemm', 'aten::linear', 'aten::matmul', 'aten::mm'], 'count': 36, 'total_duration_us': np.float64(903.515), 'mean_duration_us': np.float64(25.097638888888888), 'median_duration_us': np.float64(21.231), 'std_dev_duration_us': np.float64(20.9245116153716), 'min_duration_us': np.float64(20.71), 'max_duration_us': np.float64(148.781)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT64x32x256_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(25.1)}]","{'B': 1, 'M': 32, 'N': 6144, 'K': 4096, 'bias': False, 'dtype_A_B': ('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16'), 'transpose': (True, False)}",True,9.23973745329214,70.67404525019913 +aiter::gemm_a16w16,GEMM,Unknown,Unknown,Unknown,"((32, 4096), (4096, 4096), (), (), (), (), ())","('c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '')","((4096, 1), (4096, 1), (), (), (), (), ())","('', '', '', '15', '', '', '')",3402,36,56613.924,1572.609,0.0,1.073741824,32.5,31.50769230769231,matrix_bf16,2.045055758676163,0.13064427853186372,64.4349875964428,4.116299729742416,16.731689453125,1.0951818785939924,602.3408203125,1572.609,1572.609,1572.609,2.0135627422757225,1.7048516918266645,2.2566353647180546,63.44271532585662,53.71594253632322,71.10137272219347,16.9248046875,15.1015625,19.9892578125,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT16x32x512_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA1024_LBSPPB2048_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT1_2_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW1_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA1_VWB2_WSGRA0_WSGRB0_WS64_WG16_4_4', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', 'nn.Module: RowParallelLinear', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/linear.py(1514): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/quantization/unquant.py(136): apply', 'aiter/tuned_gemm.py(552): mm', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'aiter::gemm_a16w16', 'aiter/tuned_gemm.py(246): gemm_a16w16', 'aiter/tuned_gemm.py(395): torch_gemm', 'aten::linear', 'aten::matmul', 'aten::mm'], 'count': 36, 'total_duration_us': np.float64(602.3440000000002), 'mean_duration_us': np.float64(16.731777777777783), 'median_duration_us': np.float64(16.924500000000002), 'std_dev_duration_us': np.float64(1.079763299964681), 'min_duration_us': np.float64(15.102), 'max_duration_us': np.float64(19.989)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT16x32x512_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(16.73)}]","{'B': 1, 'M': 32, 'N': 4096, 'K': 4096, 'bias': False, 'dtype_A_B': ('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16'), 'transpose': (True, False)}",True,6.1597750352930465,76.83382028549218 +aten::mm,GEMM,Unknown,Unknown,Unknown,"((32, 4096), (4096, 151936))","('c10::BFloat16', 'c10::BFloat16')","((4096, 1), (1, 4096))","('', '')",60441,1,1572.609,1572.609,,39.829110784,1196.5234375,31.745303777219156,matrix_bf16,3.161654456289559,,100.36768115351072,,396.83203125,,396.83203125,1572.609,1572.609,1572.609,3.161654456289559,3.161654456289559,3.161654456289559,100.36768115351072,100.36768115351072,100.36768115351072,396.83203125,396.83203125,396.83203125,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x48x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB4_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB128_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_3_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB1_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: LogitsProcessor', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(285): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(839): _get_logits', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(883): _compute_lm_head', 'torch/utils/_device.py(99): __torch_function__', 'aten::matmul', 'aten::mm'], 'count': 1, 'total_duration_us': np.float64(396.832), 'mean_duration_us': np.float64(396.832), 'median_duration_us': np.float64(396.832), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(396.832), 'max_duration_us': np.float64(396.832)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x48x64_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(396.83)}]","{'M': 32, 'N': 151936, 'K': 4096, 'bias': False, 'stride_A': (4096, 1), 'stride_B': (1, 4096), 'dtype_A_B': ('c10::BFloat16', 'c10::BFloat16'), 'B': 1, 'transpose': (True, False)}",True,4.0581610225755655,80.89198130806774 +aiter::add_rmsnorm,RMSNorm,Unknown,Unknown,Unknown,"((32, 4096), (32, 4096), (32, 4096), (32, 4096), (4096,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((4096, 1), (4096, 1), (4096, 1), (4096, 1), (1,), ())","('', '', '', '', '', '9.9999999999999995e-07')",3557,72,113227.848,1572.609,0.0,0.000655424,1.0078125,0.6202156007751938,vector_bf16,0.22039436068874996,0.013737918655783806,0.1366920208220378,0.008520471472497716,4.817247178819445,0.36813716584561973,346.841796875,1572.609,1572.609,1572.609,0.2236268716676999,0.15077754382053782,0.2398338723404255,0.1386968745608597,0.09351458492406298,0.14874870921985814,4.7255859375,4.40625,7.0087890625,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb1ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/communicator.py(665): prepare_mlp', '/sgl-workspace/sglang/python/sglang/srt/layers/communicator.py(933): _simple', 'nn.Module: RMSNorm', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(81): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/layernorm.py(281): forward_aiter', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::rmsnorm_rmsnorm2d_fwd_with_add', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', 'aiter/ops/rmsnorm.py(76): rmsnorm2d_fwd_with_add', 'torch/_ops.py(1244): __call__', 'aiter::add_rmsnorm', 'aiter/jit/core.py(1637): custom_wrapper', 'aiter/jit/core.py(1396): wrapper'], 'count': 72, 'total_duration_us': np.float64(346.84399999999994), 'mean_duration_us': np.float64(4.817277777777777), 'median_duration_us': np.float64(4.726), 'std_dev_duration_us': np.float64(0.36565459651236065), 'min_duration_us': np.float64(4.406), 'max_duration_us': np.float64(7.009)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb1ELb0...', 'stream': 3, 'mean_duration_us': np.float64(4.82)}]","{'op_shape': (32, 4096), 'dtype_in_out': ('c10::BFloat16', None), 'stride_input': (4096, 1), 'stride_output': None, 'num_channels': 4096, 'has_bias': False, 'is_affine': True, 'is_training': False}",True,3.5469411494947125,84.43892245756246 +sgl_kernel::silu_and_mul,elementwise,Unknown,Unknown,Unknown,"((32, 12288), (32, 24576))","('c10::BFloat16', 'c10::BFloat16')","((12288, 1), (24576, 1))","('', '')",3664,36,56613.924,1572.609,0.0,0.00196608,2.25,0.8333333333333333,vector_bf16,0.26418305580074875,0.02341910845805231,0.22015254650062394,0.019515923715043605,9.010199652777779,0.9356385690682965,324.3671875,1572.609,1572.609,1572.609,0.2665469053155024,0.19248817655963668,0.29599596961529034,0.22212242109625202,0.16040681379969723,0.24666330801274194,8.85205078125,7.970703125,12.2568359375,"[{'name': '_ZN7sgl_hip10activation18act_and_mul_kernelI14__hip_bfloat16TnPFT_RKS3_EXadL_Z4siluIS2_ES3_S5_EEEEvPS3_PS4_i', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen2MLP', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(94): forward', 'nn.Module: SiluAndMul', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(81): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(94): forward_hip', '/sgl-workspace/sglang/python/sglang/srt/layers/activation.py(83): forward_cuda', 'sgl_kernel/elementwise.py(258): silu_and_mul', 'torch/_ops.py(840): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(840): __call__', 'sgl_kernel::silu_and_mul'], 'count': 36, 'total_duration_us': np.float64(324.367), 'mean_duration_us': np.float64(9.010194444444444), 'median_duration_us': np.float64(8.852), 'std_dev_duration_us': np.float64(0.9225923566970422), 'min_duration_us': np.float64(7.971), 'max_duration_us': np.float64(12.257)}]","[{'name': '_ZN7sgl_hip10activation18act_and_mul_kernelI14__hip_bfloat16TnPF...', 'stream': 3, 'mean_duration_us': np.float64(9.01)}]","{'op_shape': (32, 12288), 'dtype_in_out': ('c10::BFloat16', 'c10::BFloat16'), 'stride_input': (24576, 1), 'stride_output': (12288, 1)}",True,3.3171069209523654,87.75602937851482 +sgl_kernel::rotary_embedding,RoPE_fwd,Unknown,Unknown,Unknown,"((32,), (32, 4096), (32, 1024), (), (41216, 128), ())","('long int', 'c10::BFloat16', 'c10::BFloat16', 'Scalar', 'c10::BFloat16', 'Scalar')","((1,), (4096, 1), (1024, 1), (), (128, 1), ())","('', '', '', '128', '', 'True')",2833,36,56613.924,1572.609,0.0,0.00049152,0.625,0.7499999999999999,vector_bf16,0.12135509279604606,0.009707082817086257,0.09101631959703455,0.007280312112814698,5.439317491319445,0.5040695329554886,195.8154296875,1572.609,1572.609,1572.609,0.12396576073239926,0.09404269058295964,0.13413724565260843,0.09297432054929945,0.07053201793721973,0.10060293423945633,5.28662109375,4.8857421875,6.96875,"[{'name': 'void rotary_embedding_kernel(long const*, c10::BFloat16*, c10::BFloat16*, c10::BFloat16 const*, int, long, long, long, int, int, int)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(167): forward_prepare_native', 'nn.Module: RotaryEmbedding', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(81): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(94): forward_hip', '/sgl-workspace/sglang/python/sglang/srt/layers/rotary_embedding/base.py(335): forward_cuda', 'sgl_kernel/elementwise.py(327): rotary_embedding', 'torch/_ops.py(840): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(840): __call__', 'sgl_kernel::rotary_embedding'], 'count': 36, 'total_duration_us': np.float64(195.81500000000003), 'mean_duration_us': np.float64(5.439305555555556), 'median_duration_us': np.float64(5.2865), 'std_dev_duration_us': np.float64(0.4970839309549045), 'min_duration_us': np.float64(4.886), 'max_duration_us': np.float64(6.969)}]","[{'name': 'void rotary_embedding_kernel(long const*, c...', 'stream': 3, 'mean_duration_us': np.float64(5.44)}]",{'num_elements': 163840},True,2.002485892768261,89.75851527128309 +aten::copy_,elementwise,Unknown,Unknown,Unknown,"((32, 4096), (32, 4096), ())","('c10::BFloat16', 'c10::BFloat16', 'Scalar')","((4096, 1), (6144, 1), ())","('', '', 'False')",2504,36,56613.924,1572.609,0.0,0.000131072,0.5,0.25,vector_bf16,0.10746729184423291,0.007018556900696719,0.026866822961058228,0.0017546392251741798,4.901746961805555,0.36648663563973427,176.462890625,1572.609,1572.609,1572.609,0.10817467499496271,0.08500172767574414,0.11582975447680689,0.027043668748740677,0.021250431918936035,0.028957438619201723,4.8466796875,4.5263671875,6.16796875,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(167): forward_prepare_native', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::utils_apply_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/models/utils.py(416): apply_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'sglang_profiler::utils__reshape_for_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/models/utils.py(394): _reshape_for_qk_norm', 'aten::reshape', 'aten::clone', 'aten::copy_'], 'count': 36, 'total_duration_us': np.float64(176.46699999999996), 'mean_duration_us': np.float64(4.90186111111111), 'median_duration_us': np.float64(4.847), 'std_dev_duration_us': np.float64(0.36145071531090583), 'min_duration_us': np.float64(4.526), 'max_duration_us': np.float64(6.168)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::na...', 'stream': 3, 'mean_duration_us': np.float64(4.9)}]","{'op_shape': (32, 4096), 'dtype_in_out': ('c10::BFloat16', 'c10::BFloat16'), 'stride_input': (4096, 1), 'stride_output': (6144, 1)}",True,1.8045791878484863,91.56309445913158 +sglang::store_cache,InferenceAttention,Unknown,Unknown,Unknown,"((32, 1024), (32, 1024), (835874, 1024), (835874, 1024), (32,), (), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'long int', 'Scalar', 'Scalar')","((1024, 1), (6144, 1), (1024, 1), (1024, 1), (1,), (), ())","('', '', '', '', '', '2048', '0')",2982,36,56613.924,1572.609,0.0,0.0,0.25,0.0,vector_bf16,0.05458750456658629,0.003229331743270655,0.0,0.0,4.820638020833333,0.3202933594836537,173.54296875,1572.609,1572.609,1572.609,0.05594736473530638,0.045137961325037834,0.05895793015594114,0.0,0.0,0.0,4.685546875,4.4462890625,5.8076171875,"[{'name': 'void (anonymous namespace)::store_kvcache<2048l, 4, false, long>((anonymous namespace)::StoreKVCacheParams)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', 'nn.Module: RadixAttention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/radix_attention.py(105): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/base_attn_backend.py(80): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(2435): forward_decode', '/sgl-workspace/sglang/python/sglang/srt/mem_cache/memory_pool.py(1038): set_kv_buffer', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::memory_pool__set_kv_buffer_impl', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/mem_cache/memory_pool.py(90): _set_kv_buffer_impl', 'torch/_ops.py(1244): __call__', 'sglang::store_cache', '/sgl-workspace/sglang/python/sglang/jit_kernel/kvcache.py(50): store_cache'], 'count': 36, 'total_duration_us': np.float64(173.545), 'mean_duration_us': np.float64(4.820694444444444), 'median_duration_us': np.float64(4.686), 'std_dev_duration_us': np.float64(0.31601018087014254), 'min_duration_us': np.float64(4.446), 'max_duration_us': np.float64(5.808)}]","[{'name': 'void (anonymous namespace)::store_kvcache<2048l, 4, false, long>...', 'stream': 3, 'mean_duration_us': np.float64(4.82)}]","{'op_shape': (32, 1024), 'nelems': 32768, 'dtype': 'c10::BFloat16'}",True,1.7747189139568718,93.33781337308845 +aten::copy_,elementwise,Unknown,Unknown,Unknown,"((32, 1024), (32, 1024), ())","('c10::BFloat16', 'c10::BFloat16', 'Scalar')","((1024, 1), (6144, 1), ())","('', '', 'False')",2663,36,56613.924,1572.609,0.0,3.2768e-05,0.125,0.25,vector_bf16,0.027821325069313372,0.0015746796670120893,0.006955331267328343,0.0003936699167530223,4.727376302083333,0.29486444901236286,170.185546875,1572.609,1572.609,1572.609,0.028208854140395125,0.023041670042918454,0.029753431168255372,0.007052213535098781,0.005760417510729613,0.007438357792063843,4.646484375,4.4052734375,5.6884765625,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(167): forward_prepare_native', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::utils_apply_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/models/utils.py(416): apply_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'sglang_profiler::utils__reshape_for_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/models/utils.py(394): _reshape_for_qk_norm', 'aten::reshape', 'aten::clone', 'aten::copy_'], 'count': 36, 'total_duration_us': np.float64(170.181), 'mean_duration_us': np.float64(4.727250000000001), 'median_duration_us': np.float64(4.646), 'std_dev_duration_us': np.float64(0.2908131678777821), 'min_duration_us': np.float64(4.405), 'max_duration_us': np.float64(5.688)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::na...', 'stream': 3, 'mean_duration_us': np.float64(4.73)}]","{'op_shape': (32, 1024), 'dtype_in_out': ('c10::BFloat16', 'c10::BFloat16'), 'stride_input': (1024, 1), 'stride_output': (6144, 1)}",True,1.740384592338353,95.07819796542681 +aiter::rmsnorm,RMSNorm,Unknown,Unknown,Unknown,"((256, 128), (256, 128), (128,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((128, 1), (128, 1), (1,), ())","('', '', '', '9.9999999999999995e-07')",2753,36,56613.924,1572.609,0.0,0.000131584,0.125244140625,1.0019493177387915,vector_bf16,0.02859908185566152,0.0017242386549007672,0.028654830553235908,0.001727599743896673,4.610514322916667,0.3163628873091587,165.978515625,1572.609,1572.609,1572.609,0.029017126672840253,0.02293312960436562,0.030363484307970198,0.02907369027259238,0.022977833560709413,0.03042267238654324,4.52587890625,4.3251953125,5.7265625,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(167): forward_prepare_native', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::utils_apply_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/models/utils.py(416): apply_qk_norm', 'nn.Module: RMSNorm', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(81): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/layernorm.py(281): forward_aiter', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'sglang_profiler::rmsnorm_rmsnorm2d_fwd', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', 'aiter/ops/rmsnorm.py(62): rmsnorm2d_fwd', 'torch/_ops.py(1244): __call__', 'aiter::rmsnorm', 'aiter/jit/core.py(1637): custom_wrapper', 'aiter/jit/core.py(1396): wrapper'], 'count': 36, 'total_duration_us': np.float64(165.97099999999998), 'mean_duration_us': np.float64(4.610305555555555), 'median_duration_us': np.float64(4.5255), 'std_dev_duration_us': np.float64(0.31204271604349704), 'min_duration_us': np.float64(4.325), 'max_duration_us': np.float64(5.727)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0EL...', 'stream': 3, 'mean_duration_us': np.float64(4.61)}]","{'op_shape': (256, 128), 'dtype_in_out': ('c10::BFloat16', None), 'stride_input': (128, 1), 'stride_output': None, 'num_channels': 128, 'has_bias': False, 'is_affine': True, 'is_training': False}",True,1.697361829821605,96.77555979524841 +aiter::rmsnorm,RMSNorm,Unknown,Unknown,Unknown,"((1024, 128), (1024, 128), (128,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((128, 1), (128, 1), (1,), ())","('', '', '', '9.9999999999999995e-07')",2594,36,56613.924,1572.609,0.0,0.000526336,0.500244140625,1.0034163006344559,vector_bf16,0.11448449128883594,0.00615180258908413,0.11487560472906136,0.0061728189961722645,4.595974392361111,0.2723561217428755,165.455078125,1572.609,1572.609,1572.609,0.11640343635274938,0.0955922861719167,0.12127637299616166,0.11680110548621413,0.09591885815981491,0.12169068954617296,4.50634765625,4.3251953125,5.4873046875,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(167): forward_prepare_native', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::utils_apply_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/models/utils.py(416): apply_qk_norm', 'nn.Module: RMSNorm', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(81): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/layernorm.py(281): forward_aiter', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'sglang_profiler::rmsnorm_rmsnorm2d_fwd', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', 'aiter/ops/rmsnorm.py(62): rmsnorm2d_fwd', 'torch/_ops.py(1244): __call__', 'aiter::rmsnorm', 'aiter/jit/core.py(1637): custom_wrapper', 'aiter/jit/core.py(1396): wrapper'], 'count': 36, 'total_duration_us': np.float64(165.44999999999996), 'mean_duration_us': np.float64(4.595833333333332), 'median_duration_us': np.float64(4.506), 'std_dev_duration_us': np.float64(0.26861222566699716), 'min_duration_us': np.float64(4.325), 'max_duration_us': np.float64(5.487)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0EL...', 'stream': 3, 'mean_duration_us': np.float64(4.6)}]","{'op_shape': (1024, 128), 'dtype_in_out': ('c10::BFloat16', None), 'stride_input': (128, 1), 'stride_output': None, 'num_channels': 128, 'has_bias': False, 'is_affine': True, 'is_training': False}",True,1.6920089512912022,98.46756874653961 +aten::argmax,reduce,Unknown,Unknown,Unknown,"((32, 151936), (), ())","('float', 'Scalar', 'Scalar')","((151936, 1), (), ())","('', '-1', 'False')",53,1,44.336,44.336,,,,,,,,,,53.83984375,,53.83984375,44.336,44.336,44.336,,,,,,,53.83984375,53.83984375,53.83984375,"[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp, unsigned int, long, 4, 4> >(at::native::ReduceOp, unsigned int, long, 4, 4>)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3305): sample', 'nn.Module: Sampler', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/sampler.py(83): forward', 'torch/utils/_device.py(99): __torch_function__', 'aten::argmax'], 'count': 1, 'total_duration_us': np.float64(53.84), 'mean_duration_us': np.float64(53.84), 'median_duration_us': np.float64(53.84), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(53.84), 'max_duration_us': np.float64(53.84)}]","[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp(char*, char*, long*, int, long, long, long, long, bool)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: VocabParallelEmbedding', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/vocab_parallel_embedding.py(471): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/quantization/unquant.py(103): embedding', 'torch/nn/functional.py(2428): embedding', 'torch/overrides.py(1677): handle_torch_function', 'torch/utils/_device.py(99): __torch_function__', 'torch/nn/functional.py(2428): embedding', 'aten::embedding', 'aten::index_select', 'aten::gather'], 'count': 1, 'total_duration_us': np.float64(13.499), 'mean_duration_us': np.float64(13.499), 'median_duration_us': np.float64(13.499), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(13.499), 'max_duration_us': np.float64(13.499)}]","[{'name': 'void at::native::vectorized_gather_kernel<16, long>(char*, char*...', 'stream': 3, 'mean_duration_us': np.float64(13.5)}]",,False,0.13804634314507977,99.15620258807682 +aten::cumsum,reduce,Unknown,Unknown,Unknown,"((32,), (), ())","('int', 'Scalar', '')","((1,), (), ())","('', '0', '')",41,1,61.633,61.633,,3.2e-08,0.000244140625,0.125,,2.3937905214135693e-05,,2.9922381517669616e-06,,10.6943359375,,10.6943359375,61.633,61.633,61.633,2.3937905214135693e-05,2.3937905214135693e-05,2.3937905214135693e-05,2.9922381517669616e-06,2.9922381517669616e-06,2.9922381517669616e-06,10.6943359375,10.6943359375,10.6943359375,"[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel, (rocprim::ROCPRIM_400200_NS::detail::target_arch)942, rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2}, rocprim::ROCPRIM_400200_NS::detail::default_config_selector>(rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2})', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1251): replay_prepare', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(1654): init_forward_metadata_replay_cuda_graph', 'torch/utils/_device.py(99): __torch_function__', 'aten::cumsum'], 'count': 1, 'total_duration_us': np.float64(5.247), 'mean_duration_us': np.float64(5.247), 'median_duration_us': np.float64(5.247), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.247), 'max_duration_us': np.float64(5.247)}, {'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1251): replay_prepare', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(1654): init_forward_metadata_replay_cuda_graph', 'torch/utils/_device.py(99): __torch_function__', 'aten::cumsum', 'aten::to', 'aten::_to_copy', 'aten::copy_'], 'count': 1, 'total_duration_us': np.float64(5.447), 'mean_duration_us': np.float64(5.447), 'median_duration_us': np.float64(5.447), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.447), 'max_duration_us': np.float64(5.447)}]","[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel Host)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1251): replay_prepare', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(276): populate_from_forward_batch', 'torch/utils/_device.py(99): __torch_function__', 'aten::copy_', 'aten::copy_'], 'count': 2, 'total_duration_us': np.float64(9.411999999999999), 'mean_duration_us': np.float64(4.7059999999999995), 'median_duration_us': np.float64(4.7059999999999995), 'std_dev_duration_us': np.float64(0.18000000000000016), 'min_duration_us': np.float64(4.526), 'max_duration_us': np.float64(4.886)}]","[{'name': 'Memcpy DtoH (Device -> Host)', 'stream': 3, 'mean_duration_us': np.float64(4.71)}]","{'op_shape': (32,), 'dtype_in_out': ('int', 'long int'), 'stride_input': (1,), 'stride_output': (1,)}",True,0.09625194641049548,99.36181903595457 +aten::copy_,elementwise,Unknown,Unknown,Unknown,"((32, 151936), (32, 151936), ())","('float', 'c10::BFloat16', 'Scalar')","((151936, 1), (151936, 1), ())","('', '', 'False')",60455,1,1572.609,1572.609,,0.004861952,27.8203125,0.16666666666666666,vector_fp32,3.451794902703952,,0.5752991504506586,,8.451171875,,8.451171875,1572.609,1572.609,1572.609,3.451794902703952,3.451794902703952,3.451794902703952,0.5752991504506586,0.5752991504506586,0.5752991504506586,8.451171875,8.451171875,8.451171875,"[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::bfloat16tofloat32_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda(c10::BFloat16)#1}, std::array >(int, at::native::bfloat16tofloat32_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda(c10::BFloat16)#1}, std::array)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: LogitsProcessor', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(285): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(839): _get_logits', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(983): _copy_logits_to_buffer', 'torch/utils/_device.py(99): __torch_function__', 'aten::copy_'], 'count': 1, 'total_duration_us': np.float64(8.451), 'mean_duration_us': np.float64(8.451), 'median_duration_us': np.float64(8.451), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(8.451), 'max_duration_us': np.float64(8.451)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::bf...', 'stream': 3, 'mean_duration_us': np.float64(8.45)}]","{'op_shape': (32, 151936), 'dtype_in_out': ('float', 'c10::BFloat16'), 'stride_input': (151936, 1), 'stride_output': (151936, 1)}",True,0.0864250201531882,99.44824405610775 +"hipLaunchKernel->void (anonymous namespace)::resolve_future_token_ids_kernel(long*, long const*, unsigned long) (Synthetic Op)",other,Unknown,Unknown,Unknown,,,,,60465,1,5.338,5.338,,,,,,,,,,6.6494140625,,6.6494140625,5.338,5.338,5.338,,,,,,,6.6494140625,6.6494140625,6.6494140625,"[{'name': 'void (anonymous namespace)::resolve_future_token_ids_kernel(long*, long const*, unsigned long)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(6.649), 'mean_duration_us': np.float64(6.649), 'median_duration_us': np.float64(6.649), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(6.649), 'max_duration_us': np.float64(6.649)}]","[{'name': 'void (anonymous namespace)::resolve_future_token_ids_kernel, at::native::(anonymous namespace)::CopyFunctor, at::native::Copy >(at::native::(anonymous namespace)::TensorListMetadata<2>, at::native::(anonymous namespace)::CopyFunctor, at::native::Copy)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1251): replay_prepare', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(276): populate_from_forward_batch', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(113): _grouped_foreach_copy_', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(116): foreach_copy', 'torch/utils/_device.py(99): __torch_function__', 'aten::_foreach_copy_'], 'count': 1, 'total_duration_us': np.float64(6.528), 'mean_duration_us': np.float64(6.528), 'median_duration_us': np.float64(6.528), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(6.528), 'max_duration_us': np.float64(6.528)}]","[{'name': 'void at::native::(anonymous namespace)::multi_tensor_apply_kerne...', 'stream': 3, 'mean_duration_us': np.float64(6.53)}]",,False,0.06676118092489751,99.58300477045339 +aten::neg,elementwise,Unknown,Unknown,Unknown,"((32,),)","('long int',)","((1,),)","('',)",62,1,20.221,20.221,,3.2e-08,0.00048828125,0.0625,,9.000652360515021e-05,,5.625407725321888e-06,,5.6884765625,,5.6884765625,20.221,20.221,20.221,9.000652360515021e-05,9.000652360515021e-05,9.000652360515021e-05,5.625407725321888e-06,5.625407725321888e-06,5.625407725321888e-06,5.6884765625,5.6884765625,5.6884765625,"[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::neg_kernel_cuda(at::TensorIteratorBase&)::{lambda()#2}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, std::array >(int, at::native::neg_kernel_cuda(at::TensorIteratorBase&)::{lambda()#2}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, std::array)', 'stream': 2, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', 'torch/utils/_device.py(99): __torch_function__', 'aten::neg'], 'count': 1, 'total_duration_us': np.float64(5.688), 'mean_duration_us': np.float64(5.688), 'median_duration_us': np.float64(5.688), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.688), 'max_duration_us': np.float64(5.688)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::ne...', 'stream': 2, 'mean_duration_us': np.float64(5.69)}]","{'op_shape': (32,), 'dtype_in_out': ('long int', None), 'stride_input': (1,), 'stride_output': None}",True,0.05817260716342977,99.64117737761681 +aiter::rmsnorm,RMSNorm,Unknown,Unknown,Unknown,"((32, 4096), (32, 4096), (4096,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((4096, 1), (4096, 1), (1,), ())","('', '', '', '9.9999999999999995e-07')",2255,1,1572.609,1572.609,,0.000524352,0.5078125,0.9847355769230769,vector_bf16,0.09360678454935621,,0.09217793098712446,,5.6884765625,,5.6884765625,1572.609,1572.609,1572.609,0.09360678454935621,0.09360678454935621,0.09360678454935621,0.09217793098712446,0.09217793098712446,0.09217793098712446,5.6884765625,5.6884765625,5.6884765625,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', 'torch/cuda/graphs.py(139): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1147): run_once', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/communicator.py(499): prepare_attn', 'nn.Module: RMSNorm', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(81): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/layernorm.py(281): forward_aiter', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::rmsnorm_rmsnorm2d_fwd', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', 'aiter/ops/rmsnorm.py(62): rmsnorm2d_fwd', 'torch/_ops.py(1244): __call__', 'aiter::rmsnorm', 'aiter/jit/core.py(1637): custom_wrapper', 'aiter/jit/core.py(1396): wrapper'], 'count': 1, 'total_duration_us': np.float64(5.688), 'mean_duration_us': np.float64(5.688), 'median_duration_us': np.float64(5.688), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.688), 'max_duration_us': np.float64(5.688)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb0ELb0...', 'stream': 3, 'mean_duration_us': np.float64(5.69)}]","{'op_shape': (32, 4096), 'dtype_in_out': ('c10::BFloat16', None), 'stride_input': (4096, 1), 'stride_output': None, 'num_channels': 4096, 'has_bias': False, 'is_affine': True, 'is_training': False}",True,0.05817260716342977,99.69934998478024 +aten::_foreach_copy_,multi_tensor_apply,Unknown,Unknown,Unknown,"(((32,), (32,), (32,), (32,)), ((32,), (32,), (32,), (32,)), ())","('TensorList', 'TensorList', 'Scalar')","(((1,), (1,), (1,), (1,)), ((1,), (1,), (1,), (1,)), ())","('', '', 'False')",18,1,22.174,22.174,,,,,,,,,,5.568359375,,5.568359375,22.174,22.174,22.174,,,,,,,5.568359375,5.568359375,5.568359375,"[{'name': 'void at::native::(anonymous namespace)::multi_tensor_apply_kernel, at::native::(anonymous namespace)::UnaryOpFunctor, at::native::Copy >(at::native::(anonymous namespace)::TensorListMetadata<2>, at::native::(anonymous namespace)::UnaryOpFunctor, at::native::Copy)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1333): replay', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(1251): replay_prepare', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(276): populate_from_forward_batch', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(113): _grouped_foreach_copy_', '/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py(116): foreach_copy', 'torch/utils/_device.py(99): __torch_function__', 'aten::_foreach_copy_'], 'count': 1, 'total_duration_us': np.float64(5.568), 'mean_duration_us': np.float64(5.568), 'median_duration_us': np.float64(5.568), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.568), 'max_duration_us': np.float64(5.568)}]","[{'name': 'void at::native::(anonymous namespace)::multi_tensor_apply_kerne...', 'stream': 3, 'mean_duration_us': np.float64(5.57)}]",,False,0.05694424138126636,99.7562942261615 +"hipLaunchKernel->void (anonymous namespace)::clamp_position_kernel(long*, long const*, unsigned long) (Synthetic Op)",other,Unknown,Unknown,Unknown,,,,,60466,1,7.912,7.912,,,,,,,,,,5.52734375,,5.52734375,7.912,7.912,7.912,,,,,,,5.52734375,5.52734375,5.52734375,"[{'name': 'void (anonymous namespace)::clamp_position_kernel(long*, long const*, unsigned long)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.527), 'mean_duration_us': np.float64(5.527), 'median_duration_us': np.float64(5.527), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.527), 'max_duration_us': np.float64(5.527)}]","[{'name': 'void (anonymous namespace)::clamp_position_kernel(long*, l...', 'stream': 3, 'mean_duration_us': np.float64(5.53)}]",,False,0.0565247994068691,99.81281902556837 +hipModuleLaunchKernel->create_flashinfer_kv_indices_triton (Synthetic Op),other,Unknown,Unknown,Unknown,,,,,60464,1,7.972,7.972,,,,,,,,,,5.4072265625,,5.4072265625,7.972,7.972,7.972,,,,,,,5.4072265625,5.4072265625,5.4072265625,"[{'name': 'create_flashinfer_kv_indices_triton', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.407), 'mean_duration_us': np.float64(5.407), 'median_duration_us': np.float64(5.407), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.407), 'max_duration_us': np.float64(5.407)}]","[{'name': 'create_flashinfer_kv_indices_triton', 'stream': 3, 'mean_duration_us': np.float64(5.41)}]",,False,0.05529643362470569,99.86811545919308 +aten::copy_,elementwise,Unknown,Unknown,Unknown,"((32,), (32,), ())","('long int', 'long int', 'Scalar')","((1,), (1,), ())","('', '', 'False')",57,1,9.044,9.044,,3.2e-08,0.00048828125,0.0625,,0.0001083463525521802,,6.771647034511262e-06,,4.7255859375,,4.7255859375,9.044,9.044,9.044,0.0001083463525521802,0.0001083463525521802,0.0001083463525521802,6.771647034511262e-06,6.771647034511262e-06,6.771647034511262e-06,4.7255859375,4.7255859375,4.7255859375,"[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/overlap_utils.py(161): store_to_map', 'torch/utils/_device.py(99): __torch_function__', 'aten::copy_'], 'count': 1, 'total_duration_us': np.float64(4.726), 'mean_duration_us': np.float64(4.726), 'median_duration_us': np.float64(4.726), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(4.726), 'max_duration_us': np.float64(4.726)}]","[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'mean_duration_us': np.float64(4.73)}]","{'op_shape': (32,), 'dtype_in_out': ('long int', 'long int'), 'stride_input': (1,), 'stride_output': (1,)}",True,0.04832570747877025,99.91644116667185 +aten::arange,other,Unknown,Unknown,Unknown,"((), (), (), (0,))","('Scalar', 'Scalar', 'Scalar', 'long int')","((), (), (), (1,))","('238', '270', '1', '')",3,1,9.714,9.714,,,,,,,,,,4.24609375,,4.24609375,9.714,9.714,9.714,,,,,,,4.24609375,4.24609375,4.24609375,"[{'name': 'void (anonymous namespace)::elementwise_kernel_with_index(int, at::native::arange_cuda_out(c10::Scalar const&, c10::Scalar const&, c10::Scalar const&, at::Tensor&)::{lambda()#1}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, function_traits::result_type*)', 'stream': 2, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/overlap_utils.py(121): alloc_future_indices', 'torch/utils/_device.py(99): __torch_function__', 'aten::arange', 'aten::arange'], 'count': 1, 'total_duration_us': np.float64(4.246), 'mean_duration_us': np.float64(4.246), 'median_duration_us': np.float64(4.246), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(4.246), 'max_duration_us': np.float64(4.246)}]","[{'name': 'void (anonymous namespace)::elementwise_kernel_with_index Device)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/utils.py(56): copy_to_cpu', 'torch/utils/_device.py(99): __torch_function__', 'aten::to', 'aten::_to_copy', 'aten::copy_'], 'count': 1, 'total_duration_us': np.float64(3.925), 'mean_duration_us': np.float64(3.925), 'median_duration_us': np.float64(3.925), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(3.925), 'max_duration_us': np.float64(3.925)}]","[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'mean_duration_us': np.float64(3.92)}]","{'op_shape': (32,), 'dtype_in_out': ('long int', 'long int'), 'stride_input': (1,), 'stride_output': (1,)}",True,0.04013660226434751,99.99999999999999 diff --git a/tests/traces/inference/sglang_decode/sglang_Qwen3-8B_decode.json.gz b/tests/traces/inference/sglang_decode/sglang_Qwen3-8B_decode.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..b6a467c11f36e8b829a7872c346fbff6496dd0ad GIT binary patch literal 36647 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 literal 0 HcmV?d00001 diff --git a/tests/traces/inference/sglang_prefilldecode/perf_csvs/GEMM.csv b/tests/traces/inference/sglang_prefilldecode/perf_csvs/GEMM.csv new file mode 100644 index 000000000..08311e347 --- /dev/null +++ b/tests/traces/inference/sglang_prefilldecode/perf_csvs/GEMM.csv @@ -0,0 +1,10 @@ +name,param: B,param: M,param: N,param: K,param: bias,param: dtype_A_B,param: transpose,param: stride_A,param: stride_B,num_kernels,GFLOPS_first,Data Moved (MB)_first,FLOPS/Byte_first,TB/s_mean,TB/s_median,TB/s_std,TB/s_min,TB/s_max,TFLOPS/s_mean,TFLOPS/s_median,TFLOPS/s_std,TFLOPS/s_min,TFLOPS/s_max,process_name_first,process_label_first,thread_name_first,Compute Spec,kernel_details__summarize_kernel_stats,trunc_kernel_details,Input Dims_first,Input type_first,Input Strides_first,Concrete Inputs_first,Kernel Time (µs)_mean,Kernel Time (µs)_median,Kernel Time (µs)_std,Kernel Time (µs)_min,Kernel Time (µs)_max,Kernel Time (µs)_sum,name_count,UID_first +aiter::gemm_a16w16,1,15360,24576,4096,False,"('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16')","(True, False)",nan,nan,1,3092.37645312,1032.0,2857.6744186046512,0.15989855459699648,0.1598142700762255,0.0009942644080381477,0.15676364830950568,0.1614992228734229,456.93800904369596,456.69715132480445,2.841283964179698,447.9794675412107,461.5121978299117,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT128x256x32_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA4_GRVWB4_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB256_LBSPPM0_LPA4_LPB4_LPM0_LRVW4_LWPMn1_MIAV0_MIWT8_4_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW8_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA8_VWB4_WSGRA0_WSGRB0_WS64_WG16_16_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(243643.021), 'mean_duration_us': np.float64(6767.861694444445), 'median_duration_us': np.float64(6771.1755), 'std_dev_duration_us': np.float64(41.71130077943137), 'min_duration_us': np.float64(6700.53), 'max_duration_us': np.float64(6902.942)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT128x256x32_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(6767.86)}]","[[15360, 4096], [24576, 4096], [], [], [], [], []]","['c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '']","[[4096, 1], [4096, 1], [], [], [], [], []]","['', '', '', '15', '', '', '']",6767.86181640625,6771.17529296875,42.30302141272883,6700.5302734375,6902.9423828125,243643.025390625,36,163 +aten::mm,1,15360,24576,4096,False,"('c10::BFloat16', 'c10::BFloat16')","(True, False)","(4096, 1)","(1, 4096)",1,3092.37645312,1032.0,2857.6744186046512,0.15989855459699648,0.1598142700762255,0.0009942644080381477,0.15676364830950568,0.1614992228734229,456.93800904369596,456.69715132480445,2.841283964179698,447.9794675412107,461.5121978299117,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT128x256x32_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA4_GRVWB4_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB256_LBSPPM0_LPA4_LPB4_LPM0_LRVW4_LWPMn1_MIAV0_MIWT8_4_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW8_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA8_VWB4_WSGRA0_WSGRB0_WS64_WG16_16_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(243643.021), 'mean_duration_us': np.float64(6767.861694444445), 'median_duration_us': np.float64(6771.1755), 'std_dev_duration_us': np.float64(41.71130077943137), 'min_duration_us': np.float64(6700.53), 'max_duration_us': np.float64(6902.942)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT128x256x32_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(6767.86)}]","[[15360, 4096], [4096, 24576]]","['c10::BFloat16', 'c10::BFloat16']","[[4096, 1], [1, 4096]]","['', '']",6767.86181640625,6771.17529296875,42.30302141272883,6700.5302734375,6902.9423828125,243643.025390625,36,169 +aiter::gemm_a16w16,1,15360,4096,12288,False,"('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16')","(True, False)",nan,nan,1,1546.18822656,576.0,2560.0,0.22784430668329525,0.22773631836216326,0.0021934151326576576,0.222524755068712,0.23237480025639273,583.281425109236,583.004975007138,5.615142739603605,569.6633729759027,594.8794886563654,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x16x1_SN_LDSB0_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA1_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA0_LBSPPB256_LBSPPM0_LPA0_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT5_14_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA2_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW1_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA1_VWB2_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(95439.041), 'mean_duration_us': np.float64(2651.0844722222223), 'median_duration_us': np.float64(2652.1014999999998), 'std_dev_duration_us': np.float64(25.310139447666806), 'min_duration_us': np.float64(2599.162), 'max_duration_us': np.float64(2714.214)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(2651.08)}]","[[15360, 12288], [4096, 12288], [], [], [], [], []]","['c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '']","[[12288, 1], [12288, 1], [], [], [], [], []]","['', '', '', '15', '', '', '']",2651.0844997829863,2652.1015625,25.669117118336754,2599.162109375,2714.2138671875,95439.0419921875,36,172 +aten::mm,1,15360,4096,12288,False,"('c10::BFloat16', 'c10::BFloat16')","(True, False)","(12288, 1)","(1, 12288)",1,1546.18822656,576.0,2560.0,0.22784430668329525,0.22773631836216326,0.0021934151326576576,0.222524755068712,0.23237480025639273,583.281425109236,583.004975007138,5.615142739603605,569.6633729759027,594.8794886563654,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x16x1_SN_LDSB0_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA1_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA0_LBSPPB256_LBSPPM0_LPA0_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT5_14_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA2_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW1_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA1_VWB2_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(95439.041), 'mean_duration_us': np.float64(2651.0844722222223), 'median_duration_us': np.float64(2652.1014999999998), 'std_dev_duration_us': np.float64(25.310139447666806), 'min_duration_us': np.float64(2599.162), 'max_duration_us': np.float64(2714.214)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(2651.08)}]","[[15360, 12288], [12288, 4096]]","['c10::BFloat16', 'c10::BFloat16']","[[12288, 1], [1, 12288]]","['', '']",2651.0844997829863,2652.1015625,25.669117118336754,2599.162109375,2714.2138671875,95439.0419921875,36,178 +aiter::gemm_a16w16,1,15360,6144,4096,False,"('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16')","(True, False)",nan,nan,1,773.09411328,348.0,2118.6206896551726,0.25629236994956,0.257305160693752,0.006763183331447345,0.22010358625052645,0.26236321765011933,542.9863175758953,545.1320370008318,14.328620133935333,466.3160116976671,555.8481411180459,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x192x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA1024_LBSPPB256_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT8_6_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW8_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA8_VWB2_WSGRA0_WSGRB0_WS64_WG32_8_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(51295.484000000004), 'mean_duration_us': np.float64(1424.8745555555556), 'median_duration_us': np.float64(1418.1775), 'std_dev_duration_us': np.float64(42.04861841200046), 'min_duration_us': np.float64(1390.837), 'max_duration_us': np.float64(1657.876)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x192x64_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(1424.87)}]","[[15360, 4096], [6144, 4096], [], [], [], [], []]","['c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '']","[[4096, 1], [4096, 1], [], [], [], [], []]","['', '', '', '15', '', '', '']",1424.874538845486,1418.177734375,42.645073981571386,1390.8369140625,1657.8759765625,51295.4833984375,36,84 +aten::mm,1,15360,6144,4096,False,"('c10::BFloat16', 'c10::BFloat16')","(True, False)","(4096, 1)","(1, 4096)",1,773.09411328,348.0,2118.6206896551726,0.25629236994956,0.257305160693752,0.006763183331447345,0.22010358625052645,0.26236321765011933,542.9863175758953,545.1320370008318,14.328620133935333,466.3160116976671,555.8481411180459,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x192x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA1024_LBSPPB256_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT8_6_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW8_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA8_VWB2_WSGRA0_WSGRB0_WS64_WG32_8_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(51295.484000000004), 'mean_duration_us': np.float64(1424.8745555555556), 'median_duration_us': np.float64(1418.1775), 'std_dev_duration_us': np.float64(42.04861841200046), 'min_duration_us': np.float64(1390.837), 'max_duration_us': np.float64(1657.876)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x192x64_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(1424.87)}]","[[15360, 4096], [4096, 6144]]","['c10::BFloat16', 'c10::BFloat16']","[[4096, 1], [1, 4096]]","['', '']",1424.874538845486,1418.177734375,42.645073981571386,1390.8369140625,1657.8759765625,51295.4833984375,36,90 +aiter::gemm_a16w16,1,15360,4096,4096,False,"('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16')","(True, False)",nan,nan,1,515.39607552,272.0,1807.0588235294115,0.34829642598889776,0.34917679608781427,0.007117676621272211,0.32493575013378695,0.3596699771038994,629.3921297869965,630.9830103422149,12.862060341498934,587.1780143594079,649.944805684223,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x16x1_SN_LDSB0_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA1_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA0_LBSPPB256_LBSPPM0_LPA0_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT5_14_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA2_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW1_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA1_VWB2_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(29491.870999999996), 'mean_duration_us': np.float64(819.2186388888888), 'median_duration_us': np.float64(816.819), 'std_dev_duration_us': np.float64(16.860455720993983), 'min_duration_us': np.float64(792.984), 'max_duration_us': np.float64(877.751)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(819.22)}]","[[15360, 4096], [4096, 4096], [], [], [], [], []]","['c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '']","[[4096, 1], [4096, 1], [], [], [], [], []]","['', '', '', '15', '', '', '']",819.2186686197916,816.81884765625,17.09959181546983,792.984375,877.7509765625,29491.8720703125,36,149 +aten::mm,1,15360,4096,4096,False,"('c10::BFloat16', 'c10::BFloat16')","(True, False)","(4096, 1)","(1, 4096)",1,515.39607552,272.0,1807.0588235294115,0.34829642598889776,0.34917679608781427,0.007117676621272211,0.32493575013378695,0.3596699771038994,629.3921297869965,630.9830103422149,12.862060341498934,587.1780143594079,649.944805684223,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x16x1_SN_LDSB0_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA1_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA0_LBSPPB256_LBSPPM0_LPA0_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT5_14_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA2_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW1_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA1_VWB2_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(29491.870999999996), 'mean_duration_us': np.float64(819.2186388888888), 'median_duration_us': np.float64(816.819), 'std_dev_duration_us': np.float64(16.860455720993983), 'min_duration_us': np.float64(792.984), 'max_duration_us': np.float64(877.751)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(819.22)}]","[[15360, 4096], [4096, 4096]]","['c10::BFloat16', 'c10::BFloat16']","[[4096, 1], [1, 4096]]","['', '']",819.2186686197916,816.81884765625,17.09959181546983,792.984375,877.7509765625,29491.8720703125,36,155 +aten::mm,1,15,151936,4096,False,"('c10::BFloat16', 'c10::BFloat16')","(True, False)","(4096, 1)","(1, 4096)",1,18.66989568,1191.464111328125,14.943798835999154,2.8632861644348853,2.8632861644348853,,2.8632861644348853,2.8632861644348853,42.788372451214514,42.788372451214514,,42.788372451214514,42.788372451214514,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x16x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB4_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB128_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_1_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB1_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(436.331), 'mean_duration_us': np.float64(436.331), 'median_duration_us': np.float64(436.331), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(436.331), 'max_duration_us': np.float64(436.331)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x16x64_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(436.33)}]","[[15, 4096], [4096, 151936]]","['c10::BFloat16', 'c10::BFloat16']","[[4096, 1], [1, 4096]]","['', '']",436.3310546875,436.3310546875,,436.3310546875,436.3310546875,436.3310546875,1,3771 diff --git a/tests/traces/inference/sglang_prefilldecode/perf_csvs/InferenceAttention_fwd.csv b/tests/traces/inference/sglang_prefilldecode/perf_csvs/InferenceAttention_fwd.csv new file mode 100644 index 000000000..3f64f665d --- /dev/null +++ b/tests/traces/inference/sglang_prefilldecode/perf_csvs/InferenceAttention_fwd.csv @@ -0,0 +1,3 @@ +name,param: op_shape,param: nelems,param: dtype,param: B,param: N_Q,param: H_Q,param: H_V,param: H_K,param: N_KV,param: H_KV,param: d_h_qk,param: d_h_v,param: dropout,param: causal,param: flash_impl,param: c_sq,param: c_sk,param: c_sqsq,param: c_sqsk,param: g_sq,param: g_sk,param: g_sqsq,param: g_sqsk,param: dtype_Q,param: dtype_KV,num_kernels,GFLOPS_first,Data Moved (MB)_first,FLOPS/Byte_first,TB/s_mean,TB/s_median,TB/s_std,TB/s_min,TB/s_max,TFLOPS/s_mean,TFLOPS/s_median,TFLOPS/s_std,TFLOPS/s_min,TFLOPS/s_max,process_name_first,process_label_first,thread_name_first,Compute Spec,kernel_details__summarize_kernel_stats,trunc_kernel_details,Input Dims_first,Input type_first,Input Strides_first,Concrete Inputs_first,Kernel Time (µs)_mean,Kernel Time (µs)_median,Kernel Time (µs)_std,Kernel Time (µs)_min,Kernel Time (µs)_max,Kernel Time (µs)_sum,name_count,UID_first +aiter::mha_batch_prefill,nan,nan,nan,1.0,15360.0,32.0,8.0,8.0,835874.0,8.0,128.0,128.0,0.0,False,True,15360.0,15360.0,15728640.0,15728640.0,0.0,0.0,0.0,0.0,c10::BFloat16,c10::BFloat16,1,128.84901888,300.0,409.59999999999997,0.5645582448635644,0.5627077051306074,0.016168636904452395,0.5365614948712908,0.5980182812587024,231.243057096116,230.4850760214968,6.622673676063697,219.77558829928074,244.94828800356447,Unknown,Unknown,Unknown,matrix_bf16,"[{'name': '_ZN7ck_tile6kentryILi2ENS_38FmhaBatchPrefillWithPagedKVCacheKernelINS_40BlockFmhaBatchPrefillPipelineQRKSVSAsyncINS_36BlockFmhaBatchPrefillPipelineProblemIDF16bDF16bDF16bffDF16bhfDF16bfDF16bNS_13TileFmhaShapeINS_8sequenceIJLi128ELi128ELi32ELi128ELi32ELi128EEEENS5_IJLi4ELi1ELi1EEEENS5_IJLi32ELi32ELi16EEEES7_S8_Lb1EEELb1ENS_17ComposedAttentionILj0ELb1EEENS_30SimplifiedGenericAttentionMaskILb1EEELb0ELi1ENS_26TileFmhaBatchPrefillTraitsILb1ELb1ELb1ELb1ELb0ELNS_22BlockAttentionBiasEnumE0ELb0ELb0ELb0ELNS_28BlockAttentionQuantScaleEnumE0ELin1ELb0ELb0ELi1ELNS_37BlockAttentionKVCacheMemoryLayoutEnumE1ELNS_36BlockAttentionKVCacheLookupTableEnumE1ELNS_33BlockAttentionKVCacheLoadModeEnumE0EEEEENS_53BlockFmhaBatchPrefillPipelineQRKSVSAsyncDefaultPolicyEEENS_17Default2DEpilogueINS_24Default2DEpilogueProblemIfDF16bLb1ELb1ELb1EEEvEEEEJNSS_21FmhaFwdGroupModeKargsEEEEvDpT1_', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(20075.157999999996), 'mean_duration_us': np.float64(557.6432777777777), 'median_duration_us': np.float64(559.034), 'std_dev_duration_us': np.float64(15.642999795100248), 'min_duration_us': np.float64(526.025), 'max_duration_us': np.float64(586.275)}]","[{'name': '_ZN7ck_tile6kentryILi2ENS_38FmhaBatchPrefillWithPagedKVCacheKern...', 'stream': 3, 'mean_duration_us': np.float64(557.64)}]","[[15360, 32, 128], [835874, 8, 128], [835874, 8, 128], [16], [16], [15616], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]","['c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'int', 'int', 'int', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', '', '', '', '', '', '', '', '', '', '', '', '']","[[4096, 128, 1], [1024, 128, 1], [1024, 128, 1], [1], [1], [1], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], []]","['', '', '', '', '', '', '1024', '1024', '0.', '0.088388347648318447', '0.', 'False', 'True', '-1', '-1', '0', 'False', 'False', '', '', '', '', '', '', '', '', '', '', '', '']",557.6432291666666,559.0341796875,15.864896127076442,526.025390625,586.275390625,20075.15625,36,142 +sglang::store_cache,"(15360, 1024)",15728640.0,c10::BFloat16,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,nan,1,0.0,120.0,0.0,3.5701923646690665,3.5816809736345037,0.15744014539551918,3.218409363806669,3.9560644421246542,0.0,0.0,0.0,0.0,0.0,Unknown,Unknown,Unknown,vector_bf16,"[{'name': 'void (anonymous namespace)::store_kvcache<2048l, 4, false, long>((anonymous namespace)::StoreKVCacheParams)', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(1271.2200000000003), 'mean_duration_us': np.float64(35.311666666666675), 'median_duration_us': np.float64(35.1315), 'std_dev_duration_us': np.float64(1.54956371996192), 'min_duration_us': np.float64(31.807), 'max_duration_us': np.float64(39.097)}]","[{'name': 'void (anonymous namespace)::store_kvcache<2048l, 4, false, long>...', 'stream': 3, 'mean_duration_us': np.float64(35.31)}]","[[15360, 1024], [15360, 1024], [835874, 1024], [835874, 1024], [15360], [], []]","['c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'long int', 'Scalar', 'Scalar']","[[1024, 1], [6144, 1], [1024, 1], [1024, 1], [1], [], []]","['', '', '', '', '', '2048', '0']",35.311604817708336,35.13134765625,1.5715359604665984,31.806640625,39.0966796875,1271.2177734375,36,135 diff --git a/tests/traces/inference/sglang_prefilldecode/perf_csvs/RMSNorm_fwd.csv b/tests/traces/inference/sglang_prefilldecode/perf_csvs/RMSNorm_fwd.csv new file mode 100644 index 000000000..9b4752d8e --- /dev/null +++ b/tests/traces/inference/sglang_prefilldecode/perf_csvs/RMSNorm_fwd.csv @@ -0,0 +1,5 @@ +name,param: op_shape,param: dtype_in_out,param: stride_input,param: stride_output,param: num_channels,param: has_bias,param: is_affine,param: is_training,num_kernels,GFLOPS_first,Data Moved (MB)_first,FLOPS/Byte_first,TB/s_mean,TB/s_median,TB/s_std,TB/s_min,TB/s_max,TFLOPS/s_mean,TFLOPS/s_median,TFLOPS/s_std,TFLOPS/s_min,TFLOPS/s_max,process_name_first,process_label_first,thread_name_first,Compute Spec,kernel_details__summarize_kernel_stats,trunc_kernel_details,Input Dims_first,Input type_first,Input Strides_first,Concrete Inputs_first,Kernel Time (µs)_mean,Kernel Time (µs)_median,Kernel Time (µs)_std,Kernel Time (µs)_min,Kernel Time (µs)_max,Kernel Time (µs)_sum,name_count,UID_first +aiter::rmsnorm,"(491520, 128)","('c10::BFloat16', None)","(128, 1)",None,128,False,True,False,1,0.25264128,240.000244140625,1.0039052287747918,0.654200659311961,0.6439519483741629,0.06424884195040104,0.6292783638752277,1.0258118572372559,0.6567554625511939,0.646466728052537,0.06449974837673281,0.6317358398491871,1.0298178872196615,Unknown,Unknown,Unknown,vector_bf16,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(13933.577), 'mean_duration_us': np.float64(387.04380555555554), 'median_duration_us': np.float64(390.803), 'std_dev_duration_us': np.float64(24.471096357425704), 'min_duration_us': np.float64(245.326), 'max_duration_us': np.float64(399.916)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0EL...', 'stream': 3, 'mean_duration_us': np.float64(387.04)}]","[[491520, 128], [491520, 128], [128], []]","['c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar']","[[128, 1], [128, 1], [1], []]","['', '', '', '9.9999999999999995e-07']",387.04380967881946,390.80322265625,24.818198394275207,245.326171875,399.916015625,13933.5771484375,36,106 +aiter::add_rmsnorm,"(15360, 4096)","('c10::BFloat16', None)","(4096, 1)",None,4096,False,True,False,1,0.31460352,480.0078125,0.6250508618023796,4.1682095657777065,4.162462881821314,0.10389215802578437,4.030943236677042,4.8548865331097755,2.6053429812622775,2.6017510115028286,0.06493788290852544,2.5195445439614588,3.034551011473032,Unknown,Unknown,Unknown,vector_bf16,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb1ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 72, 'total_duration_us': np.float64(8699.121), 'mean_duration_us': np.float64(120.821125), 'median_duration_us': np.float64(120.9195), 'std_dev_duration_us': np.float64(2.7485319815893434), 'min_duration_us': np.float64(103.674), 'max_duration_us': np.float64(124.865)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb1ELb0...', 'stream': 3, 'mean_duration_us': np.float64(120.82)}]","[[15360, 4096], [15360, 4096], [15360, 4096], [15360, 4096], [4096], []]","['c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar']","[[4096, 1], [4096, 1], [4096, 1], [4096, 1], [1], []]","['', '', '', '', '', '9.9999999999999995e-07']",120.82103135850694,120.919921875,2.767866612625456,103.673828125,124.865234375,8699.1142578125,72,161 +aiter::rmsnorm,"(122880, 128)","('c10::BFloat16', None)","(128, 1)",None,128,False,True,False,1,0.06316032,60.000244140625,1.0039021651116329,0.6411243209576277,0.6279671012361419,0.06142780972465145,0.6127755629280172,0.9933816200080182,0.643626093915088,0.6304175325498389,0.06166751118064305,0.6151667143509361,0.9972579591081508,Unknown,Unknown,Unknown,vector_bf16,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(3553.835), 'mean_duration_us': np.float64(98.71763888888889), 'median_duration_us': np.float64(100.1885), 'std_dev_duration_us': np.float64(6.229195699610279), 'min_duration_us': np.float64(63.334), 'max_duration_us': np.float64(102.672)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0EL...', 'stream': 3, 'mean_duration_us': np.float64(98.72)}]","[[122880, 128], [122880, 128], [128], []]","['c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar']","[[128, 1], [128, 1], [1], []]","['', '', '', '9.9999999999999995e-07']",98.71761067708333,100.1884765625,6.3175549998410485,63.333984375,102.671875,3553.833984375,36,120 +aiter::rmsnorm,"(15360, 4096)","('c10::BFloat16', None)","(4096, 1)",None,4096,False,True,False,1,0.25168896,240.0078125,1.0000895153152567,3.49404016443408,3.49404016443408,,3.49404016443408,3.49404016443408,3.494352934540919,3.494352934540919,,3.494352934540919,3.494352934540919,Unknown,Unknown,Unknown,vector_bf16,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(72.027), 'mean_duration_us': np.float64(72.027), 'median_duration_us': np.float64(72.027), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(72.027), 'max_duration_us': np.float64(72.027)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb0ELb0...', 'stream': 3, 'mean_duration_us': np.float64(72.03)}]","[[15360, 4096], [15360, 4096], [4096], []]","['c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar']","[[4096, 1], [4096, 1], [1], []]","['', '', '', '9.9999999999999995e-07']",72.02734375,72.02734375,,72.02734375,72.02734375,72.02734375,1,80 diff --git a/tests/traces/inference/sglang_prefilldecode/perf_csvs/Reduce_fwd.csv b/tests/traces/inference/sglang_prefilldecode/perf_csvs/Reduce_fwd.csv new file mode 100644 index 000000000..cc4411c72 --- /dev/null +++ b/tests/traces/inference/sglang_prefilldecode/perf_csvs/Reduce_fwd.csv @@ -0,0 +1,4 @@ +name,param: num_input_elems,param: num_output_elems,param: dtype_in_out,param: reduce_type,num_kernels,GFLOPS_first,Data Moved (MB)_first,FLOPS/Byte_first,TB/s_mean,TB/s_median,TB/s_std,TB/s_min,TB/s_max,TFLOPS/s_mean,TFLOPS/s_median,TFLOPS/s_std,TFLOPS/s_min,TFLOPS/s_max,process_name_first,process_label_first,thread_name_first,Compute Spec,kernel_details__summarize_kernel_stats,trunc_kernel_details,Input Dims_first,Input type_first,Input Strides_first,Concrete Inputs_first,Kernel Time (µs)_mean,Kernel Time (µs)_median,Kernel Time (µs)_std,Kernel Time (µs)_min,Kernel Time (µs)_max,Kernel Time (µs)_sum,name_count,UID_first +aten::cumsum,15,15,"('int', None)",sum,2,1.5e-08,0.00011444091796875,0.12499999999999999,1.0737504369101713e-05,1.0737504369101713e-05,,1.0737504369101713e-05,1.0737504369101713e-05,1.342188046137714e-06,1.342188046137714e-06,,1.342188046137714e-06,1.342188046137714e-06,Unknown,Unknown,Unknown,,"[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel, (rocprim::ROCPRIM_400200_NS::detail::target_arch)942, rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2}, rocprim::ROCPRIM_400200_NS::detail::default_config_selector>(rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.487), 'mean_duration_us': np.float64(5.487), 'median_duration_us': np.float64(5.487), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.487), 'max_duration_us': np.float64(5.487)}, {'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.688), 'mean_duration_us': np.float64(5.688), 'median_duration_us': np.float64(5.688), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.688), 'max_duration_us': np.float64(5.688)}]","[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel >, unsigned int, long, 4, 4> >(at::native::ReduceOp >, unsigned int, long, 4, 4>)', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(10.373000000000001), 'mean_duration_us': np.float64(5.1865000000000006), 'median_duration_us': np.float64(5.1865000000000006), 'std_dev_duration_us': np.float64(1.1415000000000002), 'min_duration_us': np.float64(4.045), 'max_duration_us': np.float64(6.328)}]","[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp, (rocprim::ROCPRIM_400200_NS::detail::target_arch)942, rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2}, rocprim::ROCPRIM_400200_NS::detail::default_config_selector>(rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2})', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(9.051), 'mean_duration_us': np.float64(4.5255), 'median_duration_us': np.float64(4.5255), 'std_dev_duration_us': np.float64(0.6014999999999999), 'min_duration_us': np.float64(3.924), 'max_duration_us': np.float64(5.127)}]","[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel(long const*, c10::BFloat16*, c10::BFloat16*, c10::BFloat16 const*, int, long, long, long, int, int, int)', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(4725.106), 'mean_duration_us': np.float64(131.25294444444444), 'median_duration_us': np.float64(131.816), 'std_dev_duration_us': np.float64(2.28499364142617), 'min_duration_us': np.float64(126.228), 'max_duration_us': np.float64(135.561)}]","[{'name': 'void rotary_embedding_kernel(long const*, c...', 'stream': 3, 'mean_duration_us': np.float64(131.25)}]","[[15360], [15360, 4096], [15360, 1024], [], [41216, 128], []]","['long int', 'c10::BFloat16', 'c10::BFloat16', 'Scalar', 'c10::BFloat16', 'Scalar']","[[1], [4096, 1], [1024, 1], [], [128, 1], []]","['', '', '', '128', '', 'True']",131.25290256076389,131.81591796875,2.3174412724836753,126.2275390625,135.560546875,4725.1044921875,36,127 diff --git a/tests/traces/inference/sglang_prefilldecode/perf_csvs/UnaryElementwise.csv b/tests/traces/inference/sglang_prefilldecode/perf_csvs/UnaryElementwise.csv new file mode 100644 index 000000000..c802c7b95 --- /dev/null +++ b/tests/traces/inference/sglang_prefilldecode/perf_csvs/UnaryElementwise.csv @@ -0,0 +1,11 @@ +name,param: op_shape,param: dtype_in_out,param: stride_input,param: stride_output,num_kernels,GFLOPS_first,Data Moved (MB)_first,FLOPS/Byte_first,TB/s_mean,TB/s_median,TB/s_std,TB/s_min,TB/s_max,TFLOPS/s_mean,TFLOPS/s_median,TFLOPS/s_std,TFLOPS/s_min,TFLOPS/s_max,process_name_first,process_label_first,thread_name_first,Compute Spec,kernel_details__summarize_kernel_stats,trunc_kernel_details,Input Dims_first,Input type_first,Input Strides_first,Concrete Inputs_first,Kernel Time (µs)_mean,Kernel Time (µs)_median,Kernel Time (µs)_std,Kernel Time (µs)_min,Kernel Time (µs)_max,Kernel Time (µs)_sum,name_count,UID_first +sgl_kernel::silu_and_mul,"(15360, 12288)","('c10::BFloat16', 'c10::BFloat16')","(24576, 1)","(12288, 1)",1,0.9437184,1080.0,0.8333333333333334,2.4700587081645455,2.4726088311868417,0.03392069228478842,2.397131585200987,2.5559984701583005,2.058382256803788,2.060507359322368,0.028267243570656905,1.997609654334156,2.1299987251319172,Unknown,Unknown,Unknown,vector_bf16,"[{'name': '_ZN7sgl_hip10activation18act_and_mul_kernelI14__hip_bfloat16TnPFT_RKS3_EXadL_Z4siluIS2_ES3_S5_EEEEvPS3_PS4_i', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(16508.145), 'mean_duration_us': np.float64(458.55958333333336), 'median_duration_us': np.float64(458.00300000000004), 'std_dev_duration_us': np.float64(6.189793280406597), 'min_duration_us': np.float64(443.061), 'max_duration_us': np.float64(472.424)}]","[{'name': '_ZN7sgl_hip10activation18act_and_mul_kernelI14__hip_bfloat16TnPF...', 'stream': 3, 'mean_duration_us': np.float64(458.56)}]","[[15360, 12288], [15360, 24576]]","['c10::BFloat16', 'c10::BFloat16']","[[12288, 1], [24576, 1]]","['', '']",458.5595703125,458.0029296875,6.277613863685246,443.060546875,472.423828125,16508.14453125,36,171 +aten::copy_,"(15360, 4096)","('c10::BFloat16', 'c10::BFloat16')","(4096, 1)","(6144, 1)",1,0.06291456,240.0,0.24999999999999997,3.4973343217186414,3.5253933829134576,0.11894917690528885,3.1872809300944938,3.6932188397156613,0.8743335804296604,0.8813483457283644,0.029737294226322212,0.7968202325236234,0.9233047099289153,Unknown,Unknown,Unknown,vector_bf16,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(2593.4410000000007), 'mean_duration_us': np.float64(72.0400277777778), 'median_duration_us': np.float64(71.38550000000001), 'std_dev_duration_us': np.float64(2.4737914724625423), 'min_duration_us': np.float64(68.141), 'max_duration_us': np.float64(78.957)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::na...', 'stream': 3, 'mean_duration_us': np.float64(72.04)}]","[[15360, 4096], [15360, 4096], []]","['c10::BFloat16', 'c10::BFloat16', 'Scalar']","[[4096, 1], [6144, 1], []]","['', '', 'False']",72.0400390625,71.38525390625,2.508946155821979,68.140625,78.95703125,2593.44140625,36,101 +aten::copy_,"(15360, 1024)","('c10::BFloat16', 'c10::BFloat16')","(1024, 1)","(6144, 1)",1,0.01572864,60.0,0.24999999999999997,2.847481982334509,2.876543632804648,0.10273903769422547,2.545517777865581,3.0557562699805527,0.7118704955836272,0.719135908201162,0.02568475942355637,0.6363794444663953,0.7639390674951382,Unknown,Unknown,Unknown,vector_bf16,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(796.476), 'mean_duration_us': np.float64(22.124333333333333), 'median_duration_us': np.float64(21.871499999999997), 'std_dev_duration_us': np.float64(0.827839591278944), 'min_duration_us': np.float64(20.589), 'max_duration_us': np.float64(24.716)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::na...', 'stream': 3, 'mean_duration_us': np.float64(22.12)}]","[[15360, 1024], [15360, 1024], []]","['c10::BFloat16', 'c10::BFloat16', 'Scalar']","[[1024, 1], [6144, 1], []]","['', '', 'False']",22.12421332465278,21.87158203125,0.8395477383836966,20.5888671875,24.7158203125,796.4716796875,36,115 +aten::copy_,"(15,)","('long int', 'long int')","(1,)","(1,)",1,1.5e-08,0.0002288818359375,0.06249999999999999,3.768426708166679e-05,3.768426708166679e-05,5.14882737572676e-06,3.404349632913146e-05,4.1325037834202115e-05,2.3552666926041742e-06,2.3552666926041742e-06,3.218017109829225e-07,2.1277185205707162e-06,2.582814864637632e-06,Unknown,Unknown,Unknown,,"[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(12.858), 'mean_duration_us': np.float64(6.429), 'median_duration_us': np.float64(6.429), 'std_dev_duration_us': np.float64(0.621), 'min_duration_us': np.float64(5.808), 'max_duration_us': np.float64(7.05)}]","[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'mean_duration_us': np.float64(6.43)}]","[[15], [15], []]","['long int', 'long int', 'Scalar']","[[1], [1], []]","['', '', 'False']",6.4287109375,6.4287109375,0.8783592047551645,5.8076171875,7.0498046875,12.857421875,2,3782 +aten::copy_,"(15,)","('int', 'int')","(1,)","(1,)",1,1.5e-08,0.00011444091796875,0.12499999999999999,2.415369167026096e-05,2.415369167026096e-05,2.060480087969062e-06,2.269671222755818e-05,2.5610671112963735e-05,3.01921145878262e-06,3.01921145878262e-06,2.5756001099613274e-07,2.8370890284447727e-06,3.201333889120467e-06,Unknown,Unknown,Unknown,,"[{'name': 'Memcpy HtoD (Host -> Device)', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(9.972999999999999), 'mean_duration_us': np.float64(4.9864999999999995), 'median_duration_us': np.float64(4.9864999999999995), 'std_dev_duration_us': np.float64(0.3005), 'min_duration_us': np.float64(4.686), 'max_duration_us': np.float64(5.287)}]","[{'name': 'Memcpy HtoD (Host -> Device)', 'stream': 3, 'mean_duration_us': np.float64(4.99)}]","[[15], [15], []]","['int', 'int', 'Scalar']","[[1], [1], []]","['', '', 'False']",4.986328125,4.986328125,0.4253689230575325,4.685546875,5.287109375,9.97265625,2,9 +aten::copy_,"(15, 151936)","('float', 'c10::BFloat16')","(151936, 1)","(151936, 1)",1,0.00227904,13.040771484375,0.16666666666666666,1.3877524043607532,1.3877524043607532,,1.3877524043607532,1.3877524043607532,0.23129206739345887,0.23129206739345887,,0.23129206739345887,0.23129206739345887,Unknown,Unknown,Unknown,vector_fp32,"[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::bfloat16tofloat32_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda(c10::BFloat16)#1}, std::array >(int, at::native::bfloat16tofloat32_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda(c10::BFloat16)#1}, std::array)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(9.854), 'mean_duration_us': np.float64(9.854), 'median_duration_us': np.float64(9.854), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(9.854), 'max_duration_us': np.float64(9.854)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::bf...', 'stream': 3, 'mean_duration_us': np.float64(9.85)}]","[[15, 151936], [15, 151936], []]","['float', 'c10::BFloat16', 'Scalar']","[[151936, 1], [151936, 1], []]","['', '', 'False']",9.853515625,9.853515625,,9.853515625,9.853515625,9.853515625,1,3776 +aten::copy_,"(15,)","('int', 'long int')","(1,)","(1,)",1,1.5e-08,0.000171661376953125,0.08333333333333333,5.410038994025188e-05,5.410038994025188e-05,2.4407197804282718e-05,3.6841894863082156e-05,7.13588850174216e-05,4.508365828354323e-06,4.508365828354323e-06,2.033933150356894e-06,3.070157905256846e-06,5.946573751451801e-06,Unknown,Unknown,Unknown,,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(7.4079999999999995), 'mean_duration_us': np.float64(3.7039999999999997), 'median_duration_us': np.float64(3.7039999999999997), 'std_dev_duration_us': np.float64(1.1820000000000002), 'min_duration_us': np.float64(2.522), 'max_duration_us': np.float64(4.886)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(3.7)}]","[[15], [15], []]","['int', 'long int', 'Scalar']","[[1], [1], []]","['', '', 'False']",3.7041015625,3.7041015625,1.6710921977260205,2.5224609375,4.8857421875,7.408203125,2,37 +aten::copy_,"(15,)","('long int', 'int')","(1,)","(1,)",1,1.5e-08,0.000171661376953125,0.08333333333333333,3.164291845493562e-05,3.164291845493562e-05,,3.164291845493562e-05,3.164291845493562e-05,2.636909871244635e-06,2.636909871244635e-06,,2.636909871244635e-06,2.636909871244635e-06,Unknown,Unknown,Unknown,,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.688), 'mean_duration_us': np.float64(5.688), 'median_duration_us': np.float64(5.688), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.688), 'max_duration_us': np.float64(5.688)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(5.69)}]","[[15], [15], []]","['long int', 'int', 'Scalar']","[[1], [1], []]","['', '', 'False']",5.6884765625,5.6884765625,,5.6884765625,5.6884765625,5.6884765625,1,3760 +aten::neg,"(15,)","('long int', None)","(1,)",None,1,1.5e-08,0.0002288818359375,0.06249999999999999,5.122134222592747e-05,5.122134222592747e-05,,5.122134222592747e-05,5.122134222592747e-05,3.201333889120467e-06,3.201333889120467e-06,,3.201333889120467e-06,3.201333889120467e-06,Unknown,Unknown,Unknown,,"[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::neg_kernel_cuda(at::TensorIteratorBase&)::{lambda()#2}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, std::array >(int, at::native::neg_kernel_cuda(at::TensorIteratorBase&)::{lambda()#2}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, std::array)', 'stream': 2, 'count': 1, 'total_duration_us': np.float64(4.686), 'mean_duration_us': np.float64(4.686), 'median_duration_us': np.float64(4.686), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(4.686), 'max_duration_us': np.float64(4.686)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::ne...', 'stream': 2, 'mean_duration_us': np.float64(4.69)}]",[[15]],['long int'],[[1]],[''],4.685546875,4.685546875,,4.685546875,4.685546875,4.685546875,1,3787 +aten::copy_,"(256,)","('int', 'int')","(1,)","(0,)",1,2.56e-07,0.001953125,0.125,0.0007304604667363288,0.0007304604667363288,,0.0007304604667363288,0.0007304604667363288,9.13075583420411e-05,9.13075583420411e-05,,9.13075583420411e-05,9.13075583420411e-05,Unknown,Unknown,Unknown,,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(2.804), 'mean_duration_us': np.float64(2.804), 'median_duration_us': np.float64(2.804), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(2.804), 'max_duration_us': np.float64(2.804)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(2.8)}]","[[256], [256], []]","['int', 'int', 'Scalar']","[[1], [0], []]","['', '', 'False']",2.8037109375,2.8037109375,,2.8037109375,2.8037109375,2.8037109375,1,52 diff --git a/tests/traces/inference/sglang_prefilldecode/perf_csvs/gpu_timeline.csv b/tests/traces/inference/sglang_prefilldecode/perf_csvs/gpu_timeline.csv new file mode 100644 index 000000000..1d1b5ce12 --- /dev/null +++ b/tests/traces/inference/sglang_prefilldecode/perf_csvs/gpu_timeline.csv @@ -0,0 +1,9 @@ +type,time ms,percent +computation_time,492.76889453125,49.91131786856886 +exposed_comm_time,0.0,0.0 +exposed_memcpy_time,0.0379697265625,0.003845857790285902 +busy_time,492.8068642578125,49.91516372635914 +idle_time,494.4820224609375,50.08483627364085 +total_time,987.28888671875,100.0 +total_comm_time,0.0,0.0 +total_memcpy_time,0.0379697265625,0.003845857790285902 diff --git a/tests/traces/inference/sglang_prefilldecode/perf_csvs/ops_summary.csv b/tests/traces/inference/sglang_prefilldecode/perf_csvs/ops_summary.csv new file mode 100644 index 000000000..b3aaaaed1 --- /dev/null +++ b/tests/traces/inference/sglang_prefilldecode/perf_csvs/ops_summary.csv @@ -0,0 +1,28 @@ +name,parent_module,total_direct_kernel_time_sum,total_subtree_kernel_time_sum,total_subtree_kernel_time_count,total_direct_kernel_time_ms,Count,Categories,call_stack_first,Percentage (%),Cumulative Percentage (%) +aten::mm,nn.Module: MergedColumnParallelLinear,243643.025390625,243643.025390625,36,243.643025390625,36,['GEMM'],"['aten::mm', 'nn.Module: MergedColumnParallelLinear_0', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",49.43939026737224,49.43939026737224 +aten::mm,nn.Module: RowParallelLinear,124930.9140625,124930.9140625,72,124.9309140625,72,['GEMM'],"['aten::mm', 'nn.Module: RowParallelLinear_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",25.350646532536214,74.79003679990845 +aten::mm,nn.Module: QKVParallelLinear,51295.4833984375,51295.4833984375,36,51.2954833984375,36,['GEMM'],"['aten::mm', 'nn.Module: QKVParallelLinear_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",10.408742128460071,85.19877892836853 +aiter::mha_batch_prefill,nn.Module: RadixAttention,20075.15625,20075.15625,36,20.07515625,36,['InferenceAttention'],"['aiter::mha_batch_prefill', 'nn.Module: RadixAttention_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",4.073596947546428,89.27237587591496 +aiter::rmsnorm,nn.Module: RMSNorm,17559.4384765625,17559.4384765625,73,17.5594384765625,73,['RMSNorm'],"['aiter::rmsnorm', 'nn.Module: RMSNorm_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",3.5631142337312722,92.83549010964623 +sgl_kernel::silu_and_mul,nn.Module: SiluAndMul,16508.14453125,16508.14453125,36,16.50814453125,36,['elementwise'],"['sgl_kernel::silu_and_mul', 'nn.Module: SiluAndMul_0', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",3.3497884815793286,96.18527859122555 +aiter::add_rmsnorm,nn.Module: RMSNorm,8699.1142578125,8699.1142578125,72,8.6991142578125,72,['RMSNorm'],"['aiter::add_rmsnorm', 'nn.Module: RMSNorm_3', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",1.7652009700787568,97.9504795613043 +sgl_kernel::rotary_embedding,nn.Module: RotaryEmbedding,4725.1044921875,4725.1044921875,36,4.7251044921875,36,['RoPE_fwd'],"['sgl_kernel::rotary_embedding', 'nn.Module: RotaryEmbedding_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",0.9588055503285517,98.90928511163285 +aten::copy_,nn.Module: Qwen3Attention,3389.9130859375,3389.9130859375,72,3.3899130859375,72,['elementwise'],"['aten::copy_', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",0.6878720856442995,99.59715719727716 +sglang::store_cache,nn.Module: RadixAttention,1271.2177734375,1271.2177734375,36,1.2712177734375,36,['InferenceAttention'],"['sglang::store_cache', 'nn.Module: RadixAttention_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",0.25795210642715505,99.85510930370431 +aten::mm,nn.Module: LogitsProcessor,436.3310546875,436.3310546875,1,0.4363310546875,1,['GEMM'],"['aten::mm', 'nn.Module: LogitsProcessor_0']",0.08853912917837009,99.94364843288268 +aten::argmax,nn.Module: Sampler,74.349609375,74.349609375,1,0.074349609375,1,['reduce'],"['aten::argmax', 'nn.Module: Sampler_0']",0.015086823635620236,99.9587352565183 +aten::gather,nn.Module: VocabParallelEmbedding,66.2578125,66.2578125,1,0.0662578125,1,['other'],"['aten::gather', 'nn.Module: VocabParallelEmbedding_0', 'nn.Module: Qwen3Model_0']",0.013444857882543435,99.97218011440084 +aten::copy_,NA,33.0419921875,33.0419921875,7,0.0330419921875,7,['elementwise'],['aten::copy_'],0.006704792572453972,99.97888490697329 +aten::copy_,nn.Module: LogitsProcessor,15.5419921875,15.5419921875,2,0.0155419921875,2,['elementwise'],"['aten::copy_', 'nn.Module: LogitsProcessor_0']",0.0031537394352181168,99.98203864640851 +aten::_local_scalar_dense,NA,15.1396484375,15.1396484375,3,0.0151396484375,3,['other'],['aten::_local_scalar_dense'],0.003072096918893274,99.98511074332741 +aten::sub,NA,11.17578125,11.17578125,2,0.01117578125,2,['elementwise'],['aten::sub'],0.002267759603935666,99.98737850293135 +aten::max,NA,10.373046875,10.373046875,2,0.010373046875,2,['reduce'],['aten::max'],0.0021048708941807624,99.98948337382554 +aten::cumsum,NA,9.05078125,9.05078125,2,0.00905078125,2,['reduce'],['aten::cumsum'],0.0018365602944141694,99.99131993411994 +hipLaunchKernel,NA,7.009765625,7.009765625,1,0.007009765625,1,['other'],['hipLaunchKernel'],0.0014224028693682464,99.99274233698931 +aten::index,nn.Module: LogitsProcessor,6.087890625,6.087890625,1,0.006087890625,1,['other'],"['aten::index', 'nn.Module: LogitsProcessor_0']",0.0012353384630317146,99.99397767545234 +sglang_profiler::forward_batch_info_compute_position_triton,NA,5.7275390625,5.7275390625,1,0.0057275390625,1,['other'],['sglang_profiler::forward_batch_info_compute_position_triton'],0.0011622168889446594,99.99513989234129 +aten::sub,nn.Module: LogitsProcessor,5.607421875,5.607421875,1,0.005607421875,1,['elementwise'],"['aten::sub', 'nn.Module: LogitsProcessor_0']",0.0011378430309156409,99.9962777353722 +aten::cumsum,nn.Module: LogitsProcessor,5.4873046875,11.17578125,1,0.0054873046875,1,['reduce'],"['aten::cumsum', 'nn.Module: LogitsProcessor_0']",0.0011134691728866225,99.9973912045451 +aten::neg,NA,4.685546875,4.685546875,1,0.004685546875,1,['elementwise'],['aten::neg'],0.0009507786245791091,99.99834198316968 +hipModuleLaunchKernel,NA,4.685546875,4.685546875,1,0.004685546875,1,['other'],['hipModuleLaunchKernel'],0.0009507786245791091,99.99929276179427 +aten::arange,NA,3.4853515625,3.4853515625,1,0.0034853515625,1,['other'],['aten::arange'],0.0007072382057363153,100.0 diff --git a/tests/traces/inference/sglang_prefilldecode/perf_csvs/ops_summary_by_category.csv b/tests/traces/inference/sglang_prefilldecode/perf_csvs/ops_summary_by_category.csv new file mode 100644 index 000000000..0083d0760 --- /dev/null +++ b/tests/traces/inference/sglang_prefilldecode/perf_csvs/ops_summary_by_category.csv @@ -0,0 +1,18 @@ +op category,parent_module,Count,call_stack_first,total_direct_kernel_time_ms,Percentage (%),Cumulative Percentage (%) +GEMM,nn.Module: MergedColumnParallelLinear,36,"['aten::mm', 'nn.Module: MergedColumnParallelLinear_0', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",243.643025390625,49.43939026737225,49.43939026737225 +GEMM,nn.Module: RowParallelLinear,72,"['aten::mm', 'nn.Module: RowParallelLinear_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",124.9309140625,25.350646532536214,74.79003679990846 +GEMM,nn.Module: QKVParallelLinear,36,"['aten::mm', 'nn.Module: QKVParallelLinear_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",51.2954833984375,10.408742128460071,85.19877892836854 +RMSNorm,nn.Module: RMSNorm,145,"['aiter::rmsnorm', 'nn.Module: RMSNorm_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",26.258552734375,5.32831520381003,90.52709413217858 +InferenceAttention,nn.Module: RadixAttention,72,"['sglang::store_cache', 'nn.Module: RadixAttention_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",21.3463740234375,4.331549053973585,94.85864318615216 +elementwise,nn.Module: SiluAndMul,36,"['sgl_kernel::silu_and_mul', 'nn.Module: SiluAndMul_0', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",16.50814453125,3.349788481579329,98.20843166773149 +RoPE_fwd,nn.Module: RotaryEmbedding,36,"['sgl_kernel::rotary_embedding', 'nn.Module: RotaryEmbedding_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",4.7251044921875,0.9588055503285519,99.16723721806004 +elementwise,nn.Module: Qwen3Attention,72,"['aten::copy_', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']",3.3899130859375,0.6878720856442996,99.85510930370434 +GEMM,nn.Module: LogitsProcessor,1,"['aten::mm', 'nn.Module: LogitsProcessor_0']",0.4363310546875,0.0885391291783701,99.94364843288271 +reduce,nn.Module: Sampler,1,"['aten::argmax', 'nn.Module: Sampler_0']",0.074349609375,0.01508682363562024,99.95873525651832 +other,nn.Module: VocabParallelEmbedding,1,"['aten::gather', 'nn.Module: VocabParallelEmbedding_0', 'nn.Module: Qwen3Model_0']",0.0662578125,0.013444857882543437,99.97218011440087 +elementwise,NA,10,['aten::copy_'],0.0489033203125,0.009923330800968749,99.98210344520184 +other,NA,7,['aten::arange'],0.0360478515625,0.007314733507521605,99.98941817870937 +elementwise,nn.Module: LogitsProcessor,3,"['aten::copy_', 'nn.Module: LogitsProcessor_0']",0.0211494140625,0.004291582466133758,99.99370976117551 +reduce,NA,4,['aten::max'],0.019423828125,0.003941431188594933,99.9976511923641 +other,nn.Module: LogitsProcessor,1,"['aten::index', 'nn.Module: LogitsProcessor_0']",0.006087890625,0.0012353384630317149,99.99888653082714 +reduce,nn.Module: LogitsProcessor,1,"['aten::cumsum', 'nn.Module: LogitsProcessor_0']",0.0054873046875,0.0011134691728866225,100.00000000000003 diff --git a/tests/traces/inference/sglang_prefilldecode/perf_csvs/ops_unique_args.csv b/tests/traces/inference/sglang_prefilldecode/perf_csvs/ops_unique_args.csv new file mode 100644 index 000000000..f53d4303e --- /dev/null +++ b/tests/traces/inference/sglang_prefilldecode/perf_csvs/ops_unique_args.csv @@ -0,0 +1,39 @@ +name,op category,parent_module,process_name,process_label,thread_name,Input Dims,Input type,Input Strides,Concrete Inputs,num_kernels,operation_count,total_direct_kernel_time_mean,total_subtree_kernel_time_mean,total_direct_kernel_time_median,total_subtree_kernel_time_median,total_direct_kernel_time_std,total_subtree_kernel_time_std,total_direct_kernel_time_min,total_subtree_kernel_time_min,total_direct_kernel_time_max,total_subtree_kernel_time_max,total_direct_kernel_time_sum,total_subtree_kernel_time_sum,ex_UID,call_stack,kernel_details_summary,trunc_kernel_details,Percentage (%),Cumulative Percentage (%) +aten::mm,GEMM,nn.Module: MergedColumnParallelLinear,Unknown,Unknown,Unknown,"((15360, 4096), (4096, 24576))","('c10::BFloat16', 'c10::BFloat16')","((4096, 1), (1, 4096))","('', '')",1,36,6767.86181640625,6767.86181640625,6771.17529296875,6771.17529296875,42.30302141272883,42.30302141272883,6700.5302734375,6700.5302734375,6902.9423828125,6902.9423828125,243643.025390625,243643.025390625,169,"['aten::mm', 'nn.Module: MergedColumnParallelLinear_0', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT128x256x32_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA4_GRVWB4_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB256_LBSPPM0_LPA4_LPB4_LPM0_LRVW4_LWPMn1_MIAV0_MIWT8_4_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW8_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA8_VWB4_WSGRA0_WSGRB0_WS64_WG16_16_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(243643.021), 'mean_duration_us': np.float64(6767.861694444445), 'median_duration_us': np.float64(6771.1755), 'std_dev_duration_us': np.float64(41.71130077943137), 'min_duration_us': np.float64(6700.53), 'max_duration_us': np.float64(6902.942)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT128x256x32_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(6767.86)}]",49.43939026737225,49.43939026737225 +aten::mm,GEMM,nn.Module: RowParallelLinear,Unknown,Unknown,Unknown,"((15360, 12288), (12288, 4096))","('c10::BFloat16', 'c10::BFloat16')","((12288, 1), (1, 12288))","('', '')",1,36,2651.0844997829863,2651.0844997829863,2652.1015625,2652.1015625,25.669117118336754,25.669117118336754,2599.162109375,2599.162109375,2714.2138671875,2714.2138671875,95439.0419921875,95439.0419921875,178,"['aten::mm', 'nn.Module: RowParallelLinear_1', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x16x1_SN_LDSB0_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA1_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA0_LBSPPB256_LBSPPM0_LPA0_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT5_14_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA2_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW1_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA1_VWB2_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(95439.041), 'mean_duration_us': np.float64(2651.0844722222223), 'median_duration_us': np.float64(2652.1014999999998), 'std_dev_duration_us': np.float64(25.310139447666806), 'min_duration_us': np.float64(2599.162), 'max_duration_us': np.float64(2714.214)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(2651.08)}]",19.36623482749383,68.80562509486607 +aten::mm,GEMM,nn.Module: QKVParallelLinear,Unknown,Unknown,Unknown,"((15360, 4096), (4096, 6144))","('c10::BFloat16', 'c10::BFloat16')","((4096, 1), (1, 4096))","('', '')",1,36,1424.874538845486,1424.874538845486,1418.177734375,1418.177734375,42.645073981571386,42.645073981571386,1390.8369140625,1390.8369140625,1657.8759765625,1657.8759765625,51295.4833984375,51295.4833984375,90,"['aten::mm', 'nn.Module: QKVParallelLinear_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x192x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA1024_LBSPPB256_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT8_6_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW8_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA8_VWB2_WSGRA0_WSGRB0_WS64_WG32_8_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(51295.484000000004), 'mean_duration_us': np.float64(1424.8745555555556), 'median_duration_us': np.float64(1418.1775), 'std_dev_duration_us': np.float64(42.04861841200046), 'min_duration_us': np.float64(1390.837), 'max_duration_us': np.float64(1657.876)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x192x64_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(1424.87)}]",10.408742128460073,79.21436722332615 +aten::mm,GEMM,nn.Module: RowParallelLinear,Unknown,Unknown,Unknown,"((15360, 4096), (4096, 4096))","('c10::BFloat16', 'c10::BFloat16')","((4096, 1), (1, 4096))","('', '')",1,36,819.2186686197916,819.2186686197916,816.81884765625,816.81884765625,17.09959181546983,17.09959181546983,792.984375,792.984375,877.7509765625,877.7509765625,29491.8720703125,29491.8720703125,155,"['aten::mm', 'nn.Module: RowParallelLinear_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x16x1_SN_LDSB0_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA1_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA0_LBSPPB256_LBSPPM0_LPA0_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT5_14_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA2_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW1_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA1_VWB2_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(29491.870999999996), 'mean_duration_us': np.float64(819.2186388888888), 'median_duration_us': np.float64(816.819), 'std_dev_duration_us': np.float64(16.860455720993983), 'min_duration_us': np.float64(792.984), 'max_duration_us': np.float64(877.751)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(819.22)}]",5.984411705042385,85.19877892836854 +aiter::mha_batch_prefill,InferenceAttention,nn.Module: RadixAttention,Unknown,Unknown,Unknown,"((15360, 32, 128), (835874, 8, 128), (835874, 8, 128), (16,), (16,), (15616,), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'int', 'int', 'int', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', '', '', '', '', '', '', '', '', '', '', '', '')","((4096, 128, 1), (1024, 128, 1), (1024, 128, 1), (1,), (1,), (1,), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ())","('', '', '', '', '', '', '1024', '1024', '0.', '0.088388347648318447', '0.', 'False', 'True', '-1', '-1', '0', 'False', 'False', '', '', '', '', '', '', '', '', '', '', '', '')",1,36,557.6432291666666,557.6432291666666,559.0341796875,559.0341796875,15.864896127076442,15.864896127076442,526.025390625,526.025390625,586.275390625,586.275390625,20075.15625,20075.15625,142,"['aiter::mha_batch_prefill', 'nn.Module: RadixAttention_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': '_ZN7ck_tile6kentryILi2ENS_38FmhaBatchPrefillWithPagedKVCacheKernelINS_40BlockFmhaBatchPrefillPipelineQRKSVSAsyncINS_36BlockFmhaBatchPrefillPipelineProblemIDF16bDF16bDF16bffDF16bhfDF16bfDF16bNS_13TileFmhaShapeINS_8sequenceIJLi128ELi128ELi32ELi128ELi32ELi128EEEENS5_IJLi4ELi1ELi1EEEENS5_IJLi32ELi32ELi16EEEES7_S8_Lb1EEELb1ENS_17ComposedAttentionILj0ELb1EEENS_30SimplifiedGenericAttentionMaskILb1EEELb0ELi1ENS_26TileFmhaBatchPrefillTraitsILb1ELb1ELb1ELb1ELb0ELNS_22BlockAttentionBiasEnumE0ELb0ELb0ELb0ELNS_28BlockAttentionQuantScaleEnumE0ELin1ELb0ELb0ELi1ELNS_37BlockAttentionKVCacheMemoryLayoutEnumE1ELNS_36BlockAttentionKVCacheLookupTableEnumE1ELNS_33BlockAttentionKVCacheLoadModeEnumE0EEEEENS_53BlockFmhaBatchPrefillPipelineQRKSVSAsyncDefaultPolicyEEENS_17Default2DEpilogueINS_24Default2DEpilogueProblemIfDF16bLb1ELb1ELb1EEEvEEEEJNSS_21FmhaFwdGroupModeKargsEEEEvDpT1_', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(20075.157999999996), 'mean_duration_us': np.float64(557.6432777777777), 'median_duration_us': np.float64(559.034), 'std_dev_duration_us': np.float64(15.642999795100248), 'min_duration_us': np.float64(526.025), 'max_duration_us': np.float64(586.275)}]","[{'name': '_ZN7ck_tile6kentryILi2ENS_38FmhaBatchPrefillWithPagedKVCacheKern...', 'stream': 3, 'mean_duration_us': np.float64(557.64)}]",4.073596947546429,89.27237587591497 +sgl_kernel::silu_and_mul,elementwise,nn.Module: SiluAndMul,Unknown,Unknown,Unknown,"((15360, 12288), (15360, 24576))","('c10::BFloat16', 'c10::BFloat16')","((12288, 1), (24576, 1))","('', '')",1,36,458.5595703125,458.5595703125,458.0029296875,458.0029296875,6.277613863685246,6.277613863685246,443.060546875,443.060546875,472.423828125,472.423828125,16508.14453125,16508.14453125,171,"['sgl_kernel::silu_and_mul', 'nn.Module: SiluAndMul_0', 'nn.Module: Qwen2MLP_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': '_ZN7sgl_hip10activation18act_and_mul_kernelI14__hip_bfloat16TnPFT_RKS3_EXadL_Z4siluIS2_ES3_S5_EEEEvPS3_PS4_i', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(16508.145), 'mean_duration_us': np.float64(458.55958333333336), 'median_duration_us': np.float64(458.00300000000004), 'std_dev_duration_us': np.float64(6.189793280406597), 'min_duration_us': np.float64(443.061), 'max_duration_us': np.float64(472.424)}]","[{'name': '_ZN7sgl_hip10activation18act_and_mul_kernelI14__hip_bfloat16TnPF...', 'stream': 3, 'mean_duration_us': np.float64(458.56)}]",3.349788481579329,92.6221643574943 +aiter::rmsnorm,RMSNorm,nn.Module: RMSNorm,Unknown,Unknown,Unknown,"((491520, 128), (491520, 128), (128,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((128, 1), (128, 1), (1,), ())","('', '', '', '9.9999999999999995e-07')",1,36,387.04380967881946,387.04380967881946,390.80322265625,390.80322265625,24.818198394275207,24.818198394275207,245.326171875,245.326171875,399.916015625,399.916015625,13933.5771484375,13933.5771484375,106,"['aiter::rmsnorm', 'nn.Module: RMSNorm_1', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(13933.577), 'mean_duration_us': np.float64(387.04380555555554), 'median_duration_us': np.float64(390.803), 'std_dev_duration_us': np.float64(24.471096357425704), 'min_duration_us': np.float64(245.326), 'max_duration_us': np.float64(399.916)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0EL...', 'stream': 3, 'mean_duration_us': np.float64(387.04)}]",2.8273641626215325,95.44952852011583 +aiter::add_rmsnorm,RMSNorm,nn.Module: RMSNorm,Unknown,Unknown,Unknown,"((15360, 4096), (15360, 4096), (15360, 4096), (15360, 4096), (4096,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((4096, 1), (4096, 1), (4096, 1), (4096, 1), (1,), ())","('', '', '', '', '', '9.9999999999999995e-07')",1,72,120.82103135850694,120.82103135850694,120.919921875,120.919921875,2.767866612625456,2.767866612625456,103.673828125,103.673828125,124.865234375,124.865234375,8699.1142578125,8699.1142578125,161,"['aiter::add_rmsnorm', 'nn.Module: RMSNorm_3', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb1ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 72, 'total_duration_us': np.float64(8699.121), 'mean_duration_us': np.float64(120.821125), 'median_duration_us': np.float64(120.9195), 'std_dev_duration_us': np.float64(2.7485319815893434), 'min_duration_us': np.float64(103.674), 'max_duration_us': np.float64(124.865)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb1ELb0...', 'stream': 3, 'mean_duration_us': np.float64(120.82)}]",1.765200970078757,97.21472949019459 +sgl_kernel::rotary_embedding,RoPE_fwd,nn.Module: RotaryEmbedding,Unknown,Unknown,Unknown,"((15360,), (15360, 4096), (15360, 1024), (), (41216, 128), ())","('long int', 'c10::BFloat16', 'c10::BFloat16', 'Scalar', 'c10::BFloat16', 'Scalar')","((1,), (4096, 1), (1024, 1), (), (128, 1), ())","('', '', '', '128', '', 'True')",1,36,131.25290256076389,131.25290256076389,131.81591796875,131.81591796875,2.3174412724836753,2.3174412724836753,126.2275390625,126.2275390625,135.560546875,135.560546875,4725.1044921875,4725.1044921875,127,"['sgl_kernel::rotary_embedding', 'nn.Module: RotaryEmbedding_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'void rotary_embedding_kernel(long const*, c10::BFloat16*, c10::BFloat16*, c10::BFloat16 const*, int, long, long, long, int, int, int)', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(4725.106), 'mean_duration_us': np.float64(131.25294444444444), 'median_duration_us': np.float64(131.816), 'std_dev_duration_us': np.float64(2.28499364142617), 'min_duration_us': np.float64(126.228), 'max_duration_us': np.float64(135.561)}]","[{'name': 'void rotary_embedding_kernel(long const*, c...', 'stream': 3, 'mean_duration_us': np.float64(131.25)}]",0.9588055503285519,98.17353504052313 +aiter::rmsnorm,RMSNorm,nn.Module: RMSNorm,Unknown,Unknown,Unknown,"((122880, 128), (122880, 128), (128,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((128, 1), (128, 1), (1,), ())","('', '', '', '9.9999999999999995e-07')",1,36,98.71761067708333,98.71761067708333,100.1884765625,100.1884765625,6.3175549998410485,6.3175549998410485,63.333984375,63.333984375,102.671875,102.671875,3553.833984375,3553.833984375,120,"['aiter::rmsnorm', 'nn.Module: RMSNorm_2', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(3553.835), 'mean_duration_us': np.float64(98.71763888888889), 'median_duration_us': np.float64(100.1885), 'std_dev_duration_us': np.float64(6.229195699610279), 'min_duration_us': np.float64(63.334), 'max_duration_us': np.float64(102.672)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0EL...', 'stream': 3, 'mean_duration_us': np.float64(98.72)}]",0.7211344753960142,98.89466951591915 +aten::copy_,elementwise,nn.Module: Qwen3Attention,Unknown,Unknown,Unknown,"((15360, 4096), (15360, 4096), ())","('c10::BFloat16', 'c10::BFloat16', 'Scalar')","((4096, 1), (6144, 1), ())","('', '', 'False')",1,36,72.0400390625,72.0400390625,71.38525390625,71.38525390625,2.508946155821979,2.508946155821979,68.140625,68.140625,78.95703125,78.95703125,2593.44140625,2593.44140625,101,"['aten::copy_', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(2593.4410000000007), 'mean_duration_us': np.float64(72.0400277777778), 'median_duration_us': np.float64(71.38550000000001), 'std_dev_duration_us': np.float64(2.4737914724625423), 'min_duration_us': np.float64(68.141), 'max_duration_us': np.float64(78.957)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::na...', 'stream': 3, 'mean_duration_us': np.float64(72.04)}]",0.5262541852515105,99.42092370117066 +sglang::store_cache,InferenceAttention,nn.Module: RadixAttention,Unknown,Unknown,Unknown,"((15360, 1024), (15360, 1024), (835874, 1024), (835874, 1024), (15360,), (), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'long int', 'Scalar', 'Scalar')","((1024, 1), (6144, 1), (1024, 1), (1024, 1), (1,), (), ())","('', '', '', '', '', '2048', '0')",1,36,35.311604817708336,35.311604817708336,35.13134765625,35.13134765625,1.5715359604665984,1.5715359604665984,31.806640625,31.806640625,39.0966796875,39.0966796875,1271.2177734375,1271.2177734375,135,"['sglang::store_cache', 'nn.Module: RadixAttention_0', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'void (anonymous namespace)::store_kvcache<2048l, 4, false, long>((anonymous namespace)::StoreKVCacheParams)', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(1271.2200000000003), 'mean_duration_us': np.float64(35.311666666666675), 'median_duration_us': np.float64(35.1315), 'std_dev_duration_us': np.float64(1.54956371996192), 'min_duration_us': np.float64(31.807), 'max_duration_us': np.float64(39.097)}]","[{'name': 'void (anonymous namespace)::store_kvcache<2048l, 4, false, long>...', 'stream': 3, 'mean_duration_us': np.float64(35.31)}]",0.2579521064271551,99.67887580759782 +aten::copy_,elementwise,nn.Module: Qwen3Attention,Unknown,Unknown,Unknown,"((15360, 1024), (15360, 1024), ())","('c10::BFloat16', 'c10::BFloat16', 'Scalar')","((1024, 1), (6144, 1), ())","('', '', 'False')",1,36,22.12421332465278,22.12421332465278,21.87158203125,21.87158203125,0.8395477383836966,0.8395477383836966,20.5888671875,20.5888671875,24.7158203125,24.7158203125,796.4716796875,796.4716796875,115,"['aten::copy_', 'nn.Module: Qwen3Attention_0', 'nn.Module: Qwen3DecoderLayer_0', 'nn.Module: Qwen3Model_0']","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 36, 'total_duration_us': np.float64(796.476), 'mean_duration_us': np.float64(22.124333333333333), 'median_duration_us': np.float64(21.871499999999997), 'std_dev_duration_us': np.float64(0.827839591278944), 'min_duration_us': np.float64(20.589), 'max_duration_us': np.float64(24.716)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::na...', 'stream': 3, 'mean_duration_us': np.float64(22.12)}]",0.1616179003927891,99.8404937079906 +aten::mm,GEMM,nn.Module: LogitsProcessor,Unknown,Unknown,Unknown,"((15, 4096), (4096, 151936))","('c10::BFloat16', 'c10::BFloat16')","((4096, 1), (1, 4096))","('', '')",1,1,436.3310546875,436.3310546875,436.3310546875,436.3310546875,,,436.3310546875,436.3310546875,436.3310546875,436.3310546875,436.3310546875,436.3310546875,3771,"['aten::mm', 'nn.Module: LogitsProcessor_0']","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x16x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB4_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB128_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_1_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB1_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(436.331), 'mean_duration_us': np.float64(436.331), 'median_duration_us': np.float64(436.331), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(436.331), 'max_duration_us': np.float64(436.331)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x16x64_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(436.33)}]",0.0885391291783701,99.92903283716898 +aten::argmax,reduce,nn.Module: Sampler,Unknown,Unknown,Unknown,"((15, 151936), (), ())","('float', 'Scalar', 'Scalar')","((151936, 1), (), ())","('', '-1', 'False')",1,1,74.349609375,74.349609375,74.349609375,74.349609375,,,74.349609375,74.349609375,74.349609375,74.349609375,74.349609375,74.349609375,3778,"['aten::argmax', 'nn.Module: Sampler_0']","[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp, unsigned int, long, 4, 4> >(at::native::ReduceOp, unsigned int, long, 4, 4>)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(74.35), 'mean_duration_us': np.float64(74.35), 'median_duration_us': np.float64(74.35), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(74.35), 'max_duration_us': np.float64(74.35)}]","[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp(char*, char*, long*, int, long, long, long, long, bool)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(66.258), 'mean_duration_us': np.float64(66.258), 'median_duration_us': np.float64(66.258), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(66.258), 'max_duration_us': np.float64(66.258)}]","[{'name': 'void at::native::vectorized_gather_kernel<16, long>(char*, char*...', 'stream': 3, 'mean_duration_us': np.float64(66.26)}]",0.013444857882543437,99.97218011440086 +aten::_local_scalar_dense,other,NA,Unknown,Unknown,Unknown,"((),)","('long int',)","((),)","('',)",1,2,5.70751953125,5.70751953125,5.70751953125,5.70751953125,0.7077973151525501,0.7077973151525501,5.20703125,5.20703125,6.2080078125,6.2080078125,11.4150390625,11.4150390625,32,['aten::_local_scalar_dense'],"[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(11.415), 'mean_duration_us': np.float64(5.7075), 'median_duration_us': np.float64(5.7075), 'std_dev_duration_us': np.float64(0.5005000000000002), 'min_duration_us': np.float64(5.207), 'max_duration_us': np.float64(6.208)}]","[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'mean_duration_us': np.float64(5.71)}]",0.0023163091585463127,99.9744964235594 +aten::max,reduce,NA,Unknown,Unknown,Unknown,"((15,),)","('long int',)","((1,),)","('',)",1,2,5.1865234375,5.1865234375,5.1865234375,5.1865234375,1.6144684125138165,1.6144684125138165,4.044921875,4.044921875,6.328125,6.328125,10.373046875,10.373046875,28,['aten::max'],"[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp >, unsigned int, long, 4, 4> >(at::native::ReduceOp >, unsigned int, long, 4, 4>)', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(10.373000000000001), 'mean_duration_us': np.float64(5.1865000000000006), 'median_duration_us': np.float64(5.1865000000000006), 'std_dev_duration_us': np.float64(1.1415000000000002), 'min_duration_us': np.float64(4.045), 'max_duration_us': np.float64(6.328)}]","[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp Device)', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(9.972999999999999), 'mean_duration_us': np.float64(4.9864999999999995), 'median_duration_us': np.float64(4.9864999999999995), 'std_dev_duration_us': np.float64(0.3005), 'min_duration_us': np.float64(4.686), 'max_duration_us': np.float64(5.287)}]","[{'name': 'Memcpy HtoD (Host -> Device)', 'stream': 3, 'mean_duration_us': np.float64(4.99)}]",0.0020236247007507013,99.97862491915434 +aten::copy_,elementwise,nn.Module: LogitsProcessor,Unknown,Unknown,Unknown,"((15, 151936), (15, 151936), ())","('float', 'c10::BFloat16', 'Scalar')","((151936, 1), (151936, 1), ())","('', '', 'False')",1,1,9.853515625,9.853515625,9.853515625,9.853515625,,,9.853515625,9.853515625,9.853515625,9.853515625,9.853515625,9.853515625,3776,"['aten::copy_', 'nn.Module: LogitsProcessor_0']","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::bfloat16tofloat32_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda(c10::BFloat16)#1}, std::array >(int, at::native::bfloat16tofloat32_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda(c10::BFloat16)#1}, std::array)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(9.854), 'mean_duration_us': np.float64(9.854), 'median_duration_us': np.float64(9.854), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(9.854), 'max_duration_us': np.float64(9.854)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::bf...', 'stream': 3, 'mean_duration_us': np.float64(9.85)}]",0.001999449004169073,99.98062436815852 +aten::cumsum,reduce,NA,Unknown,Unknown,Unknown,"((15,), (), ())","('long int', 'Scalar', '')","((1,), (), ())","('', '0', '')",1,2,4.525390625,4.525390625,4.525390625,4.525390625,0.850737846115065,0.850737846115065,3.923828125,3.923828125,5.126953125,5.126953125,9.05078125,9.05078125,33,['aten::cumsum'],"[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel, (rocprim::ROCPRIM_400200_NS::detail::target_arch)942, rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2}, rocprim::ROCPRIM_400200_NS::detail::default_config_selector>(rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2})', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(9.051), 'mean_duration_us': np.float64(4.5255), 'median_duration_us': np.float64(4.5255), 'std_dev_duration_us': np.float64(0.6014999999999999), 'min_duration_us': np.float64(3.924), 'max_duration_us': np.float64(5.127)}]","[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 2, 'total_duration_us': np.float64(7.4079999999999995), 'mean_duration_us': np.float64(3.7039999999999997), 'median_duration_us': np.float64(3.7039999999999997), 'std_dev_duration_us': np.float64(1.1820000000000002), 'min_duration_us': np.float64(2.522), 'max_duration_us': np.float64(4.886)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(3.7)}]",0.0015032527399035272,99.98396418119283 +aten::copy_,elementwise,NA,Unknown,Unknown,Unknown,"((15,), (15,), ())","('long int', 'long int', 'Scalar')","((1,), (1,), ())","('', '', 'True')",1,1,7.0498046875,7.0498046875,7.0498046875,7.0498046875,,,7.0498046875,7.0498046875,7.0498046875,7.0498046875,7.0498046875,7.0498046875,3786,['aten::copy_'],"[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(7.05), 'mean_duration_us': np.float64(7.05), 'median_duration_us': np.float64(7.05), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(7.05), 'max_duration_us': np.float64(7.05)}]","[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'mean_duration_us': np.float64(7.05)}]",0.0014305274887112527,99.98539470868154 +hipLaunchKernel,other,NA,Unknown,Unknown,Unknown,,,,,1,1,7.009765625,7.009765625,7.009765625,7.009765625,,,7.009765625,7.009765625,7.009765625,7.009765625,7.009765625,7.009765625,57112,['hipLaunchKernel'],"[{'name': 'void (anonymous namespace)::resolve_future_token_ids_kernel(long*, long const*, unsigned long)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(7.01), 'mean_duration_us': np.float64(7.01), 'median_duration_us': np.float64(7.01), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(7.01), 'max_duration_us': np.float64(7.01)}]","[{'name': 'void (anonymous namespace)::resolve_future_token_ids_kernel(char*, char*, long*, int, long, long, long, long, bool)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(6.088), 'mean_duration_us': np.float64(6.088), 'median_duration_us': np.float64(6.088), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(6.088), 'max_duration_us': np.float64(6.088)}]","[{'name': 'void at::native::vectorized_gather_kernel<16, long>(char*, char*...', 'stream': 3, 'mean_duration_us': np.float64(6.09)}]",0.0012353384630317149,99.98805245001394 +aten::copy_,elementwise,NA,Unknown,Unknown,Unknown,"((15,), (15,), ())","('long int', 'long int', 'Scalar')","((1,), (1,), ())","('', '', 'False')",1,1,5.8076171875,5.8076171875,5.8076171875,5.8076171875,,,5.8076171875,5.8076171875,5.8076171875,5.8076171875,5.8076171875,5.8076171875,3782,['aten::copy_'],"[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.808), 'mean_duration_us': np.float64(5.808), 'median_duration_us': np.float64(5.808), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.808), 'max_duration_us': np.float64(5.808)}]","[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'mean_duration_us': np.float64(5.81)}]",0.0011784661276306716,99.98923091614157 +sglang_profiler::forward_batch_info_compute_position_triton,other,NA,Unknown,Unknown,Unknown,"((15,), (15,))","('int', 'int')","((1,), (1,))","('', '')",1,1,5.7275390625,5.7275390625,5.7275390625,5.7275390625,,,5.7275390625,5.7275390625,5.7275390625,5.7275390625,5.7275390625,5.7275390625,24,['sglang_profiler::forward_batch_info_compute_position_triton'],"[{'name': 'compute_position_kernel', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.728), 'mean_duration_us': np.float64(5.728), 'median_duration_us': np.float64(5.728), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.728), 'max_duration_us': np.float64(5.728)}]","[{'name': 'compute_position_kernel', 'stream': 3, 'mean_duration_us': np.float64(5.73)}]",0.0011622168889446594,99.99039313303051 +aten::copy_,elementwise,nn.Module: LogitsProcessor,Unknown,Unknown,Unknown,"((15,), (15,), ())","('long int', 'int', 'Scalar')","((1,), (1,), ())","('', '', 'False')",1,1,5.6884765625,5.6884765625,5.6884765625,5.6884765625,,,5.6884765625,5.6884765625,5.6884765625,5.6884765625,5.6884765625,5.6884765625,3760,"['aten::copy_', 'nn.Module: LogitsProcessor_0']","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.688), 'mean_duration_us': np.float64(5.688), 'median_duration_us': np.float64(5.688), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.688), 'max_duration_us': np.float64(5.688)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(5.69)}]",0.0011542904310490438,99.99154742346155 +aten::sub,elementwise,NA,Unknown,Unknown,Unknown,"((15,), (15,), ())","('long int', 'int', 'Scalar')","((1,), (1,), ())","('', '', '1')",1,1,5.6484375,5.6484375,5.6484375,5.6484375,,,5.6484375,5.6484375,5.6484375,5.6484375,5.6484375,5.6484375,53,['aten::sub'],"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::native::gpu_kernel_impl >(at::TensorIteratorBase&, at::native::CUDAFunctor_add const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl >(at::TensorIteratorBase&, at::native::CUDAFunctor_add const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.648), 'mean_duration_us': np.float64(5.648), 'median_duration_us': np.float64(5.648), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.648), 'max_duration_us': np.float64(5.648)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(5.65)}]",0.0011461658117060377,99.99269358927326 +aten::sub,elementwise,nn.Module: LogitsProcessor,Unknown,Unknown,Unknown,"((15,), (), ())","('long int', 'long int', 'Scalar')","((1,), (), ())","('', '', '1')",1,1,5.607421875,5.607421875,5.607421875,5.607421875,,,5.607421875,5.607421875,5.607421875,5.607421875,5.607421875,5.607421875,3761,"['aten::sub', 'nn.Module: LogitsProcessor_0']","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::CUDAFunctorOnSelf_add, std::array >(int, at::native::CUDAFunctorOnSelf_add, std::array)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.607), 'mean_duration_us': np.float64(5.607), 'median_duration_us': np.float64(5.607), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.607), 'max_duration_us': np.float64(5.607)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::CU...', 'stream': 3, 'mean_duration_us': np.float64(5.61)}]",0.001137843030915641,99.99383143230418 +aten::sub,elementwise,NA,Unknown,Unknown,Unknown,"((15,), (), ())","('long int', 'long int', 'Scalar')","((1,), (), ())","('', '', '1')",1,1,5.52734375,5.52734375,5.52734375,5.52734375,,,5.52734375,5.52734375,5.52734375,5.52734375,5.52734375,5.52734375,3777,['aten::sub'],"[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::CUDAFunctorOnSelf_add, std::array >(int, at::native::CUDAFunctorOnSelf_add, std::array)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.527), 'mean_duration_us': np.float64(5.527), 'median_duration_us': np.float64(5.527), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.527), 'max_duration_us': np.float64(5.527)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::CU...', 'stream': 3, 'mean_duration_us': np.float64(5.53)}]",0.0011215937922296286,99.99495302609641 +aten::cumsum,reduce,nn.Module: LogitsProcessor,Unknown,Unknown,Unknown,"((15,), (), ())","('int', 'Scalar', '')","((1,), (), ())","('', '0', '')",1,1,5.4873046875,11.17578125,5.4873046875,11.17578125,,,5.4873046875,11.17578125,5.4873046875,11.17578125,5.4873046875,11.17578125,3756,"['aten::cumsum', 'nn.Module: LogitsProcessor_0']","[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel, (rocprim::ROCPRIM_400200_NS::detail::target_arch)942, rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2}, rocprim::ROCPRIM_400200_NS::detail::default_config_selector>(rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(5.487), 'mean_duration_us': np.float64(5.487), 'median_duration_us': np.float64(5.487), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.487), 'max_duration_us': np.float64(5.487)}]","[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel >(int, at::native::neg_kernel_cuda(at::TensorIteratorBase&)::{lambda()#2}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, std::array)', 'stream': 2, 'count': 1, 'total_duration_us': np.float64(4.686), 'mean_duration_us': np.float64(4.686), 'median_duration_us': np.float64(4.686), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(4.686), 'max_duration_us': np.float64(4.686)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::ne...', 'stream': 2, 'mean_duration_us': np.float64(4.69)}]",0.0009507786245791093,99.99701727389389 +hipModuleLaunchKernel,other,NA,Unknown,Unknown,Unknown,,,,,1,1,4.685546875,4.685546875,4.685546875,4.685546875,,,4.685546875,4.685546875,4.685546875,4.685546875,4.685546875,4.685546875,57136,['hipModuleLaunchKernel'],"[{'name': 'create_flashinfer_kv_indices_triton', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(4.686), 'mean_duration_us': np.float64(4.686), 'median_duration_us': np.float64(4.686), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(4.686), 'max_duration_us': np.float64(4.686)}]","[{'name': 'create_flashinfer_kv_indices_triton', 'stream': 3, 'mean_duration_us': np.float64(4.69)}]",0.0009507786245791093,99.99796805251847 +aten::_local_scalar_dense,other,NA,Unknown,Unknown,Unknown,"((),)","('int',)","((),)","('',)",1,1,3.724609375,3.724609375,3.724609375,3.724609375,,,3.724609375,3.724609375,3.724609375,3.724609375,3.724609375,3.724609375,46,['aten::_local_scalar_dense'],"[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(3.725), 'mean_duration_us': np.float64(3.725), 'median_duration_us': np.float64(3.725), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(3.725), 'max_duration_us': np.float64(3.725)}]","[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'mean_duration_us': np.float64(3.72)}]",0.0007557877603469618,99.99872384027881 +aten::arange,other,NA,Unknown,Unknown,Unknown,"((), (), (), (0,))","('Scalar', 'Scalar', 'Scalar', 'long int')","((), (), (), (1,))","('223', '238', '1', '')",1,1,3.4853515625,3.4853515625,3.4853515625,3.4853515625,,,3.4853515625,3.4853515625,3.4853515625,3.4853515625,3.4853515625,3.4853515625,3,['aten::arange'],"[{'name': 'void (anonymous namespace)::elementwise_kernel_with_index(int, at::native::arange_cuda_out(c10::Scalar const&, c10::Scalar const&, c10::Scalar const&, at::Tensor&)::{lambda()#1}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, function_traits::result_type*)', 'stream': 2, 'count': 1, 'total_duration_us': np.float64(3.485), 'mean_duration_us': np.float64(3.485), 'median_duration_us': np.float64(3.485), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(3.485), 'max_duration_us': np.float64(3.485)}]","[{'name': 'void (anonymous namespace)::elementwise_kernel_with_index(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(2.804), 'mean_duration_us': np.float64(2.804), 'median_duration_us': np.float64(2.804), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(2.804), 'max_duration_us': np.float64(2.804)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(2.8)}]",0.0005689215154578205,100.0 diff --git a/tests/traces/inference/sglang_prefilldecode/perf_csvs/unified_perf_summary.csv b/tests/traces/inference/sglang_prefilldecode/perf_csvs/unified_perf_summary.csv new file mode 100644 index 000000000..2a2ce318e --- /dev/null +++ b/tests/traces/inference/sglang_prefilldecode/perf_csvs/unified_perf_summary.csv @@ -0,0 +1,37 @@ +name,op category,process_name,process_label,thread_name,Input Dims,Input type,Input Strides,Concrete Inputs,ex_UID,operation_count,total_duration_us,mean_duration_us,std_duration_us,GFLOPS,Data Moved (MB),FLOPS/Byte,Compute Spec,TB/s_mean,TB/s_std,TFLOPS/s_mean,TFLOPS/s_std,Kernel Time (µs)_mean,Kernel Time (µs)_std,Kernel Time (µs)_sum,duration_us_median,duration_us_min,duration_us_max,TB/s_median,TB/s_min,TB/s_max,TFLOPS/s_median,TFLOPS/s_min,TFLOPS/s_max,Kernel Time (µs)_median,Kernel Time (µs)_min,Kernel Time (µs)_max,kernel_details_summary,trunc_kernel_details,perf_params,has_perf_model,Percentage (%),Cumulative Percentage (%) +aiter::gemm_a16w16,GEMM,Unknown,Unknown,Unknown,"((15360, 4096), (24576, 4096), (), (), (), (), ())","('c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '')","((4096, 1), (4096, 1), (), (), (), (), ())","('', '', '', '15', '', '', '')",163,36,1111.41,30.872500000000002,2.117197817871538,3092.37645312,1032.0,2857.6744186046512,matrix_bf16,0.15989855459699648,0.0009942644080381477,456.93800904369596,2.841283964179698,6767.86181640625,42.30302141272883,243643.025390625,30.354999999999997,28.853,41.001,0.1598142700762255,0.15676364830950568,0.1614992228734229,456.69715132480445,447.9794675412107,461.5121978299117,6771.17529296875,6700.5302734375,6902.9423828125,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT128x256x32_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA4_GRVWB4_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB256_LBSPPM0_LPA4_LPB4_LPM0_LRVW4_LWPMn1_MIAV0_MIWT8_4_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW8_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA8_VWB4_WSGRA0_WSGRB0_WS64_WG16_16_1', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen2MLP', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(94): forward', 'nn.Module: MergedColumnParallelLinear', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/linear.py(461): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/quantization/unquant.py(136): apply', 'aiter/tuned_gemm.py(552): mm', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'aiter::gemm_a16w16', 'aiter/tuned_gemm.py(246): gemm_a16w16', 'aiter/tuned_gemm.py(395): torch_gemm', 'aten::linear', 'aten::matmul', 'aten::mm'], 'count': 36, 'total_duration_us': np.float64(243643.021), 'mean_duration_us': np.float64(6767.861694444445), 'median_duration_us': np.float64(6771.1755), 'std_dev_duration_us': np.float64(41.71130077943137), 'min_duration_us': np.float64(6700.53), 'max_duration_us': np.float64(6902.942)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT128x256x32_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(6767.86)}]","{'B': 1, 'M': 15360, 'N': 24576, 'K': 4096, 'bias': False, 'dtype_A_B': ('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16'), 'transpose': (True, False)}",True,49.43939026737225,49.43939026737225 +aiter::gemm_a16w16,GEMM,Unknown,Unknown,Unknown,"((15360, 12288), (4096, 12288), (), (), (), (), ())","('c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '')","((12288, 1), (12288, 1), (), (), (), (), ())","('', '', '', '15', '', '', '')",172,36,1063.843,29.551194444444448,3.695241502406995,1546.18822656,576.0,2560.0,matrix_bf16,0.22784430668329525,0.0021934151326576576,583.281425109236,5.615142739603605,2651.0844997829863,25.669117118336754,95439.0419921875,28.413,26.28,41.833,0.22773631836216326,0.222524755068712,0.23237480025639273,583.004975007138,569.6633729759027,594.8794886563654,2652.1015625,2599.162109375,2714.2138671875,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x16x1_SN_LDSB0_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA1_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA0_LBSPPB256_LBSPPM0_LPA0_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT5_14_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA2_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW1_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA1_VWB2_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen2MLP', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(94): forward', 'nn.Module: RowParallelLinear', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/linear.py(1514): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/quantization/unquant.py(136): apply', 'aiter/tuned_gemm.py(552): mm', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'aiter::gemm_a16w16', 'aiter/tuned_gemm.py(246): gemm_a16w16', 'aiter/tuned_gemm.py(395): torch_gemm', 'aten::linear', 'aten::matmul', 'aten::mm'], 'count': 36, 'total_duration_us': np.float64(95439.041), 'mean_duration_us': np.float64(2651.0844722222223), 'median_duration_us': np.float64(2652.1014999999998), 'std_dev_duration_us': np.float64(25.310139447666806), 'min_duration_us': np.float64(2599.162), 'max_duration_us': np.float64(2714.214)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(2651.08)}]","{'B': 1, 'M': 15360, 'N': 4096, 'K': 12288, 'bias': False, 'dtype_A_B': ('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16'), 'transpose': (True, False)}",True,19.36623482749383,68.80562509486607 +aiter::gemm_a16w16,GEMM,Unknown,Unknown,Unknown,"((15360, 4096), (6144, 4096), (), (), (), (), ())","('c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '')","((4096, 1), (4096, 1), (), (), (), (), ())","('', '', '', '15', '', '', '')",84,36,1187.623,32.98952777777778,19.100006199679033,773.09411328,348.0,2118.6206896551726,matrix_bf16,0.25629236994956,0.006763183331447345,542.9863175758953,14.328620133935333,1424.874538845486,42.645073981571386,51295.4833984375,29.804000000000002,26.3,144.045,0.257305160693752,0.22010358625052645,0.26236321765011933,545.1320370008318,466.3160116976671,555.8481411180459,1418.177734375,1390.8369140625,1657.8759765625,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x192x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA1024_LBSPPB256_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT8_6_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW8_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA8_VWB2_WSGRA0_WSGRB0_WS64_WG32_8_1', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(167): forward_prepare_native', 'nn.Module: QKVParallelLinear', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/linear.py(461): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/quantization/unquant.py(136): apply', 'aiter/tuned_gemm.py(552): mm', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'aiter::gemm_a16w16', 'aiter/tuned_gemm.py(246): gemm_a16w16', 'aiter/tuned_gemm.py(395): torch_gemm', 'aten::linear', 'aten::matmul', 'aten::mm'], 'count': 36, 'total_duration_us': np.float64(51295.484000000004), 'mean_duration_us': np.float64(1424.8745555555556), 'median_duration_us': np.float64(1418.1775), 'std_dev_duration_us': np.float64(42.04861841200046), 'min_duration_us': np.float64(1390.837), 'max_duration_us': np.float64(1657.876)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x192x64_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(1424.87)}]","{'B': 1, 'M': 15360, 'N': 6144, 'K': 4096, 'bias': False, 'dtype_A_B': ('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16'), 'transpose': (True, False)}",True,10.408742128460073,79.21436722332615 +aiter::gemm_a16w16,GEMM,Unknown,Unknown,Unknown,"((15360, 4096), (4096, 4096), (), (), (), (), ())","('c10::BFloat16', 'c10::BFloat16', '', 'Scalar', '', '', '')","((4096, 1), (4096, 1), (), (), (), (), ())","('', '', '', '15', '', '', '')",149,36,1548.814,43.02261111111111,15.400065946570816,515.39607552,272.0,1807.0588235294115,matrix_bf16,0.34829642598889776,0.007117676621272211,629.3921297869965,12.862060341498934,819.2186686197916,17.09959181546983,29491.8720703125,39.619,35.934,128.462,0.34917679608781427,0.32493575013378695,0.3596699771038994,630.9830103422149,587.1780143594079,649.944805684223,816.81884765625,792.984375,877.7509765625,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x16x1_SN_LDSB0_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA1_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB8_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA0_LBSPPB256_LBSPPM0_LPA0_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT5_14_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA2_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW1_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA1_VWB2_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', 'nn.Module: RowParallelLinear', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/linear.py(1514): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/quantization/unquant.py(136): apply', 'aiter/tuned_gemm.py(552): mm', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'aiter::gemm_a16w16', 'aiter/tuned_gemm.py(246): gemm_a16w16', 'aiter/tuned_gemm.py(395): torch_gemm', 'aten::linear', 'aten::matmul', 'aten::mm'], 'count': 36, 'total_duration_us': np.float64(29491.870999999996), 'mean_duration_us': np.float64(819.2186388888888), 'median_duration_us': np.float64(816.819), 'std_dev_duration_us': np.float64(16.860455720993983), 'min_duration_us': np.float64(792.984), 'max_duration_us': np.float64(877.751)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT320x224x64_MI16x1...', 'stream': 3, 'mean_duration_us': np.float64(819.22)}]","{'B': 1, 'M': 15360, 'N': 4096, 'K': 4096, 'bias': False, 'dtype_A_B': ('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16'), 'transpose': (True, False)}",True,5.984411705042385,85.19877892836854 +aiter::mha_batch_prefill,InferenceAttention,Unknown,Unknown,Unknown,"((15360, 32, 128), (835874, 8, 128), (835874, 8, 128), (16,), (16,), (15616,), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'int', 'int', 'int', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', 'Scalar', '', '', '', '', '', '', '', '', '', '', '', '')","((4096, 128, 1), (1024, 128, 1), (1024, 128, 1), (1,), (1,), (1,), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ())","('', '', '', '', '', '', '1024', '1024', '0.', '0.088388347648318447', '0.', 'False', 'True', '-1', '-1', '0', 'False', 'False', '', '', '', '', '', '', '', '', '', '', '', '')",142,36,901.236,25.034333333333333,2.7906529292315385,128.84901888,300.0,409.59999999999997,matrix_bf16,0.5645582448635644,0.016168636904452395,231.243057096116,6.622673676063697,557.6432291666666,15.864896127076442,20075.15625,24.487000000000002,22.233,38.397,0.5627077051306074,0.5365614948712908,0.5980182812587024,230.4850760214968,219.77558829928074,244.94828800356447,559.0341796875,526.025390625,586.275390625,"[{'name': '_ZN7ck_tile6kentryILi2ENS_38FmhaBatchPrefillWithPagedKVCacheKernelINS_40BlockFmhaBatchPrefillPipelineQRKSVSAsyncINS_36BlockFmhaBatchPrefillPipelineProblemIDF16bDF16bDF16bffDF16bhfDF16bfDF16bNS_13TileFmhaShapeINS_8sequenceIJLi128ELi128ELi32ELi128ELi32ELi128EEEENS5_IJLi4ELi1ELi1EEEENS5_IJLi32ELi32ELi16EEEES7_S8_Lb1EEELb1ENS_17ComposedAttentionILj0ELb1EEENS_30SimplifiedGenericAttentionMaskILb1EEELb0ELi1ENS_26TileFmhaBatchPrefillTraitsILb1ELb1ELb1ELb1ELb0ELNS_22BlockAttentionBiasEnumE0ELb0ELb0ELb0ELNS_28BlockAttentionQuantScaleEnumE0ELin1ELb0ELb0ELi1ELNS_37BlockAttentionKVCacheMemoryLayoutEnumE1ELNS_36BlockAttentionKVCacheLookupTableEnumE1ELNS_33BlockAttentionKVCacheLoadModeEnumE0EEEEENS_53BlockFmhaBatchPrefillPipelineQRKSVSAsyncDefaultPolicyEEENS_17Default2DEpilogueINS_24Default2DEpilogueProblemIfDF16bLb1ELb1ELb1EEEvEEEEJNSS_21FmhaFwdGroupModeKargsEEEEvDpT1_', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', 'nn.Module: RadixAttention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/radix_attention.py(105): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/base_attn_backend.py(80): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(2039): forward_extend', 'aiter/ops/mha.py(2929): mha_batch_prefill_func', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::mha__mha_batch_prefill', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', 'aiter/ops/mha.py(2859): _mha_batch_prefill', 'torch/_ops.py(1244): __call__', 'aiter::mha_batch_prefill', 'aiter/jit/core.py(1637): custom_wrapper', 'aiter/jit/core.py(1396): wrapper'], 'count': 36, 'total_duration_us': np.float64(20075.157999999996), 'mean_duration_us': np.float64(557.6432777777777), 'median_duration_us': np.float64(559.034), 'std_dev_duration_us': np.float64(15.642999795100248), 'min_duration_us': np.float64(526.025), 'max_duration_us': np.float64(586.275)}]","[{'name': '_ZN7ck_tile6kentryILi2ENS_38FmhaBatchPrefillWithPagedKVCacheKern...', 'stream': 3, 'mean_duration_us': np.float64(557.64)}]","{'B': 1, 'N_Q': 15360, 'H_Q': 32, 'H_V': 8, 'H_K': 8, 'N_KV': 835874, 'H_KV': 8, 'd_h_qk': 128, 'd_h_v': 128, 'dropout': 0.0, 'causal': False, 'flash_impl': True, 'c_sq': 15360, 'c_sk': 15360, 'c_sqsq': 15728640, 'c_sqsk': 15728640, 'g_sq': 0, 'g_sk': 0, 'g_sqsq': 0, 'g_sqsk': 0, 'dtype_Q': 'c10::BFloat16', 'dtype_KV': 'c10::BFloat16'}",True,4.073596947546429,89.27237587591497 +sgl_kernel::silu_and_mul,elementwise,Unknown,Unknown,Unknown,"((15360, 12288), (15360, 24576))","('c10::BFloat16', 'c10::BFloat16')","((12288, 1), (24576, 1))","('', '')",171,36,191.906,5.330722222222223,0.9726495951372391,0.9437184,1080.0,0.8333333333333334,vector_bf16,2.4700587081645455,0.03392069228478842,2.058382256803788,0.028267243570656905,458.5595703125,6.277613863685246,16508.14453125,5.187,4.607,10.766,2.4726088311868417,2.397131585200987,2.5559984701583005,2.060507359322368,1.997609654334156,2.1299987251319172,458.0029296875,443.060546875,472.423828125,"[{'name': '_ZN7sgl_hip10activation18act_and_mul_kernelI14__hip_bfloat16TnPFT_RKS3_EXadL_Z4siluIS2_ES3_S5_EEEEvPS3_PS4_i', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen2MLP', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(94): forward', 'nn.Module: SiluAndMul', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(81): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(94): forward_hip', '/sgl-workspace/sglang/python/sglang/srt/layers/activation.py(83): forward_cuda', 'sgl_kernel/elementwise.py(258): silu_and_mul', 'torch/_ops.py(840): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(840): __call__', 'sgl_kernel::silu_and_mul'], 'count': 36, 'total_duration_us': np.float64(16508.145), 'mean_duration_us': np.float64(458.55958333333336), 'median_duration_us': np.float64(458.00300000000004), 'std_dev_duration_us': np.float64(6.189793280406597), 'min_duration_us': np.float64(443.061), 'max_duration_us': np.float64(472.424)}]","[{'name': '_ZN7sgl_hip10activation18act_and_mul_kernelI14__hip_bfloat16TnPF...', 'stream': 3, 'mean_duration_us': np.float64(458.56)}]","{'op_shape': (15360, 12288), 'dtype_in_out': ('c10::BFloat16', 'c10::BFloat16'), 'stride_input': (24576, 1), 'stride_output': (12288, 1)}",True,3.349788481579329,92.6221643574943 +aiter::rmsnorm,RMSNorm,Unknown,Unknown,Unknown,"((491520, 128), (491520, 128), (128,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((128, 1), (128, 1), (1,), ())","('', '', '', '9.9999999999999995e-07')",106,36,475.969,13.221361111111111,3.7699691787506913,0.25264128,240.000244140625,1.0039052287747918,vector_bf16,0.654200659311961,0.06424884195040104,0.6567554625511939,0.06449974837673281,387.04380967881946,24.818198394275207,13933.5771484375,12.5535,11.317,34.722,0.6439519483741629,0.6292783638752277,1.0258118572372559,0.646466728052537,0.6317358398491871,1.0298178872196615,390.80322265625,245.326171875,399.916015625,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(167): forward_prepare_native', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::utils_apply_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/models/utils.py(416): apply_qk_norm', 'nn.Module: RMSNorm', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(81): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/layernorm.py(281): forward_aiter', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'sglang_profiler::rmsnorm_rmsnorm2d_fwd', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', 'aiter/ops/rmsnorm.py(62): rmsnorm2d_fwd', 'torch/_ops.py(1244): __call__', 'aiter::rmsnorm', 'aiter/jit/core.py(1637): custom_wrapper', 'aiter/jit/core.py(1396): wrapper'], 'count': 36, 'total_duration_us': np.float64(13933.577), 'mean_duration_us': np.float64(387.04380555555554), 'median_duration_us': np.float64(390.803), 'std_dev_duration_us': np.float64(24.471096357425704), 'min_duration_us': np.float64(245.326), 'max_duration_us': np.float64(399.916)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0EL...', 'stream': 3, 'mean_duration_us': np.float64(387.04)}]","{'op_shape': (491520, 128), 'dtype_in_out': ('c10::BFloat16', None), 'stride_input': (128, 1), 'stride_output': None, 'num_channels': 128, 'has_bias': False, 'is_affine': True, 'is_training': False}",True,2.8273641626215325,95.44952852011583 +aiter::add_rmsnorm,RMSNorm,Unknown,Unknown,Unknown,"((15360, 4096), (15360, 4096), (15360, 4096), (15360, 4096), (4096,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((4096, 1), (4096, 1), (4096, 1), (4096, 1), (1,), ())","('', '', '', '', '', '9.9999999999999995e-07')",161,72,731.544,10.160333333333334,0.8829756349022254,0.31460352,480.0078125,0.6250508618023796,vector_bf16,4.1682095657777065,0.10389215802578437,2.6053429812622775,0.06493788290852544,120.82103135850694,2.767866612625456,8699.1142578125,10.11,8.813,14.072,4.162462881821314,4.030943236677042,4.8548865331097755,2.6017510115028286,2.5195445439614588,3.034551011473032,120.919921875,103.673828125,124.865234375,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb1ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/communicator.py(665): prepare_mlp', '/sgl-workspace/sglang/python/sglang/srt/layers/communicator.py(933): _simple', 'nn.Module: RMSNorm', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(81): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/layernorm.py(281): forward_aiter', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::rmsnorm_rmsnorm2d_fwd_with_add', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', 'aiter/ops/rmsnorm.py(76): rmsnorm2d_fwd_with_add', 'torch/_ops.py(1244): __call__', 'aiter::add_rmsnorm', 'aiter/jit/core.py(1637): custom_wrapper', 'aiter/jit/core.py(1396): wrapper'], 'count': 72, 'total_duration_us': np.float64(8699.121), 'mean_duration_us': np.float64(120.821125), 'median_duration_us': np.float64(120.9195), 'std_dev_duration_us': np.float64(2.7485319815893434), 'min_duration_us': np.float64(103.674), 'max_duration_us': np.float64(124.865)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi256ELi16ELb1ELb0...', 'stream': 3, 'mean_duration_us': np.float64(120.82)}]","{'op_shape': (15360, 4096), 'dtype_in_out': ('c10::BFloat16', None), 'stride_input': (4096, 1), 'stride_output': None, 'num_channels': 4096, 'has_bias': False, 'is_affine': True, 'is_training': False}",True,1.765200970078757,97.21472949019459 +sgl_kernel::rotary_embedding,RoPE_fwd,Unknown,Unknown,Unknown,"((15360,), (15360, 4096), (15360, 1024), (), (41216, 128), ())","('long int', 'c10::BFloat16', 'c10::BFloat16', 'Scalar', 'c10::BFloat16', 'Scalar')","((1,), (4096, 1), (1024, 1), (), (128, 1), ())","('', '', '', '128', '', 'True')",127,36,203.504,5.652888888888889,0.4308559439585863,0.2359296,300.0,0.75,vector_bf16,2.3974276270839723,0.04285455203091364,1.798070720312979,0.03214091402318532,131.25290256076389,2.3174412724836753,4725.1044921875,5.639,5.018,7.502,2.386455825297114,2.3205335715417754,2.4921091097580788,1.7898418689728355,1.7404001786563317,1.869081832318559,131.81591796875,126.2275390625,135.560546875,"[{'name': 'void rotary_embedding_kernel(long const*, c10::BFloat16*, c10::BFloat16*, c10::BFloat16 const*, int, long, long, long, int, int, int)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(167): forward_prepare_native', 'nn.Module: RotaryEmbedding', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(81): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(94): forward_hip', '/sgl-workspace/sglang/python/sglang/srt/layers/rotary_embedding/base.py(335): forward_cuda', 'sgl_kernel/elementwise.py(327): rotary_embedding', 'torch/_ops.py(840): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(840): __call__', 'sgl_kernel::rotary_embedding'], 'count': 36, 'total_duration_us': np.float64(4725.106), 'mean_duration_us': np.float64(131.25294444444444), 'median_duration_us': np.float64(131.816), 'std_dev_duration_us': np.float64(2.28499364142617), 'min_duration_us': np.float64(126.228), 'max_duration_us': np.float64(135.561)}]","[{'name': 'void rotary_embedding_kernel(long const*, c...', 'stream': 3, 'mean_duration_us': np.float64(131.25)}]",{'num_elements': 78643200},True,0.9588055503285519,98.17353504052313 +aiter::rmsnorm,RMSNorm,Unknown,Unknown,Unknown,"((122880, 128), (122880, 128), (128,), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'Scalar')","((128, 1), (128, 1), (1,), ())","('', '', '', '9.9999999999999995e-07')",120,36,405.697,11.269361111111111,1.9172929301905663,0.06316032,60.000244140625,1.0039021651116329,vector_bf16,0.6411243209576277,0.06142780972465145,0.643626093915088,0.06166751118064305,98.71761067708333,6.3175549998410485,3553.833984375,10.9815,9.534,21.622,0.6279671012361419,0.6127755629280172,0.9933816200080182,0.6304175325498389,0.6151667143509361,0.9972579591081508,100.1884765625,63.333984375,102.671875,"[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0ELb1ELi1EEEvPT0_PT_PfS4_S4_S4_diiiiiiib', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(167): forward_prepare_native', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::utils_apply_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/models/utils.py(416): apply_qk_norm', 'nn.Module: RMSNorm', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/utils/multi_platform.py(81): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/layernorm.py(281): forward_aiter', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'sglang_profiler::rmsnorm_rmsnorm2d_fwd', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', 'aiter/ops/rmsnorm.py(62): rmsnorm2d_fwd', 'torch/_ops.py(1244): __call__', 'aiter::rmsnorm', 'aiter/jit/core.py(1637): custom_wrapper', 'aiter/jit/core.py(1396): wrapper'], 'count': 36, 'total_duration_us': np.float64(3553.835), 'mean_duration_us': np.float64(98.71763888888889), 'median_duration_us': np.float64(100.1885), 'std_dev_duration_us': np.float64(6.229195699610279), 'min_duration_us': np.float64(63.334), 'max_duration_us': np.float64(102.672)}]","[{'name': '_ZN5aiter24add_rmsnorm_quant_kernelIDF16bDF16bLi64ELi8ELb0ELb0EL...', 'stream': 3, 'mean_duration_us': np.float64(98.72)}]","{'op_shape': (122880, 128), 'dtype_in_out': ('c10::BFloat16', None), 'stride_input': (128, 1), 'stride_output': None, 'num_channels': 128, 'has_bias': False, 'is_affine': True, 'is_training': False}",True,0.7211344753960142,98.89466951591915 +aten::copy_,elementwise,Unknown,Unknown,Unknown,"((15360, 4096), (15360, 4096), ())","('c10::BFloat16', 'c10::BFloat16', 'Scalar')","((4096, 1), (6144, 1), ())","('', '', 'False')",101,36,290.51,8.069722222222222,1.4160157910965963,0.06291456,240.0,0.24999999999999997,vector_bf16,3.4973343217186414,0.11894917690528885,0.8743335804296604,0.029737294226322212,72.0400390625,2.508946155821979,2593.44140625,7.8915,6.68,15.864,3.5253933829134576,3.1872809300944938,3.6932188397156613,0.8813483457283644,0.7968202325236234,0.9233047099289153,71.38525390625,68.140625,78.95703125,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(167): forward_prepare_native', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::utils_apply_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/models/utils.py(416): apply_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'sglang_profiler::utils__reshape_for_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/models/utils.py(394): _reshape_for_qk_norm', 'aten::reshape', 'aten::clone', 'aten::copy_'], 'count': 36, 'total_duration_us': np.float64(2593.4410000000007), 'mean_duration_us': np.float64(72.0400277777778), 'median_duration_us': np.float64(71.38550000000001), 'std_dev_duration_us': np.float64(2.4737914724625423), 'min_duration_us': np.float64(68.141), 'max_duration_us': np.float64(78.957)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::na...', 'stream': 3, 'mean_duration_us': np.float64(72.04)}]","{'op_shape': (15360, 4096), 'dtype_in_out': ('c10::BFloat16', 'c10::BFloat16'), 'stride_input': (4096, 1), 'stride_output': (6144, 1)}",True,0.5262541852515105,99.42092370117066 +sglang::store_cache,InferenceAttention,Unknown,Unknown,Unknown,"((15360, 1024), (15360, 1024), (835874, 1024), (835874, 1024), (15360,), (), ())","('c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'c10::BFloat16', 'long int', 'Scalar', 'Scalar')","((1024, 1), (6144, 1), (1024, 1), (1024, 1), (1,), (), ())","('', '', '', '', '', '2048', '0')",135,36,357.273,9.92425,2.1473168822642688,0.0,120.0,0.0,vector_bf16,3.5701923646690665,0.15744014539551918,0.0,0.0,35.311604817708336,1.5715359604665984,1271.2177734375,9.5845,8.252,21.843,3.5816809736345037,3.218409363806669,3.9560644421246542,0.0,0.0,0.0,35.13134765625,31.806640625,39.0966796875,"[{'name': 'void (anonymous namespace)::store_kvcache<2048l, 4, false, long>((anonymous namespace)::StoreKVCacheParams)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', 'nn.Module: RadixAttention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/radix_attention.py(105): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/base_attn_backend.py(80): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(2039): forward_extend', '/sgl-workspace/sglang/python/sglang/srt/mem_cache/memory_pool.py(1038): set_kv_buffer', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::memory_pool__set_kv_buffer_impl', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/mem_cache/memory_pool.py(90): _set_kv_buffer_impl', 'torch/_ops.py(1244): __call__', 'sglang::store_cache', '/sgl-workspace/sglang/python/sglang/jit_kernel/kvcache.py(50): store_cache'], 'count': 36, 'total_duration_us': np.float64(1271.2200000000003), 'mean_duration_us': np.float64(35.311666666666675), 'median_duration_us': np.float64(35.1315), 'std_dev_duration_us': np.float64(1.54956371996192), 'min_duration_us': np.float64(31.807), 'max_duration_us': np.float64(39.097)}]","[{'name': 'void (anonymous namespace)::store_kvcache<2048l, 4, false, long>...', 'stream': 3, 'mean_duration_us': np.float64(35.31)}]","{'op_shape': (15360, 1024), 'nelems': 15728640, 'dtype': 'c10::BFloat16'}",True,0.2579521064271551,99.67887580759782 +aten::copy_,elementwise,Unknown,Unknown,Unknown,"((15360, 1024), (15360, 1024), ())","('c10::BFloat16', 'c10::BFloat16', 'Scalar')","((1024, 1), (6144, 1), ())","('', '', 'False')",115,36,188.49099999999999,5.23586111111111,0.4761609663475327,0.01572864,60.0,0.24999999999999997,vector_bf16,2.847481982334509,0.10273903769422547,0.7118704955836272,0.02568475942355637,22.12421332465278,0.8395477383836966,796.4716796875,5.217,4.337,6.841,2.876543632804648,2.545517777865581,3.0557562699805527,0.719135908201162,0.6363794444663953,0.7639390674951382,21.87158203125,20.5888671875,24.7158203125,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#12}::operator()() const::{lambda(c10::BFloat16)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: Qwen3DecoderLayer', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(384): forward', 'nn.Module: Qwen3Attention', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(263): forward', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(167): forward_prepare_native', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::utils_apply_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/models/utils.py(416): apply_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'sglang_profiler::utils__reshape_for_qk_norm', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/models/utils.py(394): _reshape_for_qk_norm', 'aten::reshape', 'aten::clone', 'aten::copy_'], 'count': 36, 'total_duration_us': np.float64(796.476), 'mean_duration_us': np.float64(22.124333333333333), 'median_duration_us': np.float64(21.871499999999997), 'std_dev_duration_us': np.float64(0.827839591278944), 'min_duration_us': np.float64(20.589), 'max_duration_us': np.float64(24.716)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 8, at::na...', 'stream': 3, 'mean_duration_us': np.float64(22.12)}]","{'op_shape': (15360, 1024), 'dtype_in_out': ('c10::BFloat16', 'c10::BFloat16'), 'stride_input': (1024, 1), 'stride_output': (6144, 1)}",True,0.1616179003927891,99.8404937079906 +aten::mm,GEMM,Unknown,Unknown,Unknown,"((15, 4096), (4096, 151936))","('c10::BFloat16', 'c10::BFloat16')","((4096, 1), (1, 4096))","('', '')",3771,1,33.07,33.07,,18.66989568,1191.464111328125,14.943798835999154,matrix_bf16,2.8632861644348853,,42.788372451214514,,436.3310546875,,436.3310546875,33.07,33.07,33.07,2.8632861644348853,2.8632861644348853,2.8632861644348853,42.788372451214514,42.788372451214514,42.788372451214514,436.3310546875,436.3310546875,436.3310546875,"[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x16x64_MI16x16x1_SN_LDSB1_AFC1_AFEM1_AFEM1_ASEM1_CLR1_CADS0_DTLA0_DTLB0_DTVA0_DTVB0_EPS0_FDSI0_GRPM1_GRVWA8_GRVWB4_GSUAMBSK_GLS0_ISA942_IU1_K1_LDSTI0_LBSPPA512_LBSPPB128_LBSPPM0_LPA16_LPB16_LPM0_LRVW8_LWPMn1_MIAV0_MIWT4_1_MO40_NTn1_NTA0_NTB0_NTC0_NTD4_NTM0_NEPBS16_NLCA1_NLCB1_ONLL1_PGR2_PLR1_PKA1_SIA3_SS1_SPO0_SRVW0_SSO0_SVW4_SK0_SKFTR0_SKXCCM0_TLDS1_ULSGRO0_USL1_UIOFGRO0_USFGROn1_VSn1_VWA4_VWB1_WSGRA0_WSGRB0_WS64_WG64_4_1', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: LogitsProcessor', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(285): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(839): _get_logits', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(883): _compute_lm_head', 'torch/utils/_device.py(99): __torch_function__', 'aten::matmul', 'aten::mm'], 'count': 1, 'total_duration_us': np.float64(436.331), 'mean_duration_us': np.float64(436.331), 'median_duration_us': np.float64(436.331), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(436.331), 'max_duration_us': np.float64(436.331)}]","[{'name': 'Cijk_Alik_Bljk_BBS_BH_Bias_HA_S_SAV_UserArgs_MT256x16x64_MI16x16...', 'stream': 3, 'mean_duration_us': np.float64(436.33)}]","{'M': 15, 'N': 151936, 'K': 4096, 'bias': False, 'stride_A': (4096, 1), 'stride_B': (1, 4096), 'dtype_A_B': ('c10::BFloat16', 'c10::BFloat16'), 'B': 1, 'transpose': (True, False)}",True,0.0885391291783701,99.92903283716898 +aten::argmax,reduce,Unknown,Unknown,Unknown,"((15, 151936), (), ())","('float', 'Scalar', 'Scalar')","((151936, 1), (), ())","('', '-1', 'False')",3778,1,17.706,17.706,,,,,,,,,,74.349609375,,74.349609375,17.706,17.706,17.706,,,,,,,74.349609375,74.349609375,74.349609375,"[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp, unsigned int, long, 4, 4> >(at::native::ReduceOp, unsigned int, long, 4, 4>)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3305): sample', 'nn.Module: Sampler', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/sampler.py(83): forward', 'torch/utils/_device.py(99): __torch_function__', 'aten::argmax'], 'count': 1, 'total_duration_us': np.float64(74.35), 'mean_duration_us': np.float64(74.35), 'median_duration_us': np.float64(74.35), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(74.35), 'max_duration_us': np.float64(74.35)}]","[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp(char*, char*, long*, int, long, long, long, long, bool)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: Qwen3Model', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/models/qwen2.py(340): forward', 'nn.Module: VocabParallelEmbedding', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/vocab_parallel_embedding.py(471): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/quantization/unquant.py(103): embedding', 'torch/nn/functional.py(2428): embedding', 'torch/overrides.py(1677): handle_torch_function', 'torch/utils/_device.py(99): __torch_function__', 'torch/nn/functional.py(2428): embedding', 'aten::embedding', 'aten::index_select', 'aten::gather'], 'count': 1, 'total_duration_us': np.float64(66.258), 'mean_duration_us': np.float64(66.258), 'median_duration_us': np.float64(66.258), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(66.258), 'max_duration_us': np.float64(66.258)}]","[{'name': 'void at::native::vectorized_gather_kernel<16, long>(char*, char*...', 'stream': 3, 'mean_duration_us': np.float64(66.26)}]",,False,0.013444857882543437,99.97218011440086 +aten::_local_scalar_dense,other,Unknown,Unknown,Unknown,"((),)","('long int',)","((),)","('',)",32,2,80.821,40.4105,1.331482068974266,,,,,,,,,5.70751953125,0.7077973151525501,11.4150390625,40.4105,39.469,41.352,,,,,,,5.70751953125,5.20703125,6.2080078125,"[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(661): init_forward_metadata', 'torch/utils/_device.py(99): __torch_function__', 'aten::item', 'aten::_local_scalar_dense'], 'count': 2, 'total_duration_us': np.float64(11.415), 'mean_duration_us': np.float64(5.7075), 'median_duration_us': np.float64(5.7075), 'std_dev_duration_us': np.float64(0.5005000000000002), 'min_duration_us': np.float64(5.207), 'max_duration_us': np.float64(6.208)}]","[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'mean_duration_us': np.float64(5.71)}]",,False,0.0023163091585463127,99.9744964235594 +aten::cumsum,reduce,Unknown,Unknown,Unknown,"((15,), (), ())","('int', 'Scalar', '')","((1,), (), ())","('', '0', '')",3756,1,25.288,25.288,,1.5e-08,0.00011444091796875,0.12499999999999999,,1.0737504369101713e-05,,1.342188046137714e-06,,11.17578125,,11.17578125,25.288,25.288,25.288,1.0737504369101713e-05,1.0737504369101713e-05,1.0737504369101713e-05,1.342188046137714e-06,1.342188046137714e-06,1.342188046137714e-06,11.17578125,11.17578125,11.17578125,"[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel, (rocprim::ROCPRIM_400200_NS::detail::target_arch)942, rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2}, rocprim::ROCPRIM_400200_NS::detail::default_config_selector>(rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2})', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: LogitsProcessor', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(285): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(404): _get_pruned_states', 'torch/utils/_device.py(99): __torch_function__', 'aten::cumsum'], 'count': 1, 'total_duration_us': np.float64(5.487), 'mean_duration_us': np.float64(5.487), 'median_duration_us': np.float64(5.487), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.487), 'max_duration_us': np.float64(5.487)}, {'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: LogitsProcessor', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(285): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(404): _get_pruned_states', 'torch/utils/_device.py(99): __torch_function__', 'aten::cumsum', 'aten::to', 'aten::_to_copy', 'aten::copy_'], 'count': 1, 'total_duration_us': np.float64(5.688), 'mean_duration_us': np.float64(5.688), 'median_duration_us': np.float64(5.688), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.688), 'max_duration_us': np.float64(5.688)}]","[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel, std::array >(int, at::native::CUDAFunctorOnSelf_add, std::array)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: LogitsProcessor', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(285): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(404): _get_pruned_states', 'torch/utils/_device.py(99): __torch_function__', 'aten::sub'], 'count': 2, 'total_duration_us': np.float64(11.134), 'mean_duration_us': np.float64(5.567), 'median_duration_us': np.float64(5.567), 'std_dev_duration_us': np.float64(0.040000000000000036), 'min_duration_us': np.float64(5.527), 'max_duration_us': np.float64(5.607)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::CU...', 'stream': 3, 'mean_duration_us': np.float64(5.57)}]",,False,0.00225943682314527,99.97902361998649 +aten::max,reduce,Unknown,Unknown,Unknown,"((15,),)","('long int',)","((1,),)","('',)",28,2,92.18799999999999,46.093999999999994,39.59373710575954,1.5e-08,0.0001220703125,0.11718749999999999,,2.5935888310650906e-05,8.073360302448693e-06,3.039361911404403e-06,9.460969104432061e-07,5.1865234375,1.6144684125138165,10.373046875,46.093999999999994,18.097,74.091,2.5935888310650906e-05,2.022716049382716e-05,3.164461612747465e-05,3.039361911404403e-06,2.3703703703703703e-06,3.7083534524384358e-06,5.1865234375,4.044921875,6.328125,"[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp >, unsigned int, long, 4, 4> >(at::native::ReduceOp >, unsigned int, long, 4, 4>)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(661): init_forward_metadata', 'torch/utils/_device.py(99): __torch_function__', 'aten::max'], 'count': 2, 'total_duration_us': np.float64(10.373000000000001), 'mean_duration_us': np.float64(5.1865000000000006), 'median_duration_us': np.float64(5.1865000000000006), 'std_dev_duration_us': np.float64(1.1415000000000002), 'min_duration_us': np.float64(4.045), 'max_duration_us': np.float64(6.328)}]","[{'name': 'void at::native::reduce_kernel<512, 1, at::native::ReduceOp Device)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/forward_batch_info.py(443): init_new', 'torch/utils/_device.py(99): __torch_function__', 'aten::to', 'aten::_to_copy', 'aten::copy_'], 'count': 2, 'total_duration_us': np.float64(9.972999999999999), 'mean_duration_us': np.float64(4.9864999999999995), 'median_duration_us': np.float64(4.9864999999999995), 'std_dev_duration_us': np.float64(0.3005), 'min_duration_us': np.float64(4.686), 'max_duration_us': np.float64(5.287)}]","[{'name': 'Memcpy HtoD (Host -> Device)', 'stream': 3, 'mean_duration_us': np.float64(4.99)}]","{'op_shape': (15,), 'dtype_in_out': ('int', 'int'), 'stride_input': (1,), 'stride_output': (1,)}",True,0.0020236247007507013,99.98315211558143 +aten::copy_,elementwise,Unknown,Unknown,Unknown,"((15, 151936), (15, 151936), ())","('float', 'c10::BFloat16', 'Scalar')","((151936, 1), (151936, 1), ())","('', '', 'False')",3776,1,10.626,10.626,,0.00227904,13.040771484375,0.16666666666666666,vector_fp32,1.3877524043607532,,0.23129206739345887,,9.853515625,,9.853515625,10.626,10.626,10.626,1.3877524043607532,1.3877524043607532,1.3877524043607532,0.23129206739345887,0.23129206739345887,0.23129206739345887,9.853515625,9.853515625,9.853515625,"[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::bfloat16tofloat32_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda(c10::BFloat16)#1}, std::array >(int, at::native::bfloat16tofloat32_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda(c10::BFloat16)#1}, std::array)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: LogitsProcessor', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(285): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(839): _get_logits', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(983): _copy_logits_to_buffer', 'torch/utils/_device.py(99): __torch_function__', 'aten::to', 'aten::_to_copy', 'aten::copy_'], 'count': 1, 'total_duration_us': np.float64(9.854), 'mean_duration_us': np.float64(9.854), 'median_duration_us': np.float64(9.854), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(9.854), 'max_duration_us': np.float64(9.854)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::bf...', 'stream': 3, 'mean_duration_us': np.float64(9.85)}]","{'op_shape': (15, 151936), 'dtype_in_out': ('float', 'c10::BFloat16'), 'stride_input': (151936, 1), 'stride_output': (151936, 1)}",True,0.001999449004169073,99.9851515645856 +aten::cumsum,reduce,Unknown,Unknown,Unknown,"((15,), (), ())","('long int', 'Scalar', '')","((1,), (), ())","('', '0', '')",33,2,62.45399999999999,31.226999999999997,9.093393206058996,1.5e-08,0.0002288818359375,0.06249999999999999,,5.398809357889497e-05,1.0149336986167392e-05,3.3742558486809357e-06,6.34333561635462e-07,4.525390625,0.850737846115065,9.05078125,31.226999999999997,24.797,37.657,5.398809357889497e-05,4.6811428571428566e-05,6.116475858636137e-05,3.3742558486809357e-06,2.9257142857142854e-06,3.822797411647586e-06,4.525390625,3.923828125,5.126953125,"[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel, (rocprim::ROCPRIM_400200_NS::detail::target_arch)942, rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2}, rocprim::ROCPRIM_400200_NS::detail::default_config_selector>(rocprim::ROCPRIM_400200_NS::detail::scan_impl<(rocprim::ROCPRIM_400200_NS::detail::lookback_scan_determinism)0, false, false, rocprim::ROCPRIM_400200_NS::default_config, long const*, long*, long, std::plus, long>(void*, unsigned long&, long const*, long*, long, unsigned long, std::plus, ihipStream_t*, bool)::{lambda(auto:1, auto:2)#1}::operator(), std::integral_constant >(std::integral_constant, std::integral_constant) const::{lambda(auto:1)#2})', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(661): init_forward_metadata', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(2654): update_single_wrapper', 'torch/utils/_device.py(99): __torch_function__', 'aten::cumsum'], 'count': 2, 'total_duration_us': np.float64(9.051), 'mean_duration_us': np.float64(4.5255), 'median_duration_us': np.float64(4.5255), 'std_dev_duration_us': np.float64(0.6014999999999999), 'min_duration_us': np.float64(3.924), 'max_duration_us': np.float64(5.127)}]","[{'name': 'void rocprim::ROCPRIM_400200_NS::detail::trampoline_kernel(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(661): init_forward_metadata', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(2654): update_single_wrapper', 'torch/utils/_device.py(99): __torch_function__', 'aten::copy_'], 'count': 2, 'total_duration_us': np.float64(7.4079999999999995), 'mean_duration_us': np.float64(3.7039999999999997), 'median_duration_us': np.float64(3.7039999999999997), 'std_dev_duration_us': np.float64(1.1820000000000002), 'min_duration_us': np.float64(2.522), 'max_duration_us': np.float64(4.886)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(3.7)}]","{'op_shape': (15,), 'dtype_in_out': ('int', 'long int'), 'stride_input': (1,), 'stride_output': (1,)}",True,0.0015032527399035272,99.98849137761992 +aten::copy_,elementwise,Unknown,Unknown,Unknown,"((15,), (15,), ())","('long int', 'long int', 'Scalar')","((1,), (1,), ())","('', '', 'True')",3786,1,7.841,7.841,,1.5e-08,0.0002288818359375,0.06249999999999999,,3.404349632913146e-05,,2.1277185205707162e-06,,7.0498046875,,7.0498046875,7.841,7.841,7.841,3.404349632913146e-05,3.404349632913146e-05,3.404349632913146e-05,2.1277185205707162e-06,2.1277185205707162e-06,2.1277185205707162e-06,7.0498046875,7.0498046875,7.0498046875,"[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/utils.py(56): copy_to_cpu', 'torch/utils/_device.py(99): __torch_function__', 'aten::to', 'aten::_to_copy', 'aten::copy_'], 'count': 1, 'total_duration_us': np.float64(7.05), 'mean_duration_us': np.float64(7.05), 'median_duration_us': np.float64(7.05), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(7.05), 'max_duration_us': np.float64(7.05)}]","[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'mean_duration_us': np.float64(7.05)}]","{'op_shape': (15,), 'dtype_in_out': ('long int', 'long int'), 'stride_input': (1,), 'stride_output': (1,)}",True,0.0014305274887112527,99.98992190510863 +"hipLaunchKernel->void (anonymous namespace)::resolve_future_token_ids_kernel(long*, long const*, unsigned long) (Synthetic Op)",other,Unknown,Unknown,Unknown,,,,,60315,1,5.008,5.008,,,,,,,,,,7.009765625,,7.009765625,5.008,5.008,5.008,,,,,,,7.009765625,7.009765625,7.009765625,"[{'name': 'void (anonymous namespace)::resolve_future_token_ids_kernel(long*, long const*, unsigned long)', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(7.01), 'mean_duration_us': np.float64(7.01), 'median_duration_us': np.float64(7.01), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(7.01), 'max_duration_us': np.float64(7.01)}]","[{'name': 'void (anonymous namespace)::resolve_future_token_ids_kernel(char*, char*, long*, int, long, long, long, long, bool)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', 'torch/utils/_contextlib.py(117): decorate_context', '/sgl-workspace/sglang/python/sglang/srt/models/qwen3.py(507): forward', 'nn.Module: LogitsProcessor', 'torch/nn/modules/module.py(1779): _call_impl', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(285): forward', '/sgl-workspace/sglang/python/sglang/srt/layers/logits_processor.py(404): _get_pruned_states', 'torch/utils/_device.py(99): __torch_function__', 'aten::index'], 'count': 1, 'total_duration_us': np.float64(6.088), 'mean_duration_us': np.float64(6.088), 'median_duration_us': np.float64(6.088), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(6.088), 'max_duration_us': np.float64(6.088)}]","[{'name': 'void at::native::vectorized_gather_kernel<16, long>(char*, char*...', 'stream': 3, 'mean_duration_us': np.float64(6.09)}]",,False,0.0012353384630317149,99.99257964644103 +aten::copy_,elementwise,Unknown,Unknown,Unknown,"((15,), (15,), ())","('long int', 'long int', 'Scalar')","((1,), (1,), ())","('', '', 'False')",3782,1,8.563,8.563,,1.5e-08,0.0002288818359375,0.06249999999999999,,4.1325037834202115e-05,,2.582814864637632e-06,,5.8076171875,,5.8076171875,8.563,8.563,8.563,4.1325037834202115e-05,4.1325037834202115e-05,4.1325037834202115e-05,2.582814864637632e-06,2.582814864637632e-06,2.582814864637632e-06,5.8076171875,5.8076171875,5.8076171875,"[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/overlap_utils.py(161): store_to_map', 'torch/utils/_device.py(99): __torch_function__', 'aten::copy_'], 'count': 1, 'total_duration_us': np.float64(5.808), 'mean_duration_us': np.float64(5.808), 'median_duration_us': np.float64(5.808), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.808), 'max_duration_us': np.float64(5.808)}]","[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'mean_duration_us': np.float64(5.81)}]","{'op_shape': (15,), 'dtype_in_out': ('long int', 'long int'), 'stride_input': (1,), 'stride_output': (1,)}",True,0.0011784661276306716,99.99375811256866 +sglang_profiler::forward_batch_info_compute_position_triton,other,Unknown,Unknown,Unknown,"((15,), (15,))","('int', 'int')","((1,), (1,))","('', '')",24,1,104.776,104.776,,,,,,,,,,5.7275390625,,5.7275390625,104.776,104.776,104.776,,,,,,,5.7275390625,5.7275390625,5.7275390625,"[{'name': 'compute_position_kernel', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/forward_batch_info.py(443): init_new', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'torch/utils/_device.py(99): __torch_function__', 'torch/_ops.py(1244): __call__', 'sglang_profiler::forward_batch_info_compute_position', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/model_executor/forward_batch_info.py(1123): compute_position', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(326): dispatch_wrapper', 'torch/_ops.py(1244): __call__', 'sglang_profiler::forward_batch_info_compute_position_triton', '/sgl-workspace/sglang/python/sglang/srt/utils/kernel_shape_profiler.py(302): impl', '/sgl-workspace/sglang/python/sglang/srt/model_executor/forward_batch_info.py(1142): compute_position_triton', '/sgl-workspace/triton-custom/python/triton/runtime/jit.py(370): ', '/sgl-workspace/triton-custom/python/triton/runtime/jit.py(708): run', '/sgl-workspace/triton-custom/python/triton/backends/amd/driver.py(831): __call__'], 'count': 1, 'total_duration_us': np.float64(5.728), 'mean_duration_us': np.float64(5.728), 'median_duration_us': np.float64(5.728), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.728), 'max_duration_us': np.float64(5.728)}]","[{'name': 'compute_position_kernel', 'stream': 3, 'mean_duration_us': np.float64(5.73)}]",,False,0.0011622168889446594,99.9949203294576 +aten::sub,elementwise,Unknown,Unknown,Unknown,"((15,), (15,), ())","('long int', 'int', 'Scalar')","((1,), (1,), ())","('', '', '1')",53,1,17.926,17.926,,,,,,,,,,5.6484375,,5.6484375,17.926,17.926,17.926,,,,,,,5.6484375,5.6484375,5.6484375,"[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::native::gpu_kernel_impl >(at::TensorIteratorBase&, at::native::CUDAFunctor_add const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl >(at::TensorIteratorBase&, at::native::CUDAFunctor_add const&)::{lambda(int, bool)#1})', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(661): init_forward_metadata', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(2654): update_single_wrapper', 'torch/utils/_device.py(99): __torch_function__', 'aten::sub'], 'count': 1, 'total_duration_us': np.float64(5.648), 'mean_duration_us': np.float64(5.648), 'median_duration_us': np.float64(5.648), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(5.648), 'max_duration_us': np.float64(5.648)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(5.65)}]",,False,0.0011461658117060377,99.9960664952693 +aten::neg,elementwise,Unknown,Unknown,Unknown,"((15,),)","('long int',)","((1,),)","('',)",3787,1,12.679,12.679,,1.5e-08,0.0002288818359375,0.06249999999999999,,5.122134222592747e-05,,3.201333889120467e-06,,4.685546875,,4.685546875,12.679,12.679,12.679,5.122134222592747e-05,5.122134222592747e-05,5.122134222592747e-05,3.201333889120467e-06,3.201333889120467e-06,3.201333889120467e-06,4.685546875,4.685546875,4.685546875,"[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::neg_kernel_cuda(at::TensorIteratorBase&)::{lambda()#2}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, std::array >(int, at::native::neg_kernel_cuda(at::TensorIteratorBase&)::{lambda()#2}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, std::array)', 'stream': 2, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', 'torch/utils/_device.py(99): __torch_function__', 'aten::neg'], 'count': 1, 'total_duration_us': np.float64(4.686), 'mean_duration_us': np.float64(4.686), 'median_duration_us': np.float64(4.686), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(4.686), 'max_duration_us': np.float64(4.686)}]","[{'name': 'void at::native::vectorized_elementwise_kernel<4, at::native::ne...', 'stream': 2, 'mean_duration_us': np.float64(4.69)}]","{'op_shape': (15,), 'dtype_in_out': ('long int', None), 'stride_input': (1,), 'stride_output': None}",True,0.0009507786245791093,99.99701727389389 +hipModuleLaunchKernel->create_flashinfer_kv_indices_triton (Synthetic Op),other,Unknown,Unknown,Unknown,,,,,60316,1,6.69,6.69,,,,,,,,,,4.685546875,,4.685546875,6.69,6.69,6.69,,,,,,,4.685546875,4.685546875,4.685546875,"[{'name': 'create_flashinfer_kv_indices_triton', 'stream': 3, 'count': 1, 'total_duration_us': np.float64(4.686), 'mean_duration_us': np.float64(4.686), 'median_duration_us': np.float64(4.686), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(4.686), 'max_duration_us': np.float64(4.686)}]","[{'name': 'create_flashinfer_kv_indices_triton', 'stream': 3, 'mean_duration_us': np.float64(4.69)}]",,False,0.0009507786245791093,99.99796805251847 +aten::_local_scalar_dense,other,Unknown,Unknown,Unknown,"((),)","('int',)","((),)","('',)",46,1,25.929,25.929,,,,,,,,,,3.724609375,,3.724609375,25.929,25.929,25.929,,,,,,,3.724609375,3.724609375,3.724609375,"[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(661): init_forward_metadata', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(2654): update_single_wrapper', 'torch/utils/_device.py(99): __torch_function__', 'aten::item', 'aten::_local_scalar_dense'], 'count': 1, 'total_duration_us': np.float64(3.725), 'mean_duration_us': np.float64(3.725), 'median_duration_us': np.float64(3.725), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(3.725), 'max_duration_us': np.float64(3.725)}]","[{'name': 'Memcpy DtoD (Device -> Device)', 'stream': 3, 'mean_duration_us': np.float64(3.72)}]",,False,0.0007557877603469618,99.99872384027881 +aten::arange,other,Unknown,Unknown,Unknown,"((), (), (), (0,))","('Scalar', 'Scalar', 'Scalar', 'long int')","((), (), (), (1,))","('223', '238', '1', '')",3,1,10.857,10.857,,,,,,,,,,3.4853515625,,3.4853515625,10.857,10.857,10.857,,,,,,,3.4853515625,3.4853515625,3.4853515625,"[{'name': 'void (anonymous namespace)::elementwise_kernel_with_index(int, at::native::arange_cuda_out(c10::Scalar const&, c10::Scalar const&, c10::Scalar const&, at::Tensor&)::{lambda()#1}::operator()() const::{lambda()#4}::operator()() const::{lambda(long)#1}, function_traits::result_type*)', 'stream': 2, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/overlap_utils.py(121): alloc_future_indices', 'torch/utils/_device.py(99): __torch_function__', 'aten::arange', 'aten::arange'], 'count': 1, 'total_duration_us': np.float64(3.485), 'mean_duration_us': np.float64(3.485), 'median_duration_us': np.float64(3.485), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(3.485), 'max_duration_us': np.float64(3.485)}]","[{'name': 'void (anonymous namespace)::elementwise_kernel_with_index(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1}>(int, at::native::gpu_kernel_impl_nocast(at::TensorIteratorBase&, at::native::direct_copy_kernel_cuda(at::TensorIteratorBase&)::{lambda()#3}::operator()() const::{lambda()#3}::operator()() const::{lambda(int)#1} const&)::{lambda(int, bool)#1})', 'stream': 3, 'call_stack': ['/sgl-workspace/sglang/python/sglang/srt/managers/scheduler.py(2919): _run_batch_inner', '/sgl-workspace/sglang/python/sglang/srt/managers/tp_worker.py(445): forward_batch_generation', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3123): forward', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3194): _forward_raw', '/sgl-workspace/sglang/python/sglang/srt/model_executor/model_runner.py(3003): forward_extend', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(661): init_forward_metadata', '/sgl-workspace/sglang/python/sglang/srt/layers/attention/aiter_backend.py(2654): update_single_wrapper', 'torch/utils/_device.py(99): __torch_function__', 'aten::copy_'], 'count': 1, 'total_duration_us': np.float64(2.804), 'mean_duration_us': np.float64(2.804), 'median_duration_us': np.float64(2.804), 'std_dev_duration_us': np.float64(0.0), 'min_duration_us': np.float64(2.804), 'max_duration_us': np.float64(2.804)}]","[{'name': 'void at::native::elementwise_kernel_manual_unroll<128, 4, at::na...', 'stream': 3, 'mean_duration_us': np.float64(2.8)}]","{'op_shape': (256,), 'dtype_in_out': ('int', 'int'), 'stride_input': (1,), 'stride_output': (0,)}",True,0.0005689215154578205,100.0 diff --git a/tests/traces/inference/sglang_prefilldecode/sglang_Qwen3-8B_prefilldecode.json.gz b/tests/traces/inference/sglang_prefilldecode/sglang_Qwen3-8B_prefilldecode.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..e3031dd070b98f50d504becbb74e115d812c6d5e GIT binary patch literal 1174357 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

    $)IRgDc6u4?$ks(y4 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

    R;WH->Id$akZn-B5Ur=b?+Gf12 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

    G@#GrlI4pcPFMECehmEN2a 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 z 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�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

    @Q91tdxC)$WoAV3oRCwCe@r^Ri%p&p<%4 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

    c|wn>j_22?d?G-gz9vzdkC3xJ5DfDhEd#40)j^ zR}gDt9T2TveJbF7+;qhYN$dR}G>u6l+cjd(=qr8NBpGu+6j-B$#3-bnu-TvfO%e6< z(0m+!q^c6d4pAArB`_py730OVW8}P(l}`L_rx?G=>}&pYb(0be<2Vh@uN3ev>dc;~ zwv&l7;Fh5Cv(@$X8!--|P^6?JH`?d^9I)g)FdG8e+<)Fg@_ONGQ8rVesCVu#$-A}7 zFsc>17iY`XOm|#J2dzlZTdv5cXHD$4mY?RLOmk!Q%eu(&j;-;qEc6wGhVd4};gwzoSgz26&TK+1I>27(q(i9pOIx zqgvAl%$(MFRuKIe#Llz=wcW2Vu9+-8bE?y1qx_lveDI%?hFTq#?6 zKWo)()U~=(EuypYLeFqDB5Vpr%bJXC*eVcCL$ z`|*ei`d4iCU+_(0FjY;5Lb+m$(WsJHA9kiimp)NZ6>jqnyziOJ)Uh}Cc<4oTMRxTV z@is&JCi--*wo7$Ahom#hQ5f5(Ea!7i__N>Q_@?@hzMCu#bS+Vo!3sP*dLS0>^S5B~ z&(P+x081pxE`KOk+sh-eJGEhH5Yk7<8Gu0szX+Ia({t+}%gX#lTjNUb z%+~V_0IQQoAq5jKoE_UMVs8xxI6@k@(;xKCb=OPd%p}j>6@sAZAs_6x*eTN^b$|gY zbI*k$#rKoG!l*p}g{A^p07O?kfJS8XPo)RPwO&P zc;9pY(>!wn+*dWUNs-JSR0MNvP>nLHUPK~N{`J!nfbMF!fpPbhjNd?eI8afq1A3^o zx^p-ZYDPJ*6(yvG|JBQJn#-gMC)90j zfvb$+1u?~{0)bOg>-83n7=MlBt{JG0>t0L*vu)Um361~qN=AR2CCZ5InhOMnX-W+Pm=dUAw z4rffBH~!4mEIZV_EF|z+Ha>JOm!E%~vj;)Wi4ZVkF3w7hLqL{)edrYMLOZ`cuKUzd zf|f0OToEoET^waoU8f=N#}MdRLkbb}yOvRD9!iO!PRrquDSEFd7bjz zRs@871uGCZ)tC7o5U?}f*oeQRMfc0?=Lx(JW>8Qw-3RGCwf_QP1pn~0d0$-kQ^-qz zdeLSD-mrlAP8!0Q9c-fY$P``B$rdv~hqiin?W*9)Sx;U!-o5IgR5J8&U1=lqU!}8{ zrFFpM6{g~MAU#Ih$G8PivDPoK-z;qXfovqiG~&hLd@tq|g+PKGk_-hYU2LFHQmzxR zeO2H4z<3l8BPn-jz7ygm#H$<|B^aKX4pGgNYo4ZZRs09|K@n!_)MA4DM~(^S?qZ0h zsTP+V(ZZBzLXe(Q@eif~3T2>pSG!hqD4GIsS{<)&t_S; zakIZn-H7SV-Lv!edd+WEt=UWw#HqOD%>lqKw`G2@J&I@>Iz!rrFO}*3e9L zwM-A@r%KM8ZwvOhY!N>rwSCcvd9vx%QvB^l5=<7t6NII8(=Bp%RZBc*7sW)si?M}F zdW){nQb&1&xVpRdGqJgd5!+UL)BTrekN!WIHih`n|IV~&4tqM0L)EKXKR3B53KOD> z4H9ERMYh4L+Hb5{!`R~DHMr2s9>!zhrDHSZINJej1IN@(^FKGEcDxMgK{3nW_u+5 z#oO?0$>!*Wfe7z;)F^MAoLyG_o7rc%W$-|};T#j8-yPh^%q_7PGxB&P8g7u}HSGW5 z?K~bo_3ZZ;@gD3MRUNW6AyJ5eK7MiH`ade6O5w^jPEpu`dO%G_?9SeD zY*+5oh)601|EVr7^Y5L<8Kqs|sK@q4Tx)yjMpHA1du|@DH6(mrn&>1en3<+Gws8KN z$HKr@gONP&uDN0O_;BLv(KiW{AKcdrRF~~DGdT&aLgFS+_u2AH@hdMm6>4pimJk|3 zyu@|$7mwvX?3cxPD-VYLK}uHKg(v*0fdlj*1!=M_S4{Lyx~`{v_QpY~eP}x|XXFD|K^D<5O{qT` zv&hmhGuEH{5NgS3JC*TIZ1$p!&d-}F}P&ErYO1)N})L6mWKC)O_d6^Mg{VZ1Oo} z)V}Ax(3}4Mgx;T0fzZ3%#P~K|z*5D*l-+H*M|)(RO;r~q?Q4mXjCOg?KS$deJ~6e~ zwwAQAVjAC8%I65*9+Lv-#gXB!S1JP?l|=>E3%dhb~3tB{6B0v3~E=)`Lu7o z9#k!pP$i|^m?t>~#=A|>Adfz>PC34MI`nY}IC{nVd=8aP^TPrMIpZ4%O_e1;%f6C+-qaD3!dt}R+;4Ey3}N5%BFpfN19S?6cz zla!eucMWryo}|Lz3s|Q}iL8MFgk9iQV151#Gzi?2HvYi@ z=$hN7x!OSAf%>yv-gkoF-(DK>G|B3X9%xt5o6~aSIrLwf%vr5tdGZ_FfSh}c=D_~G ztK-YWtLfre;~}R9?@PDesU@!2*S0=2G|sI& z@}}X3Xe9SLt;NeMODoVAsGs>tFCFxlTcl2jS&0m*0H;rc0)Oi5U&e@mF1n*Ps*KU= zuyXM~`TW`HL$dBZQjj47M7;LRLFTibzj}KEGiqWKF_BO8V0Y&-e!<{cV;zPG< z1RB~5H+J-Ep!Nb{;3SN@U_hSR!l~{QrQ^zc*hqgDYi3QGkA)$}OHl#A1e1bV==DqRo z)g0cwUBL^{|H;majrc87)oG1|3AhX$2K=d(b6@5xq5n=%*>u^NB5evM%qyjtlE6?6 z=b86F;&AniA-i7wTFPFxaY7802qd{{lE*dtPU`bU4UjvBv)lSu3GaA#R4QTSCG~_m z&lZ9K^`O3saaX3m6l|WbsPTB`o`OQ#44Q%O1fn^~ z!g5gx4H&TlyfZNLO;-(wNFZnEgjeEACNCVtx4gexqI%RLqb)NoO+w+ab+EF|YwAvR zRvatkVNAuzpGH$zW*&Er9zu~%*ZsEb3*{)_aCltaGc|5;rDkJntNL1%S7^~S)@6nB z{GyR>G2WdyKc}RzNIW1{REHu^-lA}7!#g5BsLTaR|SbuwU!_(>j$eb^OVL1i0z?+^9Lgd*fA-HU&qtRI7|@e`{rPf1w#!O{ z9xp^=jr5S_60?+0(N;{XESyntIS7j(o&Z{8>XlQQ+xR+pq|-XUMTqKAw-3ijEvN{a zK|X^3@Fr^?18OVt2Y|Ku_1+m>BlpzaY6PDNB z^>3Gzi|ac+-g?!siDK~CA98GH4%gD2DjI+>;l~^U$Dg#h9D;hgc7)=h3AP??bhRUPf>h3F$asTdg`icb zLBuu0+#OVP&tID2!_RDLxB-xF+lyi})n7i9?6*-{2V8lvWH|~&yiODJf!I|2LT>#8 z;{jFPht9FJv`Pi9=lj|e$6Q)>P8=`gyLmS&NMbGCqbO0noYls|nzs`|En)L-fljEI zS_h!8-O*rsiGIuuRxE1ELCEd4c!skY`|Fkk%7sK1y}7+OK9p0dhE zXd6RaIC8%8r+CXJgEeuE#^55zDp0q6c@2K2IijG9v#4-X{GCshgujtLB?2b73%}CTt@{>G2 z`vIQdMeCLl0V?!Hy@yNAVsk^cOnC{}y*#Ctjt)Rqcd{doLHKc;%U>IEb+e~0wFOwm zX{eD_dKV<5ku>BYe!`w1Lm&-fDtat2AV!yRxillZzp%z;=%&31{^ez}m9ZFbz=A02 zUus@Ex?!<2Rv97XbjTO_o2I0WGmGLFf>DZjW1}0}!Vdm&{jpPfilxZQ0l|0B=!>2`$e3jd4ddii|lIyLlOeH}_O}0gxdBwJ@`af!pTx z+K{0J=fNw$b|47iSXmitCM_nVt@%lmWq<4*PwD$vfnq+libBPv(_Uw;OsGA0+czIO zV&Dg4c}Jz}H!z9?b#4EfS~3HeCgKl6f?DBcze>hXB>jFD@8oJy#TNI(*bseg{^iOC z0%=4Z$PgDkQGgKY%FH2ubQhZ|r5LsLoN#;#=NSCE4J0|>;>csRp$)M6D(r||!tETj zeWl)5U^1Q=xEmtyAQkaNO00q7e2iIe(G&RAw`etR;1TFngmwruBtUPqu3x-4$-aOB zY`1|aeLRb)kD2g~VqV56mfvzYx@)9?Ryi^<*!EhvXm*ihZrzTW2G$XN7U5f(KbJlY zJ8Is2iU6E5)?qT1*a%}?Q{WjT2RG=bmXE#unF3ZgNaaWYCcl(M0XqLIT(b)K@)G{Q zWK>ylKZLQ^UO)k^ED30D27z;UzA1Au{R4`rzKRqGSUy^YTRfjh-@cfg44Bg&vyBm1 zw&91bRa9Sq7>N$4L!On%W^uRwLq(pu}_sQAWc_vw(_U+wt z1fd_2#pE@=?IS0E5hh#MXx4;%7N?d%JN&Me_@(>La9cbllTdk(!gS67qbtI#Xo*_{ z@t@xc6gK|`@LSz%fM&m>ftY%M@m|VLtwQs?E~|c(4XY$Q`?`OUt5`sCm3>{}_D^zE z07$MntDK^yp}XOB>4)+d2y*gx1E^i}igk_tvR#cP$KQFI@=5>c&nvsD%la7j%873c z^U(#X#cJ#uU*eMWThOJ?Ze6|)=#&n zJO({2QsQrdnQw&EU95T`tz~^X&4rm9zyY@4*gnA38sx5e!J}yyf7i~ArZDzu$6q@e znX_SN=O&i2?|7`pAd}b=g>5{sE#{6cYScwdLs!FZ4|^+k(P|2dzcQ}Ehup53kL$t&Z;pO% z#J-h+vb^F}hjG zsgZ(+bbBrmGb(v9MwL?w^tfl|z|QTmuSJ#^{mQ8?y4^pd##^WwsS$>c^e2?T$BBNQ z(9d_0Lwt#9_>JIIgmotopJF8eDb%qaBBEbP3-+gK~I;q z>!EhJTa{mNd+YE08q$f3?w3T9z@?@s3W);iu^3C=DO}&O-d#6(aT5orF!4xWDA@?? zb|2*K*4qcoWOU0!{6hxvD(x2EHP-+BT{(*m1$+rn3KRY4!=EMhKjs4Zz-1fDiDnF3 z^s1Cfur0*fwbVlr$CM;oW&?$6N`3qi)n}dTFQ^Sh5mTbnUHhKNvyv-PF&*N+pi%~| zubxIBahq~iboGL+l~>vR8&$_Nm$d=I`cvtP(=X?y+NL?B5w{=S=G_GeLyUjdA;}Vl z@d7%%Zn5B2lB z5CZ!3>ZQmLMptRZVuW}Ff|IHd#-)P{Tgp9_!RkS>jA03WCW+|pxX&7RQa$DqMJ`Uh zfc>_=hrJHMU%9rvCp!!W&Z{V6-V0&3bVwvheqa*Rck$uNHav|R9TCY^@71~^LxI_= zmJL>wyz0gG9%#Y|rsF$E$=7jsB#0g=B)TCen5{v)0p{NkpW2U6VygO%r~x=9R=g6H zJU-7NHZm*o^qU){ zx%ZK;c1ty5xnZbvd=KH@Wd&KFtiE~w%n8XE@%up|!xT(PT!vXz`>+pucsO$&TV^R; zv=0n^#rt2r$ETm>yE;4%pUwXId0456iQEZ6q?7#fihcjQ5H!J;`pGPLkQJ+Sd?HEx zh4sFg@htfV3;Mx?oi7``bR8C7Ve|YY<}p+L$mN>~(@b-)Ka2Tqz1w=OCn3eX`Ip-z z(=^S8MDlz(zNO{-CUAuY)cOmpSDkNW|5W}6K~mp*w(G%u0Je`K`-Wb}&A`1E{OX57 zVE8X}_%oFejMAhiTT#>&;uqqhorwwp3MvcKu6FBek}Zc!Bb}Q!zVlJUpBU+4jA>++ zzY8dQMrZ{3N2JNcb{~g{cF=!#TdVk$JcKQ$$ctF zmK+6A+q7!00~#J32iPcTb6btazHedVr3zXnWh@mH{tn_{%Ytu^Dm`pc3u<@*#w$w? z;UkCU2Aqfq%WW6KvetUBXP6-|?Q+70qRU}BLgGos0cU%UzAWKb+-Keg*;0Cy@MqY>KMRXaaX#|`_kyCnq=f;-tGuNU zuh_AY*~=#N%?qcT_0US zVNR@~UwNPx2Wt1qs)~RUOwZ>07RS~K6_Qe&@U)lFkIwz0)YM-iP7kvS#8D56t7;nL zt49j0Y`k1O0{$Pz)DBEet;}V749pmjjYspsOcQ}Whu5}NIDYaO=`1pNl;|9y#?c9a+9mc7$M8%#f12qVrO@xHI2uk z^MZox5=*3m1_P}HOu>7AE)S=j$OMgo%neg!-7AGer%v!o(QG~zVXs9#h5 zUp&2aSd;(z|E(aPgorc<2uO`?Y3Up=V03qvbV?&B-CbjJHwZ{~H%LiHBVE6X_vilJ z|7~L%yRPkc9oKojp6BCHQF}UTogEA;Hz;k5)?Nh=cC_MY`*~)o&*sPyJ;60?KVNO4 z5|<54e_iF7qp^EUZC!KfLC^harxiajY)KiKk6}n~TqTxOOMbs$qGj*~$ln_fS_f0n zB?9{k`r;<52+6tnz~M$_ZL57)dS~Qkri+c!XdX`!1Amv(vMt^7E;R;1NFm34{=R@PI?kl${Wq1c z>04*Dv?RAL+qy3wMv=E~Tio*DV)}jbRtjcr?g%|wvK;w~V)KzgTBk2x=-RGVy?X&N z_@&zN3B|EQr6i|_P4WyQj&CY#S&8vekLdu$X3r5-_?8N@^n%TIPP^M7Xbc4W2`X95 zorqrTA2FEA^=Ao)v}5e58p)Ud3Q$f$rIY%_{?LomZY3xcw-v+ogvmb&CT4EtAIf!9 z4&7TICY)lzub>{y8;_)0`XGF?Q({RSLgaKVc;Z>@UZvtgfty+Y zRrHRr`^x~Z>Mbv*TJEqV{5otH56re(Uh?}4N=4$8HaG{ic}jo9Yr8xz&MFO|K0`x*2R z_wis=hFoI8+xSljUDC1|51a!kdHfQyNG*SEi`YxDu5hvN;#(0iq}4(*yHH8#JX3Ny z%D~-5#<3bz-Z>vnODM<1I#OTiT)DGxki^HU=ArX%5at{%N5q+VD0Uf)Dmj&%k1sSS zea2pCq6ix9Kzc;Rymk+I8Zs}jzroXv3q5`5)9Tz{5>SfNyvO&VG`!7;dxlV--DG}8eRL02zsmVTYjj0grRnL>DNT{3s#$- zQKZRxsYI4J#`~UcmpDB5xLs=aj);2Oq$KM!zNr}OG!-^{AG==-{c~zJwbZz&9#SM0 zNCPI#1aClI)(?vMXy!jTwgT;BPqw_1JMrkxCPxW~Jg(X&`TTJl&ZRU!W}w7+9Xo%p zbHDQypD6kRY4y9f*%J}P9+Om@gc~YL2TX&&=9%V`$IgJ3>q$DRhxZiU!AQvvow2;S zwTsk^kRzZqu3zV9qemrhUpN=PhR@Uq(J>ib>)*GQRWs|j>6#m&@AQ5Q2pd<@F#An& z#e&o+rxHLvbG!M89LB*hfBc#5ryocm%z_Iv+RR%w*OKgS406PT{I&ZVlwDn3B->&( zwXMq~lD_~eT!P8A^dUnJ(yG5P7XL&%W!H-GyF~k0>MF`|WnZ$Q7?i*N&KQ4)6_cw& z4s{GvUDzU5{xx<`NYR_2kDp*Pvr_gC3t+?g^Qrg*aplzhg9w)0@*JP+4He^TQ2rq1 z@T@@JN0oEDj#KTh7r5qSa?{~uO+Q&kg>-v>P2dv1hxLZGeG(Yb%0=}^VRozJ*7<3I zM35l*`__+6V|m%=4PeANIR7+hWPxu4HC7Psc^jsyt@ya%_9omC=U}trcU7rFCPVoyO5Azh8i$hNkd!NwSVV^A?7H|zDC+DlK@77e(9=6)aK@D zBHC1>W0A?uC_-}l%JFdx=|ONdhT|mWQtZgBxI(t>OUHyj#gSF?2viLE76I!kb7bQ@ zn}R~aZXn~hB#=Gx^-G$&(+~dB2^H7*aumwM)3cDn=j+)`>(SUrNJwRRHldx9#Xn=@`G=>tiRaQv30Bj zV($}<+qArNp&cwkef3q44Bfy1qFy~~9ajowQ?akBKGoI8-#m?H^f?uJhKMw$-)cze zES)VD0P`y#&LZDO$vi=cY`Ky^VWcc}5?L(%G{&O>zGptjw)Whlqr%Q`X|K$Uw{(yE zFU6ieskHSD6vs;7PS-_|EUq-}J3m=>X1>Gn^dzWta zm5MqI!e5`PrZI41MjsBCCA}l$oMtlBC=Fxln5Tnu>{prlJh3>REBO-T=w)d!K(3$**a_GQbsB^UhE z^NBMW|K5z*ydmt3Q5cyc(=cZC%YF5+qlHh*Ytmnot{}`FoxVpNE@Y(mP3+QbK9nLD zhe*fjW44@|t@Bd)&kC&8?>4hFo`9i4ss2@ARq<(?x`~%BZwdKA`d2s zK0UzIT-!;IImM~S)z!*&YsbYIQ>lDX&X_~zd_j5o}v9_X!k z?EH7HrLBXr>)ICY&pJ_AnPiz+iHN^lQ{Lu(+juc=ij|$JG~Y`f#cs$CZx^g%;w!7~ zkIzWrw|Ix!s6vT)#V+)tW)>|@gXo=HGvJG&;+VaKU(| z^w0g{PN(&&-t$%s>ofTjE~IzWJ6PEm<#_OWzjQDVohJAqRd<2nILk`P{jL%hEBg$* zFMr(6pZsH+xfcH?3?Z(NOkMjv)|Iy7g+xJoAV9Yxl{*EjqYTmquj_L~j9x}qeza)e z&pc5tToKFHlx)^jC&==j1uoli-I8{&Nr&L7>eG&Tv=eAU20#o$A^sqqLt8r-@p=Bnl%rr8GT4uj!uP3Ri?E^r@9MZZ3V6x*V~YXrRH|ebK5t&LV-S+ zPM*6|TW`?bCoW)9vj8F&8rvk<~7zM&g7Ztwyl#7PWPDcOF9Efokb<%eD9FS^!gsRjN^|1(z~!lfz`h$HRcL zTB*w8apk&r>M#M3M*d^Mof3iO{0g78nTP>NP^)z>;|nb*u0~0ECpXJMe|)e+7LPL? zKFr4_fQpO~yNxX45@r=3)}u|Ib;cQOgsA=Rg!}I=>rRV93a5=Bn zaL>a3L@9#wX)$X>a{%eC`6lxFu!kxaQb2Gh2z+2J@O!=T`rXHcPl`%ft_BSj{J(RC zN-*(Z#XBvPxodCgp6m#jC1vHI`?pM`%a=F*LhXiVoKmykJ%AfZ8PmD~S5RARjHN%1 zM7}l^&#>9u?iL@nDluM0utY23pZ$~D&7ZkzJqfj-p@!e7VqTcfI|Pg${wQiu?+9Sk zXrc_}XVn9W!LC$foxf!sHcstnnt&Ut_W>)&kf{Xj{XN!F6m5mq2!$7a28Nn}k~D2N zjjmhD7GOtpfXgj6dRzVdFZcoAOO!5tZnw)my^@4p9}<%d(pIPFiSu4S1nLKs9!DA~ zda3T$7t9`U?JgdCM?O08b86HXVq=)(4_YU<-!I*B*?yj#=J>QM>)U^aA`8E0# zhW_bAC1LtF0(R2uuBMszCbhSDkza}^FUkC=!Ru6)6?Yor5{Q_G0&1%yQV> z0|)%^_R*NN<2=|pzA)O7M*xY1zg?dK<$4R$G;X{5KXE1K$zSnDymdnk_pD)Dhq%uS zR(mI$d_k_v4K#Tf1qY${QqtEzd&q*)IR7{fH>Fni%kYK>HTV_JG1^&Pp3Cp!*V|05 z=zLx}WUvUNx4U8lr$+8qmopvCye$NMC^K}5qNTUBfJwF->`svW{?URf&G|+WytvH; zUPN?lYU+Pqmpu(0U26XjqUSqRrg=94SKj#!QL0&Y2^9< z(!Q3y9sij*mp-iA_sm2dAr8XT&y)V|rOf_|{Y@tKjwm6@G$x-flyTIDv8lB~?bL@e zCFx>?c^LuyCqy%|RMBlP@sJ-LBk_>D8{Rv7_XP<;nUyDrNsbc(((gx4QBPN$Z zskDPA^H2L&tzJ|EWpP?2f`Y5j8oM1~xgmu|9P_z65)j_6EIqOC#n*l4h3T9T>B4En zWGovagokgDzIMp+XvQqTA6}-MGlYJ{$s5z&uvMhPRM@-*~(pfBq>f zq*cYRBv13P))&}cFIL4nr$>S6Wzn{d3$GF`Ado`kOCtW@C#n}%&Z&FbEZw#Vs{!6D z*(s&Ye5d2i2-2|aLra~r7vUb`vNKiYqj`H9^)F@3Rfy@Xi}BRSFn;7hKf@B0<~>PU z2r8)QAUpuIvmJr?jAcr_Tk;~tF-@k~|GPN{bhWpaY6uD&Xq)zSj@gN8UCtXS7){3E zY)R5|l55GtFs{1Q(9heK9Ll0UM(y}HxUrLgww`S%T~aO@dCH;do172RY1cMMdLpI? zmIx*;J3j$-k4bq}_3r$11V=cyUf2lCnolWSaCFw?8>5+Xl{SAJW&r)Nw zooXNOQ-e-m$de>!ZBA~=pOadCTmFV2Oln!Cf3PR-N}$HXk84zUXEEmrx2*Vy3U5+l75^I{t){NcR5l&q5Gut%)jp0mHj67i;f0V31S!xZZ$<@7K!C z$-n%F(Y7kDQF_|c=lGaa;Y!Wmm@mVpG~TZ`hp5oWNsWnM#L31?ixF0VmZg_}qp9%>xAJ{)f!$!i*&%Om-(*6LLWm~i3f*3o@-CJY$e{f}9U;N5JewWILAFOFI65Hf?ja15 zT>|6x8Tw$M{p3gG@2^kz_@!QxE!jSu)kS`dPII-vn$KilqGAM!U`4##>cT~{^(Hi2&l6DHhm8ox%-(Q zm8+a`T^@J?BCFWaA}xa#UYkF)SKGoyNIZqbQA4f-&9!t}piR%>c5>?RROw(M z=iWOAlGR#G(0tq4&f1Zk5aznCKzhd^DH-WeVPpxa9ZuGL*u_v1u=e+-#8m97-hIzM z--rbqSs7&cD~YY*r+;V_|EOTf>*FNBwU%lMlF{F6+5hX1?Wd3@D0?)-S%PP_0{c%l$< zGBqkvYrM!p?Y`CO`D&P6(_AZmy4@8GUQ#9<_gYcfT&oR!BC3U27)I}z)Cfzh0qFGi zv{GvJ5OPyuC`M*$Fld`iUDK)Km-tNF=0julb;3Uc{KMvt88F)$5{@zEf+2rHhqdXj zQeiEIekdazk)lPf%_(*bki(bPcHVI(4!e9#7{pfH_=t~Ydt>KMwN)CgK&l~5wTB~ zW>c-r>5~7(aeb3s0_f~@4b@G}+$t~dFU zpwyH|sf^r7hy|@|)V-Ls<$a;rqJ8~>8>Egr8x!xA@i}kL^$K9y^yk|GG5+Anwn~l= zfb?z=YU@gyqxPPIH?c^5N9N2&zh71_j?oVy`;|%@__$a^j6>6v+5-S5hHX@9WgBAV zNX3_7rJl6~)N5tr&ddzhElw)h9*}MaDljv{Rz09;FCfpEYcP2R^mBZ&ttKJm%~GEpCx8LL1nN+2B4Jen0=+dzz(_d zovMs2XTj$=^MyR>-!d0ibX>LfR-EF+5|C#61j~X}*g%6)A$|f@84M7hdE>D59El9?702#ZFk?p`O0?jyYZ2GS}JV!a~2>*OfUbhQKUry2W79SpPk9~Cfm={RK!6w~f4^RyV?27oBGQd7x$ z#uXzjvou*r0)S&{wXUEY{nA9o$L_FhA(we)e ztC|Bo8#GnT9Nkyr?Ma#7G?JVl;(}PQE6=PjohgwJPaMQUyqjy?CVt}11(8&gni#qS zRfrrnlzK+yFO(I^Pog>~7naYmvbXg7NF+>i{+;*njT|n;;_b0iw&udn*tvldn5x>= z0*87JhAK8!oREc5lRK}X{|py+UCw4=oA{W%vp!L~B~niI*|NN}^jh*(Hb@7i(TCSM zEA_~7AdPPX24_Om;>?%=WW5Z0IcQQ++l*s^r8DYU#-CFa95!kNgfcJgU-^_yqzFnV zo8Gk3jqpi=!*MO&msv~Z+_bT4ObGkS--=o7W0#dK7>g(LAu|XvYIhahPKosG<6@d6 z(CZ4||DlJv<8kY@Z6N+uIi<`gc%e9BW)q$H)^?FA&bg76EvIUyyfTZPx(Ld+h+z(BXuL)9m}BZwo;_jN=8=O zL?qO=L4Yk%Wr)N#m~j6dsuO%AeSx<558GKHuA1k5-L6VUS@oi=^Ox)=iQIl7GoW2Yg%qMvKhfpVqaImy!Z~^`=vMH6c}+6isQzZu{UaJX^0l!jH^E zQ8BotlNJ@3O~7;1n()hPk#VdUWSU94DeKF-VA^k)YYn@l^6uEokqB6Usdg&wkR2I( zM+M2>+wTjNyK@VF&TZO#j{zEgCH~iKnMSx>H#ak6==`RZm{>mHmDES&WijwENWLDH z(DVnsG%))bU&yTA0-YD=T8l3@jZHK#qokGet(x67uICifX6E+prlv(19j|ZHt7u%M z|M2pWT$$huVa&8dw${?UY7WG}Y4Od|w<*+Z#8=?dcF_wyKizD|C1`?e8`;i;$}po! z8BKTSRo2g$4(>ek$-1j)Gm4(iZQMl_ywf0}m@B3#Z{l*$n|iM%+c{nONs=W7DqD$z z2f`9BlJ7*&?PBxN!pFx>fTxtU;e6^AVcfm|$==`@5JoSRY#35@M=>CO z{KGo^YfXsTm)a;rofph72_43V^91c<6BO(Hkrg*qnf9Zp*u{(si)h}kn%JTRF4CNM zd^~^=eNEmO;o4l(Mh}u&2{q68@gh@}G^GtLIuY0dl z*z&K9DC?^)<4t`qZ{uXUuK506^6tT6u)xy=Xzb}~6Z)u}xgsVl zw1}I2hc_k)DGCkY??xP=Xg77fR>;{;jJkvg{ckwkAgLLeZdnCNFcoXQy;u{?h%o67Gl3;<~S5t0OLX z$KeCs$LnrS#J@e6PLZ8i8^5oj^U%$WIW4{wF0pyTQI-z#dWuTVWnA@*X7QoF!m+g8&nk&3VA|aSn09wf-w1Yqctvf*+7X(kA(aiQ z_AOj15D(F~DOF6!qic4$bUIH@qFXuf9L{Fr+S>SQ*@V-$Rcl6bS&R?bx~8vPFKvNO z^5ybuKGZsDA)!#`(YWeciJ>N#d1w`xX5#0f$ZAM}u;;b3Mftv%GuHEszwS|(p%z1x z@6kvj#X7FumcYBv9P$cJPhStN|32sMU&|mI}Ix<%+aB(4YnCMP1?Arj@x)i*$?His(#qo2znJKu4!zSn{7#u#qh~|(Gz^azhqLvVm=hHQ(te3Iv zD*179r!?Hsp)lsKh$&jJA9CvRbvaNe-JLvkShJBD7|R7d|0Vu0+w{iBLP~%0>y(dl zyttMUb_6SiPH=zRlyt72uWoJ?r4xEeJ|L#(r{c%$&nkdI# z{2e^dIWjOYJ?sFQ9gSmAZM{-a*6o0mw+TYNT(7ZWbNEkcKm(ME$_*|;^ z3Q6auCt67@y0pd78%C@xG3U8_cta*Tr3t?s_I(aN|i_kEcQkzf9f=qf^=u-Z95) z@W6E-m0c#y4AG%oj@m_o`L+&SH+F6J#1m5vmvfMBz{@|Td|ZD`qTutnlS~92Q2dCd zysXMD(bf11sSBmp6b;E&#mUO-)vVa;C zFA=pSNbP_`<$d~k5vVVbD};QvoNfHLZs7?^cUcLMMbh~i_$rs+1E;&NomhNujxgII$ zQGby)`Rgo7|1=aZ8`YNi*XJrM+7H82H^rCmcA++Csrtgp-Q^p1xfv+`;G>A($za_7 zl_ZSWZxXwKWS)ik6rIHv`{1u-?Z9{{!#_mqUQW$K3*r|xRkDlU6x9HaaO%rE$L>X4 z?J8E!kt@KU<*YLqTok6O2Zcb2s|L+F-r&}1{wV(5Zfla;L2V+2`wptDV*Ys{dI&C& z@?&w+s>s6xeQtj#cl2s;Pf(?+qAwR0a5s(qlP2_+o&ZRb=qPQK@jzW6E>QsS79V_P z$6KkoEdpmtKSVKAslmz<>2A`sK%_X1f}c{zblb0@p;6)wq)y~s9t4L2Q^AX->i&iU zg6e0Qmea3fl}dH-X-VZ^s(SdG%G}znufA5taO5-X246LOIaQabT?8v3I&}kTGTVCT zLgbxbBcM!?V`s=$ugAxmH&stGYy!}sjx!))pdfOSWKoP{QiLTnVC4b@kvw;5=ydo} zs31OVb}|ca8W-PrGb!>X20jNIU$3CaN{*pe#UgVyaOEx`$-wIEp50&HqV!`VwIjLm zk!K|IfqkgfnI>}1EUqpfzwOXbl=>_ywr`sZW`F)xeq`7xcEu$C>Y_z4;)O$0@jDEY zlG9wDafv}6eYXFop^JjV3w!Uy*-f-&T9sVQD1j1+5~!u>$iWr0FX4b&jp)6Hfk91| zmE}+CPnWVpT*xJWB<)#ZHq7a{Dohd|dEgXo$S+kQ;%*skjdKhbZRi>H-K|xMv~arf zfxIVRD+B6X&#BaW;mGjFeV1^|ppU1|^njol<~>)VHYNBkruFAx z@|KAA_%r)$$j+Et@Tn$bmX{+E;g%RCK#*z$9+8y#f_U4*fZPtMAWz~G`KPU&5ulU4 zbUx#>N%u-~%|teC9cf0M?wQ+_zoPFqE{VwpiIwOo7B1Z9zZd(ft1=Hq$AS%%Ph>># z{a9#xJ)xoxd70a=&`0Y3^_zLk*2{|t&gQr;Rl3<6AUY(=SgYE@pn@jrARxKw0@$5w z6Q7E|ux7j()Qa0DV%RsdikP>Q=>*h8B-W8JfV*fDIPp@f8De2Z%f&!NTL8GrWcMYU zjlN)*Mn0$emB#_Sl?*E}lrG9*20aZ91pTS^R5)jzb;w4Z2ITwyy=V??s1DSQV0mtt z9WB#oA3SbZ3-c@Svw`EF*GENyM!yj?5$)zF{pcv$Eltj!&YJ1VD;r)Rw=6{7>!4J7& ziTac;IuMLTT}0&Sg>R4?|5kiFk-Ycl+0;eIcPfc)41L52`Y-A}bJ8}XFbHsQ0U|7w z$~eUspcj!R9fZ2CtG*Ae(!{`rf-;sB1d?3p0Rm`&zxSX#Ki=!5{mopNR}O%2tkvHp z7@UB*2q>urf#3Rb^goxtPPIe04HCHx#C_?NWwJ+My?`odu;N8zE3qGM9#IPWVbF4QdNusyW$vBd9Ud1jlGA6mhAWBDBp9Z|j!@G<>AL=Pv5i=E z!N%xc?*<_OVslB20ei?1!`tjFOlE3r7M4p#7ROY}#1L zW2*cJ=(=a%OX*1gb`6%B=8Q7K!c*HIL9<@A|F%`CtBL)&wV&z6&yE+W8vYj zpc)zGr}@kOfKu7|dKs9wNujvw$BCu_jsm2-#bpxKm)J_kl|YwqU?ia0;vr{AhW6jh znme9-QZ$)=xt5oX-&6ZUXwKCYW@K^||Eeommh9yxga|0=X($3+8QiL3eGHrgnwiY% z(3h4Ce3?;6E9LLxdKlGhkcbj!XWFY(zed;ldbQrwx8TtV;v$SLc@j~BNuTXmn#Fa= z(DVSnp7r9%DrsF?g2r2ujtP{?Li=Hc0sh^TM>qJc=!fai!)H>3EPzF#*U__Q`uS&H zw2DeQxDuBwmEY#=fGf&Y z^6x+l(UJ(U(UL0#_jb7s&?lj_02&;MfCDOZ(z1JtHVu$3!D?4onryh2iVr4%W`;cA z@`jg2E*!P|pdVX|NQZMqYEeh?bsHk_BsebGCTkO|SPmBlPuX^F!I$6Ie+QgQ-2fL@ ztc0~_wL>2W0pyVI%-BoV{?C~;3d4xY;{-xb!B+Ydt!FP`GnqXcN=4I>1pD5B^!=;T zv$H=S7^d|log8uXggi6)$bc(qlQf2NOC^A?#lVr)?ygBpo-^5jn7Z$*JsUWHfSDyc zHDeYt%@NamZS;@LF@(Kq!?R(+c}KrqEa5_e--JXK(sQyPD-u(yZC}I#uMqPCj<5c? zr^CPk=wjz1(!*H3VZ@2Huoh9E1JZJWIhSTsM^M*K+vH`!CE(y*2ONg6oS=CCuCcBk z078O;`0M^6IxUwRlM(kM$O*Ku_?gd_SyyUC%Kc1h#Ks~LhpndT4fP0^>VvIX*SeM- zBUBh@_v~ZDRaCFa#3{cC0nRHEb;XM!)VB>Kzq@1?O-1E#KLE)waXv@*?{VOyeh1uF zo$D^RA1o|Yfxo416I1KWTro(?W0ZB;s&?{>7OIXi2BKfIBGYrrMOj6tO>U`lY19EN zCty10joC%;07+@38PJe=W5!Ltp6>SdjS~AGm2M57DTV`l*}*l924~PwatlZJIxuV0 zH2dFUz*mTzGjW;T>>f}uWzXDkt8h2fpu`k$Gz_YQrE!-!o`Og(Q9V1z4}a z712ABuz6Y##ZJ06>I)1ssGWR0;o;`g=|5oL*EWQWe{b9T6lw5zS5r*O1hw4{k|g)* zN(MJIBQ>}iG<70j5JTOHyL>b7e?6}BOw!Som~sXQkViBFwCDX7#{SL}uB_gjhp9(L zy37}vV%RUv1<^AC^DJ!>ux_^3z3y(hkJeA=(DQ$2Mq_H)UAelNU~1|tqst-2O+wL0 zXROP=o3=c)t{rwgwJhk_3f)=oUt4%JV1F|J``){J8anN#+(>elFyDySV>!n*>y{xhbqYj zkMx-AILy#6Pp8HaT}4&OnC(+oaDGW8Ivz$#Uq~NF!{VWqZY5YgC;R0j#}@(d0+V;d z)uxPLKc?fSxk!1eCl7j!DDn8xm<$kmj`kQg)|ZJI|9Od{HaOd1?c8%Pt%8`5eonq9 zg?Iq&tjGV)o%NQ-^gnmj7fx;V0zF`Oc<}tCreQ&|9Y7TDpFuLX3$fpFzq5b3?h}zn z&M-%#hM2NaQ+?#j?So4E3xr5v6C7Wy*|s{l|6jNbRk|!SYZKJJxM6f=9_=xeXHJ2f z1@P4jUauYbMxyO6Rp3Sb-p{-4mkr_Zxu9SP7oZz~`3aP>Rr)4DeC|j^2E&94{bhGC zFss*&r5MVvvVa0`MybRL5NG`$*9-_OyNNHZeqXr3r}id_fT>~@ zMrngkUxARj#`B}go4qr8yA8{m#E^pBCaF#mnpR=fX zmK#4sE1&pWK@6Bf-o?p*+P4)>!uT(!>)3ZC<}tv~RsxbW+n92mkG9G56W3fMjp*MK zj_4D&)t7!?IGg2sv|}6SZs_!^bL{vu_~X30$1l1_0DA5I1`z5t?_aZ8oPCJ!__qm) zetcC7&_GyNB~+3xgctK~b6p;2(_qYIUDj=FLibtg|2iIg6&pnHCM$F*G{xA4TL`NL zYDg{rL|1=*cXw^yeswduh2^LwgfM3PAfam zJ5J??R+qz;3>{I9u|q!okg%3BoV! z#JP8=_(6*}$25&d*Wg$X-m(SP;>Q;W*J;@KaC^0VQEOAYgf2G3dWwFPlCpiZ@qIYj zmKDZ~JAiIbXkor<*@+!RksucpU`|MqFBOt69Ko!tz7ZbL0XBoHwl!v7=EjZ-Y)BJSM@6Rt8Rcm|2!z>ISSvzuCAsELBli!(ZUq z7WWRBcbdxR>A3Oe>p1t1oY6 z@Pj*zF;?cOR=7qD#S=+h*~fIopHr{3eOXzD3r|_}w3H%~KtXkZkKOWjig*^jX0(1lw3yh`I}UuQhHJcJEK_)d>hgWkXcJ<}hRJ zndqF8|0AS+d0L9#j-#;Ni&o$xD?xdh5?OV>bvag^zj4zdAi=jG%hw?Luvq;vau@4^ z0MdWftlEwy;=$NZ&$~qq`p*=_Uo6y6IL=&eVbligE#8eCzJeqVV{Rt~p7$=zZEc<@ z!kAN#nAg#a-Gl$Uxekv)?n2HRx*CgN_RFTwD#j5I$U0(C^LJ@V;qp>tS-J}^?~g%Q zbrI@3Nu(?oQhr(5x+%h;_W)td7w>p^;GYWuHMH~?FZ5qm?P*mbm*M#FA zFWiskVxCBo7BR<)PVI_f(cCOdvpuQePr9SY*+Og4AT zLKGtZk7Ax1JWNi@9wOW+w^~g;$(lnk+vwxk=r=MtUpr`2Bh3XDQFG3BYdC!U8m|p% zPZ7=Kt}5N4@-Y-VA;Y!e*lx=@JEpbRh#+jcZ;Xc%(2qO0Wy1xev|0neBntkfOx02E zaW%fz!+t^;L8}f<7@|4{A8P|;gYZf#5L^G_u>88a`)S#$^z$ya%j*U8zu`rM6gI$@ zW&S^37H9N5U-e)V%?DKJ3ssY}@6FCQ1iMn89jYv2I{$)^KRN1w(=ZM|h_ zP`%$w!+{{@3HcZnHOu9vAX!!*t_oKkpyXY&MSxsZ)f09CCMf>OEnJpE8b4TbAy1#Z zL{Zzf`ewu5Fu3Iu=Y|>hYt+K$*6j1HG=8SMGP-x*s~so-%-&YM`#c{m1B8{ia6-pV z-En&}T?ea+_aFP*qzNTG!N1|U*mP7(7f!-g4_b6v=~sPc=@LeGW=f~yqwhoO^&IFx zz2F;-c9|n?^W)dnQ+ylttxu6=tIs`gw5&8YdmHUN_G2o0c+FyMlw0$`SW=N*bkdk? zMad-@ippIV2%TeizTbYVG^A*SvJ!k1`bQyxrQbrMTw`)xC8ErdBt}MkFsLQMsu19? zynC0tQDIerI@?l@5GTXFv`g|!Me@8)q_H@BA6K4*MZ=!g9a~&WID6)q#-gADXfK2J z21EyJDC|2JQ%6(=@}am!QWq2Oc1&ROu%*S|zE45-?P?VMkdoY0QIMNQFb%<<^}T$y z+z}Fc=+}@Chq)K#x}$~xBWe@vEY4z;lsvny-Wg@tT|rH`HE=uzfdL&N<$af}`sxRIm2mb8Ai zwYtfDhyJLqht_qiXyA#W^cxm|a3Of>mnb50=-;4*hFgxcec$3zjY<(#3O#|+8#HU{ zpTF;q6?y7Q|E4&`MP{9BPLV&>xwU6)k3;9*D zXMV(!=t&0Z77h>a$V*|a{zDmuiL(ExqTXrRlFF>cS2?5Vr(AF=ZHCuh(O{v6oen|% zmBaj!F4TR4iHFKom2HH%pdGZ7G=h$t9W+&$!dmTMKjjHl@%kPFgK(ssr&BL-iG@!( z@k5|*a;mEaX(&6sAu?4w4a;qTpN~oHu8MY7+34J>_UQs5T|_tPmMH|^P8E`aQZOTZ zLL^B}$*y)3`%M^JrjE+lC^BiVAngnk?x%jKlXm~qM-uv{^)S3kC|%m%s|c;V}o3@=rGN`i9D zTlqCE{j=vQJb1r`yJ4pASV@d{vDbT|do9D#w%ew?Z|-1GkG)|x*z)O&349P9&Sss7 zUzhefjr6F}L{~F{t$XOCM(M2<=a2cxycZ?t*u`VUqM$w(j89wj)C~d+tJjZPc_v2w zj6_lq2bolxI-4V`_e>LOmF=m0pgxYaqa~5rS}Q4+`2{~!XBYK)-1k$3{F$gwe@2~` zbO*!X zFhL~Pr&$=-ym~y@RzWk3yNWegYUd~568%Wm>o>CcqXKh@_^0BlGRtq3{W+8JlRHU^ zb)6wzdmfSamKo4U%x3+9c9I}jcTzN}u<0^&9AX~14yBNU`dtP->9%h{sN$&*b$Lj| zgoyX#d`mXD#dW2-)KAS=WJ~NlWWT*{v6@Hw$Sm<6N_a7Ai!eyYT9u1T2>H;);iCvT zmHEe97!aG%ecJI%E`-Fy_9=4%_LrJ7a@lB!RV$T>7PLG}7W4T_nnN67bKd*g%^k?Y z1H$m0(n;1ar~d zZ6JB_QBV*_^u|xUT#ZO9CFcg_Wx#799Bq1$-$M&35@TjiA=HeLAuw(+$mt!oL{CJ& zE3;LHvDA_#ux%}nR|in1)6=beOYzf}|Hm_RVveP-7$r@7w#-m6Bqo-TvqH;|(SBvq zDN>MQp|Z%LdU@NdXkjjdI;7MvA(CTo-I%}L?3WY5L&*9zB6jW_#^iY3(`P~+kd52g z-#Zakdp09mg<3-qxbD=unP9@Np6@FsqbR`YFwO|VpaN}f1{EUH=|kxkH8K}XhiB&X z;ND2Yyk9Q$bi}!fEF8eQRCt2LRESM~ERGw5=kn3H|7)S<+f^40v7Wc89iLCNzH5>w z-Du(QTJBiR1PyR-XPhCYs>dbdArBWtdK3R4_khNceBzS3Znds(4>jz5`<^&>AYVgy z$~y}v%T@4Brky;AINWWp@kM2o#kBk*6^Jf}0_b9eqNqn0;z znAwrX{Vi|W0q}=Ym&HIZwqU`x$#~#JCgmAu#wPD`#X;N8F3C)_v@vivF7KM6&fu)}P6wMOjCqonnxKESzI_9+}RB3unH zZZJm5_H;(deBa^o+!+KeoZY*-l0BAAZLO&;#RwovQ{e~04OS!@tj-+OmomRc%Gr#m zW!05mn(KgljIZjXB*Xtw(~V9#AI|5Pp6hTdO|5)&ide~bqO)@$^KDt^u@z`}7#U%@ zUpGpvUO;RRQ!7{E>CcXhh5fCzwmO4Iw$1A&KaeIWO0a6C52B9cUy1+ZMT=mYSn_M5 zDVvC(DH`<;+pXp{F;@kzM(zm^b_SLmt#DF)B(M}#5Ut5F4R=}fAJus^7e#E@Ecj=_ z*Jwb2-6&C*8_uw+QSiNeCNo+kRXMtEF$$rVngmJgK8G$$`ZD=lTbTeEoNbfj^5}HE zO4>-XFmA;KawnF>*?DR1e|RGmNjTzDaz`EoXL-zt1QD3bA6Mb;K+nqIoSFZ;$%3Kcp=_J3j!$8WxY&QVG zi_r;T`jxNS^6t1C(C=WnCdAjCIH1Mn!b)lXsvJ%fFP_U6BAAt|HuL;VkqWyR!IDGk!hKPyT#7e5SI zFkG^+>g33g`f3sh7a)Rq8icGukofc9dct~LqTW=?pZBolte*3~ zgD!@b=HrLkTw}8cTy$$_#8j&w#ADaLm75I8-;cwY9FjW5?UwSY8uUyK+RPj8k2^?? zwzD3$*IepRhmd$0%ukCstad4n2DXTq^4`U|h(08W;?(L%kjowB-UFn4-of9^zW=n| zLR`Ewc0W03{HWRSFqb~s_Dp;TDt38YvZc3S#x=vR>r9fEVJ5<;z@0agXBCQQDSnfw zd3tm5@2^3-cA9*BL8M^TyqXBQ>5p=EOK5l1xDo+sB>m!=aUjj>9YwRe|Nlq0`4oU$~ZjC_9ZVRK!d1 zkEWFP9zxz$Fdo5sVG=3`i%DIZV9RiBO|#lQ8Jb*ZwUpPlAX+rX%V{i~)dx`0)#B>K zlq8;6dcEPwd(oQ8rQDq8}AYK{W-&GGV7%Jn;-IxEBlE_#6>eCFq;$ViyLW338LUDJO;_kuS-Q7!DLUDKZ5Zv9Z5Zv9}-Q}cv-*fN%iLJ24 zNY?n~GoLx%+7;UN%5uLlt^1p4>>1&^mWuDaV9tD;0j6ZP`blf^vTX~e)7m*8KWCsA zlo7s)k(Z&ZBa{-P1zYH8Y_6@}&e`@O^g*%M7Qo0%n>hQYDgY}mMbDq#$E#6r>9NEQN<(D$&$L%wbb^J3$KTFm&=}@EBKJ{_T=8%+k0ggLD(m>q>WE~lP z)_o*z{T{O_8>);Ne9Zze0cPgNhS4A%NtMilz~<&-hfp+<*u zwM&aRXH7O9O2L-xMK&k!m!XFWrd=;8m~U0EaB7p*zY*(uCa2AVrspxn?+FM~ULN%d zUZ*3=-z9C;wq}if{0Jh2{*AU|7~2;c2tf2U_=b;wtQxQ6-*3tAdzLN)SHvS6TWnIo ztUHutWN&>MyuwtA;r!E)W^h~BltgI=m$ib3eJwcuIw~c-L0izN67wT`MxL7zZk5O zLDhs@FQ~^tZ6EuO+%Xp2j9G!q8->E%yA8?y?UmvtznE8vKB_fHeSEolQc=rxnA(@mfSyg=QduO>-))~_=UJ2_evhgO|6vX#e zto@?LUDYvC$CUHGJj#4x!XB?`wa{k1t?Tac1pC3tGu%#~ZILu|Sl zlHHX9^C%T&9 z_#K4OfZm&m@h^XOHj~WRb2kkpT5s#VR<~mf8tS9m#Y?~ z-*9|(sxJThr-1CMcp^L*Eo$Yr-|lWQx4iPy1u@w25Xrsb5;tHn`CnTk&ZD|mqtBWJ z@r-9VNiH??dQdtAB7{^dy|}0m`_NhDR673&j(!8ZjC)-@qhL>W8e| zxBT*AhV7yaC`}lO(!kTD5do~SBC;;T4U~r-uiGl`F@|E%q)+S4A$CpHxv1N`Nv}C% zDCTYa5!z&}`Wn>El6q}|;qZL#@C^0Q(ficgGRtf(xLaETZnDsZ$fRD*i;I0aN=C9& zavrZ^ORO6@>$x3)-SWHa`$2PL5AvJN@dt)-q4*mI2K_{}$2Qv6MY`e((GVhf&&^B6CJDz*CT=l$xX6C2gIq8u05z%}#3MepOd_ zGHlWGJ9I=+t}c$?f%5mC5PIEe?asgCfCoIg`D|?Ata#h{qu2AZMSOMiY{(tiq#hlB zyT*BdEB{F+V^4ZTZ3!THVZ0~oc8SR}dNbPmAZkeXfw@RC8kbuM68_^d} zIBfWIUz#*bW7h|Bv!Voh3dAh~h-Sk1)LcaHaC0>hM~}-vi;60T=#S1B*~~=QrGKWQ zoF&Tl%qMUv3??col>QZEdm@bJ&7-G|Afct=&E!GC@w@W;n^ErW9G$!GLapP zaqa}mXw@}MyH#!(=9BwF-VR`ofoG{@iMTuS9JTA_?)v57;b!r@SJJXOyddwYPo`{h zbN6!h{8l#QK1gRvu??}Zwj(;Z@V|@~ij8Di+BxFbwUQKTK8?yf_{bi~I=+yd@H9DSU6q(0~j zAQ1)8YAyi4Oq#X^h5N3bG*ew@f@})Tk~@|lP_YZP9@GnII0`5fF{S3XR_;Mpp+)!b z+sILlTWoTud(o-A*IgR`p~Ne$4alV{@Qmnqkr!z>C`Aw0E_3mAwy;fae}TP?t)r1jhmgyuIHg{R4f8*16cG_9>$KT>&b%7D}H z7Q|}sKZ$X*TUZy#CS_FxpqMIVzMu*gMn^eUda9x88A7{KF^zr;%i0xRjar&LAHv1n zwG@EA|E!V@Qw)|89Alv0h%VPFzTmX}Jt%W71P{lc23E`DSH3}*%k5G&vWN&h{i|PS za`bC&79~|eEPo4@B*|)HDM+52le715WSA`Rws6X#m~A(QIa04J3$smf?e567N&>g= ziVOB#D$98CeH+0SInZwDj%fb77J?xiOdVR{}_tsx7J)Z$28zg=BIs z`!8zeqy{DsRU|AOYi~Oa>pVfBRdn4t3-|rGB2MXn``AewRwq>>HYE+5iY8N>=)%*A zyk+!2^Fgy;w5|15E(kGyO*g+Iw4uxopTXlrM&xbYGDr9XX+ze5Q=rTm)ep5=J`e9) zh0E}l#6c(c4MWZ@x@qD-PPl+n@Vef^S8AyGqQ z^F`nRv$lH2KS+pQyZv7qKCTx!H%?BT&u+fdu@LE%-@SACpdp;4$fDguN`}TJ#&Rdf z(2VRwx@bC!7%({CV)+&GONYS6ZcCf^+-vK~kN3mDfw#RjHBDGJ>_Fq{Uo(NUXHw|3 zYOAD+Hs4K%%y5?d`HruO`jnfWr!N_>m{v_tWsgvW0Em2LA`vTYpc3g>|hh?s0FPh4$1cxJ} zx^ddQB8Oeb38ae2lJ>#jn;I{forN z#=JZS;2$GfkCmgfRPi{Bd&B65XX~Z;FzbU_f&n~1lIY8MO8t4z$q5M>lvVxPY7N~}H$J&h-cC{@kZH_l60hqk6j`;(?NxZ)FYcBEQY#& z+@<(E{d7fL-Xr{7>{J~EA9Maw)jWuC0qLNmY#e+eY46n#3{zt+bBLr^DJOCv->OZ$ z$dk0eTAp?l)oxX}phY!vgcPrwWYbEq=-zV}=?5?Uwe@P)ge%B*pyv}A(MV zW0kZNml9zT0>t8PFV=anN3ocDSJ*eqa7wa=D-U0~yLTn?#tr4~HTM?=MfNXV%2kEA z9&q-bHKz&xJ|O-XNGPi@sIM^AwdEjP78xmITMudMK7YAq_L(=Q?c!S83|7R{h$;zX zWkyUA)2|&s5+#59M9)MkEetRlN2kx{ zf6ThMXg%2M8k_kUJvPk?Mlt|HS_t9A!zk%-8m-=l+;8#Dhb$AfrCD`~Y9$!Mur$u~ zK|%!rohz%|L!TmCDeMbL7^5D9G3xw)B+LT!i}yv})Yzr>eu|B_JhWA42dw2_hU#>r z_~j!&S>^W+ZO1#vqhw$sANz}WAU=C?qar2EZdTi-0P6RXn;o)VIja`|mhV}OFF@vX ztDS+xR&H8sfHwJr)}0E zdnU>UBO$s~9LaVh5Mwh2q}tkt1Q-sCgX>gYoC3)qY9%5SiRS}iT6ai707Vi?_j-%| zE>zePVN!T8!Fu{w2cIn^grufJ5ye0RuD{S5fSe3K+!zF>d-)tx`u0EqXaAh-dDSAB zzVFG|cT{wTUfZ9q9+cyEnyVUCGl}Ia|tbm=_Ap`7fN-JcYq&)!NYomd1*^a0${wnHlm0O{8N4H8+XL z>O5=jXz2`QRAl&&lM6i_t?4!uL-&tA&}w~o8P0RV#&t8~`ah7}ax%ZE@84A^FdUc; zpw$J)fAUbmJtubp@__6UmY7G1tr-}ia;0jSV56$l0JZ7lNphzt8F837II~KpPbx8B zG6fo#q`aVC`zWlh-i zx-4Qw(8*!!ob3T66ZtlXF;bz{@LWp6WSoYv^b|3k+cCi^x_4O;AlUvWn*zNnv6M-kq!hsH3&hhEqzZ1$QdkE=4 zJMCQ$j^ZN$!{h)flW~x&asnVfP5YFu!P_G(MHR8=+NDo08CO019KUmFqfM%(Fv9P7 zE?cSAL6__wwPySOskPeZ|Do33(!x^lila? zjlICIK%n0Ylfp|IX(N@+6>+StjgLej9BcMxPsc)Nhxk6yn_9oB9M9T4W4-5yTI{|w z`i0_yIR^MQ+bcAW2StrNL0|C&(y%9rY`qA!pSrZ*kCJrK?vMs-zOYz**IG96xZO8> zbzx1E6$|vPqhHo-hn@RQXsFX=sT%2XhImwETp(Ce1Bz=l(~teqJegBzSm~$xNB2Zc zilGSD2Si$lNjfK2z4PfN^u&-dfwD=Zu?)d}=A0Qz_c5<>nlD7~LNUM96OJ9K%VyAZ zOMAW44`)yH<*XOFW&ZxM9tyQ>S@Kjp8Fw$U7@xT(2qLvW-%W+R4BT5XJM7PDydg!W2lvt-9ef5~ zxLqq+Rg=|-nN6|y!<_7?E_XBo!{{b3ECp*;OMOKW!Or@yIH*c(8od+}s4h|trt{dW zS-FEWT8P(!Rd#^vx9ItpET$H8&nX-m@4Rpi@)OohU;{{CziRR@sgrPm)T9~`Y^mK2^0Gr_pTzl3ox zUU}t_4VQCv@BXP0t?sul{yfXGpO#Ss-AmhW5z$dJLToGAPUsTgnWv3wHL0496}hrX zEN)pyg#Jstda-@QP)qJUZYMZJc`O{noMo-G7(xp#D6xBkk&jdsrLE<_&x+Jb0GRMm z!qB;CcrUk-ulTBAFA`^Kl&IxKwq2EPzQ@I=&OM@jGGSL}Pbbf1+uL-Vz{MJBRk25+ zz18JNjfw|nSQjS@SI!y7S4NG0TaqBQ>qUL^82PBLcVj4cx%zmw=;P6t>BqG?H)kI~ zr^<{r#1LU_9QtV)9b+nEX9G%P4&r|M~GG2i6X*)h8 z&r#5`!79!m0q?=z%cyx1-O%b*lZ6&UXDOS6SwYZH+epXAN9E*z>-o2%ia*uC8$K{p z9`wEuA|fmwB4b;qU4ObNO}=|!0Ml}zcA7qF=LXRCMF?1%@I31J5v(d-@gdyPV#CV> zg%2~YDH#x9#0BU5G96P}w>P(4YS_8DZzR(5o08V~{|n3CG5iOXt7-m&<%xs>dxLqp z#TEt<1Nrw9&~v!j=qdBRm^WroS}ud?gQ-#FBf$@f?!QsLF6W5l0*AOJe*_Q8x*rH| zuc}RlXMI}y_1^BJqoIB#ABRu?Sd&=MjvV}-9h|`?(%M#3N_{3(vQ+*x`1c`}8_v_d z%9x}6R^T5GY-ax)sgM74q&(;w7S@J|5F~1M2*keZJ@Rl?B7yM6N z9$q{v1R0~few7QSmoG5q^bDanL_LU|40pBh`a;WSid)=`l;e`yk}fi&-QlsK{gZHZ z)fVeJs8}~!r)>20$Uk|?SGI5#mVhO@+x`4(V4R%nt`99@TM=LS0FZQSJ(U^#Hj6x}nfeLy&1+fUk zf!}svU8bLE*P}#mTalef%FSAM+N5$EWh;RLouKP}1xM}M-iy^g~ zg;&4QJD{eOO+L@Nng!Ild(BuIo8Kj*QF zxTgt(6=YEfMr=U-al02(*vRT`{Q%mB2l!yWSeSO%EP58J?)BjT6z!;D(d*H2Bn*TDYmd? zzh7X)b5&>MYpGS{$Oj_*3_*41&6{MNrN23~qNaf;3pX;eGIz2r}VRvyV z>fi0UPN~&2c&-n5FQR@0su%NJB-))D@wf!%m&cpfjelh?IH?-tfd(?%RV~B&+o9FH z8ww>)qJygQczgUtzH^F)^P}|kFDKtDYbrku3vd7@fMtqqw%*?fyu2{K>!L)X;w5N7 zeHW)XwO>VtB|RNOt@4<3fQ~&_sP}SX-4Is7z|+_f7!rK+HGsIG)Sw!7E_P43%lGRL#Kw`MZtJ^e>x5&haW`hvD?m(^F@tfy# z8=r4=Xpknq?ROl~(W((=x@JW(De#=z7(mkEk~v<3zf z#6eUAW91M-$f`y5=X1YQ>RzUFqk13juPPY3xfDfmdO|g_%4~eQo7{!J$InIq6 zP8bQd%N1ls0A=cg;kHHH3JfD#V7>;0Sjh6lx#boSnF^gs-wmGpFAX=0gz@DHI-^D< zjf5sc?w%Ya?m$saI$^r@=`>->*?TOTIBKIPSw|uJ>n`C-8}c41I!l=JC5r}oi5-}8 zR`5rNrI&fq9z91E4L_bbLQ^Om*<##8>l3S0439#q_!rfXirfl5*KXl>QiLK5MD5=& zPfWSzYrL?m)~e-WxY~%c4KTkaVYF@15YdZ=c0fW-IUS3W4R%ZRYRX|EkUhEZdr<`gAbZl0-84vAFClv7q-_!iGOPIoXIJx&}HsC7GN0B*tnkbP-u zJKK7P3n>-Y=|5%B-t>MqX z?4sD9VllN=Sj>CLxVok#>r^$_8GWh(rr!Y1VOhzzuBPQWAC89UxGzv_ z1Vyjg#Pg-4Ia1-4GPA(yb_(^IG!GHgatw>&kR_fuCEl8k(>3{E8&aaF2>0y9*3wew z0Di2_(I?DMs7v=+wiT-`aFH$E{gPx)-|tiP^}b!bZ|5NZe$}KZR6`M z{$z+rzFN+reHW|A1Pl;Ik@Joi-=LGD>J7nb)WPEdI`=(&JM=}W#kK_7YJ#f=(T9uT zaf|3EcXv0JH*HmA`Bb1p^fVmV)Q@el98_T1VMSQhRbHK#>O+MNMXM5+u71JhkD_Wy zG-QGj@Zyo}Su^5gY<<Al}=b*f66u3qTSY1giDcN zfuX);T5oF3H&;rO2OYPZ7g6+<)y|9%+$`8MA2jY#D*w9p%nBufw8f}y>AwQz>z!}PIt zN$ATRir=}pk!3FrNEc-cr~=dQlurpOY#st@O%!UD)Qaiqn;oJPVDt?U!yLp{Tan_p z0ziTfsm`tV4Z~g!J>e{%&j!+9Jp-^D0pPt%cqg8k8C$2?NTd|L!R8E$9u?Q0$gZlg zri+_*SUl>q=(!Vp`0h=hap6@fG1#*yaakNGA0hnU)KD%8dpa;bu|v`N>LObYj>2Z* zEE~q&&}vCpj~q3>=T5yTF|-fXn+iEv>o=WYN!BsB>!OR{zYFKZ*=qh#HK!5f`0QJG~nB6zX0##(xs+nQxmqzQ=rVq z&?*q0tzLJLN^gd;#lijq9rip(e#$bs=@1JxSL|N+ZMQJ^nwEb=LbIaiDpfq7R+YP0 zcVSFBPalX55^G%sfwfh6&Xs#l6IMm7j1&>WNu)Vzx`3x1vHtZ`uy< zCt8}+4oYfQHGQ-vR;KP5jY5CqqQu&^^5GK?V~t=~@bFA?Zgk_$g?ag*i;_LraC;~b z&PZnms?_IbyhM|4I#v|Gn!t+rK_VCNS$tPJQFHAsdl5bO;^K5w7Wmvsl#{X7FW*!3IY6C7tQ|zsdn2-B~W&_J3 zCdlu);@8c$$sTI01u7!TYc5=Q&;JV%3J_~jP|=tZ=Tz&+0CBlLBel0lQ_5GRO|&tr zUEF7d!w9?|D4byMz+8$O&sO;`t~59guu@2b`79MPH5MnFHf3VVd1l@qPwFb4_>Pbq5aD;AFoc%-TV;`&KXA9_gh8pI_)0| zArqvG$r^3+4kW`3AaGWgj%l1eZv6iL&Ko>xEa~E+na2Ln(8h``sS=I!UG6u2-SKdj z0utLTWyrX1)7Y=SYm$GS3>k?aFzsaC9~5}89Bn=ff-!_iXgBn78})a3LA~?~Me&N=Mq)(avs&RV0kk!mu` zo*K*jjPWi>5u!fvy)xU9U@jHGg5ChkafJg1PmGU#s5cK&+t+j37@@9(r%1M=wP?BG z&;h;Nz?Geaze@ZiJ~p)_#Yh5-QQ31$zk0+=j+kJXgT0{f+zPYmPUKx{gw~;2Trv)$ zQNzhy#g#1k1`fB_e6zQU)RUH!wqtlYsc0XFLoV+c=k@KVM4?z#R0?wDFiFS;8NgvOi;l%DU@fzKab(7B}vi(!isVn}xBjU%l7rT}8Kr)`In zm^6890x`oTCh(`fgJS+R1(>Wn=oy0`;K=8j<{>p)E7Bvl%Uzkx5VL{vMvkN z^KSCa7>XNtjpKwRT`eEIzx|dWO=NczpiR0@b1i%{nD%}#nmR=`4!{x8qbh#@R~o-T zjpH1;X-tjFX^NyU;@Xh~Xr?%K)~1zX&dGbtppzEjY0ejxaF=s3@B-MBH8pO?2G~$> zScdk&y#)h@eI(Oac4m>m}fYnw3rp%QZPN?@LvqRnpecswQJtge3-a9*{uu6``EnF`#{Hb zDb1mn^F2@Aet5(lmUks(9#gnb1sfK|UFqI3`wCKK zF>9^BDELDz{Nj@5`9HSzN;P4i>iLtE{7P}( zI7{1>OG_B5cU{oPnO8ik4@kwc*@=u^8#o9rybt|Y4Nq@@T<)8gQ&l0VyCja2T~=Gx z5`bD6DRXVygo|3K^uv?$N>-~QmuLD%(7WP9`$w96G`AluP5kHN9C4~Eui+&_z-AWS z0xW@W(i=inKsLORIoE3uzbt0rRY5|*QO8SHAAo)ZfW0XnN2=p1^4|E;=H2|3!jTbP z*JiS`uIw!FZLUl+?(T#@ZsS6ilkuem;`kLsBsyFzS}T}cIW=?EM%MAVZ;a=mwX9y4 zeec4qfzW`1BVfN*h8xo@S8QU`44a$Ho^vUj2|u-C=$$MJBebJxSI(ltjtjttr(T&* z-Nao!uuzO&qt3Zxzi49<@Qu!Ba$q> ziinZ-B{9mHtQ^See{0IX&lV5pwRTyyX2`)n_xh_{{eyh+Lx0m-q}m9k+={q=gGxDn z&~A{vBoz54cz;5|3~|V_o>J@`Rf3ajd?q_Xl_ydYOvE5yZewbwXFEdYge| z3*sS48eQ()ux9RdQcZReI&3qT6`)Ama9G#4*&ur&$_qH5IE1q(Wu3KK8*N6ABtuEc z{v&%K%5ARNEk9X$RcsM~4M;En@S7oeW9#IgKLfb!DnjAW!sotn5M@ntyJL9Rq7w9> z`kuGyv25`1O@3>Ot;iciFnG9)1PF3ef9>N|h(Mkf4+g|SF;5p5qjHy&oN`Z1;TkZn z74j~NK8M$ZE8`P6?KVZ{nkjn?bt{=_PHahVl*sM%+D?t$|6~#s`+H!XE1;eHTYRM; zG5U58J^ednv2D3Ia-K+U{?aJVjn7CO}XP+4ukYUhGo%OSU=TlVcvK9+FO_|nRMO<8aH1c~la zAh>~c;dZ#P_fM|$)P=b>7v#@CZ>dR%oH`KWOLX`rM9EUWo1k10@j=Mey2X4=^gL?z z#FUpoOn%YGe)D*Dgk~OBrBq*NP8eqd%?Ps zztVWgJy2UvJczrVtoEsmVaO$}SAyHp@5amROC8F9Hsbp1C<VS@;t_3f|ei0#(&b$Z`Y2!lr{G@N#~_ z(yg-nO@RgeKF;>hP>rL457Vk>O0r-w(wIasvSPYQlpmG43~BZe?unw;>wU+KF6w0$ zhzwcK8nQ90fL+;sy1EZcbX!I!guL2Z<9f&Srs)^ zmsOkLN%AG5<)w$nrEseiHExqu7Q-bxwM7DH|-66`h z@JHY??~M%FcYwL&n0M8ig2QG3op&O*X3tzqDy#3-&~YHt{U73C@ubBNqy&Z^rfy*Q zFgWL&S)eGA|K?T{CC1xO7f!k<9{KRjs<2SKYE;aSNfAB8_cYnw;g|0E@V-!8e{qovGWmH z1>Gq}3RtX#IG!FZnY9cX_YWHMp6L>u7RSA8Qus&4QbK6w4*6R}`X%}vPtK+b8lv<@ z`b0SU61a4ELb?#;;NdoL5o25Ebf13N?>9K=$16_MZxG?K>JN4edbL+m60&C{?KouR zfwp>1!AoBoVcU~VCG4V?0NO_6v9u>Wj8WWVxdA3tVz}M#EW#}9^Yb*T2}?Cmxi;uN zxfCLA(|n#Qh149gDC;p(YvZdzO1T*ae&tS~J9V#F8oDEK4OZwStkkYZzlD(=#Qr*|IHn4igo@dRVW8{8{N zoRcq&o|a=6ZN(O;%sgBxM=ADSUr_5`vdkRR4`0fnr8#SI#W@wX3^sGq!Sh*eRh8FO z0gQvZvE4oSnel0 z!|9HDWw1}x?UCB&pN>^!Oj+k%E-%fsB1|}%$r^p6#>Y`2rV%J(t_xLf2{v>>(^8Ab z{?ekm{eD$${sUJ#7#$;KSlEf4Sh`ri?-YOU@wu|Dlv|icg9hg#13EDRasRIcVE06K5l(9tmr>+#(_Ve(4L+9Ito>lScvqjez z%WmzOK8*HH1~IjpvmzF6>`$k`BCYb|q-@u}n~mO#;lTb9G#W)?uZ~hs9qgFxBqmLE zh-^PjxB_8NHHE1M4be=(y4Jd$@Ms;r3rVGt0e2;%s0;1dFc_1stB8N?yUVbi-EpwJ z)F$miRRFBd7BS4fhlPyF))rSAIr|53S7hKe3REHUZ})bu<2LEfF)@$uT@?zo&s&ALc;J04N&^g}h*Po+FH-gF)p$9i9#rB(R! zBz>;(j|HI%{JO#t$A$Zp`a68)TQQsI=-RaO7d&sKbBX3|DJ$-$8t1TlFXBu^uDNEw zt)B6hF`tU9t&?_QW;Xr{UaaU9S5m1A&vt36m%OiT;+%@iF+PAtH2z9Y-*i9c*HvtX))*9SUGTy`_6 zQl~sfC+z%ht|ly8P0A+ZDO`7^YdJfxxzr%rSv1?Rx%RL;Xt#*? z;;6j;@YD3DLclJx^3=0FVwPEYC>*2qET_!I0hVO7QsG~=N~+T(#&6l&lEcscgvt5> zhpn?GvhB5(tQGfVuxs-iRu0mYu1s(t5t&`&-2X6WlC)}i3ZPu5(zfQ{9z$C?BX8I; zUDI?8t~;K&Il0-~4SzlH6l=rcJ3-OEtfl39Y-K7{+MSnMc_VSuIKFag>lkeiJukv= zWmoUE2XN^5R>`-GA zhOWl7zSU-V7I{a9Ps24?(D)63R`a6X%n2>S|m2`46YV~U06#d_+e z!jAMUGUFk=Jb+R&Xmhvlj)vuK#MHf{cZk zy?63_d4H-m*k@D(5K67Jpsfsxj0ZJdRg~`SX_#B9j_t0*5b-C)jZEi|1I;6o#!gpa za8q1^A*&EQBawTNo87^tN>-q+Rud{RP-Y7Oxz<-Z<^<0P-6~f#;@*F|W9+X-=C#Y6 zi%&#kTA7}JUx^nddcdxP+$!{g9F+8zQ&D34%RUonPswGtxO!L00&LGu9Bv+0 ztkA5<$2L>%rxUMk;v6hdu0rns_J2x9p+J(CC9{J zhZi7b`4?#Ar!RH9+LV5PV1=Q)Vt4TChHhW)E56<4*!F6f)4l(TOLJ;*gdl+(iu-!x z%dtmUSoC@L@nTmpo?d6NrpsXHXg*ZBit%f%*Ts|#CDS9M+~EtVFjFNLImXiy(`ElB z9`B_e@~<=Ql{JL-ij{7(Xht-;=qh$lqZEZtS)&BIsWiQ)G_pCfd8i3bIh3@lxMxP2 zZ~GSsIW0KEmV6@^6|D9rmQ^%8(}uCY#-nfhANe6qPyNzNw#E81%_aHO-F|Qp#nHiX z%=L4mjT2S%NZkcd@~_L=?5;NxcUa1rYJCRP=45mE9i<1#idv$NJ{}L(OwCul$(T0} zl^I+K9sW(e4GXI$Sg*ozz&w)_2$E~wa9QSDN5{F`fM9Zh7u9TsRrEBwfZqHnLHpC? zKE})4U2Ovm%W%(zZ{yj|XuD45`+i#FB1_&#bt9ak933u@q21y2<|rRAg0SAJ`>Pi@ zC^^PGBj*U`uNgV%jf%t1S7a3QjorFM|HqYr#{OYQAuXu@uOxvn{}-)Nluvb94!&CS zE#0Z7AIrBd8k_08hqkJW;8W?jDvR)ZNpw-iq3CAnZZx)zCDmS&xm9zCq5yHtbe@A^!MO{O_7{~UH_f$5u@jpk56wicMi~BZN0Cb zbvK?)fgqaeNvt|@AeC6}>6y)Cvp~vI;mz6T&^cF+RJIO`{A&4G#skzRC>T`ICi1U{lW=_}6PujY+ zw9nCuy$HQK&2?r}Vd3e<&hAf64X~P5x@;GTTv~vGN;dz2|I5f$Z<8!Xi~{jgJ-Ae( z#i;Zo2d?~* z?clnE^s_B}(rptq&LB6rM8JKN&Vfu79& zf%+|numqui)2-0CC@3&gqBvrNy$tqV498y=e0rEVzwpkb1KrR^2gb$ovxmWXBuQhi zW}LMJFS4xDthpwI%a!{=xD-CAq~7d5XFl5!BcTA+l;@}+j_05|h4q__<6Hf(OYZrV zQ0QuU-CJ$WXUPE4ov<}BUK_mMV9Z87y@sS|g*Ue^4}d%6T_60%s(TN{Y+O@eT7DRA zEC*Talx>ZoH4ZPL4DBisQas2pHwI)P{s>#wQVYslh}C3fP8<;Z@1l%14o?& zp!=KVjzF#Mh(?j|N}Wpek?%!@$6$MFyV~jXqm;3r>sxJL}S&Bd?imShAlZ!=FMT8k0Tm>HG zUfeZnZd>AV%5uvT)DVmuC5@T<*c#J>99a^n7BCUOrC`u>bEG=1)gT4`ea*`&Iw11XEoYT?AHBH{;v%^&C!i0>|W+=W&QjX z6{rh!pnd~3@=5foJr}!t-umU|?IU2S<6nlXvv1{;uI30vaKhlp;E=Vman0^0cZw7C z<*Qi@UMi^8t;zbOLps74cA`_rEHP@mVFW8AEgP)gV1Hz&N32wHiF1B04>l_Ak)?%as2~xDa)WdclTUPHTFxN|-G#$(?$#ef(P7}{-`Yj3lS~u&m z8T}B|r}}_C3cosMj7&jZ@&wkUn9K?5Vr}8$fpB(mhRI)t-orbwrBaY^$euh#=lXqF zoVI7FfXGuL>lRA6&;+im`j>7y1;a(sPK&z~4c6jLaSiSs+@ZKrD6YkeI|O&P7I$}d2rk77e5dcdcYQx| zRx&v=nMtyr{RlEQB$$(o{m^z?TPrYm7G&`W-1VH^O-jaJMh717L!;YVoAr5k3yH05 z*89mgp5=DCInE1iSe@0g7Kv03L`(uqX<@26oL*Z6yi6~sGAo4G5VLTCDDPL-~`IK#35%U82iQt3>AgDE1* za6pR~!F1Y7OZSG@99Nhkb)5w+OUs2&r@s(Wx`oUj}@e|Gh!mx!0f!xX!CE z$8}s+qVaA>!ZKI{Q-54O->4AkbSf9~SvZ3} zYc1kFnwovfJA_jidJxBY5RduR{ry-c(m;X&wHDaSxojK7!6AE&vP z_n(!xD=lmc5wQB0w7o8B9zSQzCLid5W$gd>GX5CP&_9}LAJ3%DZR9AHHxGkk0A3_k zlL=b6urA@z+ME`Zv=dcxY84c+2F%c0faJf&7S6rP8Bwud)A@+DI)LkpZ63}ULF)Q4 z%uF+Kj_W*QH)M~y8kAt0RIZU|^+ocjVaN{174^S{Xf)hqB24#{?_C|VfLkI0z0i9? zw8|p6-*K;S)1seBs5g|OZzfK$bo1R_JSn;Fe=%}bBDcDK1|1|D6#Y`*r2}>M8qUCX zBS}PL@?|B)MDk z)IS}**OZ?kzd~MMANC$uBo7hr-`LkbE!EzRlkO2)U>iuP$`)b&&Wnih$ix^@d9;-q z7oE@oZG9qs9f^WGpw@6Hu*FK!$c50in{I2MCoi* z77J0W=&SLYkJpVzwY;oJNEt~FxZ*SnLlcBqa>=zL|G#lwVBFpv)!y-7LDHCr-1qt9 zgtFf%4vhy_t@t7hr0@}0wp=Hc?G23cec*FV8fLH}7Hz zkNr7k^`t79T2CTVKuavbuf|gc zjwxPZE%>WE8Wz#@2I%O;Z3m6)atoK4Q+5)q4SJ={fw0goxce{CN@&GrO+ivZUt;b& z@5=Y$0(O4k&Sx;FdM=ZB1Af2qX zG+KmQX;}`hVTwTD%1U0uDYO-R@h8Z1a=xOb3pI`O$C2Z%ms8s#1CVXCnm9eX!CMW@ zkaRgwl?>Y(X(;6VoT-Y4>$3pz!VEe2099xWyv5(wTsF`<=J`m;eaODwfKn0v+6|0F zOubx^iG0TUds?u~w4ZLs^s7=KPv@-vP2|xbV$Z*0VEC~^&mqN~gLmyycQphqc3}?H z?`T4kv)iS?5QB&VbMOS6eegjWF(c7(VaQ*~7F(C;{Pkw>q9M5~1reKkCVQIlU0 zBp~2~hPx43$x2^{OmZ%pP!n<%le2KiR^TfTFF{RP!=e~1)ILVIrSF7W8u&R|)Vwuc zSOGG{&ZU-jCh8ob&D97w+sW+#z<2OxYf>q>O_*@0wo%(Q@w^=M>M-)Y`^_;bk)dK1 zBK{fc6z>4Lj!^#esJJJe-;_m0KK zv2PV|Pp*q|!zQMLH|^)TfVUe}=GQTHImct~&3hosO5CP0J)Iag5wd*zn((Ie+~+~B zZCI+`%E%yNz*fBw(vPxUwB7s9_Tp;()b&3nbIs8TyyJkc)8raeM?w3`EnC>pUt_T= zuzhAYy~2abnZ2{r@qlP5J74V!?H1*}%tWh&A5VWky|!y{ z+y@~=deC`s|F~ug)l17gr*H9-1i!Vd%YD@FA`k zZePhBoZeJln(r2qCLO0b2P&W@zDC<(fdIW(U)`zm3P6%Or|6CS6S-#4?Ss++(l3V3 zG`2l!?tlRI>8U*q=nljFc;s+&YFNq5Day6#t3uh;wNBh}SXa%+ha&X_AFNq}kAi|& zMHl@w+Z$*PV$KqY5`fWvTce1WlrorYEJKCWYYG5 z>KReSA(3*Q4%rCJCu{<3ba+|XTtF+GkuwXegFwe`ajFz8EC5cB^rAIk?$m^t>QZ*y zYn@?>oT&*{>^a>pv!->576*`9+TaUcLnsG(6dV@pwgAvp+a3td)9%@@&+h_769ka_ zCUUda8|L&kbA7K+KxGqgd1#qPS|Q>=J_3{V;Q}6%5>c{*V=i!_bxsT>aP=`tIei`D9Eb2M9K0yln7{)^BuhDMX-hNQlr&{ z-MB8Gg&XIR;aj0u_xnrR0j+jbBG(D(aIdSWR@lE;0HvR6!#ulKJ>==%>iip^UlPJI ziGuQ!+>W&!hj^iHfY$=@qJ0}su&&W9Pw*7qt^zPE(~{A0O=)sh9KKg5g(AT`M@18e z>?SynKNkbkrUeIpR9;h|!7En08LXG5xBzOECq#}4YtQ>?$jNlY$|M@>*?q6%(f$7V z;g_O4CfT+Bs9uk!VUAB#kuWV$$Ff({w;-$UJ9Lbz#S;vMIdkM3$ipRensgi%6NAC# zV*r=Dc(Q+}(d`iydJ=R-6*@UEKmC&r*TuJf#rU^GjJ|>$cH&LO9~|uq&s-(dL8h#0 zCQYcY#YjrXhmj%udg6neqbHijMM<0FyNoiwp?z*`n5U3L9z5e^JE(YqcK-1*q4;1v zhS5h{E9^=Mi1c*n#=CaAcCtLBH|m|dAoiMT-!wvML+k0%HUzLudn3TY$61xY5)XIF ztCITDQY1mEeFm)Tnd?(DbL|?2GJW{hd9_1f>h!uq-2ti`hz~?vEthwQ zCQ>e`$<%qb|Btn4$pGrMv^}C7(SRZ}R9K`JUTg8lXgx>qy(e~3Qu`?h2{O*-!WJsS z_Ue5r0w!$AE;}|YLbKLYNdy}ZQUcbv1O>~* zZ*nAJiDv2S37^@csAaHuq;k1wJW0IYgRrIZpsHLTY`UqK+^LRbY%%{_M5Kg9l0@w) zeq?OwhExTc!%T6s1v*7UtrA4WGhm^S6I>N$XWxop-@I)f3gx%L=8($6R9W?o;19<( zm4LwPmWK0Wl#JJ4@Qe&CV37ohAzL;r#ADyQFkaIi7goPKji09jf<(m8K7ca6uA-p? zh3^3b<+DI)Ze$#RK4d1t;=1UWa71QR%BYUgvm_P%>5}-c=nbeUVsi~5qiD-Kqj(DI zKq7}B4{)SS!#M#d#2F`&QX#6N>FihUmMGjI>~?U5F3x&VHs zN^ce^GZ{dC<_XD>A=ud?tcnEM*q~liW%__c{X$xi?Ek{l0-Avtf_f*Q(lQnQ^c8GU z1yX%{E;guuHiMBYh}xq_hKoX}U;)^pth1%eN>Zxyu6ZD8!$-RXsB#%0hji3`qaG@0 zRwScE{s68K1c|p> zvY^?cCWTyyuin@RFc;2J#oQ+058|Jft@q0nbGVylowqz!SLw0ozKDw;d!ZC}yG7M5AezXgp;qLKRjduBCq!0&vDd&m>gZ>LH5e zFy2f%zxZ1a1`deg+pLM1j z1^kjwrRuuW5eeGBFZj=IHs|F-inLp}m>!Wi;s3dbZHnjx4qrGoc}1t}F-LA+JWp>= zcPCd`_VKJN#Bh<-bFZkH5ns(Ymr%cgLZq(WefcH0vflGmZK1tx-Hf%$Gzo^A$uqB{hQjt!H9(HY|?ctwtlz;yYm>2ZRGkLmoi*)mGvB&%EF( zApJ@|RsN`17;V3?bdz|yWclA!AgD>i^`j)({z>qlY3CU+N4lF1&F$)dQn$-FrvCja z_8%!$w5<^)(8(p+K%#-N>WrKD11d)D^>Z7S*;OW%*u0dgjpbRx9_}-ay#p@BCO}|< zT`~VtmP!N2qpBfl7I73{{QjP;>pFFmaB$=ctIkQ2N9+iB$|^8Gu;-|H#14?kWS@%A z@Pm(P{gmgYd3sAMR@@_6Jj!wuF~`phVAiW0PIWT4A~rvD3wCA#qABGD(DKp_c?TkP z=(+-zJ~f|60@n_h;vWGG%~asxC!T8}C+x32-Wi?q%sVCdZ|>^%RJEv0xv$h`mN)i) zD|LsBT5*3|Q-2&pbewSr;FNnVBv)hy-1M+~yLYsQ^>?6~RO_FbVG_~I(<0#jO_iF@ zXWxRIDIb^{+iD*%b^1zKAX|7?otZGlkG#Nm&+eV@BmG(u>U4G@n%m;?a9eUoBw8*n zbaQsBp__*>rEcj)h~r`mu(=m2$zEKfyx<~@ZWWg$q z-8(&cEWoYF*#2CRotN&;$!JuxB|KfOe4c)OwkAo2IKi&Cm|;XsiaF(%KxWln*v-qs z$tEm$zyIl);@QIQ1=jtS%=>ZjY8uu(40C_{yP4cQ{j}+N``6>eeL+A_z?*-KG_&wl zlvhykZ+B7m)8_EDimj#z>xy_I6iY|~VK%MCN8<6$yUkDV{IyCFxgUsP`}%O&lPw?3YmXQ1DXV<@zSRWM61e`Wl@bpIwX z^U|jya{O`s38pIW%-jy<6wg91T~r({XQdPp;MeneuJUsCj_$_4dGPcc_iXQMFZUX^ zV%$cVF1Rx+p_rF-rowB9Flv1SBCEDuT9>jaghHgf-^Jg#(w0RqJZ#UGZa+m~w!(x^ z7Gr!~QqsCD{o0`T|*Y6=Y;?SsmVsCza8B7u0`a zlJ~n$ABL09`Q(HWCsA|ZYuWKlf?%-8QX8PzFKS6oVGnNO!Pi2U*u&?nof zyS(}cgJ~GRX>zq69K-t|s*e!pz%$nTqC?l<$?v@P4phN{?f*oyzBh3+VH!FxNkT`+ zo?HC@L{_N>(9<(0l#BtMrpOM7YMz~Cl8|Ij^0cF`QI+e4;;`joOj%=S!>n}Oei5Tk zbi<$oQ9%JIJySDk?YaA{yABo>!%uBh`Tj9@Q;O=vAK7IyqNb+K7Qlzf-w-;4Ny(J- z7Bm%>i`o27g>>j&!rE0JQES?*pv9@07;HavPGhK}uV>`*n#gB2h`^Hh!-j7C*V}@7 zz^kRpW>uF8{+mVb!5-W1b+{Dw1GDGa8~+0UR1O_O5xk`!ch*j7t%I|*C6Ya)aM&w)-nrX zFdDaFW3R$1MLk|O{Q)Ra>MKK3b0G;zjs#2RbZ_sdIFfVrYjI?X)jDp@*avuda#_+x z?>|fEncf%nbI&H28Xr3y90aqdH*b!INM`BZC~#eQV!yp>EOIBft!wr55ENKZqj<=s z*Nc>CbyFXy= z-8u_n`j)zv^A=qs!WHX^4A~M`-r%E>JoJJ>o>7Yd0}n&yMqF0HqGX>RS|>qvPhGB) z`fELlo<43@FT|%WZg&_<4gLO0ESXcXds2A9FE7XKtB%AxN#*yTC-@(53wPGm47CkB zY+Tc`(?b1YwwgaSl_jVNOk#h_6=(T=JO6R85m5B%EnQQ|Vd1PyF_jO|c@%=7@yU)b zM$5g^v{;Cbw|mQf`B#+#@Z9DZHD@eUI zcYk|#vdrVjqa4ToiaO%{6A(+soR&uS0}Ua2bqB%x*IYHgsqF7NMOwLJnspoWFPu6* zvi!atVlH4IYrkHV^`;nwN5|C9?-#+FU?6kw%?V7X}SAm6dcfd zI0p;7cTdZF2Ly`;G{4geD)7k%x!dhU zb$$2B`+yT#OYKe=aKu6*XgTkmUik!Nb^`?^20j~Xi|2=KecD+iQqp$Lp0k>MCLh^a zy|?rO(ngTe3SqAf`|V9{xf3z39xZTvOol+Dd~9pr?Q^JQ|sCus`$Zn>seCn&e9QkL4D zse1K|!K@vH+YUy*qP4@7BPj+MX(i0{;f^_$0;__9nXK?7G?P@HG(u!s&Di9A)KuI= zk)y(@U-1r1OzP$_=|){{pZs{smxR1pN-PZoQI!tEwCbSlgcd!FVX7vHhO_EFO}l^^1+}o4Z|S zFRxn{L;<;eaen@KRN3jq#ky9qGqTJM>^`t$P`G?}xK_}Ixs-B*u@cLncC_UoOY@H* zXKhRG5?5x84UkUPuJ|uKydP}S{{>*-=fF~1g;oVtj(xQKp3s7Xzh0;WGMeVafe3Y! z&()adMXuNH?vHWSg4DuYp0o=v1t%A_-g=^ZM4!?uJCwP=mDk(&+iB3eJl>Zz`-MH5fXj((=POL!9cehX#k`fNomm`*G|C2#?w*fM!N9mLseej zM(#FW;FqGv47AK4pM|DZp+->fcIY|9>5cBom`hCj<%Quuq}U^CYY66gGl6R8*$*Cn zfRMSY@=iW&2o}f2H&S7kZzyAa(j%uF2hll4|cO1 zt57r@JuS(2er5A>8f-TlXRu-$d^EL@rs$bCt5^Gl5{f zm(V*WV+){h_f?cp=XJDpDVQv5|LPg`_wVDy-{C3i(x?8(0UwB3aGkH8)@f(stC*Tn zFhkf}Omx1pJ~UxC3BhK@xb#6PpEb#O({4Mpq`#&X9z(j@#s$Ztp(f%dbWAL-=)H;_ z81@c;V%55ujZ-fLS9WHxIfF5~I0?mkJsuz0UVuF=oUptkzNuBZ^-!br415K3@ls6{4c z|1VBdkwY@F_m%IM6{JNkZZ+|v?n@sHKUG`_K00$NQc2eq)T*=o7I63FlhJzQPgVsl zL<g9+O5g+av4@9 zlG)GTEh#{E1+jOpS@^p!imd5+_;Fi@$13P3Q;QdWLt_ShxU^8lw-Zs_*kRU9vekbR z^y?k1Ocq$&jQ z3vMBP^K`LMx6#54&zyQ#VOEmon;!*}9G3etrDrCvA2-;C@_~ruUClC?<8WCR2n5zg zm19M8r;!Bn)<)mP?6c?-Jb5Zz5A8pE~#NJV@iQ=(h5ztf!MVSI@(Wo8RZnBe*<59D0=E9!U>e3|=1lo+iN?2CX(8Vu??y_ns`lwUm&5q!s02 zIGR5l2`3$D4dN$|@KhQ3>g}E^3Y#IY3_Ui{j`IuJtE96S`cEYYfP5K4rPfv%|gA4z6#s>PV^cxk41+%VtV;%Ld+l^Xl-E78w)j}K&@x&2TCtr zCOy1>VQ~{F#VePbF|FC>Y^0>=wi#JKv$Y%6P_M~Z=hXC91}Uj2lMH7zgAtO$J6VC3 z6j?1c$|&|#d9f>-(mWLU_;r=PhZLdf+}E(BjnNee^}4SF7ar|0*sza-hy|OdR2!B3 zw_{1-+^@MeMrzjnh#sPzUnz6|8LZ~4dN$JB%*PTWTp6@HFKRS`YdR>rX!YcfpC1~2 z???4&=DhokPYnu7Kjf5ZFGQLlx-5(*lx4{E{=WBJ=2`o- zBQNpH$7AZFEmo3nIW9JhVz>KSxf_DM>&XA)@_=UhK16cbX^E) z4%ySYE^Dv9(u4vX%pCWHfWH0zmoUIU5NKu&9$IGoTjtP zzHK0O7y3lGj2!txK&v6f2%4 zrkg!#bFG=v_CnrQQN`3}&U=t2$5A3Q8bT%6u~t)=qg$5I0maaBZ3@SFUOIbO(Xr2h zVjV6x)~^T^W%U^(7|{$`D~~HgZ*|{6cm7hKhlQuQ)O|}z_e^r-Gt1o^jvtV2G!L^I zkK^)SA(87`E3M&Mm>+ebuiTJC>Q3WNLuZka55fG_x_!k1;r3uduQ~qRL>O>e&*-wO zODUPyJsLbHt$0yA{04x`IOV6##44Z!JVVr{oN^V*v3VvRx`PM7y3E=0@p-g$*xubc za}9(}>|seF&QtML8~QJ$5~ZBlVzLx`aY%Z;XU$)NjY^~5{sGj+r*1-{14?0G4Kj@N zDc2i~>YW*-`Pcsuv6vPfVs6aU71kWlGeXbH|B#~$UtgdK` z8a$vBfCRuj%hANtKZyapP@QGM=EOJcAqhO2$LVBN=D~!jU368z#J4K{z+(H$CjWzh zU{uk?)wYVIt}`}XtQ%d@pRY+4hD-&=uyK;R$gjOzF3d1_f6iIQMDR6D@am!?N=H!T zYn+u zcA2i6?0A8+Dg=H$wvDY38LiK*&?OVB*&F85I#Pg!e0rr>jvCxFn>`s95O}3gEipDtUh-g{1Xd%$kPR0Kh}N zc*Mb6Xx(ABY=~W^1%lNAkv%MCC7E7H&_9p^q?45KBe>R?fJbCu(~?6N(JbwvuM58a zSmOL2X0WEJhpl(ndL_E(1v$RWeVP2*S8D4Z+N0u-Yz+*uiX&J7oI3vQp9gLD;{yIH z7u}oI;&9?1{W-_P!2(`o!=o#rBQG$KkDZztF8N8coO6@JvK=&T!K6{ z!9(26O-V;26*?Tcw@Vqtix~~$7nDbG&RxP%*hWWDz*C?{m!SoE@|djiLDf1Uc21d0&nY6x}ove(DnpdI1me(?>uG+bQjusdef<3 z5f@1JD`DB_<>Z&ZHH5h(H9y~;BgejeMsz+66jNk+@%RIQ-?<_w)h&T6JmpTQuEJ2% zvY>Z;;?f31A+yQMyJ5Lbt|>L;`<7iIi)*PUE|WgXRc7DS@U*4dR|S@^ALm)>JD@bT z#ri5g;Sk%!A&A!~K|~1Kg-U+9%0t+jMa48&rlif1FOYaAaFeRVkk^q`%JK$jwWZ+H zy=`wXozYiUamMU->H(^`&JQU0eY^k<=LsxNkUCLt+Y$MOH9LDw?z__59cVrJ9Xe)A8KPm5a~r{m7op65em!mPc0fN`i)IZ>_*tT*}a|g@2b)VZ^%)J8$(s*-GRzMhq#FOP(?cMlz-6Tt#A6nL8fup}VhmN|h z)%z?m2Xq@pR!yR}s^NPAiCb59f0nuRs`SPhg3$fnO0d z=wTm`bTBoMl!Qg!{*b|v=^=TKQb&iU!Ba4<9xoK5kk!}ya_w;I2&7Oy#g7+nuXd6s zY(Ez}_)yT8aggpbiYu%BC^_C0x3~15=)CY1V4&<~-;Hu}j1@0(u^bUn$0OTqqBdH) zQKpF@HZ_u2B%A1YzKjY&l1#1CHT)~@e8U?aaH}FttXNFgSS(lKLlXt!l3S~y9oL%> z(64ZeVIjWh>^N4~-+npnCcE0)b-sr=^OtvOD`EHc*pHgkzuuX~NVygkKJ#cE^6EI| z-n!X*e%^HE@pIVxL%$Qb4dY)sxw*}9<9b{+=%3E{1PT~mZa2@IP*QfwacZw4sZ4@f zDU0L(Q#1a6O6PGKetJDM1opYMCux*h(@>Ds^3S}PvXf=j-ZN3<{({4Xx0|b$27)C; zr$7bb-nRwd#h?H>o`X0A@z_~UeXW5vfJdh_Cr1l*>fUH&ju@CwBExLn04>Wve)~7Z z)>DC89BZGon`jaxGw(&W4_*?uo|OAl@ydmOvUGV6OqM4rh)hs|f-#{CDkidJ>Y;vDBwD8*rq9e9qZ zRR;NU-A%H*9Yb2_!1u{B!K<}2u*JJb9Qdf`8^1*Ve08d`+^_S7oqX{ z8NtQ*Tfcn~*w1}uX?GSd(;%kRupL)89o&ftu~CxfWTTE3ACHW;^cMe0Kx7mpfu=|S zN2^~50bCyXkKSuS8Cl&@qJ#7RJ=Cz>4syQ!IO)8c2fL$D65-d_7O z?TFJg$YlR!ClvAZz(4<20D>qZ!U-Zx*)9g1dMCRu3G;P7M!Pm*xVdfb3JG~Jxf9Wq zZ>U^LP-LX8=SgKsCaa1si2AEvD*}}tK2Z6ML%OG@YXrXUvs!h0bkquV!g>>sL#jPX z19`&+`W98R9MY{hu#dw{J z#!aC-a!r&xqX7h$X{4K{h?uK?rP;H4y=E0dM1jq*;y#{i9FDNGw|Rqs;vV%-t3h;( zxPO@5P8;jc737n2Y)A%~h1z~d*RSIzvh(Ev=pn1*4kK|RONbAI-z+LheB##QLdr_? z_^q(f!c2YiY@{SLKBa;ImCHv?fAZgrLDu-<`pzkNX?@}(^gRs@Bq~aiRFwpJsxd}7 zZV7gV*jfmt?Sg>9?s}n6vd8_!{rLlY@BQ%hPtD8GejPWRhMm@`5FfqEFtA#O_25O1 zoK3022oh(l6krxb!AbwInhm}lhC2CIb0#PlzwJ(UhDIE>zA zo;*6N<(eB8{Xj9a8S%9P8V)?pZ{*EPqq_kV6-@ex(@hK4Kx(kh-Sh(lm8e*_)5NBA#EN}6sM?h(U z7U!2Uqo!-KS3*%{a<==*u)uWV$vDI4GIWbQ4doh43B3GWMeq}@^sm`Ev2#x6}D zwC+)asC-S4y2RCnJi=+uJ{!7rJ{w?kc2-ktmV_#N7W6WbPPNo{4V|7p=6`M1;51H} z`-LX_O;MXxc|7Ect>n$wbEbfpmLzAX*0@K}zYI1=++(aDmF|U$yoMm6+!(QvbT!4% zhp+S>=ul^?iit~7R2tYrQruAI7F;3{|F<3hH_x39+f4>xa=O*d*s z+Z7-R{mWek_@~GUcu7XzyHp2Bt8?f%uM8HVik?PS-2vUwZZC;)(I-O(fP3^HygpM0 zw~C;WmOMTALV_V^6JsFX*yv_JJJD^@FdS04INCV)e<*G5=z|GgOqv>p0r8MVK?5## zX(9bBr%h>LMms3azF5~hh-EQIgxX}Ygc&=7iBMFP5-XL_7$xyoFQ>{4q5M$q>!Sm2 zOxC#mx}M^0Z;`hfKgoDdgd5a>Va^6+JF3N9tu?&SW_lX&g#|w=d^4S)0z*><5h|7V zxX3ug?j|?F3=L(2Sn7^g&3cSc71*%D`;jk-dz4Ifbs7oI79iI25L)~qps z0pBH%Y6RF;l9-L%FObtDLq)+bG@?t{9u^jgn;u5d5?7Ye48^`~U``i@I;VLBr^p4x z?TPyrak&W6@6@O0Za$%}F%xgNQZX@65t5YjYIV7Xm7G-aVX(C&e^F`EKkH7Z zwUJxrGD9f#mvyLofwxI;5OM- ztId4?a&{RSj-m@$RujX$q?vx_ZPhqNjK6|wh$d1}M&OjGRugznxSWR|#dVZU-KAKH zEQf8Tetju9ouilZ6KEgcU7vL+T~Z?RkpXeuZ_9x@MJB1DMEU#?)Q34cS(5a&9ChkV zX8n~Jqv)Jd_P?GxUb)p*#j_uUiBVLO4lX~Q1vQo5L!97hP9^#B5ok!4w{~!7sdWhG zY)rpYSW7!&$+#%W+9?{Bn>#rfXW z;P(-q)^jEWS_onP)3=&x52bNxF1@i8pcOM7qkz%4eRXwuNfgl~;=3(C=A2kv#pukY zz7YA1`01|70Rz`;@E&%z{MAnbADyphD>Wk@siW%@VTaR27K#?{`3#1hHGU&bcjRn7 zHBx|c1V2awVOQO5owGJgEnFW}-yB_xG)S?^m%PDuQ8kVKzEm$8QqRMyJGRtY!cKZf zXTBU$)Zty4vt;LY)rJxjS)|aq4g2KFOf~Oh&RhAz6oD7SG=K1LE~3s0WwvrlGSw@I z(|e2UN}?$GvE79$bEt`!$m|LGuKt$|HGTtuBAmUDP9>LaW}*^qy7VZ-lCi zpJ!sD^z^?L%4ecMj9+o63QqkUU+<6qYhb)EAn>H~qlQl>usCJPN zY2R(#TU66;BuF>CcdP^2Y@-B03GNHqR_m1Hc-5@X+5;n$<5W7WUgym_tLPYs!kS7> zx>nw9kH0*fVJO`4(IXc}{%r5L?Fxqm$QA@8%E{@qQ=6Lp#IAhc`6C3NpVBQ)3^xAR zP4^)+mr68{2ow>pa=Vcv!fb6`*AOQb1&vd!3UYzTzxUba7vU!Tq0Uj(+sFXLko}2R;1P`}LcDdry8@n*rHY)#Z{Y zne*ZhCEUMQ7XuZuQ9*{e>ZK5oZhGx(jgpHN-ok!H@6ZJyYA8 zX@oXidIKf>=^IROY?|>{9oHPXcc`25%YHwj$Si;{xXeW)=g(4V1w7n?pYRhL()wr% z%?Rc1Ofx}dd@@b8*X9$+nHEm^c2~iCgAr(i2|H<|b{r&eeg$Ngoa4;&J5`YHacMQ< zRePSi=Z6OdIeJyb-!SlIst}&}Pbn#tuWH#ICnsw8kI09pF&?XIziZDnP`qj7??kmr6LgAE5NDy& zbze0OcS~lbZ>y629tRGbw|{I+zNqPMx;0q2_%rC2kkv`$N=OzK6H>D~5JZTp;yu=c z`FcjbM$JE+Y)SbOz1-K)(>M4fAi@WKr5R0=0WZr~s_6wDVWp35)zf$Px-x|YOcjJW zuS6|pO02sGKVc;kHzR+-7A|d}8F7S8;K8n}HTXPrEa@eTNW*HzEDgvSUc?Hf?`u+Q0k>k|(vuLkpe4Q<#ia8lOUuK?y{qat~>Wy=J{Qsuq2f>M0joQUn39R^mat#)&b$ zSRkB7EDb8ux?dVHH?sI<7Kp*DqDqpVx`_%z>XJ2Nu4M@4IED%7*b`2_Q@7Vy1P6(T zrU1b4Ll8q>36SDsQRZlC-$k8n!J!LfOE^m8*qJqLmj+1GIU&A=b-B%kgs8UDiF@sr z!8PSTl+|=1ZhIA~J)oKW+%i?8u~em8Clg}fU%`I8Bo8E_4b?oB=^EYI{>% zzJwOs$zbB9?tIqDxw%d zn}(r_e?HYFA<12BWNiUD1rHml0I`;^aG50B2!vR=pqyLZz}i6e)ADVwV|SCjWjEof z)KzXsLrumEB7bQ4FOe4;Q@#uvi%wBX7g*5E!q8lnO`uUn_ubbQM>l3FEO{=FxbT^^ zscGfw+OJBgqx@pk5WX<9Z9K+lE7IJBs*Ijs50x~ofpAj-+pV_LNfHxU?GR@g6e?j;PS{LHT4rH+%orbg zYmG*L{6T|33P85`ZcqOq+XGysnaFNtRxX<@62{iM?&A-qjWHok(Wo?l)Xirrl|L0d zxc*FS)mBRvbPT#v>TRNlDe7j3o2G!@IKA_h|HIr&@K)>2YK7-z_EP<0j7a}v@ZcaW z-Y{cq9T7}unftl#+)Jg9*!#T1)o=xCO=WA^IBS4B8Fb!ZVSo{vE%ibsZd zpSM_AC_d#!FVn~5fiI3Q$bl3WbNEF_kHE~2k?!j*0BnXm!&EKvaNE4?Nz3B0(XG>kl_5NAyom0Vm;U# zqjmtssNLwQMCuB;M;=4N6HJyM*#zWC#9VA9#T3vSt&Wb3p8v8t?M^5pB$(JI-p|rk zi;hzV4o27|I9obk+DPFVFReXSM#Lf1E4^-QQSUs0@-=SB3EqFsHm~>97(YA<6qlRB z_pRZ7so}ftJo2t~T-G~~F~SBB?SGETr8LeCs^6dD`;bo8}~@Uqn=;rJfg^iJfMZG+jDr=Of0qF43&utQe+*D+cr?mZfXh+Usq z&NjdDlm6khu(lsjk&eJVB2Ow@IIyQ?!^NwKtI@4j^3K?E=Yv-}K zl^H*=6sv=w23r?n%0vlmgvc@Vt=YOd8n-LzOKS%np5v8Kj+9nABMlQpft3}CA(-2SwvdHbBQA?|jhoI03 zp7PX4)1nHpZ7p4V3uaVly@knVhx*ee6^e}a1uphj@VPluWuFS{$UOi83w_GVqVsL% z2MhtI3lYX4xpk$1F`1<`K(+AFN;>-bP^90S~7mnE8+H4>n%A+9bwgY$^-ma*ahz z1=%@+=zR=dM}@r|?O?1EdbhJVf5+7C@(b&46QvbZ^-KRkv9hONv!e9ok8;C>Zba*} za-=mmZ1qXton(VtTit@OH8RL87#YQ?-N={W3CITwK+TXV`a zf%M!}Q>`keEbi3a;%h_DzPwq;KO_kZSUcqCK6K<8p8(lfKt^6}c+_Ijdp;Z(J(bBFU_ zy1aOMQu_zd*T9yLE@b;i)% zSMJxo9Cb@AQ8qNSMiUaNc=WoXxO1+05*1K3pE$2^vZ9ux1pT((Gf@|;9i+>4Rq0;$ z*+0QFEy#W7E9)Oo;ied{@T{2iS{r^S=6sNQm_M%v=So#rHP}*_d*5j5q4}yvlu%;Q z;m&%6_wHZ78o##ax3Ac|BSDYo9{KBh>ri|9=JJ{gyHEU5O4xk0Q~obL4t7|n&D^{^ zM#X5^3y^_@|Ge5d{p|hMmN7CsPm3OJaRk6yo3gu9>k4+&k!kW|#u?R9OvLq?hnjpk z7M?p__JwW~e4_~dm*Qr6RGy$u*m3%Oz@D(Y;+1OiaQT#uwq3!?l)2K65oLXBRaRsu zdE$M)BT+7Kv+-4%f;6phWQ$AUqxUB6$?5-r>vmzW9;0+rKgSLO+OR`=8h1Gpg~GHr z*3&N-ZGXqh;DV3qN!R=q{xPl6fUO@QvQJf(F); zXNBF}lgBQf%th6`c94MFBRQ+);u!tUSj|Nxaw|I?#GXgi?MzY7l#U*18(`OwFS94N z7LwNXt~VNWDOJLFfMwhy^R_ce#sB}&be2(ZG+oz@5rPMI2qd`6K=1?&&fxA0I=Dk1 zxI=K4!QEX01PJa9LvVNZuX8`&`wx22RXwYQUbRo{voBk)c@Ur<(<^I^_3-{HGN7Zi zEC#i-oStQ7wh^?pP5nR?#I3cGSGmcw5JX9(v>n}@m0T8gTlfW;n_?HDqLXj;{t9-U(*ej4DVqU$wXE*C>Y1cdR z?LzvV@zJ% zo*t%_UXQI2T6CVic3Rnhq@)MFF``+yl5z;ZO^LF773HSHoW3; zN7sJWpF`#r$5Xs}TZ~y9--YC8qblBU+WL4YAJ8bgZy0rigldPjwjjHFzG%y32zkp* zsZ?1IG)q~r-?Uom#Vv5oQ8@&;y-qUbe&x6PPNu~A4fHDYs;t`+uHk-%%g9B;+IkH8 z*%u3r^=TcRc|}%C#_YbH?0VsdK!!}NYj<_-{gf#gQNa>imvVZ$OtuNF#M@E0w%w!E z0Oh=6K1TDEq$fW>*I#f%Y&0J2uROoK5nAsVzIfQQli{CYC%0KXR3LgSz#%a%GqXX4 zBT_PSw=!^L-bo^qXx*6BitJPI`rs^A*F9O()T>*TX8Nc^qBqWG~< zcrZ0+0sp+i#s1Aov;(NNvcA4!& z^f=Td{42zs8j;aZ&}*=jvSwRHqEiJ5OM`2P6I%Qqdi)z|B}ZN@s~Bo0tQggg|6b|L96)ZLXz%bp|q~w3?@aW8<_rfOb@iod8gs1k@*B1}=W8tFEe$V}lXV9D&uQ7@7mg0T@(3?$SFUuVJ92 zu~3d)jI}%kXte|v14_4?xujAdk9HYFx+lHSQW3crXIe7vU49WzWRLTUT zpcezCnmUEV;;4ik0&P z5J6pxBilw@#6AqnU^b0n$$Mwx3p~rduDTo-z}Cv|ZpLQiY=MDcs>m(Al)Nj!v*@ zr`}4YOudTJ6UtuQg1+oPk(Hw1_Kx~2{8MaQA|6^)MD(K+fW~6ZNa8ZLwi;iWOQKfw z=-l1=j*Ro#+b(gN$`gkzzuzHG0r5NUo2UP*T-B}|=rPDmp!K|K59y^s`*1jGgKf|3 zvGfM5|H2$~2e#V-XGJJUT}+i0wGHEUAma&l= zH&aovLr7*vIIg$tk4Yz>WY|x727$1*K!1?k&uNGbFe8&w(d`f;G!91M(ASKdMP=({A3+>96w(N*M-?TO}s9rpgID-<4#R z0>#(reEIeB)W^@koj7FUx9YJWMzS*y*?h-RFmZzuX)pgyc&Iocghn>CRvgmXo{DiKmE{38DGl1%p%sW3t7b<1Ax@ zdQq!A*XN;?1s9X9yln=Gw1pdlT8tlKJvu81ud-NQ+>ttHvaX*?9>y$mDSs&MnAX&u zg=eep6q>RmE?J@~VWLN@n%N5xYl|eh3(85XHW=F=)A(Lxx^1wOpDVg33TCg?lOD() z97385l)gS%wk$CE9p&Aqhez$N9^(DlIueMH92k5dSrjy~lz^ery8K{P)j8bhO0BL~ z4nu0#Y~AiMdF)cLiUk>bAVFqg<~lmWqpa*Q`cC(Xwy*JE{RiGJW9_o!&9OGoz|fL- zk!vFMm>x1&AgrUF{;)|+D+{60EgC{aP)u8X?_;j3tqZ(^-Gft^^WbEIy$}P?Ja*j( zeZ}Ehb!#bK*+K=F?d)bef(v7{XGON~cgjFrJ?~A1e-oMNR-a`ZLoAL1qfY%t2h@-_W z<}ZKqI(yiCEp$_`?QOWRU04tmD-KbYlZQOD@W(%Es-@Cqgg}rFf=OXKAzFw2RS^~ohMwNh^Y1Uhb5&n{fl+d6{XXhXr@dm*q?BO#XkN3? zwOtC?pmoVzFuQF>R8wwW)%j*Z8=MP2`I%}jkq+S9WvZ3XT7G(=I@wiSy~3BGzIB+X zysxy?)g9i80UhjAK}}YOoTF&o>SX+y$cfAj3(Rzy+Emc)&Uhjqad*i9w78D*_RdpPqJTb}e-Z zj?`!Atfj8svRka<%`B9Lv-jYAjFhsAf9*C~EeG>dO`k8ZrDhrpMWQnDrHr{4)t%lo z`kk}LZct5`8-poaC7Ev&d1+ODqwk&lg$pN*xK8AHP7#OON3%=(tA=HeuFJdJnWbKq zVYRqei@7_BpBO)&xG!qu8$zFdWy|d{BY&)V!V3_s(YV!Zyq>_N_?ljrLV~JGp*8Cq zYKeVgbD|+^*(K_V6H{!os0-`a7hf~y@8C~&POPqpc@dpSTJDHl#mS=(OuyIg%dPfC znbY!6&iRw`&X#rj9?!*9NwbE)NuV9Q^=Nw~!dErd634!1j6-j+Q=-wy8X}Wa_S85o zG7k%R9YQNK`eadYFtXGimG+weaMOcrbD;2$QPpCQ{ZUtNlEywJA>(m1C1p%A z7Skn^So*R1)Jsw!3bBUVzlkki*5+b{hpL3pU0Bq1sHr)^VBs8SH*pmF-?Y2Nrd}ik!n-~D zPm(d2sI8QOg&<3`CpE!HB}#jIH8sDRV+SfReBK8w=skbrxxV&jr+@!z4oO!27gGWl zF9gzqOX_Ma!oFFEI-WH^=I+)%lfNt)7~T)f91lyA%-XMHqP0W-b0NXqphrzvMV*$@ie>T*2K9mu zV4!a%pG$Q{E`EhN9e8Mz^0%sR*%h`>S&yGkU5$%ZjJEHdht_RU@+nHQ8?CL9v93#4 z&t>1WBe$vxVuyrU7r4KfmW8wKXH}agO5?nLr%vO_*jY3U3}Kr-6=)b!2<8$kaoAU` z7^hse0`f&aFPB)x(@drjg`hcdG?d5Ajm-jr9>^q0I}D)mx43izl4yX#0El9VY9@X# z8aFBcR5+ibZ+=~ooNM;(=q=nbMze@mR+016S)>8ao1T-!N}T$qj57x_7#5Ui?nv&# zwOl@v-?Gs7`?W>NrGY{2@4FV)i#=z*JvS3*5?lUfzr76x&WlxNKln{5F8K?~utV*{ zS6OT?QV+vR8Ho+;!C$R^E?FmOpFlS7`j-Ry^J;tg2v9a?lWxYKA$2n5v$WB${rdIR zkIA~H#nwKkCSc;hLzk4YUeHI0`QMx3Xn}D?47&aKxQIk{eC-<2bhyo-3HuwIpQV_} zxlqZbZy{tX1)bo)I`%W>OO-Qq=Hf0a(Cg4Wi})xP?;z60I-J7N;N{$I--)or@^&fr zMm)pB@4eI-8)1Qet>YRF8_;3!I|H#8 zUCthf2Z;T4{?-MH(=t(l4{7wTo8P;GS%RBNxm2b7f_!B;F|FjUNAZdC_M_G+?{Dr6 z`VeQ=%Qjrc00TKLgf?B;IoKC^o-wz$v53zJb}5mWYDu9t$7~}rNu56k@8mZ z!MvQ6sK`H>C|4E5$Q~7q4K0U6j=av09XuQ4OZD`Piae6DnsobRB+sHh=-Bg$t60*2 zk4$0zgjF9w+r2$I0mphBaf)|tvuLgRN5G3L3++u*Z@1dVPU%35SuxJ=^BznZO=T3G zZ5>uWiguiR$#Dv}B;2sD@4oLGzhmmzy-M}7H&VT%zL&lrym_(9jym7;aCT>}^G@d> zH@#j2!;MBQtowhJ@MhUqukZ?aCzl46(d{5gKE}g`krStYExoXBGm6=waS`xTolMK; zqMwo3mo%17&AA^$Xj~fxklNFmF$6py*1Ed3L>iqzYsC>O_n?=T<7a_G-!8!DdFQ=~ zIGV98eFqao7%KDh61Utd?X9J27%YP46>gtLxY?h{5F$}kc0TD0F!sma!@N*CL+%fhvec2|D%`XcSl<{#ADf}xUTENrb z34Wzd*X2p-3X7UWAsCrgzPS4S+gJldvzyOCQDY0gsHe>TzbZIUmtSniy)`6Vp~-*# zC+XPzGUl;6`{AwjEz-d&QmIna@MoBev8pWqAO ze_;`3-so$0tj&x>Gk3W)%lVSEvP`_Tcf_;)YMTHghTVxa}39cpSE zeTuEwUenfjoSH=^9RMwgmh0r7GEZZAN~m6&*Sgh^BT`sPalefjFZGcq+*H%REHKu< zPRZgc@viU7iA+kqwR6}_R7u3ejt@to|7PiR)t4hEt~z@B(qUmj$H)g$IL{o~ha)}I z;A-0&2eb>6<2k^d2=r&*-( zLV>IKIxgZGBk1&K0es7jyCi1tX=bJC=a5Ywk7){hH34ro-)z3JSC{r)CLd|+QcN3N z2Ih$9%|`W!ilR)mU#o+V8&3=I8j*a*z-j2MkHyp_gDHlUc<7pn9F-F}(FEVMQesU@ zCp#_^fiHbz+Sm-7XVUIKAdOD#Grd3sxUESxp$5_FW8n>v*-PSpW%}d$$&km}iH{GN z&$}H@4=c}PS3hGy3rVnROk}WPv$Nmp3{#&>wR+x(HQr|##M3>IJALcW9n(ceM|Ocy zph6%RlvEsUvAnmPzWD70P|8!`>+65*{rj6b>ggj!nd`of!-qb6-<56$;ORpk zhPWKwX*!&IFW+z@yg)zEE+6D*deLh-f)P63s)U)|svJ1;g7YL2(Z@$_=L`!eT{+~f z3gtGjH#I)xhdhRMVeQ}-QlFXcTB%X=agsNQyMg^%pxu0!3_GFP@$?T^%Gy+c@#i1l zD$FZNf?}%jJ0CiWw}C{#`(*O8uM+Bk3eUdnB+B3(1Sq669-jJlJ?n9y0#^Ykh!SQw zZh<86PX|hVRR12j=H9@WBnG8)m8f+6UHA%>D(L;ccE;*5>TIz#3S$;V+2McPg*(7@e?j*E8Q>@@@oeYZ#hEo@+>0<8c6g{$rc zZKt$F^D3Hg#P&O}+&CX4A_50tb3a@06YzisviLU6VksjaqZ#ZLWGFJ=rEi@jzBUG1 z`Z+~ov(rFL1;WPM3_SS6&AHAXgM(M8VEt{`veq9Q@jFnYibA#^zsg6Z7ea<>(GAf1 z>Suot7HQ=HFR_Wsu4=i4yH*7&1)3^@xiO2{n;(XLH`FL2{9G2-=;haQ!n2O(-WJnrhhFZX^10?*hpG3`to44EQ zOkx%leRTO-U&jf*HDn>Q6G!Ec?Z{5n!mdbi9sjKOl12TVj_qRwD+EF6^ggDS_J3fvt4 zY~3ncTuRd4^{Pq2O}}z9#h#VeH5SzW7*~Qnma{7z?^bO1H(uSflTEpy zrQ>2siNEQ|nGtGgnV=G`^3h4S{e^>yia8*&Jns3cyX~}Obg-PaKTuK0X43PQ(c)P? zvh*A+Ro%WTFViPte|o`m-J}ZIPs5d`ljh_<%*nN!braEli1s%QeDJdHKg8`0+9x9F zy12)+nIW(=~>ixSk0$-q&RbFIPQ0aHAGG4v4|G?OuSAi5+ zWFKi_4N;PvR5$GN{@%RqvFYBrQH~2(SY_!1Yp*#n@({lfS0XeHA_8uZ?Q@ohL1REq z$EyUdHc=N?caZk2Jdd@cyh-k|#HFM*Jw!%`<=H_=DA0zTS*~wCG4G`Cue7yoeD|ENx$d7g?GXL`U z34uI2Z?aGicIV4q$=x1N?9PwiB7ZL6ZW<{9j))&_NR36 z3;2PH%Ir-u7vqG|uI2Tfj_*@XZQn7^h+yiNjojWPtuESKYVxN#Gsu_jSc^b5>Feon z0*i(?Gx*b$vX*aHAG*tyBsA#MwA+#${kM1CjUqmsC&x4NL;A(cAdX@(pL=t2eD3oY z#?&UyfEJwqyX5$X+s4Au#+{7_8qLOYa)Z?;N6DdAGw**AWPM*#(2Xf_wf_wuG;W;XFA6IaZo|XaqNLj-y%wJs_tv~ zS)-L0ARy2%Q0cdpPsw{V85e+H6{}ydVcb_Oh7sUStLw=k9k6O#Fk$9uKsjc%FUBQ7BBHj4LIQh&4JKA-rHWO#jxDV( zoYXZ#m-!Rt6ogKxP3>6)M7S0n`)17_Ofkqdsq&_DkJ4)!0C^dCMDY*v)W>;{)G~Ri)EVV?P9NlqfJI0070=LC) z;gSaldVWj4_#pI|Q<-wfOdujNa&$Fsa(J*W$|Opn7I2Fc&?RwJ`x0C#G6+4^xzW|S zRQ6o9V93ETWncXB~MMLXFo;PL%Zky=LHaQg*>lJ8h8?6JTrXHqO=x*;|ONX2Az!!n=K7|M_-u*_xj3 zi4`7k{Z#Sv=vo$mxe7a6oJbbd=jJ=xdd)GQ4B)OP!B9HZrjiOfoUzF9(r7e{KqQ`X zmsbFXOls=)T>Z9X&sv$kk%jZw-UA*FOD-j$qOz%IYH=?s{~m!sxyvl@E%v6Moh^hr zcFT-`iQSu!Tu^M_w8sa+&@+9uT%p^Si(DmM9=@WEILQ`TPIn1Owhr)Jp6zS5*ad7pCR-DLceSy7IW!Q+ zlU$eimp3G`OL=}c+cJN<9zC{ad_gipU3|Ho`gT^fZ#G(0W9u*F{Ex5tuiut)@BdvL z&kMI=v?6ogqsab6jq;$A%IHb~f*OBo4G>?60ellR7{8CaycfJv zilvukAEz4u!s9{);MH&kCNboI!Y2S%(9xeW=r^2|Am>HD{Io|iycukyUXZA5 zmHNxi%N{rTC7*z;?6MI1Zhq8(Ya=mAPR?3$E+bv?!Qh8Vme=01?WoDHXeBdrFMJ1D zw8*dsaVs%f1*>+;u)v|eJ9M9~`$moCO>r}*lP7%Z^X9Txr?(^^X<-!m{ENY>XJX$Y zG;bF+*VnhcyE2VBuxg-UBC9`UEdM@wIf=eY3U0JYB67@?-uDX?a+U` zTMUi)NHbsZmxAT-%r}OgxaaMAZ5!#uW`%2wC9w4?5$(A8d{Y}X%$UB_o#(ipN~*5- zd_Ded0+OE$HB&E7J0mfdl$~AU9}L;-mF9@yens<#9Y!<8WhM6C>|u_e?E2Au$I*sY zR!6aa%SqkaF%tOCeve=*{fR`==19J}3`$VA0*|2CS0qe#7w%o;<;sn>-uQB6HKESzdHjRqX(@XF1NUiQ%8BzVV zdF@=a{Km36&=N7wuzNRBe}M}t$jp5-eK(eiggDI-q)W>URFy$Y`LckF`3yMaKU3FP z#-n|;3O3jY$P+CY7dCQbI{`#ltqt^TFQ$y+o3PCLeIj-r<7zcHtv5-#C{=W*JD6uW zH1wyG(;p&E)Y)qr*>`WLK$!zneaV#E}iCKD!vjf_ML7O<0;$}rNm5*-()#t}-wQZLzV|W1SMHFdJY=qf6=EnV4#W#~xqizAc65TcwfzW)MPSiTA!JXI4Z;nBdq&A?Gof{@m zz^OpET?~}>aVR_tWE&ot6p>RrQN|_nzID9d1e^(!T*Zo?a-4y%VctSW25V z^{9Y}=sXPQX7})3Kb?JIe{&Qs%m*wLar5fZ&MK{lWf~rl1BrFKe6vvg^&mFn) zW=LnmyK~}dpw0+P3iClJEaL}^zcqP#w%%9&FC=GsTlfpd5HU8YTd%|}V%$zNQ||uN z$ceD&N6Y(GCBa0`%TU!h-;{5O>u#;yiKc;xFB%&a{*(ja#l`BY?80>5^-w_=(%tgu zZJO-^;O>_U*hrB*iZ=<8LD?vD_y!~x7oQcUApmqM=tIp)h-VMVFoG?Pv?%dgJ-f)( z7m@a%Q-PgMcK5SXwm8bU+^E(vC72TZVvz2?&9h57i}P~8 zp@rFBipyc6PxM$6?(!&1?oO(0l|6Y%8qh!gIxE;32AFuQ&3X{Viz8L>c~h1@p$w+Q z;u;0T$Z|(pap+AiGgm9M)n?C2Qr%yepAH!OeBBRoR1_=YVdT(g%QcxeR?SYV9kURb zDJN5BwT7rEQ#&|e#%+kj7dkzf{*KU|9y#`<`G^wS+G~sbZViSrl`k#SfkN1mD9?)` zL({2%QhsJ)o%rPcjIOuq51D8V^$`IVEDKHO(I51R8Dzp&z6%{lR)wgJW|vH#fAE#} z1P5`FV;e%8wW&9z<(}`^Bk52*vcLG7$S*|o_#O+_-@#7a zPnzI>^;nBr2g^$c8EB%bpYEEAfJfS$j1BS1#PxTJ*4E+Wj~is`<&UnzP>1i*1SN8Y zzRK3X8f%E5;O%h{?0Sul#Q6c*LYd>wn(FN;j+tGI!!760|0Lc>=^Uf`gMO->O~6cc zj%$s5&CV&nmc2r@90&g@vtO`w7X0gy-+gf5=aBzL`2-eNBg?r|LqkSWH?dBl&ri@T z;qab2pk{l&_gTxeAo0fv8Vgkv!uXAr`XfNQnq6V`>DbBofM)6k#z7rCI3QcD-bI?c zHj3sC6>hLK@O~>sOF~R3j}cEpM*G+aqpa0Z@y|%>bHbsF;-^a;^VXj8iW#d3`J?L7 zg3PJxU%qaaIkt9*b@~4f*2|TsUdGHE$K{|$XB+Ybt8R6jdYNjGMXn|KYUET*SQVnC z@9^AR?RReNRe4(~^Ew4b*9Wv?7Q3B7w%E)3N8_a1;$vfiSgghjG%XhAmwQ4Xl2GQ#-Q@7~{j zcT|>Qlo1P7z~-GSVk&RGveO&Ko0Sl|DPmu-mEWAP?DnM`ciO`nx}2>H*PH1P6URqS zIjffAWu~Q2a~o&~9^CxXM$bxpmVvFI#Sq_WEw1FwgPJawv&yT-oNXklpNnsF{_C3t zo6*>;E_$oH@tg1IY`8GY`qmS98WlpK^+8y_8?am3^?bNEJ2`80tmP)VI2@LMzSW^N z5cV_Y=|~0VQ}$?y5jTzzuhcyCu%&nMgG z!6$pG4N?6|p_U^8^32|-zLs6Xe1A0ztF8S$zeHgKmU@(*B?}0xD>oJ+`DgWNohj$H zDY^9BT(4rd!6u`9&xFsc4$JTurdGyDugQ|FRNah*5RESq0=*4+ef$;E=VeHn5sr$H z1}Lxk&1*g$a+_ef!9UYD5pdD{gr?wxyR5f8BOW}_zF6Q|P$ zSJ-z`f00B@P3fWvBqzq&qY@K-vj)Id7x@MrGc$vq#0cy8f427L9k04RBQD*4O(GWQ zS*l9S-E1|?&*5KRj4{<@!*qj%ww_bR@`rRgBUQ`(<6fEfe8c57O@IHAgqZqUX9J4$ z4arh)C|#rg?#4g#)#o12dbE=sS-GsB`7d1*#Xmq;Bcv-{?{XnmzuOvBam=}M9bUOG zGi0l5B@BfIwivou#8P?8<$pzPn>OIGNpahfJ+-7<=s}u`}b1&JTt{k!C3NMiaXaK5pRjwU8M{etI zLrR-f`+h%;11Lq_@`*y~&2LuVH85GZ9S{cq2$=U;AwemUk-|_FiEx0Gm4=yoCYr&^ z^YOr&V)3HGH8FZi##~9$my3;(XMhunn7Uz{rwVrIkXHFJFc+%hOw?&SmGiBzG#XD* zdkRuJKPZQd+8f%!AshZJl09MyNTXA>F;yNWkw_O`Y~JLY2;)#=RQ>mv?Pl^sSEG)camhC%o~j6RdlGL!lO*v((EZTKH_~s&rZG*? z>SWilc`YaR*3tucIjJ`{2h|me4Qf#4^XGe7s#0&>R|zLzbG81o(7H|&XFJL+FxT)n z3_*1RXV;lKoXYu?!Q&|GqY*Q4tmbxw%l90|2YxB~o0U9ZsRuy}E#b(5wuA1@G zoBQ#l+~UjFCm=QQpKK_ue|f3Sm5ZcyfZzB#K(qUg96h%T@yg)w_Pq7l zvHw`VU>3%_6j|V;Mh+N7ll$K&cS~97XCKNUL1S{-&AQyQWZ{;}7Oj9qXAwi@kE#>H z&JL4KCNWMF)%t01a&Q)x8G*Y&5p0@Mlp9LqT2aeZ;a)<_RNIyR^`eX2PDKPQ;S1wD zi@Ew_aqHXkQu8b?eP-s0qDEJ-Fbg7H9T+WFAw(Uy%8`Z9I`z9AQ5COFHZ64!L@)6x z<048}ipp#jm=kT;8XUKhJ*T=Jpy`M4_{(vlR4tZk>@N8;U~WRKBVws_rDk?F&{*EP z7ruwA0S(l)`Gmkq!FTb*I7YPMH(*E{r`8R$DIqWw5RN7T_AF_qW62p2Cz$%*pVair zl=TD7q`!c<$$}dV47HtQfSSQkQR)JLkCv?37r3J%<9j_w82w#QcHoPtA=dJd0%}+k zjGjyshQJmgr$(Ev^Z4lwC3Yv56E)18YbMzB0-YM>9)SyDKoLvS#{ycXLl{~u#8Jco zS^ou_asj$dwBRF}2Q+5#4T_jJF~iE%aDhO5FoQC^?s8T%OTSzqLjt&_i0o zi|y&EODUEB&|$F@UG)Wp91b4N7AkX(Je>8E2tax5)~6_1@uvU-s~}&3>6kx7i{})L zl_dmUcVTJP-Cp5nj$?)Bs!xCb;V1lEIkZnPn-I8dAzunMPY5Pvc-LG~UaB$(DFP8?k=fJUk;v#t?SFx!^0*a1mO zaup9N?o3IAUUyBj5(4lfDt80I>B0>e*fc%eJVRb43U0UPFRe+AIOVU7|#aQ-svXbs$i=BX-cWCcuB>~ zODe^kDh{GRD_px^!E1i`NespT+(JY5`z<^a`7(s7t>Z&VppOGq>g-SKY z3L@F)rAFZGVb_4auT{x1SaHfyb$iH8Kr-BsWtIAa0h2%H*(b%FWU2hvFGv{QfZ2uF z(s4o!TjOb>h5MA*0bEvSNMWq981~D6gyN}w#c3ltWlRhv(vbMs^m;qM5BMRSEQ+CaH9OHGu>x z=NR9N5@QnpR=G2dm+qiEs`obo-oq5!?=T7mCwAjYZK=BANMR9Gd*XPy{Pchn z;TBc<>{&+8p*XgQ6itn4)TVNYCO4;Lo*blXq`H%f7+Bf#Ax(h1ep*#J-T~={dQ-wNvyo3liEuStOLxbv0e`%|%wN%*&q^__~0J=UlhbwUmcY*T4 zVyP9Ttp4EXH zU)5QF63oy`?vlFS7OV2{)CQ_(U-?$otH6jgyXob=S2iM=s}KduRECxa?)r1c0V{He zG`l!NlNJIo2{R)uY1{=#nzW3Ie(!>^F!pHSHp8H$Yd`{XzG^cH)F__7JrBo7GXn3f zm%g(hMX}Thlw!tE;t%|zG6!skbbjI`SVoi<$X`G%lx>d=bf0gfdy0 zpP1eE^|i3HSo*91T^`AV>E_OEvp3(rNWIF26gefwcV`J?JtN-e@kPm-*v1r{JudtE z*cNJwVsF~>M_rFnj4$0A@Mj4A;|e`t(WISb36Tk6kz)V}l|cqKnf{qWYiU$>FSh|P6OXiz zEoO@C!ztcd4rPMHSO*i?BsVR;iZ_oY?tPYSu!@ z$dCQ_Jnzv!&F%aVdR;L@KKFhEN#-*N+i5y;{jAlf>spIRWq*ulNvc(>73tQjO;%_b zvtxFGtp&{ZzPCDICg$RkLJ0nsHQ7mvdP7X=>Ck>Rue=E?o*8|`iX`m;$cDO~q&izu zO#QS~A5kg1w(+yyEj(bj7sry(oG)gxV@v&2Hq~>|af#67 zi1;;zw?I|y^NgBQDS`Hm>R)v)x+X*0c~p`TmONF|@~#0=t*?>Oi4zReh$EU2JgR!g zsxsED&RXMC_NDD{8f;Ct!@VRW9CdJP)^+hFLY@R0=tEkE8q@EA9FiM3#aJye6FvOJ z;5AL02-5U;-3red(PH3_sq&q)AKu6Z#<0~aOIk9U z-{b4UlH13PU36XnuDRD?MY2(LPZFs5MS{|}7{t}6#DNtnUA?dXk*xcd9C%~`&$RlZ zJW1PrlD5ZS(GtO`XG4nXV;?2@O=y1|S46vmRYuvD(j=0s`6MGuMEjnNgauWjNHLO9 z)!%HVcLCl2nb|H&O=iTH!=7>Ng{sU*XZ_tsRiGa)+Vw-pbG3li;3o3I>l5T;--uR~ z=;-T~!Jzx+?ZMrL-LuAJv?tTW^&po??~{j`!P~o|UH8V0)_cyhsP4zDGrRlGR%D|E z*FpEI{Ou$$PbO>Rf~b9~`|CX1^bVaPiX-zho+LP>%cxL}nV`W{*Cy+z77Bdk+T27* zM=tT8Ag&~D6z82Y+$!$VA6p?tpo6_OJoLM%xt7re*fcr+$ zq#$T~y`ud$i;aELJSX2|+>vxOFOs^LPZc9$wV3ziDeL=>yAqji9B#i1IlNXfZ~7{6 zT6x8huK~Zm>62l{hO~*Y2gexPs%`v)Gw;8I)zJK!kkl!m7e{B{k$z6Tf{a5b!?|R` zoRu{UU%Qxi&`S?2GxGEE!%cgBV{w$Q#&ct|kp~+4_fd3KPdLZN!;=ioUENEu;;&TX zt*vA1$8J(r-y5iy^A$@)wtk3he}}6QKgXo2(Ik~h95me3jWt5wShZ9uAS-rbISN!! z^s1U`EU$6w9u&7ncRvf^d5CSDY4v${ZGYBL!sUk<-MsgIkt6YeK zi_$^aefzHXa^ec(snWs4-F1jq=8$s&h4Q0zL74&=DR_BXCHkJ<&{1TSki357D9w?F zv?2&YzMw#wnhpbxD4Hv2TuI}|2c{2L3uyv}{I_AcwI=0C$vvVnxU>7uIP zRlkz#dyG(5c}x~wgwZzr-Y9nLXumzF6*w-~{1bJQSkn=}XX7lNxW7vgYpc7@LJ&Zk= zv|p*r?Pr-}NeP!fafv2<_!F9k!1LroKw_+w`Sy2XH?Kg`Mn@BsAIZ1QkPMY*J4u;| z_#S^hiYi@(vn}uR{az&)J3scC>=ma_Zywk{rwgoiIw?Y;B|NJL-U^`Az}JbW)d09MoQbSRw?a)g(qEHk0~HbUDez9W{AU(I}{jPr?aIYs2<+DLXDpLXD!&qv@ci2ukmvKNdFR! z?gug3&>(?v1EEhKOZ()zi^dh*pcS_)lOt!VM9HJ8v9Fjy4Y(qa@fxXeFXR%LGEC{I zofQYHtj6Zs`V%Xw%#6nBK74zz%Kt3t@Djt43v#y$?W2ChMNL0fscd+4EEg3z#8h-5 zAE$@zpWK#S6aSV_x-OdLZRTVLv%-z z7QbRX=78qeyttooI7w)OeDL#7rPOVPkqOxB5L3)KnvmLNyjml-?-pqVH^_o2wiW|4 zeoV$KG3J>*o4O#hV>G|N`HE}CTf3~dUAm=hPv!{um1GMs=E|>CX5^w zfvR>6AUl@6Zqk`n@EaVe@p=*dWx^vq1ohldawZ?QD-{*=QEGHNPnOq^dps7jgz^>t zQaCB_&eikUc0p(vBXKcmy)$+(F7mb4;)-!(Ev4|N-pQZ1Pj7!^FJN(h852W$A1QIR z`0l3S`7E=5#T%Z{aDCnVn2FwJ-~ne%M<_(fVbK^Ilr>;@XIgT?`L;pt_ijt!%dTUz zi!!un*NPY|shzG5Uq`xs$;OP;gXeu($ac7NFdi7;+M|oht2dp;Dfu4@GdmKOflTb7 zy_TU3m<@vn{AFSU+2QIFa&uva@E&B#>mK@95563wH~)DR=bYQ^Sbm#j(Lq&$`vp4? zi8RdhK~-4nQ{@h}yNbrtd(1|SMu%yM+yr1hQ{W8MP;6*jOkCSPx(`vr_KpkFXh^Lf4yD|Z-^bTIlxGa2%GMI zG#5P8ZWm}IaTYwN&R##W{fnTBOH#@ZaEM95^AC8Hy4u**LVlIpi3!8~HX%MQE=Fs; znML&|Ne(0rakor%cTb-FeF_ISo$C$j)-KQdesYsOnCJ3Lj}sT)xu9f$L6f&ykR@gP z0t4gQ(pO7J!qWBizX(CH|BtD&jB2Zmwl!YdU5mRr6ewO?iUcRPySqCScZ$0ODPAna z-QB&omtr^l&bfEof9#QrWDiJq*Lv1mbG9!5nR7jauJ$qIc5-0C!I88Leq+=lV@_|M z6fYV4jDu{w$2KW0R6O-EmW|%R$1B1Xg5_#I{yRbaFm>jm`!n9rjOvwl<7+|)TC925 zt`P=t<;*n|s1trTt8vFHIoX7{28QnBDwQ|NIxvzLt1$(JFubnKEwWO-i_|q=eoxp_ zDX&6#UGL`OrfMn+l*hES;i5?|m(F9jaUkiZA#%<)k1|lqyDvtdLa!`u?qk-#~6N6 z1Eq@LO)Rz@lf2SVTj+X~A>bv#^-f$YBWZBrNv6xU6ze>#`Ee8@Fg7NPmmk8cccJ00=)$@OH%d zC(=*Y6(0pCC>}ln6J2twZ?;2(n_^S4X$*>$fxr3&xD>P84_p-PYHE{HrD(}QRjddJ zQ8>+gb=L$$sm(7sr=wx#fIFqu^p+$aEW*cY6(Rntgcmf0yr)^aH8^8KcyQjByJG??;#*Wwc7MH8SuN~3US97q+6TeJB9&nWPnC{XRI!-{Zm25ng>!H=t8*i?alYo_R`r!A|Pf%ZsO{9Lc zo8q$_w=G8vUG4|-m<||ng*rYZ>TEGCm*tcNweMy+y@R?n6{b=wMo6dZTn^Db!@^=9 zhfBdzZ<;^$#RgH)Ym!!0ceo~1MNg)5>s`b1eb+R?=SZ+%pbkRU3}NGS?Wy^*cc!7p z{yL4zj-$pwO{RysLaAxgftp%p*LeOJUFGxQ;Lgd9b4r863Ku0Kw%Scgvy#wpsFK?WTqr+N z#ztciw>8kF^=!U9WFn1GOp9z;_=pZRZdoXQB*b7Y;3Fe|*srKUI|#1J^Rw^}e5x5% z5FXTn8p5uq*y%qd@#o$+4xC`o-j;x0${Gn*a~5E6-lo@xpRn~AoG*DLc<~~CG4j22 z%KvIMOiSBDEJ=%0vVIgAvkHW|XfHr}eZp!m`IOQ5NBy#;Vbv82I!!_XMQYz)y3;;qh(jMfzG6V!N{= zVK%|V?9;XlE;ww;!lF&~XqwqX4)SHTx}Azd5gjd*^It8~ktro}xGI=Xsldun9|Nbv z-X2~D_}(wF7ROjhel;Rv7sx3B@&%(gA%H>%L5nCcTBI>~dYJE+d zq;oN8QCZ2XM<^4MQy@LrK3kNOjr(%$0Q30Kw_0#+g;F)RntKi}g{;+N+QS?MI|}gv zNov)BbJY^sDIebc>F*G!gx*85WOc;=>NX$pDxY?!g<^ZeaeE6S8lnQ_0z!(@ z4n7gWO=P1d7i(_*rtL%s?E}63w2$NC-sQU)6d0bl1Pc7NS|aNqh(bf<*3zD8 zVs^c(#LWhCrciacetWmzkLG}ZGnv0=3v=?JBifDBjMl2n8Z*7S4fFZDMU( z1Dzy?1UF6xtOG`F@tz;UW9%aJgg&b&M0#^m@;QvYR;tov<_5RZPS7y6ShXVbZV(q# z=t)k~SpO!`gW|it_eS_?t*#+E_3RXg!0>x&y5c#dJSTVfc9f@xl@O}c7;06@JDxAx zaqfLYwm19b@e>M`ssK!_gZ{?!VX#gl%*uiViZOAhxEO~6WvllqHlZ;{2B8PickvP^ zM!37kp($nzqtZ3K4ojd!HP4O0bFhTObWn`DFf0|{J*9T?{rT{LZb{A;8pTs2sHpD4 zJzzB+1C4}S%NQ8l@5P#aZ9qC`Gy>jT^ zNv>x?W&Zwvu=A*ya^$=R&0zCsn#PfE!G_ADPi#PP{3to^13aJUNv{o<` z&>a4jpk3gbZ$j>-whw}iAjlHfKxtLqTxiD3a>kDla^F7-A>LZVA&&~gn9Y3^BN6zv zXq110iCBrrZcReHF#nl~%0M=P0rrRs9~9c8+ab>;k$99N32~Z1MX^PL{t1HP0r$&G z-gQVg8*_0`*NjF0Y!M;IKOFxv-YRC!x6l&E;t9HMQo4#%Xl{6% zY_tFXY=@Qk8D{;JCP1Ls#0>}4k~Qy2zQ+^& z9y*bo23pL0e+Vd|-h|vl)GtI|p&l*=cnvvZL2 z9D&2--cnVTTHPzQTIuM+pDs`w`t2ZF-Z+J-IDfuk+-j++w5jNORL@^^?(rg&I9C=z zF-Ewtf6^Q%>9YO|wNAmd6m_z{@i}}P0mE^Xp1(CBLFXt?VIP34?2Jh_?*Y}KKslyFIrGYlcylznX?AfR`r+{U4p7P&tjfLRNS{Y3y8%M;03)n@ z1;PM#DCKptFf+ZGXoK#k>OA7<>I8EcEtou`$Uou@h zRGVkt*_P%c@k?+nxPoxyZiQ@g>_O(d%QA;B{8O7^7X2p$>PfV;GI)cb6V{-xW797y?Lp*6_R|_>YkKw8Q1fS*w0MK+NFjT`C41JzSW`G>h3_u z37JqkTJDNP#L)|ufEC-T-ThnLzggM`$>LlWWy9qFa;R`ltr!0OPkTR-t&b8|AaZb7 z6ud9qo=eMDdEXlrCQgKKVE=hwd8akb$wAa4noDlwQ$S6$e?AeDi1uyKq%7DM%rtk!E)xI*0oHt?Je5J$o6fCJpeQDGrYvIQ5 zV;fR~W3OLDPh--X-fg0J-*RSzMd&3KReIWAlzuOEfCBp-R?E_UdW>Mj;yJu$1t!-P zucDIJk*wbODdim9{@5+d2!l5)?>dAbcy=RMy!M*tyFOdoqgzd0F|Kz2FM4+zR?yl? z$KM+yr9I~Gt~GoHsK(J^w-}<>x1xFc;gd$+YMLB-zcv@R*?PM>iXSO~7=cjJ`5`6O zLE&64jtS&(wiiu~En;$>29Cke_NI6+WB#lFCu~Pl2DTV_0Mo?_aTHbsKHr&P_@V*i*QArEz77I98E2v36to*U&Nzl4-C*_pvqzOT) z2PT@{^Lq0)XRUCMzIh-rNqX=)tN5+8{QTPI&t>hq{iX=nP`s z>oF8H+<|jG;O7lyUjf8ztJRV0Xu~d(Js&Vo)9BS!TRQJSeNajhzNLxZ&%i_tYckY7 zr7E)>tHEqZW0hq#s<(~@GY0Y@HE}Owt8_~|8SRxH!NCt9gTY*umBohCL$bQi9Uzm%o% z$f$M&j$vnQ>AJ1F`3j>Y^)oUUFb&b&SXHLc>5;H+MQGv93iKLRKq4BqoTBi^$p0Eb zPu3ZA9?y$$5(UKk-?RNBcqYpWTZjNnF3Vid%A9mzl&0L$XFjF@&{hvt*Q6`!%2^|`QQBKi_uWI^o=}!iC$xXsoW~}grHC+T24;-r&@e!At(IKcao8} z;JI9s`Xq5LYjv;k&%0M9SoGeP@)~`(Nlh>^eNl4iRXFGozjT#j0@5nTRm6kJajv~^ zF=7Q6Nsye`?!5-?UiC)y!&ba2_Hd!(a;Zk6@$xh_m{dOHA(7y(((ndn< zONFWQBwwVYA2%E)Tg0ageb>u6JA_tP2E^n2kd88E0j7-sS~W!W$tXFDFt1=ne(34j zirUmnXcVirpR_PJ!m;kSY9qVf^1pNHpE1qvDkI4>K>RodJ)twskAPKC@yuLVaeuu5)j`oX><5|eEp5_22pl$zW3u_p@W&L(moZe> zCUb_K&+lI+O#5&b71}e$^=h46J3lhUBd6PBKgN!B$$Q^kUuEJE1$6%WLr#>gQSoU2 zN*1BIt7s4-D`}-;Yx@?U%R7n989Q`g-7|rTIG!LPi20?8GJD$jGe~IOMYB~{9+Nio z(MKqrpNY(w0I_(X!;2Ql$B;((QGit|S+_n`3x}vV)VR#Tts!Xsw4+*Mo5%DjOhIGY z1b(GV?$_0o*XyD5!2Q}Drq098>*NJjhW|&4#Tt3+td_5Uk3;I}_0>U&L?)KyI3XNq zCA8ie3cH(_WlD}wheO4q*kw(ZZuFnS;z=Yk`Qj-zO+xgjEQEnQietzwEITp8k^-!a zS>H8!NG>8jJjwPL*!Pxq8}w~_5x_^vzV+Km-1C}&KNZ*sjy;EeWIuA}w$R^|GK zN`}^&z z)um`fGyz2e*(i&p?aeO4G$0=pd5sx-4E$Cv4iMW&sS$-*SsEeBw#f**g+bfZC~R2i z#u(d`Ng@0xw(ctCs*O{_D3_Z($n~^ko(&D9t4$%4^R#MiDP1wIh^sXcr3;`zWN1Jo zaBsy{i3umqGMwd|gW2e})3<>YXKk{%Sk0u`@p;4iI~y$Z{G{Y)3MsHAE)o}ow~4I~ zAvaS8iM37S%j^ei-pAH9#!$|C75MS_!196{BDlh*v?;#TtiIhz)WKurv?=ts>lcH@ zxN=^WKGZu!+mNU%m>D>;feK)s`M8+A7LHVmx0L&;TQq+1UN_Rp9yf*D?pFS(gj%r|19~aU7o5Tv8aLmW4NMTnaWv6HSsb(eIcq z#^zQBRml|}g`8H>tov1^!znN3jL-D`{-dv_Pfm|+WDl3*jw2p_{|pX)nda}QuYQh# zz}uQ^80w8=Dp!(^EYb+o^3_{!DgWqgu2W#2o>H*!8{D1KN}Fn)hiPT70zU>@WFAK6 z_;y7BG)og+U*G7w#JBBXMgd3y7V6OX#w%zFH6h~6f&D9?lM@w6^OGDT0qettS7=W8 zUf(MbJweNmRup-I9Tf;~@W*<=i3AOCYbud~gE6zy-BhP6p7c+xh>XZMH{u zmi}~&5NC$$WwNs{vfg|`QIk&bH)Q4~!s5r;w&-wH81Rb&3~tH6hv!T&ia<*d##4nH2eT;~Ti)iH52@a?ta z7-fgT;`DMRArSmb=%2u}Q{xU>46vRJmZP(1MN8IJ)Le(_!{-&ZI>clE&&$L zBJzuXq?Is!zs`Olgj3<3^Kn;1Bt(s+q6}y;%C7};`v+{(E?IZ!r{OEffCa@}K zwj}0zs{|s^%nPB-(FDFW@+rZv2ALvh%>UiKpXknVc<8avV*PUQKwntcS<|*Wl=q?L z57L6^?do?<{&?BTZ{=h6*M6&L8DkbN1g^WgXbWaeVp{8)%exP7TABG2c!OtNqMjlY zq7*HUSu>gJQV!`fWVgTUubstUnHSx37~tvoyaH+h?7U=Z8)rm;_@08GMmc)Me3%wx zl7vv^-c z?mXWx->WA2M!^@k7w{(=o()Ocqwd?+7MIv#faQpcb`~@zd-%Y)Cdq8Uk}M2%smoVUMd+XVwL6%)(N| zw1%2$%7~2{UamjKs;pEKQ=&67uMu{H@li^yVLPd14eG|&u*~0qE+#xYzRIuSiNYwN z_)mW5R)606zUJAW#f){orG1`wwO-(w1T7e!+(xEX`%ZZ-QaqXiRjyQ$^6D(#WTg1* zNp&t#hvd7hs}Bl2Iv2k7Z&usg4SkXe_RF`!o;FUk>_*FMb*KjJcl2pxyQb{V#;j%g zQ(LTK&O2V8Fy89Vw+hIbLQK}noGnxjMUw2*6{UC}`+rc3 zq^6;O&sImJ#mn=`e<{AR4%A}SSiH|`vJDGCrp@h%vZc%y)yBRLnha-rl(hNE>yEdR zjBML@;(hA3mdzT3fdZRUeMg1MapBNe(2zR5nvKeMwoLAh1?Eu$q+8cSHCBu=ddSX# zBbHdv_-h02tfPb3%Miz|X?9Z5+ij=s9Is~4mdr|=a6&9}cScf*Tt_EIBcF_Ik8b;F z=j6^!2R%5T$1^MAdA74@v*Uws%spgRce*)#Ctc zSCczzUAiZz%vp3seb3!VN5%hDbv>bfa+?bNyOnhY0M}Maho*MVAm?Q0l;n-Z3b1QA z6ljU8raN&Dm9wCURqZ>?A)wg0OeMx(fu1r-QBp|8THWvM5@T@4J`t;SNL1~Vq2Z6` zbnYnD%9jb8zhlyuauI7S#G8o&}eS0?=LAgtD>-f^@h)%q1e=i=2YvN$k}2 zBB1R2yiX?h3=YXBb=c`sx2%^Hg>Oj^BETJEJTnIQt&b|;wgE3EqjkvW*FV*$N1BiL zl9uGbdn_q72=O&QN*WGy$5ku8w?2IsA_rReP=R6$&?H*HP&|D}?tuX5d_`*8hP|u% zY!n0_D|I~-xW7VkE({ygJCnJJ%*GNN<3l&j1>x0K5MIs2(0|JgBB%gOGuot2hsjUa z4^>vkkpS`u^6|-GX{L-U$}Fd8T)A8b=>|n@P!ZvB z=CQ#{pplWD0jXatZ!N=%J>sj=VIL-aG;y%1D z!ruooNrJ>+7wpJ-r$9_+)uL?s>(fJh>*5`C(@si%c2?9u#1H=)1We*TRaz6jmRuy& z(D1!hO6v|5XzegH)Mj5Pt`84NM>23J`Cf*KSlSR^Z~Bg{F{&(nBNclvzCvwt=Y znuN|I7z2wlW9$$C4jha0_JmX+%sbi9|E?hK7p*mi30gNU(q8pi5UR0g1}z#l5~LSG zP(CwS*1e$A+5&H!q+-oS>w!lj@U3tB#eShP)9J1ZGN z$REQb^bv~$U4dim_iew4B#$@TotKY3k0Al-=W}aAxgsz+^P>$@EDJt$2*mZgY{5Qk zKwj#~p*=atLU6!@mdYk=c;ffRo~(xX^$DrPiimj=UMib~sHD4g%gaMPmkh<;O7GL# zG3G)I@0E^$eyNItg$>;{=rQ(N&`bs&{us{8{zNl>m4ETB0|AsMGa|6nDOCn)jBsZE zx;an=LaZ_W5$i8=$(?=vOj*a>^12rJ_^gShrPSjwBk`l2{Q4h?^ZcG8m|gs%`KVO)+3Q34RH zjM$*j{@a#IyCH931(8|}Xmft$udE^ZZ2p(`9k3H=x9E3Qa8ao2Eu)VA?vPsFuHwD@ z)!{MfSb*U~5hP_982(U}u;3_g9HE+inF_jMHGX<13s?|CM9Ht=TsLd?TPNMfcPGnR z=c6_-jDu-UnS~GFlmZ+x9v>Z@O^3)kBFIsMClmo`%SX`=`OAkIfV6w+2}3W%rPp*g z4qAj0Ke0TOiiTX2c#~|8B4Z!pH`W98pC_K#pW_`LyH+k9Ngg8~ulUIyd$&m@&DRB{r2t^oEB>VF=TKSU@jz8;3bk>$NM{yI-s<-#!Z@-eJ_>)P@q^Iq z5ekL&ALeR~7K06l^IbX*|5SDyINdGka>gvk5fB=D;?}hOA#Pg7!cuu{B|8}GQx_k8 zx21jKs%FU(=d*i+ot8y9rnvFdVzvR}i-k7yw)ibZS=787v&8&fwsQ@qyLSA^Wdr}W z@*(2z6B9F~kDSu#VH!LV0F&Pd*f?;7J6Srq-{Wl*6L`z`s%t!4mUGPsZrFgP=au$D z$fzIar5{!vXZ;3<>*M3^NwkdHpcvFRI%c2{Yo21_YKBB{E^|G+JoS`@4o?D7_o{92 zK{On$<)&0>i|m-DWQYUy5&RV2TaI2e_zyHMCVJeOd^_}2Fmw`Q##bFUl--g`Nn(k$ zxPy5qc^dKCbROO~ag=Y?vs;m1ih+WF9T^DGW-78goEy(z%SIMu=~``5@m2DDCVW2D zP2~8}jt9YKgv4P>!_8MRyt%!^b?X~{4{izeVmy3YbU?p;5%wP3WuO%X0#i#gq&^J* z@w6_iMHHNi5!j38nq<<`8M0D)r8N=}Yrrw2HRZIY^^vE-{GIfAF03!Whtw{V$Qh7e z1<1Mp6MkT{dN@W1=AU>?UXmdXXSVr=KtLTM=!FZCU!_+9$*(doIqF1u<4n;DTX3@8 zvb-x$GMO<4ERirpegN)dRP=(8$F34~VMWIH@$3KqqHE7)p`7)v^rvR0V@R==_(RM^ zu|M*X$S?prf$hJ9|I?Il6PF)J4SRjd-L}a|b2OyEkF4$bp)jdUy2g|2ou3}Z#2uZM zb>iJoHgS8Rdp#`--FxKd&twCjS#&Gg8_AY!VtK}tkipCQ6*F0LYc>I7UO*)|?WAJ9 z9K~OYi04mQx`pV%a@@NdD(CL0I#s_9hy~WbpLf*hu~K7N^){F3UUQL$^A?!f{%$mD zUn|3FCe!U5$Oa9w`z<;?i*=*QUOO&TKkvP&uCfS-&yV9ss3{3VB7Y)x>?F&YGm$oE zt)+3((y6YXQm3)E)3`g62fkVyh&?-Wa@-bVy022b3JhPjNAMQ-kLBp_FCk>)L6m zwx|0b)fXK_AfJv>O+7s6KEJFLSW00DX2Q3K~pXJ-u!b^nCb~Ja&kgUM|qd4?)?rs^ZY4FzLX%NHDa;6UnPF6Z@PA^hhhZlRoL~vJ;n7`b^C1n@d=Ot z+O29+hMf%rSK41ZY&i&^b|$%;Ih`tJd1km03vu#PpwRPcWxZa zquARP6?NNSiKr94(oYx|IjnO=nHRb(6;>Df4MK?ZL6C2KDWL;fFJTRHzHP>oQJqHE znsauEBui8b=ekD_=iD`C(Ghp>k#hE*kYgpE58rg1 zPae?ElmT+cf{3Ujof0`tJqLJqX0?n>tm%k<6y~zk+{mb63fW=|;BkIJWAh=2@#W&^ zBaWvep%~L|$&aj56e#bIL{cc3zQuWJuD<+3xJ!ptQy~Yo@a*WJ7!34tc5&i|r2FwL zG@0$5w1Z)Q)&%H$RdG($2wL-1J3JS}JQYWCfOk@1$F1$&xR4jHCCP$Rn;I;$%{)hN z@QpFp*>m+sV}ar1#tam$w0gW!@wYFYC{tBrizD8R?%lv|9gVQn!q{GyTd}yM0D9e| z?OvIUhu|e`16Cu*6q;rfBio^j#uUGFd}?)U@0F4n{6+lij3&>zf0kTxFgDU@3tnr* zbLYA1K2pB^+w}K@wcFONnN%~EfboG^3?>Ccr_K?m3Er% zRU(Cz$#)lUnLBQVZqLwCZZ?;fe9_ zLw@kJL!UNYYSIO@(s}gEQ_-1eR_bp?z(ncqgC_mGP5^kkdnqqoHxnLs52HM>s7VrG zN!%Z|4WZdt(b9=L{vGJPjRjlGpI6(&aZyjnR=!-eZRLoFA(Fe6uc?cEpIp18tY(_K zMd-xM8@4U#0-Q6f#t_`)^2g3#3)Pz?GsSZX={Rq}l<6{(Vm#UyxCu{fl#3nCPFjM# z6q~DI1^MD}3~0O0Tsi?C5LPj(&AgfVMNl)bMILiTQHVvsUv+8F=)dg({pYHP#BLx1(h2qz`~@cr4s7YRdwywrCOZ{44D2RKvAlo0TC`To7c%Uim} zBA3PWV~i+8F_16B-@VtSmmETrMW4HR%4Y4R{YGb;tkLa%LJ~>`X z*Jl}Xi`xy)Z|)A|yOE-tR{2~$S8@ZOm)6aRqm=YRijHKKAHU;0ZSr&7Kf2Kga28oB zsAw<&ReTYYY?@_Zdt06FAF)8e+Qzfh`=yA+a`5pEBYyrGI+DQ$R#Mpx;=++sr` z4MGxT<^no~lqzzwut>$!%;gx1Us*(InaQ7JPsUxOsN-_}Q*IHN7}qim*lc_$Gp2X5 z5E{W%B3!DK!5PCfg@ivXqM}seD)<6_`e0}Whu4l|otLOL>p^7$foUe%Rq8x5eQU)` zb~WlXknO%ch>(hDVAK!*gxz3bsZqD1PlGYD@m_<2yu_MZDb&t+H*1ahnY<=)oBLFA z{~*&qHpG1i(n)Zdb7|%ERwZc@W57yadB0K zgu;$v!kRwK1QF#oLKR(QF96a!TSd}xrvDBv1#q*3HwabYO1f3!P@V0LpU6wcP>R=j z;PD#U%-P293IF<4Hj(R*%#aSUFb&5;F8*23FIkVwWY;&YLmzAs%~8vQ2b$xuWX5Ai zAI9w5O+XRmaHaE^P@Ai{fYW1h)nZrm+u028>hbUBu}EG4X?$7m3j~yabdy|8-@jh{ zA@-XQaMaiepGX(1#$%G1J))z|Sz9*Xf}W_kN#4>|L}q4h*y6ODZupG#V*B)Bl3LNq zIkY*L%X__Y%ct$Ak$()+E7b&LOaz7mVc)n<5B>bs`?}*24`A6u(-^jM!CFL}Pc*Fr zpTvx$C9g0m<&p~1-||h4I7-!lIW6(_0i4c|O}A;tcAM3%$-w^L{t^PD@iiDYuo-C| zv#wgmG+i0cWS2e}7O2o7Lak=26HboyFay~Ca25$DUa86)-CTq`pK)+azF|4wKjl@{ zvkqoh@MItj4&L(eUFPk*JcoEm*h`+@KarIpgE%{yEN-Yx_JY_I$;C z61r-8U2wu!;5Q`=NSnv;055ODeKJ%h$#<2iXmSLmQ^Iwm^YGJ0j|bvpq#iwfJnG2O zT-pDk1Set=5n8ifiSc|7l8T4Q+~>Fak4jBk%R;tf($o9!GsE!c7`e{n?7k+sqq ztE*lvl=O-jYv(p@Veyh^n55@1^^7I$*nDH;KM-{1&B)m?jYde9>RX~^fdlSIRWyuE zYZ;Y>^sM%l0*51Gr?hJ>N(`P@n^B;qE=54NP%IBI<4s>(vmf_dhn2&s5%^k9bOW2e0(s$=B_n6PRsw~=+;+&G^Uiw4L-uul z>d(#(O-#=eh|+Qhm?{bS)%`#Z8bz_KInJG(I^y|l8$qv`%vHA_UViPyZ|ym-rqIj# zs4u3V3N0|(x_;&N>hzDFdS2ZA9mD2~KRsOe37`vaP)IT)f(9}}l|bCA z)AedeI~00TC)u2gV8H6tv-zFta1+7SN%ntw;38;K%U*jwHrF;C7%w~I*e;f?uMOw$ z+J0|X#3sNOmbO?^Y6Eyd0UDT$73}MzGg|S{6&PlYZ~N(1^~VeWJA!TtR>0sQUvCK^ zjtz${kibj_1!2@#ODyCcx{K8@#D`&63kM4Yed8#pKuy^g!n<4~*F>!)vC7P-@xqm= z1*Z)G>&^ZB9t)6^rw1qF{wkRj%udx?Ew*`DVq7<1XKJsf1`NKE!|8iBDV*&m%fD2jet@7L!{@AS57<=}C_qK84f6_Go4M#( ztW7kjEfEJZU7&lCrewka`f}Rhm9P_Db7yHIRT@y->^LTpw0T6kP0huwWJ0N2-oq5J zn6K5$HyTBO?$%bT@fnnPmc7UbCBOo3%IZ!#LwEEU%i+&4_nU7x=DN`)bH{?PkvB?m z{F?dkEpgh;*repX44@4cf|g&I=|WN@3jOC<3n`f~M-Y+#zk$LE*+xxC47Y^)#58cg zf>^83aT3fEz11oASADHgc+umgbN#3I^q23QwMMJ0RFuR{EV!|D!<||lx)~f6kDlY$ z$|+R_rO|_MwqFzi@B5VrsL3)(ooZ3Uq<`b4@^zmb_e#p7?@H)2!vVXbYO`GxD!%F!g)exv<|NaW@x=G@s}%Wl_$uH3|> zvyTm8T?Nfs)4px0TQnQ3O@wCX1u?g zv%g>PC&F-5vUHg_1Ec0u4P)voalC%xh`myEKVwQ?T=y)+y?KZWlM|a=tnj$nwj=iU z&Q40Z-Ng>n-GuO|dF5b$-Cac-J(V|}22ORL^x^*z-unxpzJuuJWInEAifm-?cnU$gTSMkE!VOpYGYW8AK8e6q|j?#3k@;xmJ4j0 zzO-rXkT|-JOcm^yRU!CeQZj)%mM+;N1tdvV?hklP&}*-;x}EQhmM-MuF&V;y2i;F4 zuqIJ9Y-f+`gqJsp%G?Khu&$uW+4~{m83psRV|KuhuY(%-LuTZP&9GqXI0#!;KZH251OaIW3RHfAKA<>~n86ch$&cUd zAsg~GBD1gr0x}Gx$VZp8Lc`6`%l#{O3d?57!zUi$FK1(izdH93*Sak07&$?JJ|O*- z$_yHX8Hde>7F7xNpF%!Oqhog|I17T_?VJ{vZ9fYb;*DSmZ^j}dJca`hbXkX&FASZI zQ}|v`pf;ICO!NAb*jdUTB~@OZeSHaZ7(tr^9;s&9sdcwHfHY`Q?Jn2_u$$~ns!NMVKs^o>u)hKSu46Pv$YGO3h-$z2ajBu&1$ zQVK_-DOd$4)X}oA@X=g`4|qeWNIo-2{(%B<1?xZI{(;cxIE$KMtKdW8GM@gI1>0oe zDu}^HI+ePoLi+G@M+B-Z7ShjL1s++4N!8$p`!BWHp0%#gA2hggV2x%cV;y&C`OffX zJ-R?1ZmSY?^4~c)NbwnB>Yf*3FoFsb?N2)}q0f3)=XFVFeBEpth1*$^Olyn(*o+VX z*Z0ZQS&~czOMb13;Y((__DhMA>1enbD>xL6+eGH3gv<>K@Gt6))@AD9&y)Y^Ye2U>IL4C@ zw>Jcbqy3alD)jXHMn;joUCE=sm75I{1P&?9I26fC`}Ey>WrK9o5$jXjHtXPQr~$b> zp~(zBv^l2b`O^xjedIekW;4#KgGJ9_&SG!bT?Qz?TzZSvMxhRAq)us{J+XbRdG%X` z|Hu-TSVIK^;KA1cf5T|m5}betvt#}SlfOEJX!4?H;6N907FSXZ%wlN7HjtB(*Ke)s zzFXgEwgud_$PGV1ZC;+SxfTR-+`3><8n7wIPpFC6M=R~a<5q(wBFoRc#Wu>2_y=1f zJ90MW4tz#Af6azq@m8bXeG4e5DfmT*HE4E8z%d<0I^XL!#thH@hRJkb2SPaX7k^i%a z{-BBq+ik|D1%m#O>lKlXuSaqT-*M1GeqCG_4U4?Fhmd%Z(|RSVl59gO^ry^hu=6Dm zNYmZSNxUwB@AGoDQpm#b-=J(qH*&btCt+ttke`Q2X7)tRP}pPqcBo7GfA99?I$(5D zH_|-A6WvE-ERz^!(xsU@Bz>Ei(-vI`R}?xM+iXU( z)dmdp1lsjT(oR{RaGB(yF*nu8oZs`6&0-SGmubv18mD;7%#>^tGp5_iQEKL*owmDY zH~ZQ_TscjhEeGoD1j>$U-yVJWQ4BA_nHnZKL5;CnnS1I@tzZY&ve^icj$z=V2T+ru zhx0?(3h8*s22$m5Fph^YftKeda!(btcvdl^1jz5F}bp zMTWmLF&JygGJ~RU=!?e!M2cG&3h4tfTJh;(n^qbE65pl#kQ9I{8|>DZSBD)`6Q+?4 za)lI`nosVKaGRh$#r)j-t+5!j;_Muy^|E~Py5I}S3u}~;vUeoY+;qzbI|m#!$$6Zj~+#+GQx z3OWMntjigUQA%awd5u|3_(Z^AAs9=^XR-nUAcN~-DMP>r6%)F z{Zo|c&pIGb4#+t(N@I7(s+Z+WkbcadF_;`dK;aGnntwHA^VVKQOT)iGqwv-RzLpoW z$#8Kf8LMJZ*E|Z`G0R-pC2sgz`~$|L*L6P*63{IU(vuZ06Xhe(PkA?`>f>*{aBPvg zoguDu7Pk(+oR!`MRqks4r-r8EJ>oi3#mYcr2 zF)r7?`Dg@>3Ex()mF#9P;tNOstdTc4!69GOS1z9Zxqi5OjnYi_6|_Tt!lOZ11}HE7 z{jrn>1)apzN%?PBW};s4BOgj!by1TDiiKoAZ*(wnE}*T){VRES$p6-H(auH>XGm1k z5{qV>H8|2a@=r*vmEIR_ij66BO?@q3OU!MRdgZ{lf90IGVT{qwTm!wEs_ZW9QtDT>+qe=ueX3<9J^TXB;f*Bl+@ob-grzw77ne|uazea^8Q`2*;G-5-0%)zpN` zJzh!i-!V&_##8HKY8;*u<7V2!n0jFSw?g_SSBRVHqXkysud3##V=E~TC{?L0=U>gH z^glJ5_#u3*Y%5c%vYEuM?WEkb{kt2dl{4j`(;e{K$w?zAOzTW@Hg_Hw3`xXCIUe=_ zC}ss|l6qmShU@0P4~s&Vy~J=y;yZDvcx`RAK^kY;0kj`x4?;3narrOGi>O2a_Dq`x zS-G&>H}HyBbSZZTrfO^~^l8Vpij%=Qq92NR(BfqKt^^Byd!r*xee(9Dz}Jj!;}6oX zIiK3^^`%C5j4Xp3G+@S!6W%P?y-%Hn#z?4R9PqEbaJC2$3#nXr$PprdH`rTRj+*q; z^AB|P+#D>yJm)t-{Xpv#$WkFnV5JT_3s_eT(&2e$JmMsbTCA0_sR6x;O|U`y0uIHc)j5N(Gon(9wbsvTrG(&jV!Bix6w+w(vO99)Jv{(zv>3#1vUX+8N!yiSBIk6 z39`i>hntt!@nSSAb2Mr%f*>1|_#`s5O^f5$bea&~yn(0_w+mo2sA|E=gwdoxud!L` z#KH^^OE@>t`Kyqq&Xw6eV;V%x+0x`0UD%2)*DB#b6_jB#U~1`LZ9PO{D?1cEsWrm& zfUg8JwYOdwHL7caisFE>E~i7m>Xj&qe|^yVBPigeMCq&2`8nZ70v^P_Dcjz#Q7Yje zF%2SjD1ta34VY=x^Dc7m$0Yt7WJ?69nYqhy(J3->)x@r5I`)j%nTIL-bDY{Rn~+zE zAZC@H@}8-b`Sp@F%t@o-u0Z zwb882&=4(17bv&YmJk`f2a2jgP(W7+Q|6K@t}71jUMAE3KU}?4R2*FwuA7kH9%x)b z2=49>Jh(RQ?he6%y9al7cXxt&(8k@}on7C5_P#lHHCD;$s?puG=A7?*A5e>bmBDP^ zw~(;EQRDp}a93wnETV#)TCe55z+RGnuSA2~^;TJ9p&#SSrD6ES6C#rNFV6|X&H4db zRTkuDC>y`K&Hq+ohnU5%rIDL4C77S}>!6rSLO-Ul#^p}xR0p?GU&)_alo@^hcGe7OzonxNrO^9oaR$QIcW^n98Xt$Vs z9ZrB%T@z%KyAP@Vu42Mrpq^T#Cdk}!S7*L^=ku7?hW3FLE8KIl=xsrkzP+s?$17c& z2Ow#V@1%EGnxy^&3x}~0&(H}-zJl`*c$jjiG{eMKUlBzdECH86z@kf*xTQ{ z+#N!@b`m;~pZ_v>Z>PquODh-Z?Yn|^2;RB7BA26>dB>sJOE~ujU8gG;Tw+v3QLbjV z|KBY#{9XqwXrty4W^OzhXCS(&={3|^F-#Lh0bYi} zfM%J)n1eUMfX@q=NU%N(%Is=K^MrKc)d;>1^RI%YM$UyR*bm!;P; zbfZX3Z~o1Xr0ca%so?-0BSEiS>HVj%b0MGho~s}0tTZz4IW7CsNBCE_KuO->wDuV$P*-tM}H&VpXoJXB_+ITE%g7n>D1#;m6h0JLWa7s6`?=0yWRCz7GgDD_p_Sl9dKyoZl%QFx7(R*RL& z$6^95OZT?)WQVCNO%7cIPshW%jZPYd8AU2?uZSzB7}kx}&!0nTYGRbMtGxL#lQ&yL z7q5U|We{^#dh2|*X1fN|#$_*^-WJ_=rnE=k0&#tFnawY8zyhf)PHQ(fI57}Q$7zFj z?e)0Ji!>mu*jl?DtoZFu4Inc$-a~S62Q!-|<@(3#Yl63NdsvC#Kqnf2nU^snE!i7N zlc+hMx=k z6?}REss7-#!5}mz+G__p z=IYjTho4jg^8zL^$Z>r1pXp;l$>6`K)K}GPcQTisYu$E|lY6g*M3FbHss=TkGPd!o zuA^>y+mXDly9uNRzrIHhmt3qqw-Jsb2MwLSH)0}{CrRUfT7EUdbjAHP>(mBzNs~d= z@0$;^is*Pr_*3?jO$Sf#BQ70~Uu;+Rbx}J!ba^(fOB)ZK2R(20yiV()H2uRl(_QSW zOds9^dGSJCBI(SueIs_`rsqtc;)>jTlY9o#PMmd!r0Tx&;_}&a)4z|f+Si>v$};_8 z*fc;0n_Qz^u8$TOV1b%99Vjow5`K6dPkMz$i*vc7-qwYiw=7(<>66w8NsE44m7vdn zZ`Jz_$(P2#0Rn~PGl|{7c5`YQmyd48Dzjti+bW+%YBSx&7hos%jh3Vq1NHl?KP#uP zLv<-@V92f>s{d4vodr*mep$)<0cxQ5S&`F$v_ILmGqq2VxGePSV4w^24p8WtI@ZVD z0@Jg9?m6gwbt5_K7k0Y+n}Hawo$wH+zluU8REwZR`yRFg8e6Zjx(}{;cj;&qSo3CJ zN0g0G&yzMu8O3e&lkLx{5>ffkk-JaBOnar5xQ2C4?0s;_s3*Eu*ws_@>eU~p4tts& zH#SgYwuNIDYBnzC8nYqLIDYqNiC;tnHnvsGM_QU?K9{Ai6!HTbr4b?8UT$f2dY$mM z7{1}~(W}S@O*?6WpP1X(jBKPb$jNg5VKk{s#aFl#gA`1nDq}N$%EsVi=sR_4IDL(s zB*H_VpfTaHsm?A@Tc8czm`*wW8uu6fv^m>;5L!m{c#Q;E-|B5h@~U2)=yyoSGW7w6 zb=gMztX&swCrTRy$J==(@%*ZFl?^>X)VbWY-gL$DQOfOEFL!6E&<%PPZzSEcVGWZ1pzo zmDPpldkYweiGObV!fResnn#GsdN!23UQa4)VD%R>tz&uU#4+!a?;kfAtLhccnF*xO znrS5~A{5==mB|s9oRU<|W*UE!6Vt-<>2T*v8%{!jlKtx4DxEM4J`eMeh|%fBZ$fIl zwM{3)cN^?aZKr438}I9fFV@$t+^ce$s+;RnIxAtfhmL~Nf37A)bfUyFp3=(0yl}8X zh+?+(P*W?U)~R)4iQ--I!L>h>*SEaTQg2Tv2Yy3Ah*!?Ht|dDinJ7h1#w!0=zZk{J zL4cAKoJm55HZ*>Q*cnO+{11$ty{0twLszuie&=S60F&0n!C|Kb)o!wVE%H--+9g!M z?LyR4!LBtrBKijv3`nl2W%Gi+NuhO$;`JIG{|9c`fBGQwZugi5ckredJNC)kwTRNk zpnig)*Y5Hmb^+}VeHl2cw#rBw)XW8X=K*tkd#22pSE0j;^cY z1d!A-`YcPa<1>^yhNaT7_9*(Y$ZH%PL186Qw71^2U-o-!SMBJ3+^!Hq9L1>g&{vzv61kjuJ=~F?hz5(aT zFq9vDC>dt`YazS@*tmQiKmz9hv*vbG(*mWspaYHDR?+FP3Z1Dvcev`!7L|5l9MvgG zd;?R*il>!aPTEV0Zz?;;R$7%{ik6;``a;08e>X_6BgnFL!rU*gKj>dawN=}6ucEMX zEM7XJxu!l~6#qnE#R+)5|F?NU?XksWWo}gl`XGfa;~}G%4ag^+gDqG0r-Wh8gJ?>s zQKs9mLADLQdI~o*esN!+i7cw%eNOYTq+3Xl5165hlq~t+;cHm|NDT<*@#mx!%N6R+ z0*$kQygp@XoY#Z%RAG{LmY#~UDUOVH^VCO~BZs6bW4K69F8-s5)`W?nShy~=Zkp}t4kW$ z8>n~pel&6spf0ql7HDALDQ7aNFe%mK0ecjUnG06<`PaOcPlE54i=L0k;^djwu6uIK z#Z;$Z<9)1a8_)@f@wmAwYH5I`9;D!gaPwSkl!eXBNFuz}57H>p>cLG?AG@gsSP#{X zvsj45iEp0!cJb_ATkwmAPKt|2%w)8+5#!2sOk@2#?lltLTd%>WefAGet`o@NaJ{{XOODbX zyY)9YX>%>_1%r#Oq^Q3hF(NPO;}ySv#b3eN^8Ff7t3{hKt3}>uSo|r=EyE6v&0MVl z$J|dYrW}>_Ow6>bLlq%^dYS&cx|h4NZ?wp`kt2*1GT|%#YBbOq>77^U_8Y;svCSxx z8bo2##pq|hR$aA%(wwWI8W*FSE;0yQDk3}CU*>(br9tp3KT3+_=2K>PWN34nJ0aaelr2{aWDxVi#emRzm2%hYxSg@yew^E9jV zZ?q_J5nn6MqWMBZ;%0d_PSa&-!=WR-Up;rUt5r1_+eOn6^3{U>Ct{4(_}kw<v4o;_H2%=tQ(rKHN3rp56)>!M^^D=G#z5p?@0}8MI6uNKC=&w!w^bw zpp=oRiiBo=qMAkGPP7&ES{{#rMf$8`Z~_^~k4Hu1TodWmCb(oYPaqon&`0EhT)m(2 zyG+~lwj50x%P#<6reCxRMkSi_N^c%{gl@GCsJzabyx)1hFrN#8^n5RagS zMFs!Xx=x~*{l5kEIV4;t?LQ4&^1|HaC7HcqcxBVC=%<7Z7Ve_gjL6j@#_+k z%_;nml>r7bPq^KMszn0A&rbO6lLKa6<5iKJoqZ^WU&rvGS^3yi$E#~hFkjoCrP!SR zc5s(&wm$Nvqn>ve_lIB*rMnb4rv*L4`UGa3th1@5YKre(-@USRaa5xILAJ0^whusZ zafTh{W*Y!Eshp8T+9M-tr>b3rueqvK^T%gAL9@IPByMV|Yke)2iI*5ZErQ!<)_YVl zqFMh&zpd^es<%_YW2&M*fccRCyPU7!DQI3tj3t-iVc1t!9KAHl=L_uz9&~a&M(2JVN&9X!EG@J(7OS9r}EoZb)_!Mi9xpQ*1- z+C29UUSGV~31|=RTttCL>qaq}EIw7>>I0S$tQL$*nJQ5A4_!r=1%buO}xzNbq z?~Yn%!=VD>3M%RuL-k_^9FoTrPvbJmHx{Th1Xr(aVNg}_vD%+QXDViTUA_zq^E6Z} zuu=1$k7jp>NG-@Zi#7QiI2g1jA5~0RhcnLKE-rX>{u7EDk+(QdJL!Bfv-rYu7V*Jd z8*lt_DVve;Fyr8JkbRAaYV2#M9*0n!D)u(z(PoO!A=A2I-G-;YiSc`Y2S`EUsGf_VrbMrd3e>*rys)t3N z_6MyXK>aBHl@8*7U}%XzdaIsK@>DzGI-o>b3Fr^-h|scJI~a-Sqi%T zQ1KG$6P->{EQRc4F@Ikqb@vn~E-iZrHrpU-+XPE~c5DlIpOciA_KP&PYRq&T%gQ~0vK6h7TqF$@JPdWIv%e;CdM$FOip{-I%b`al%+U|ZU5|2-hhE*PR0)Cl=7h;BC5 z(Ti+Nj}su%=nS3QtyfE&TmV_^OX~g(W4VLiK+vgE*CSmQt)S1iia7QKi(u&F4+j%uBT8f=gnj3GpWcDrpp0_fr`0M|)`{3n*JE|hw}$_wP7 zO;#bql8g;PM)_#@kN2!v59j6X+3ccimSat#|Q$Xf?9GN>0EmJL`)|KY6 zP~Q!xl@*?SpV~K@^XDpp5W^#LGe62yvl`t?>HIRPqG42L!{Q05SIdH!#PWZgfk)hV6k#)Vl~ ztT=xPA+A90s<8kgS5c2rl_r~g%HR92h zvj+fz!97Aanwsi)v|4Pe5Mc5AKlx2ES~*acHgzU-5@)o;Hy1t$wGqj(#5~kIWKa9g zyAtT(ZCH9YY;q+1FaDrjlN>bkb|5uppoW+f(>7vq)B@D2K7?={i{|RFn08XtJYKV! zqNYE&s=XiP4|019q-;oy8OkqC^+iXj7v-0K&e0gFtpZAIB*@{L$eIQ$>oBgG;gHQe zMeK!(o|^H`8Fbn){9Gs`MCAVt_@cjDAWX}KdD>s_*_IWxW~N@DTy<@#_CFaBKru>9 zg=-qRTBKc~oMy1ZnXzgIrU1T93GIJ4|L#qSIk)~$2uM}YAoAeFFYwT}C)WVll5L7* zu_?pgrh$-jQN9p+zH9-CEibSj=*Y!4H^ib*X<%5fz zEb5sW<+%Yq0!y1J0MzVm(QKN=T5aaPrsmZ{DABeG2Nob8b!tMyJjL1-Lk0A#VpfvI)*0xqyS5|?HgpARGob4FpAl&( z@+r_DJ^fz{tI_8)Vu|DZ!(2J*Wa`r*-aH}=drf7pP=P-8E*la$a4>ZwyKLvUro4w0 zDB2{DK#W+|(x^(pqS+>aMl?>xlADaLd_6~|Og&8KFAzVc12`&N17Oe(EW|<^Phyg0 zeahDu5&lSh=Xf*IFaY#Uk3dxNLYe#j>8MpvH_}v3!7XUaBU+~N0J!JEMOo&4^iu1x zNaRziiq&FS`v8drGZ{e|O-r6bOmUGiNsZvBhWXO}4||nj;LJd~S{gN5xpO%-xULnu-o2qRTIdqM zP*Hyp!B9PJq>|@t+^Pthm>QkqhFC^f%#{8_)7Gd^0{%M^HsT*}udst8yQ7u}7j{gh@#b3jzw{eYt(E$rMJf7O_jxY;6Z0y%_?BogU}<&^FYvjcuDV8$XrqLUqkx^B&n~7D|;5hp=KPZ zUuwWr5~Zngv)Rz4dH=Uh-ylUt?eu7F>cgDEvZaK5C2pc9ZPPfJD4K-^2%IZeYM4<= zm7Bp(AndO^sK!7GK|ur~Yd%mq1fq48@#D*$U=)ry>ioATMC9?KUH$C4Z_PDF2LA=o)CYl5}q3d z?$xMi5rauYrkv-%t(BdS*j#wkiZGk0xH;!5qgyrRN*PR09j1)BHieSPraD)x^Qj5jR(@d#MS-!Bor~e8b#rKIE0KwSjwDA}86L$4n>?svr(rRoLqDCpt?bhI4t}5!z7Ka8Mwo?4#a34a#{Kt)skC|A`EMVHJU9u3J`+V@t681j zou9){1BQLmf&JX0JCsgH0PD&SAaDatzs)PE{RxUY>ufABLF8c;lnVTHZ>werItrR&hUN9R91>-BbJ$)=*rl2V8qc)4}*GS z%H#+LJu-~(VVVkTjDX43Xo1OQfXUh+r(qm!Jeh1H;+G}>S1ScTX>E;{BFAAjk?W9) z-_CanxbDu#$&qg(%pz!qVf9w72{rpk_diJ~$K<@#y7bk7k5xu6DgrW`0YYjaBsuT1 z<8p%D$f(R3Wr0uP--#OJI2Ka8ahG~Jm)pkvGF3*IfW(RcOtwS}!r>j7+EhVd^xa09 zTvmm`xl0`6hzuosa*ldjt}x0X4rv>8fXAgiVU@hnKq`*Dcak`)4Giep00^#|l!zf~ zV~d&iL`=GEvR19h4#9AL&~Sp47=4TudxgeN&`-Au z4+(2?-*__evt9B9>^z@_I@tBfpt`^P3Dm8AS|pDyZ0R1>Tt5!G};SK^R z&<_4P06okv>G>O7jOO=W_~c3Tz?}veI`!?8LXz=k?X2qXCgisWEJdU6qO4W=aK&(} z#emIFd>s3w-#usD;qxs;(zFfX=Q+ zkFSl3pu>`1Jgw5=*45_e`q1U&!Ts*;wziJCY5F|#KZw<>Y0~xW>ger*o!kAf9X~Q^ z+vwoyb+re-K!*T7(*EUb4ALaV`;9&)a#q%4fqlwTvR5SHWSb-*sgJ!N^q_ItM**Fv zqETn>R^pL|-tdp=TG_0AUx`ZV!HpaEI4+wUY~Yn}$4$#0@J%D^?Fwqm2+`2LylS=h z&t%^wTTzNeXWTdde9uoYYy}V%Qn*HR8awg8;H$BB2Nr5qZ0SSC%1>Xb;ysne7~QOi zd*b!e%uEJ-%>O`E6YgE!u9O}VM~5rrqmi=#ZDISFSZw&Vxey|OvtMl&0>7S*U&RH2 zVFiMTU8K{hiv+w|crsBUP6yt{7`%3t1-OtFUN1M7iEDXK@8$OU&M=m>JGCnNw$CtF7GKdLf#$R3X#Uh>Hb2gd=@ml*1~1Vw1l= zpP0)13Or}-uTI%q=MxWOt9l3}fApl$c@n>C!I4WplD49M?2(76ypptSIy!v3CJ~^a zVCZSs4w94|62R(EuXe^fq4K}q)}wGP5Z0!0Kaw1ICE(@f7r+es`xxV?y3~tKR(t3B zhse+`SJ4TS(37Qq|8k>6Mn%Z|(J%nirimqbW`$~{a{+$x=0-px(|d?*h_Xp`u| zKb9z=_F@BkqYad9Zm=%xs#1@`!r;S~WNlV8{su+YU*xxAeh^bQu3%1E_t?1Rslr`* z%y4oTQpl?gjBJ1dqqB`(B6gJ-S8kZA#e0>}9$-|{n=K0jmhZpLY+q*~l8l!V!e7TS z?yLV5@sB8mQhl8MM7mAQ$bZ(g;`Vsu)Ji1K&f5|HyES!+@|MgPi&D-nmndH5W&?;a ziGnUp-xivSI^QfJue|R(?m92Zkc*}$D~4+qMPmtfA=LQK9C$_`iW0T{uX%g1?lb=7 zhCEtH{h2xy^3oL!P2PEeF4IJRwSc|Vu`V=G`@s%6rbMK{yINw1HL)<5+F zym^8VTdvREb{&4Z(;BdPZNFv;VZuM?m*BxFkpxGXpJA;WeLinUJAen0NF8AGY)tMd$^ z2pRn=RmvPxDqW#!?9HXK{`knZhR#UW+kaFa1-yxhNEPEGsN?b}M^(6PDSigd(7-C8 zVUZ%F-V2h?VGG|Dq!u$2^;&g!^S%i59eO{%XP*U}l*~zoTrRWR5DOoFXQgJE6AA4A zuvSmE^Ht|MaXnC;;_E!5q7bN)cmc}E^{Nowi+m(Q%0A^d{JEt4zBlfd$OVnNv&>cO z*se3Eamyfr0`;_k4?4+oCTt*#d&LohlNJ*e^~7GpSpv2+6YWvI^o9JeghIBY3;9~} zH91=kc5EK(76f)>NsX6P;N9j*>74lUiSO?i@yGlUIA-bwFdd@CsQF*O1d<@(TukO<=E(cs> zv6D*d|0=2)j0p;I&VG$@^`>k+XNN*Tl|clNkBMVD&MYDB*Sd^U4Fm8Jo@60 z^QAGKgE*QlR?2XMUu|=t9?X?!b%ud>sY(#xL_wE(tcxSWomgcT!E9i*v6WIl(!Qk_1W}8dObH)bhQDQLs?vyaQ2kN%mQx^?Ew2`hm-*G zi(z5&;_R{UpKR6|4z77`!oY+2lib0}&6O4=-u(y)=kaBqqLDmfrNyxPg9Jh5FE81L zuIzW~0ZR$2sGGsjiQuE*cXNG6i>KQS&Eli0E)K!4=%wLw!9jL$eXh9E4raz9!%5K0 z+nGKmrkFUDdOB{51T?jRuf`+KZ{;|~^;H2r{?7EMw@KG4eUCSX)-LY{?!e4KEp$W% zy1t1UYwlB`;K8Enq~7L~1M@}}wmO8{GO#9MI(R1DgRn7SW}@amMo2JUI^O2Xx*jL?jCzq2k3L-mETz=x`B$m;r`mh` zVeja))3&6UhnbQsA@5ToP0TNQ4UhLRlqs4bO=y_P#bxeF@vB?`&h|@=E!$0z+XqF# zx&*`m=Vy2KT_~b-DZ<{Bz|8x#v&uIJ!&VqIN6v!pJw}!zz!YFHKCp zL?7R@cQj6vamo(|6bM-#{w=iYFDs30PhagF6RkPeDg0MQ#L>z)*SIGv8oJM(kQ;wA z_n3N#rxkBh<_>P(Jb)1oIGEC6Yo}~ndD7@U9yRBD(D(F2s3+ddppgvo6wp*T#CECc~V9CB?~*aG_fxNIFIRKDxU!Hby>Qo#Aj zhCvns_rHTY7rFcz4hhgZdsj0L*OSlwkP)MZr3#MxPJsx+Ri$Q#zsQNIurwXdpEU^p+j`YAvLH^_Y;i_Uzu zi?P@}i)wxfbB+m0UUQjr4zVHa;vmHBLNvMePYe!6F3dSbD(jTY*ep*)||8bM%LGoes<9Ln<_9l zT{M}OMxc1c0JfhX?{!29?D~^!QnQS=pft`D`GmM<=_ZWZB(0Ea_cfAdVz@(Y~lmISdiBY8uLy3SwNYg3u7n zPe4?qY*4l&o{vSl*=s#uokKKo1xxgA?B!eF_t`nmnc`8kye2dyIvEHY9q{^D&H%4}eVq5peyN`4 zOOuqk!?$`gIYf4bOpv-OIaPRd+b7Mr)lG9=Mzg$5as&TSRmh(nfAxVpp7`?gL<#C| zR%_iVY_`eW5eRyH05?GXrgb0?!XZa5mC=xzod43(h!ioCDaZ0@{pP6JN{(?@4%vgD zn!V#c!qwCVFP0T4a~wM8eFZl1QK>Dum^>(rIgicTip~t1TY;oRTFzZnkkScCi=A&I zG7io=p~c`{0^jylejmq+CsD7i$Nhu6yhSnP?dUXZ#ldY=9d6(nt97t%1vXAnm$yhd zPMt%N{5c<{nBf}oytuIOsUSNcGNy!~$m3y9xpEUou%dvSu){nQltd;AkcP_^T?v=gri_-VN|ba0*Iga= z3ByxUv-BG|weYaVMEuElcXih%41=~$r^S@~%q=_pI4)j#*4zRF3@p$8BV552am@sh zz@_|cskolaHayi5f23q5CvFg+69K=w-F6R~AR?vFG3GQ0>;+X1nFbh#me=6Y&Zl*1EY;wbu){>^nAfBbX3BS4BeUe9@p|gMUQ-V#nIGMA?)nWL0p=O zvCUyDBmzxFMu>>(e|)QdpDiMM>=ZuN5;fBXe&|;%dqX1OQIRa%T2^TzLh@i??0@n- zJU~_{^!e$Z3N$C}Hsx%N5>$1BR&nHDDBA?K7tK5Rj zeEQ)QT0vN)k>JDl9Ec^v4#=@v zAm=^l!3&W(hEUTg;++P2J&^V~D4w7_4m8$~5OxwaO}y7+v0|ZD##6c34m-!A4j|EpVOics z2$T}iG|rhKPFJ4`4{J*GD`v6Edd5H{Q!C36`lBzyK#jZZJcooOiL`wBB=Ut2n|+oR zhmyJc7}f;Y(kVLF1v2K`%CDfaS}Uf3ja-#-{GA0;zZF~qqoK_*2(%4n1Gi<;{1hNY zxy^%ge$RlqAjE9$nm37fT9y*m0W)SkZP6`n-YhFAj4_}&XOT_F=9p0*MBct?ma}MQ z;$Pt^ZiTCxqZ)sbgU{yJxbVH99&G$!NseW|l`e6qin_u=dCD_&MuX0wj+@d(WP2Lv zPfe8zG~Sb}qehu{dA{y*#R&koqWWAfJ-NR5v!>ICup^5LzzenUWrVl6n-0I{PqK(- znaZZMC!=)g+A1%O)9FiNW6#ik{-O6FwLKjL^`~qwnlIqSn`)Qdj$a%DNQNqXhiS}p ze^8ogr;fntx5<0?lZ}Sd~gL zQPv%^N%0W1R>ULd$F_9pY83cQ)o0K&fVqBBq%|Ir+qhMq=j)FIIS}}bBipyX?`W>& zgo&NG>o68aG(oUh#$`%4-XhL_eWbw_K1rTIHI6<^^l&OWiSv`HdTXw{ZD*)3&E|ceKpX({hzq#cQrRKHZsm z9o4ZQ#>;YVc-59#fy+B<)gEfXBcS7FdvbP1DsZy)?y?x@!q@h?S$*y8l9g!%_<}C+ z2uo4Sy>O@Q-_fLPg)4~nsBNacVs*+3ePL^hhKoX@K6YR+PamJ=OmkeWy51Qw&66A` zca-~=mXc@4wqGf=J^W|1e}Ph+OUyD(uNVe!XMCXQHNl;+;#0skr5nr?qH$1FEj<;}^j0cj!>~Jr9NlQv8-sk_1!k+^#~{<0 zT`y$BIMA*(KI}0^dDq3uK;xEpL(@pF`w`KBabMfA7&m(-f?@iaTDU8rK8xt&XY>K^ z*E|@lU4z%wPc@)*9<=i_UHXNhK_N-DYZye6&Xjlw!4Q)UY-aedC8;C!Yy+#awkUbAfSIO8L!pH4 zBGBaHF!;97D?!WuT2=qtlwlpHju)J|%a8>M;De4w$apc;|J}wBXGZqBV6zDa|C5~V z%3FnCk!N_?HM|jN38(KJ=Y@MMdL|INl)Z%QtutIr^xf`yE=5)zlA$Yl?S`xgId(q1 ze4A2DYr2}#iPMF*+Ep3HfUeD9R^p4ZT=J5stRQk1OivfM+cdcaW&iNEspKx4he}f_ zz<&4!30KdS;!s^4tDurdR_w-8?Fsw}b zPjsSN#+=@Gg_aFWHRH}9!pVumM44xIIy|25*kQd}sFU^-DdjCa=FF6oNNnq~DqA6q zjwPH4eU<&970n}fzZ;WYn9~K2g5Mu+F0NdknqDCcC4GHe1af_ET8(XHM@@0+X$qps zDiRZ4N`_Xo>sO}Ew(|7An9vi~g})r4MJ=5x=ZKfXqib3Ir2S9{iGzr-y6u-quSsbx zL}#fb+bY&MKZl!$OlCq$NCf-?`Toc#9ZyVDJZ;dpA<%@h+so}~P0?po)rK<=+;?@J z$SrJppZD2bpY5`~IZ4VKSG{2bGS$=#`jBX+CAsUuA&fx4CfCL-Ac}w1{8xTW_6=s-{wN%b!KA^hMF19M;Q4Wrh1T}I+?agKz#THgtC%yZeLCuu2V^5Zw{|gHRJqgMh;}M=Gwhc*E zRxl)7=cOML2817trQg5MS-)nB#>W-CM=z}BcmG)Sw6PlOnEj$3zD_EQITW-t+?)y0 z;J#z{!dpyaB+Mr8|E-7-_%K8UiZG!&2HePx}?^Z{ft+ZuF{F(0u4$v8ickJSy#j z&~rLx;Jr19aoOXQRbD?a*z>nCN1Z8mJa1o+D@iYU`Dm_oz|FxKoc>avr%cHVeZyf^ zul8AmYi1)XlaKuFWYR$`MCiUo5vy#snBb$i{4>b0WRRxNc3qN$B8`x}nUr1bbSQtR zha7sP)ytV8GfEt$Ro!Ibzh7OfqfGqDCa22f>%zk~)IN>QlI?B>Qq4TL-B=v< zX(N}jU|4v4bcbj74fVe3F53)+EC$#na7U2yUY(DQ!q9c+Z8&(wfd`2+`@w^SQ1}Il zrCx9)&{CYc*yYQTeDS-ey!j357->1^@MS$B#(Q{k!!p0X#-wJsx^b7}Wn<3fND9Oi7Ae(j-tMkAfK}(E!v(*d z#zf&&q!2Hcx29acaIcbtaX<5A?||`AQ&8gTWQI(WfSAod{YrF=wg-s0l4@4n5m`< z`5;%5^p8;khG^XcX0#Z1E4VX;7CjpXr*^IPuIu&na!l6 z;9MvwF=TXZZj-%4%lu(i6W{o310HBa5`-m@BG#m&>gi!m%tl2tYYnQGSzvf1Q5@S= zokfPCAN$SvQNf5HhdL}mSzR+ic7*rj{;SHZ2W7Q@ur1CiJR(5&%< z+WS8*)F@txi>eDoeX#+H!&Qm8%y=CA>g&5Wct2Q=O44_rMv5+Bc>CMDoQ1-}upDMa zs2?Wom0Q2(A*MYr*4Sx^-6C%44kN7>5?&f^E#(ZIwO71OG3r6w+#OzP30?^9VoKXJ zL$-UjZ+>?kNx+_F{$_Gtm%0N{r|Zr=*joOgosNO0PIx`mBZC#J9}L?AnRng3vC9!Oho?re~AY?b@>&|tI zZ0>0=NyA}GuI%>mKl2U{EDt_FC@PO0gP&;>x`?~{U01`;S3)6aVNuH zt10}^>g84)KVZ-xU06A&_n9CGRY#4c2B&Fan#bPvvhi6gUjKl5i*76p3`unpsl$T` zF&g~rONbGGrrBzO?WGy9OnhWP1CnQ?F0)6Xi_O zDQ(S43G!-V_|*HO2MiVGmtk7#{n*>*MUWue>!5X8bZvw#%C0tN^Uf_*qbXYNOJ>k_ z=^E!K)t=1}$T<}esCBA1>}NJJri)Z~u~F3;hh-ecg@k^H3|@e%)OBRvr2`-FxlU!@ z=IXU|MFxK-6Z5}=wDpBKZ;}0?q})`f;n0vVjVtN}>~H>~<@vVn|1XQXQBnA#I_8~M z$Aw>6?jE39>Dmyz;<@mzVZ(?!Dy8yD4u~1(!jY&)FAh<$1AHswqSw_vJIaX2P=mMz zKWY8$jqK`#mtRl$g`@}c$;<8kza*}2Cix&hxGLmWC!aa9clG4l z_^2Su$4Xw;xfL)`&YFD*9j6Vb7svo>z#(L%g_e{LLSyg^d?JhFg1_#~lb{R|D zUOreLq|1b!;w%!wb5Y;jJk>kEMCUVIQV zo1dnnyI|@=I9)KlGLbR(1e@blDwQ1d z-Vu$$*v-AbOTu0=YDD4@fU9uVEMO{Vr_X92faB0nk6<1Sk(535k~Q~@stb|bnCpFf3AMB^=@2%0s?WYvE- zbG=NfCbOGW3$j_Dh@=t@pqtz++N>e-W3-Ap|G?L%61m6iB8FDRP0HFRff!-4m%1fj ztH9D&JQ8uR8#@qBrZomB9yP!i=Ak_C`l{kAU}h7$*FKxx;b_%c*r! zPE5Ymr1>&x<1ac@9Qk;+4}h&6Uz`NA=-V!JY2gry#-gu0e=Fkt@{xLtAiE<) zOMHK`*Y|2en%QyZ_u@VyM%X4Xt^wCdYivrL=zTp&JcHv($h3V^7$U}AS1i)H0;T>P zfazs7Cj`y=bR-3BZ#`%CH$YnLO7w1y*5Gvbff1E7c(x@}a`xqJt6EJrw zt`x0nQCzpYuI-ZJcX^`^{D6WcMK{7O)c+4pZygZT_jY|Nf+8W(F#<{qFmyLaOLup7 zN~d&#bc1x)&>bV)-5?Fp-S8a0@9%#98_vw^eP)1j_I2&G)`u%2W?$e|!!cgHexhgn z+x4y>3;qh0QN_1?s&I=THU&*ISaH0h2(R+FltfaeoT>Vpcm1kOJ&)yjb8hQtbcF|# ze%zePyvJ9LMQg0`KiiTr=ZPOQkwXS&;SQQu^iy$7VUux~EpHL~*jYGP*X7>~v|@{r zv!c}_eUxzo3006(l-bIVGYidwzBUftq`W*Y*j-!-4C5Ium9NSP;=Ra#dNRSm^s|K>TKX z75Zsawr+j>{J3&G4umV&a_j{zOx#Pc4}Q;{?&jiy?E6(@=kUbGC~|Yz2yOoa{ z`)$uig%CFB=#JNqflDMdnUAAS&y48ltC_C?T>~i68;q3X&HNZ^>DIL3y3sW0zDfAJ zbV{9oqY8JE4vrm&Ga;G5Li%!zp*r=@D}gR&lvta=xk%>w5(I1))>afZw+0K}SEi(E z2LvopW;v7an?P{lT;av0430Q;Z@-lMH%X;L-YJa4Z^+as$xRMI-C<{G(o+qwI!UV0 z8MO~d^Y8)+SHTtM@+Q@cdO8tti`bfw{!ChI6}D7Fpzt6yrv$rT3ryg}ufaZ$J=!&k z_>BowgAU#xz1i4FC`_F%6PARg`Te#*ie0qEF}4RIvbH|T>r8g48yF%qmG>g~&i(F9 zVYB7^X3JZIhre?CO_L%#A1bqhQQhZfBn=slN;<={dpteAboht3^07;0*2aUwXKgg_ zrY}l9oOcmmYA+wCK#Z)=yttQ=GU^XMj|n}BZXy{Lp~tNmq>DwxBV*J1X-&Wok%8Ds zckg7j81;F4?1IYs{m*8D-rV0t7Mjd_Wcj(?AU9<;aIsa@lb@0M6s$a#BJ(j(;gQjs z$t~yzkBm93*F{*757yvT3B@(x9&EI(GyRjk`q#eW+#$s&ip^XH%XZk>tTTB0EA zas|+o0ooPkjA5as`}IAaq|#`)JI$((MC?oZWb!$J!v?{?Rw4{`=IC~=EHXyF8q|rKNvNRSyyR_vlhm23w(zQpH;7{LOOd3 zle)~N=$B!43f~IJs4JAJ#a99e3CL`7TKJBLb%M@9&h|PQHuwEs$oPH4Ke4PzvVB5w zAr(Qf#(5pD)2bYqPQ0kV0K&JQYV|VpMN!6Xc>1m~?Uds?6P-0ET)(J8ky=v# ztpx*cxbnqrz1ect(W*&szJ`u1(mO9 zZLPV5!$HFOVo_aornXrbua}}aVsU{{j0|WZ0}cbpUE_&&u+=DK1OC>T;N_?>GsJ@v zP~ZOT+=%cVxd{w2Oeps8H-;^z7SzutOl0d;IPBT_ZRa$U#Lrmi6tStOpRud4ml1yk ztRr%kW#<#NemxtzsRv?`*$D0NWpgF^p+84D<*dG~qFFgK(YgCK!v{GCh4CE(dChd^ z8aycMJ<#PJ2IfcF1O_??mFNrw83R3AtFm(|U=|}lcT6yOslk%23wA7>`PdUw`_zdy zQ?4SU1e&~3XZy6ylNrML1{iQcM~kFnq2jLdR6IthY^-@b#PQ!Sl&i?pHqlCffeJ#Q z-lak41rrV-^*ag!-g=3tY=u~X&)W*cz?7TyGs416*^ann<74xHKC&rWD#=(VV7BMK zF@WH2VKloE9MpJ%k~!9}cX3CZa+YR`=roxj*c%^LI`U205+fV+Re*1+eNEv)M-6>UXj-8@O{A`VutIAD?a^}aIiBq=z`$WxS zykUrJ1?5F@R)Dps9UH-$Iw`F+jW9KGxa`Clydw3`q&J(cXG?&D2G55Ks6? ztW9@ncO<+w64VUZN5ge)I^81%q@$6{)H#{7uDqC{Gt z5~(KMQGd9y5>!$2O5+=eNe@SQNLaH|ATV=d)b`4{TNe=L%DKsI|CtbiwY0V1SXJhg zdu~Jg8WvU_jtlp*3S2FnDI2UxRwxwG39NvnYv};XETtz0Q8VAT!P*kJ!!+O=DU36lFWnDJ`RX9W}z7RZ~8!sa}D`Df8;jO{|6n%JFoVW@%ox zD7)2uJ$2XcLHH(tL%d#;Z8FbsT9VsM0$A+*&hMasd`r+~joWG^)SM|>^G5#p{`~QDyTZsfA&e)On%uq=#t*Ih% z6)uBDHB)@ZA~130T$;9Y&2hMn`h>malY+``CEo?T@#!VNma&(e4$ZXD`VB(+nu9G?dXu(^jC-!<~p*m5FXUd573K(k0MQ zF>qo;e`1AYc(Ho3e@?h6gP6XH%h}~2hS>SUhx<@)Zg=I`ZvKwHCAja*Zv4&6>?*zn zS7B{<4qft4s`7pjazyiTJZrqsGvXsJ<4~)Tih7#qB$sBkQ+-a!GqZuoVSD`p-YiUk z51*HB1d5~}?qd>IFcbFI1o=-NKdv7Yz$SGP{K^oiSFrnccYin{%G@BM1dqet^E!Hl z9^DBfwld#ZL{SHJSEF83w4AI4ebcvnO%;;3hAAqAkpV;z#`4V}c~xK^Kv-bX*T;AJ zO`<0Ecqx<_$-7Zyu~G9#gw@ywl+3*8k;HF}kD|d;%oF<>jO_!l6nBfvOefP#KO+Ce zg+__s5k>Vh$tg4H%5T+GL%m@HD8#P>(hy#WtU;I$suzB9(-W<()K68%x#MkLUTeUY zg=7-q2+?C2QvZ~H51o+?b|Kce-i0Y~V>=#?bUV7dI5hF`;>h>fIAwGH9D*>4FRD=2 zmaCM-v~`X&+>8Y}3dU>9N`DLq3ajdlZ4TU+5iT~{Gt+Szha^0IL^r}?aVlK*-5egiq~zA{pI&$6#0GPU zIgZOZl>@JGQ_E#a*xUpadtsWxNB+DTadAJoS&M}5t6KA?ZC9^d)0-{n3XyLXvZXhJ z`Yg<*A0z{Yxa`#u;YE(>2BW!NL(+A4<84gTjcj;xy`_?eq1mi;8`AK}Yk4>TbG+(C z0cTZ0;#4a}eSSa-M4(Dt(X6B7#$!BaTY_^cXJEe~@5zxqeoiPuNS*ow~O4w!RvF;3akcJmAzrNT=aMJ;B(7^GE3{clMw7Y%5D90SkmX`rV?ETn)PHbyyWdDJQEe$v3vpqWy=G7`dsFedzCw%jLc+lN zdtc3>X5N9@IFZ)-x_lkUR7~uqI2m5_xs4o3En@;c%hsoV9rUxYxzd+Sm>e|cc}YX~ zntzhYKpQnn#^sMmsPU3j(VK>7e@y#N=Oy-9Odf$cn-cT<6w6{Tx$8U?dA^0dS=Aa6($~(8>0v#+NJOlQHI( zHnfhB|3p^%qoO{nrc_~}{j+Q6j3s_M z9fg#bY_1UkZHZ8RJ!`Yycq7BG@}C?z&FvNb8A&Z&8CVzE#-`fv9`0+jhg&s73KQAb z?wY=`=|v2pL3-nRRXX>Fj1cHOukh|+w_z=MB<5*0?A0|tafm&Lw!Fd zCSY__e0{%-1>3X8pT$~n^y0R0iTMdMr7el8yudgeoHVvL@Rl99w5B^v$za~-t9gC- zw$=l}qX&f9wQrxssXI;sWeJUP#G_sO($hY;q>Mcj^W9|j^<>UenlKvJxLW=mXai6} zYY&@;%?(UeLAfy$m3SQS${J6k^xsp}Om^23)LCT|KQp#cZq^>_WLtk)ziwf`jR+}Q zdU^lui~O+pRJHKZra1a~b*s`B*%FS!gkLIG65qt_>8@Olu8%aSwv=ifTTTmy%2a(Z z(H(MfrU(ztcrv0|T(_#p$3XK!0x4jNW4lk1S}&HKP$bFmOo#8LNJBNW#r{LXV_m_)lir7iSG`1pTX;5abp+DPSOE$LFK{_rDcm|w=ugzsLLzr-W z*_0YHP<=RN$Pd)QheDWKKiPD;_#RI|-m7jf>R@B0YzkZ!R&y;_J^ZpTh@eP1Dad>o z$LPlz+RZb^s2Npb*g^lYyWQdFufuz-sgX=0Eio$Oi|g}8I~oncu4=us#r@MkW1IBj&GCLtvb$-z1r6%qwb!;c+L3cjT=3?~bQ!g0F>!D()JpBEVvUe${V#1jp~%{j z8o}Y-UZu4#J|o{z;esJI+gpkcc|xIE_t^Y*HPEbt`r9y3uzwb%IwAt79#M&lF{?1 zqrH#YeX7i7=5R+&18$<-f@;(3GPe6Ax>dLKE#xw){i;@GztZ>JmmTH58}iq(A=59U zd^I$Mn<-%y$el82#4+sgI&wOvE$dZ57`&23a^r)!nP-KP^T_d}PFA?`EZ@biJ>;KN zssAXzF3x(n=%65PZw9N_`LIQ0IrWDPgg(KsY(HI=1T)*4PLwIe%M217V*gsYM8caJ z8)(09cs$X+WNY(wBf=P~8-DO`k(D&mGqqJ>(O*e)6rG-LqVp-X(MRfA7cCJ`QL34_UDlH3lbR^367U*7{ONZ!*xAywV zi$-nqg70q9P@lofG1Vs97>{KALEfdn8y{&+@vIoSZNfI z<`+TWy805sYCAH4tIOQXsD*1B&{)0`0F8Y3=6&Gy1=oC}dE z)Asib3 zgZVVnbxrDULi^K$Yu>2Iq0I}%Zo7cwOUs}>uJuMQ5$DES3rM38d}-@yAP=pA&X{E{7F~Mzkm9cWD37-S zoO(Fw#_!jRVpA#Qby&saL(7;9ZGYrH##U-bD@=bW{WP7XcgAs{n|(RKtBt&9DlRX4 z3it{Ob~UQ3>8P^xl(9R0>2!)FkhlWAQuCS#;RF(4dKwTvMp2hw0*MhljcF?2Ekp-g zqTq;sE>RM;5{1jscTudM0HFjDuHyJ{l<`^uX(g&|z(gpoYz>^B1bPMFi#`@-172E zHIP!#h$6)xWE!YB3;F?nsgM#+Y7QL8IE)4GSVnP2&P9L+vCM&JusIZDD<0c}hjB6ISuuv?mAzi%Q}$XEJg!`R!9mU2I#CR1JOz zhDfo_LFgvX@WKw8)YO*IB9k*hWrJYNh-Y(jYu8-CV~3TfQf6D7{GVwT%h2X}>lbJq2%TzkN!qtC*ounXI%Hb#92EE?JAqJ{Y_ScaRA{FD<1*)gZDQ z;ZmV+=Q0i(dL=cvI{&M!dRDsZ+HYb8q)ZXSXVu)ed7$u04z>p#OAtiA-2X^&YS*fT zNf++&1{<2Z92&B$@-ugI!l7m>f`L|28HT}Wks4iH2}X|J?MM9)FM#o z_K?d1Zan3LdJs5z%}Y6wvxM%*eP3L5XOKE1v0u&!e=#xwlOU^|`r43%Z`L{@dd;Zb zq1&mHQDn~0dQqZ!+I-f3P13@gv9YGPb&`^*YT{Zg?FfKkH8Pa<%lrLvL=LDdcNY%G z`=yA=_TLmTt)b)J=PVT+*rVb>XmYvRN8-PT+!Uh0%x@n(=^`aP&xS6pH}Z0!0%FG2 zQmQbFF$yD3)8xLwIL{(z#FKiTwg{bBO7zxb)*A_i&HKPW*-GsvD*)V_(OvU2kzYK| zG1J#Cj9ZhU?TzafU@>t^oM9W?T8W2$I;ix9W)izhrt;B_pIpD$o{k6q#gdoLlU^P8T0k1fG+|RBTc-Q{ zyz^$}gQPHCJ`rrg$mYrG>4ehm(hFv_jAJt z2~)K7MiMgc?~q@x$xEL@Xn*#AQ0LvAqgn54u!%bXX>?{meihcHe7(?QsbRNu5x&@1 z8(91~QO9cM3$3YGPs>er4~J*Nio8)F51S(^ zVq11JlU?he_n2;a;^jf2%Zp7>Es2HS3+5q~-CsH6)Pp9=TUw~>YgFi&HFObQYdC=h zxfXsEGpM@dR*S^hObzCFpyHX1baMEG%CMQerm1+FgslhHWyH@g5caf^*h%JBOn0?P zBza-7ng3DprW*>KXS8}RNt(ESKHY8D#8Ix!tns$mikL<`83X8sg{!qmec?_12(%8< z7#7j2L^gX67-~D%B7m-+V2#~^*}~T;3z#dAs@JBbj=lp21R;RkX+bJ1AlhjHsq1bB z02`P+sn@3AK`DZ#9O+D7o6S~kRW$eGtO$f$ni5jPmb`ymJDjUt98Rx*J1%F>uykjg zG8rINVa--)L6dPMAZ7t;28*$vOW-1Zj3eU1`kZdVn_n5KR3QIqykqfnWESe-K${wq zo4D=?`xne6)&%PjExk?n(z;AzrcWi5Wd&o`96BB#uiJiC&cbN{UM)^s`7T|V*-nM5 zTFsrEQoqh`O6w6Kxdp7&H~0}=!TiF)Z)lBgTvb{&_N}IJqe{Y;vYe*1t+L3e`QFA` zJf8fD)oyck8Kl0}2|_@#R5;a5^0JQ6Pk)&*RrPX{ z%dUhg2Vc2yWDn81;_gsOi0iXwzCM5bQ==B?Rha0ycVCXox~NmkyjQqjx93Nb6EQ)A ztP(_|65$0hdRLg0_R9X*-LP-preqpBg@WK@j$%s;VatufNCz?5|3q~&rsQ9kvfq@2 z--9YMiE(&WBDbELISrrSbRUTp!Q7admrm>om!CWzlsC(W+$D1eTq|aYg=p?!AS&(; zZKT^cKmXYj$M@k_5$xKno<9=Oc99px z(`O0`F>*r}he)!_v0D#cp#kCY^1Pph|0}<2|L|}{hgUoN&7}~A?-Nn2tCndwJkFAt z+YC-BOd4`Pd=#HDA9b`xR8lhOgOL1aRtW7~ic++aQhrF_q%4M7)ollaxs6~}W{ad0 zZH+yOjt155uPHn3x!YQ{znf02GkKvV9&lq|P*@L0bDi>V{<^#m9Fo>J+7*xQaVE;Uxis&~ybKVS85Cdp= z(AK_H3>*m7N+DrPpTcZix1eth5G4W&PZOin&*qsZSj(x-nYDh8k}sam?v0(S2wYI? z_xQBY%SonzpqnCgg4@-~-y1oX6Ekqw?yDf!eHp>?r(A+a?E3`}%tL-a1%#VA1DYD* z>H2OyYw;mxlmSYrT8fE8FapYTFUPB22=nEF?dd309y(f7$(bhejlNfT&uj|PUftn1Aktg0nWjsRJy7_p8=tjq&1Cz4D85dbGUS=Bms!^)}7 z)+Jc1FH$)Hjbhhe8=qNLTPSr&VD%1hEgeIy3p&aJvRq_pQ-dkl%8mo`9f70`P<`Ay z!*96>3yhrkD(5&S6QU*i1td^U$Wi=hm5$+nN*q>x$ieL1SloLGko6n04eL(_JDM94 z1?{LJZ6INJVhuK%!ebAA<)9^D9h^OJc9e4I%eST2 z#IGvCp01MMesJ|#*YiUulC~3BCATP@(pMRp3Ys~tpkJdb`T;jSXg1;#LR`&Cy_%TT zA^&gcemTr0o2O`PwYbz6UmB>jXTzF7y}N^nMojKXeZE!hvmlWcvStNtT;iZ(#;L-iGAFq_7-%V9noe5TVuKQtc~^ z3!;_=RFE1r39@d?hUBvB7h#*(A6pIf#>}q(tm~)SWpl(Ms75 z$uZUGm|-g({-f^APdYY`>W{DEBT6II``#^`v>Ld&ED6KDMtgHi6llOh2Db3dM!-K8 zk>sYmhU@VD{%0FHx$KClN1CJWVtpTh_OEc%DrDWaWR zd3tjpX!LHkBJY4V3V1ITy*RYCUtD-NYPC3 z>8Hfe=FX51_E9+#Pn-az$r9AiDsG&zmX9-r5f=iVAyW%j% zOif$-c{o0ahvrXquf_I4yPy|58+LQLy4% zYmR1D(HfoOWX`7KxKwMNB;|3W(Jo1+m)nZDL*e`>Zuld!2iC|ZM$a}7grH4R-vciS zf$pIFyZy%bp|rMplF$)_7A}l&pp4&jw1PZz+bzqUX*YoAP-W8l{dtT{AhP77{z^8i zIl*c($nXoCJ!!!(As69mCDU@6X-TgpI6T#nAROZaEPz~N`!*<5!uebmQ7@MDjSwT5 zvKWJ^P6PB+ki<7sO_IG(ixnT7d2zg#oIpdQIBAu)f)x}M<&?I-)HwUoI z`9ZO5IH;sRojNX8f}1!46oMv{E4CA^#@9-uEaR7pB{CJUOtlwVtrPpmsFmf=w#@o> zEQCoq3qbNoPqx-t!%-}A2klr-@W^t$bnM5O;Nuj6Ge;@x7Jn(cSHbPGDmB(~AA(-l ztvpFv@q zQ+3Vh$lbqPxWN7KAWd#($^|LR0XCT}?GpN18I6^~sht(?U+HTJL?7VS>B1TZAS)>b z;pk$;W?Qn?eoE)3MO~t-esUfgi3~J0>H}m`?OT<|lq?cAxitn}NMI*D-W=w;Bm7nV+ zxqo}>h(~0@o6uMMM>H~K-Zxw@r~hyxOP(oZxGduRB206sK+8Kv%iVWJt`cZLRxauU}C}pC$Z|8neW*bxtEcBGUXFoePChNG?+zs^I_0lG#eCmb`tr zEquA%=6`YG5k40zqw2XTe_$PH_Lj!Y<>pN5QhYey$5lK?vR)>Aa+c;c`5+N(-HpNa zT^TdNEUiv!=#nBFV~j1vHT(7BvHR+pha2v7;lVhCepN>cKSLq1h<`LwLr=SvA`4@0 z5y^^XNq_JYu8&3I5z+s-Nw1zpnvFae|F>L=7@!Fz*`s}GWTMu7WIqbzH;`t0_(4y5jOJH>K~d{Ma(u}A=T5GMt6&E{I0F&Rc|rKEotzTfZ4?)J z3JIzn`CV1AKXL&#VeCjJp5K{_GK@$n$%R1^ZW9rF?~6|dDref;I4L?jkLWg3pFxo% zN&M^IqkEUAWZ3+&0TV118ju%HwE_NLEB`Ci55{V+-L!Mg&p zn$VCi{|P{zkys8USzP7@hK>Dt=9{97o&iDy7DezVw!akMP|UKSe6v(_s;O2 zHiKaXEu!Y!V-A5q2~-vx>eq)+vHjj+K$BT*z(s5E z4|L9K;JhGQ67XC${+(uJ`$=UED!~LZ=Kc}H!r7i z)~sU56NY-srf$7c9cW+P&WlCrcb%HotUUV$wKqd=WmclDn+{m9CWQQ1p^?hFwje9% zXTUZq5)Ifp)Z2Ky-5Q_qZFEkzHN4a&K1~~Merdaj zObEV`>#4Q>uozarqXZ(UVi>vluPeA&^;RB^u=*-e|*ZRn)QD zBWUM~f*q4bIFLtseIgah81}qW5&7~DPdXwJxA1pBo=v=6zVHh^%C^W|u_$?$ywbo( zs-&C4j*(k4nRJwat464|+Nw9Qdjw6?)Fd@Zlt-iX?7CLb#bcGT5wiG4Y zj=u2TJEBg%K@EBvlsKAqN9sXr$!gN=!;yq1`4(in0TH{ZxRwaR$Ti8p8ac9f=wnD;tI^_&qp5lJ={E_bdJIC?DO#6o;(rMMXxn?4%}T)QkwtW(h_cV-f3XEl)L zDajM|lXI@^hRgr0*|1^%auPZkIiwY%?S> zd?$*q?w;7PS0XEg=HW3!L|K)(k1{U@d*yad7{hU$Po1qDE;oU&;m}MMF{PACapMq^ zbD5gABM0TTt0$i9POkI@CnjkkTa&@n zsg#AOWIZi&D+FRlDO>vq$n52*z3Qm}t-Ma&Ox?sR4w;y1s6~17ypqq0(Pmwi-g`m! zLQNOHTX}j@iz@>m1&hjz$Y>IxxEpU>sbjL$&F4Ej5d5az6*M?_ z+7Y+1ka#@WrP4cs^Txu0B)oYvBx`v<=>buMowtl6JAm$FwBP%EekX8mGpP<`0YPdi zY>uvE3KmzKUvl1ZA@6%TTDb6LEb@Y)pJt)$9x*0D0uAzo&e611=IGZzznpuDY~>mV zsJUk6EhSGXI2G)XGcXygOGl)e)5u^7V>_;hj0BKa$Y|X34mh!@zj7~YE-BWwB1ohX zY#ekTWXi9ao4A*%&!SB??ZrCEHf07&S6&pSqrBP{OW8SdLm4i10h{fsT5)ju`2PHr zqs5IClQT;H;+D~QGgii8Mnc;17Ee8ZK9-+VuOlaxHw=l$tOze-gQXUjG7Q!#0~^}5 z=Y zk}B9HLt?jlv7@|^SK)G?9Mfcv4HaLCr2SoyxF!b-w)`63f)fT=4JaH&}XDieiT|(+gjS- z)046>QDU<;Qc_X#EUv*PVd8RrJTF-nq1{jA$!_C&LZyH94Kk?8wxX}K_mGt-u22uE@N--IDKL7t0cYq&Y$HSUy20s=6deA=9%cU4^J&aC0812 z_cT(C;F?uCeU04S?@O(ZSM!U|jkFI5Qg*&BE!njv+m(Gal~$jAyYp4q-FTLnVE9l+ z5`I@XH0fouU-kKP>_eLl^PU~m5n}FEnk~qS!$9_2;iWy{PR&jY!PQmR+hRvLJ|>dA z1TscXV^>tF-WyrQ#`^E$tK_b9cxCi90J}))s{X{WdGI zuINqtMjDP8k6fA{Xti?lP$#@#;!1EftRgm(JjuQqKL57b`b55NB5r3u-IO*30SB{0TQ3sLjU)mRILIv!h3W3Pq)4hq>yE}~}w)#v1 z8rc4eAy+e^qhn(s^qBN1CQL<<$@>k*&3fMzp2_K|vR@fo7ize8aWq=se3+ITb|SRs zkzE@q<^s`L&Zi@)!1E!ond5hthBZI=w4g=X6&ASd`+Q>jSmj@D^7@cUUUjY z$8Re)RVV2JD@x$7V(zw`)qd|8I))>%_`F&@I8?*QXgURb`vLpon$nt4-vEz({Eh1n zSn`^-a)aIpR(8r{|lH*wH~-L3AvCsK!xkLs<_YF~F^ zix0z{A9r@Z(FBNLH~QD?{qIOUPkz7%60a`No?Kzhq_d=oAmR|Eaa}OFiic$ z(S>XV%#z(^laQ1IkJMIzhaP<){n>(;PT9ILe1qJd=dEGRNm9`q(=Mf4SX+tXIzbnO z`VPCu%tLmB7NJ5{55d8OEl)6;YkDkU5qaqVYMaI!E%yiEJBoU;7cADwt*npOwUjR^ ztTf3TS_{NcSuc0)S3aJ%I(W1J%m&~q!S{*v*q(Gxj)B?VVja0{Rk7*J?ju>N?qV^))rT2_=emfYV;+KE;cTX~-VNV|&%3B@^r)J(6+%)nZ@k`Z_A0NCvSZevb zzeW`ikI|!}f*d2UXLH5fy7*WS)w`Q2K$G#P)ci6do66WHFgK8|*U!^Hg<1h8s4V;r zJ8xr!pJ}}y`q0%C4=I;42ZJj!q26%71SKLn-gC+XC8Zi&(dxr9)_2OtsQTtHBJ zAhtN`Y4P?Kyh_3dz`3FoJswQ$e#gM-GxRMqL0z4|BuQ?YtSFYW8G-e{JZKdwwoz4EjctMy97Zo7#eUz@s_7mq5y%VGXiIe|QmC;Bo9 z=8C1Lf1m>*Saxd<-}MGk(o$){3DFjSu+cJGBOnNvjA|oF!U*|J{0zmyrOIzvf3nR) zcKDwIDtcQz;RX;r7I*1C$Q87tk@^q=#{x@x<;Q9eT>F`-L={JNE0BSVCG;;_Tym|D zM(=$*ML7XDo}PfGB)Jqs?>qVX)LV~1tAyoNbu}<2d{f z<;>p)!Mf^_malQfuvDN)%&OvqVD^I?5qkvu1%hhmPD`+HRXR+-Fip_w3?H5~sS-lz zYXNKI8xplUm@9ApFKDGZwg5X(xK3Za(paeJzcHE)*t?i2GaXdR2r%+RsWl&2OM@a0 zrY!*lzS;u%@Mu?A@fV>sedVk`Aq-QiQhJoDpc$_!EPZ>)1_GLC(Cno;2i7_e0aJo% z>7g&aqft&!#9DSxXF-{>=$pN0S4)~~AITJqbQNR>q|i)REyxwIe*$8RH8ZHNOHe7? z%Lztna|Damjff%AYScZYK=_JH5@qVC$^dI17i`~Ki^*M~fI87NPy*)EEHoiZHEThX zGig^pHeav#M!=&s-9P+ZYv5Hdqmsvoj3 zQpI5qN_!1Mo^MvqMskm0hWtxo7Re7iUxCCofJil=cfd*U6?0N+6Ah5@=wCwf0 zCo^yu5EPWAnOz>3Smi>jVZu0TXXpRkHD_ybgc2 zZ5C_g(D@B*9X_t6wqk@0TPmeu;~}d!;eR>abA$0|2n)xqTslKUiAbW!;bliaYrXhX zBcEwO0f=HHZa@40dw3dxT`BYz_O!CTRyKG-mT(+2S$6a^-P@0dvhJ+u9Rm}$=a8~( zO4kmZaq+ZIa0{X9%rs8kwRA?41hMa{fpl21M5!}Z8jKa{~Bc=eu^5`M^8xIC@=lKTHi+dx%>O;Pgn6jL2siE zG%QWHAavPmDD5O2O|PQ-$|94l(|&}TBU{2naY-km`qwn76dF*7XMuB;! zXf?pHL`QMg=wA*^e$SuLcwE9fH1ZEUY0DL^aRK4ykT^0RdVu(Ce>6e7Z`D2lV>Q%hD#kpAgcmln~p1ESgOPVc|N$)*$4olxf0@ zd82PmFZ(b%0zUpMNf-&K>ifj+aw%{>^aZZK(qp6kuVoYFOwaO~Sj4`YgO7mb9vF&J zao;cB(N=tMiPqgsVaUy|PDkuQ@nWhiHgvpEz{)2|2eJQCLLy3eg>^Km$=b4it)KM)g+E z3gvMn?Ld>pmmAF6|HSzNdtXZBXsCtF%l)_%U8Ylrj%TK7TWQIPnJ1`I&Fcp&AoyuU zraFGK`niwOt%mzyC@XDl`wRB^?KuK0QwEy})O@c-&m8W4et1>FN9)1jY&TVmf4!d5 zk0@x`Cvlv_rd^$!jmtV^JA=DLFNVffaXAGg7R>Q;(3zO+3>Ij1yWkqE85Q86Vwh-5 zHE)|ZV0_uqJh?P^m=+hmJp9}rV$XVk zubl3jCNd{H#ud*%qK3*?lX9b;gsV_O}4eK7|9~C!i z_MwkO42d--Dd@)12*ef~Q^GK9o->Bx1frB5>v|}lVPD+qvg`F3Hl)gr>g(78t)De~ zm`T@k5T5SMQ67u@{aDgbMdcaD)|rz&NE)rGeN-@_dp9{Yvpg{3r&PfE{9Hn|2u z60A`c*y}1B9WlPCB%w+j_eoFj_LFO)i|=pY)cq>NYsOXZ(73a9A~*K`rO-$hO2FkI zFi!Z7wqEBT2Mg3Pnf6`{Ss^su=EXJqE?khq)mZ#~c{KNX=WlgV<#Cj-^lNN_T;?IJ zsJ7tn%+>7-2Xbj>Hdn1@oVs*5qQ{j|-`jZHc0$meavjdkJj?oA9Vb z1paz6n5O8Xb)ij{ln?6Asj;?}l9FwuR$|c4{l;HEw2UbMwv}OX8-!srzEn1))k;*% z-Nd?ZEM#?Oh>~*_9vsg<{D#zOBtl@uTsy1Z?#`)KDL{15Y;-HX%2*>l+ssKiHswaP z5XeCtni?{us$~Ck`Lyy-jqH%(XaD=$O-HsdOd03sBE>KbBF7w`Ttpo)%;i;@XCS2M zwR2nFw{+1G!jHzU9u@NZFdSMAu0kb^9T{PEK-QbWBn&KyTT0!_-Y-n^nunZJ2$I)C zn5~VaFCNN$CmH^vJDh-{X9zJZ1BD|+ zr>AmTB)_4Aw3E+~%ID_N)9vQgo_{Ce6I$7`X~Ub%3pZCE&*WpHFjw-F%ROs8MVZ=i z^;WsAatoZ(Aks2Kr|l+aD2kgvqWz+9qIML3v>NF-c-C3$E@k>Z@<{*8ap@icTgZg~ z7{t8b(>!lsEl&DiI|XI(H!3NGT0o)A;=E69Nn(wD;pDuBmlL)#u?d2iun&y++R?m< z+FmCdVC zta{zs_0-3Ag;+$7gTPBK_(@Lfv(3m6TwWE#O1}abrK_GLWw&mk=5DyQATAY!8{e+P z+wV&>wTSvEYO;(4^PzjEd7Q`E=KeZb|4n=vx8iNsvPMTkCNZm;PIZC4A-oKG!6c16 zjk|Ux`}n{nhgEXt5|AGq?&};NdeV1s-0gVo`>tN<&$KmedJAV`vBYlCqKcEUD-8d6 zk%0Gm5XBmcUIW7Dyz{$7h%ygMTA@at|Ly3lXxEBmmc2E^fur8)kCo<_8*gRU;gKFj+C%fxM!9t+<+*miu(ZPD&2avfX6%>gkfM|-u6R-#h_=N)dnV&|@d$tpTr zR_Zc<$#Ur2wdC01TGQp+9nWv(aH6yA4Jev_2oR_cSe5-L)w>)|M5gR)Tq*Gzb!0kCno@w(ALyPwo} zh*S*^Qw*7q6Ihv_x%US}6D6%oGQ-CY*vVEooxSe>Oja)*$uAN6!nSs-#isU(!nl{Z25A{ z5vAYG=vq$Z`ovZ6w8wtXfItJWGaa=vbVI)z<(Q!lLWNXT>zDp5zj32hIlHpI zy5sPYqQ)7@Yq*1v%Cv|Cd8p`4OU1+Ilx!+>sAhiHOEhy*f`@pWtOrRfG}do}41_MC z^fcHNY!J!tyy(Kmr;VlCVQRg7xVY{KRG=KKs|+Q6<*=H9Y%v*-k0 zc|&T5S@0i50$ z!QOmz4-P@Pt%VsYeV@YREosy%usn+aXY;V1!LIU97SoPa)1 z4d5Cnj#RN20E5~G{54Sn1fBFWJO7WVw+?G#YoNVrP>L3}0*4m&;_g!1od$PzhvE(g zcS&%U;4a0zxNC~L`yI}E@AG~Ch2bG1nQUgSz1I4r>1+N5C|jEYMuF30<~g%^fCDNV zsgicp1N^aCFOxwbL$^(a)N(eC0I#FC@%9HWT;Y>c>8B(q_}oofpoo9I`w zTe6I!S+rtR%(t6E8fGok6=l&PHDjb(qEUp5mwnC@4gaThQURP=_L(q|inuv3Qk+tg zl$#n$$gR|am^BPr_!<&d9*hVJQ)tUkfiBXrdSDCRNKq)uLn(5D&P7wo3owD3F_#zp zwTHA~flSQ(EB7GgUc4_5lBbLVA_rxPZ{tOiRY`gF;^$U)Xxiz+;7f#URKP#Jn&*c5 zgtZq5hlAp$YYAniscJyEA6n+NPJLb+eCf#?A&UB8qUtK7Jf9NhqQpwzk%Pjg+o}T1 zfD0yeO-*;Ep){qo^ggTeud^%v`)pudHX_&e&U zO2URYJ+OkJceorc4oe9(4k9{veX7!>w!R{i4m2G z6D8Q-ldbAG`J|ev*%Xp=Bfy7Jamse(CYC+}UW(Q(nbcg)9|7kkMLDb*W2}WeE>)|8 z9ema8P+hIo`zJW5wEObAkYRL{T9Pvcy?W5zmjB=CMhg`i>Pb6Q6@rR(O(}cPQYy`5GI*BB!Z@4kinP{ml<@A@@Wf~z;E(612 z>LxplGAH`zKF;KOHO?8!xDt~@o87mx8OK3aCH781x58)|8#2IsU$%`zq!$EjQwq0K z>kN6W?6y|PM-WzJu~GnlSpsGKo3*Nvc=tV0fVfjvDlO`(A?eOorp}jd35Yw+O4R3}eG$>}xc58kaqz#6H9!kyRuV zKji=@I9FcUM}g?Vi;%+Mt-^8pA^hn3r!xRzRm}to5yC%#Dm$40zz9I06~$%21O`Y<8l_M0_c+5IYnwCpBN$?0xgzgt8Iro4 z$fk}=Xf3GpIe4{Yc^sw{x~)@|lWRQlOw{0=YAk+)_4gs;TXwjf8ooCX@Q*Hhx)PJJ1e6IB7Ma*i$@e z!AUxh2I4cfOR$r&#mk5Q+LG537ML2NPA;6_xM(@sNjzq$TX20hzS9N#413W0O21Nc~oa-}Ho z+Czlp7Q5T@&Y6J^=cO-I0=^7eN`c~tQ7woJDrTi+t!sR~jW51FzO9e- zKb#fJbUgW>CHY|Q`EI4M2gbX6k|l7Q9lSCHJA2ymX^cb*F>*`0l?Rs0PWSed2yk$I zqCqpN0K|J$j@MNEs9koJ{Laq7vlpJ!StDKhQ`V~&V39`pR5r3XvVj)6Fvbj@L0vPL z0})AmBXxaDK4~YW1qu{2_uSo`)e!Ct8RX?IdVe7YC^Le%G*@EKX^2fbI?|L$e*RR=F|uSjXY;^lzFXR06XsNHq35SR8^8``d4Y$pQU_0 zp!C5+o4Ld1EZk4zyXoQD)GFN~P4sobL_5h*UcD%btGS1T^w1L>FCXtp^6%dt{l>?T zM5#*HG{08^x?EN5&mdzv(|JBV{+R)(yG2CJiPpn?B~sxfH*=nSDKtt=`@Kg|fEY$g zzm~To`=ic2s;;P0yvf{?Ai|AvYp7uY=>mHubEUaD6zx}TZ#pdhP0pe=jIHCQGuaiy z+Im5|XB3kwZjOXxiC#isbB(3y=3q^ur}$9LoFm`aoMZDs{l$}*m?UecZ|XC@r{~@r zU3#6}a2~QKhey*;6fqvYy5E`p%iY*;a{tBEE7JWOd;?#(foa;-S%a_>mU`)zv%-s9 zG{%Qvd##x6H!nV)a2=9YHeh%6w+f+VragoukSMJV3b0Un8SB7HGwtpA&3bRkI|;MP zlyA0g;tP$<{24R%-S;;)ejiq)`s)824v8DwQ!8YMWjJ)6XIALwOOmpa*e;`mZ}?r@ z`cGj8+O*Z!wCUUL$2G*dUiWJ&4nm*uFtYa3wI23EpS=g1k|dhyhl*dEO9v#5!vca7&eO*2=%ZXuh(s$FRC12LnXeL`mQO z`JQ2idE?)PT3OH%6F_G3m1dZGFqM?@kdUnx{IQp%myga%hVs^br;TXFo*8Q8h%a+8 zJ0P+~^AG*Q0pkt)9iBq)pKhbuUAyQCsNT}bI!%j+4wQ-MP^#i_KhrL5i(kR^8aq&Z zPnCvOiRQtdS8O5QT)nay!a#UVe!H@$ovlpTywfT&U-A-qm!oky6tugOLd%=g;Hf)G z?RqPflTNWV_k8@9plu$G+cfj6HK`rkVl;>x`TW0au78Kz#gLzrSdtFF2Uzid0FYIA z@IJGSF2l}>?ZZPdWcFhpI&t0U7#)%%?T3iB4o?ityy^c|JR(UW@*djeXpDQxS$8Zu zRuFkew<)BN@XD{6(jrw=Df$}_F>(QgG2V|gIO6e-r`5ogrPl4*jTIMr{aXxn8bJzn zRhTi?B-D{e$Z6IlvGB%jUO}i@oYLW@r^)IITNq(v8X{eSvy8PRUO@2=m0ns0W^}{B zfNzIUIg6L#w@0jx?M^oQHacX`ex0`YfDeS-aqyOo};GnkKC`x9pt?;YPB=X%4D z?8XmTfj<|7q=^@b%CNXU7(Ap!s+ph1OwWfAZew0fNn$!)mY!=mI!KORU{1u>$wY-> zzrd3{4Q2V=-v4ULo0(dkvcgX>ZoXHkE5Yt2LAfmdHse;Uq$R)GlVg$(<45*4{kgf6 zx7!JiP$K(2kSW4-Zur@b+ZQ3dU=Lxx-`4oXHRKxrwqkPMU9#SqBWJe!W*INxId3Uc zzF+rmOLEhiFEPXT$#H+BRfZi%aPlSGSOyoU#5gt-Jc)VmFHnjRLIfMWBe2X zFLjebKL=%Fb_b}rUwct^o>rdh=pv)TT9jdJS=Ex*;pIeF4FbERX}|A|Pj6389r*7A zwkG?J_Ac)18ef=0hzs9;!vX08*Xd(n zt9XuDL5q6f16S17m}yUxucLbtNplmYi(ecO6}J z)CG>skCAMd$W;%47y^Rv&oJW?_1G6;^+i|4owGvanV{!C{qM0ik&c5GI1FNBlwHifmSl8qFS62SL#N(OaGu2!$0p^d1AnWM_{Pjv#@6B<=BQEX z1cNpb4Sb4$G7>*zIULP3{#;3MEQjzLPhIR?lc$Zq3lD}E27qWa6{t01{*}BNAX@!x z_W_7jO5@)X2YX~nh^%PA35RN01nVkywCS&=`N2B#FZR5Ak6ncS!K?{*acVt(PBonJ2t)Yn@o*-_pp`ShMmgr0L&J=ix9^i`m@i6cX(llsv zi&NK^IE&Kgf5K&8wh8l~;^ET^uF_QJ*?_WE=7|0*Am9r~kurN$8DQTlB_tfDRc_J$ z=Sw)VEFlUhp>8w(i7#ORE}Ga)XgG%H)gjp`SG5l^rmAb{BL5+3%*{>DZA^9>4sWFT zP=+i=p_p5w9asO9rs*UmVD@FunpxVgUuM32xgVyss=B3FVs&Gp{%c%KS6ZM46o(~< zmTGax=sovb>Gj;5x_v=Rb()rvJqLPLp1TT=rG~RknBQk_6u2p_@5!T(E2NJhO*PUN zz3Cu0&cF05Q98YCqsJ`s|H3v=GKN%XdwJxP`%+x1BUHS5&3)K5n|xz-*pYLIMn#aG zd>J_?8De|8#~j#keZ0}0*EeA%HFAib8rQ(DwN`qTBq@L#)rOl;FThVG7x~d~96a4Z zRcS6>6x~hgwE8F?@;)feC7s)BX1TDw$Vl2`gCZXjsBS5^M(JVneFh$5d*s5u(rkp- zUpsV(XtiWX)3xddk|-LpUpkNm3XP;m6fu@Fbr1#{MZiVT<0RZY3bb0t~` zq=qny<0@V~d4638A3Ecw_WOsn*BxbCvf=!lP~G06ok!L}HbaPDhX8lS$GITVP|JTc zOqSyEo1*V0tz-l&40gUT)Qnk)YMFq&YMmaw*-$XvLnO4g_ZV}lWBqGnJ*rXBNNH9t9?rNI zz*u20{Jj<5-k^+m!dNO~x5isVT(gU@-2vffsg1ZK*tsazll#q$v_czo7i<2s$Xr0| zpdMR2N4sA1t`ukj)Z0~J0X69!NP5#pL$IY(pI+ec#iZd1r_(IE?JrV;3APl9HVf4f z)DZ^_H>yAW<)?q$Mz}EX#lD&uH#U9fM-oFB`Q2@ETFyQ!$TY(`W8YIOoBz!kcI&p6QKBZ7--Zk*)= zewxz+8CUO>tIx!GQ&BvATaJ0Yt{z0;mY^_r=;Id>kh@=M%;{VMiw7L9p%PURy1hEF z*HB68YvHG%R>M1y@-A5crZMMIt56^U(kvS5qd8mtx)5;;$kB6F1dzqgwd#u#Wk8L} zMLkX#Zc;2D+w(Qltv|&DPnFZ~PS|Ki*vwJwJMT&L%HhjG>vo-@AP_ZEXGvn~%DUY= zb}Yq_dMUyp_P}E{tyk83IqCj5n=sd!y<3NGQwL6*riHdQh>Bg5vKkzwS20OX?xAYA z0qpxgYg7b_uqJ+f!pP%gRj(E~P2O^_em;gnuiw?Xz@MNl^w4Qv|3@iyXAV+b5=6U% zRdhg2k4n_2{Bu(iQQ5BO*5GCuwVF_{mguYnI_+Mv4{gg*Cw8KMw)A|N&M!=c-u)8i z0MrSs{pj8m_5}6|C2I3Hn{oJ+tU9Z6BW^d}Hbv_Ow9e8vGF9|9(@ZskQ+uc3+g`}% zjRJhSnCp-arU9LfNn&$drjkl7zS-JrXcDt~kbvw;!ANehQ0 zCzeyQB_TU*c)Mx4O2T}JS4_<)Ypiv0$j&-(OUu(hOv_CNi7VJ~+{Typ7%$hm8M^0Z zVR<40cKa;aNVTu^ceKQ48cwPY@#3(-F4Q4>Vj&R;+7Pqf(kc016>z<@i4HQQZ^wl*z94+>`hWh-E}UHS~41q?{|R}Qc2HK@zWn^ zgl+iuR5P^S{1{iigw9$&maSD`^!SbElp(yaXjhG%Rb~;YBwAfjo2o`r1A097wLTn% z#<8Sp+tc#=jEEGrODw)Ri2kkSb?~E=rcv&%9AKTM8 z+Ik}&=&&iK@KFJ9mF>ZO)`6c~Dp%&%zR-7| z9e2M}F?n<}tfJdN-5@-|Yj=fH3QAf?ycT}Lh5VXd?N=(kR7VMqhaU}w$lbI35Lbga>RhZMWE<(R1AEyhH9ZgV9P5O3ERNj9JxhKSg0L~G5&2a#sKQ@URE~S__qa7=-pTP&iuvS8pY3Z-O{i|am zjvMD}K@*1B4d?S9`%aAc6en1=no=5gxZZ^?X0G| zb7a(5>=|jB1O%@vTAy3d>&cgI4@YO?R0(aQsz$Hc&N%cl%UT&-B&r5hO?WNkOf_i2 zF8M4w0CW|a>3`^|=*h1PA{0DnjM^@)2X)Y-$b3R3=!frXa_>zDZNgN(d^CYl)XJ^S zfH@k$o3`!m9T6OLhK6cz{HZhWjQoUrhR+2A=HNRNp2@u|3}OB{Gmc!MU89~3b|Q48 zVFAB6Tk|!%h#5Lirr?&`nn#@xL{m~oj!90gK_XrcxZ#_d2+sA51cH<&){{6Z3T?&Y zy|IH@_ekZVv`<={GohCINeQ~a!yy~D0>me}#A7e@9k;dI%P+%wyoZcI5y+;2HJT@i zvJ@x9bww1uQPqT6hF*9^U*Jv7yZ;4Q&~G+(Fn;GBk`ljums-r`ei^!YVv=~{X)f?^ z#)8BmXHjnxyRmF5-A>dcCFZ8qzZN8zqur`+CA~L&kv2f63u}|(7`(uBisdNP*+%Mr zVq|;(gtN7W)1_8Vt{8#LvEnOS`EW=I0>qRdSLw5{ikO1Jbj5iNBTq6XFF!ADR(}8j zt{hl+mNT=m=gH>f)ZDc};E_8cCP?u+w1|nZy#^H`qvQn+XwxS;Nd`2Mb(z&%h4@x~ zF4NtA^jqFV)re(SaqSM&Jf|yVRklTG_?Os`08||C;u$4;I8qv(p4h#QRL&LJrY*1 zCyv8W8q7ASxtS+5z(FOy2VcJgA4FGHy~~d5Ri8b#ig#_Df8SZV|5o81k@gq0bwuU4 z)wuz&=NmkmmI5xh<--hBgsdLNEJNipEE=tD!(yKC1Z&j)Kp|{53>?p;!%IbC`3d>2SZ|w{PS~lGXhVP#pz4AU%o5?pdu>`RdgR~Tt zkJTIBL~~2Cx*I?IH}%_Ckze<12Vuww1)x84KcIH()SM-Hj27ko#Q;J=1Kl2Xs?QMn zw}id(B@~~E1IaVaKOH0$ht!CCK%+itz_ro2zci*{QcMdI4|1FeQr$z)BJK)nMWRV= zMeS|>B;F`)IMAp5Zv0^_xR|%5s6+_K;P5e23r1wX5J|e9tLlyA64L+hp#RuE4nie< zR{*mr*`n%>_i6c@*}1b)(3rqnGcVs&wqJP4c}!5Ns4HjK!!upu9q`dmv95KLSuyqV zXJod?lB7@nLsyXy$B2-|hu&X=$xtL22|s-ko7*AGk{{aS_-_{ZAx@TTg4G6zrjs$m zlNu#Ae|-q6^cT5Zf}n$PgAY*GI^(u2yXC|e+lzx_q8bsTxi_6Hf5Z6V#s7TnpsPUx z8!X$tAPOIbf;9xE7V?$;SQV*Awd{h8iuy*I_ac9pzF-B(r?VpoxE3d%_O3!230x5= z;ql?-OM+2@$XTW&uX`fUE|2$oe7$`ybgF0%3L?iTpwc8ZEDsHIVsKY!kS7Q;qvonN zFCVtJ$tq`hNSu2Xc52?V^mdNw=s$?xpf?>|wuXK)oYKGPh(nUM+L`{D+Pc>kMExos? zA)zWu&6TX-cr1(!=&dH~x#3n*Tm}G2-3PU1^Zw5K2i@b}r!Jx)9G~1LnXDQ3_&v5c zEeBpc<)xBuEV?DOHgg<-rcL3m;0KEu*`Cn9A$eKaEUF$%{I99Z7WS2|s|Nld!~xL6 zR6I42XaXD61_VZNmnqr<*Pf@-bpTo=Ki;#ghnJ-x@bGiX#+U!N)rJ;amoTzsM*uMs z+w4O{7q=Zcp40k^i9-uYa#wQJ*G9-~$Zw{jWY#KVZZJn`EoxR{3%Cs!q?73Q)ziOm zdf)^CiP9ouu1wNw7M13RP3AX{H}jsTL_Iq*?+^`A@CaxeKI&c8t0X5@TB%)#{(Z*~ z&QRVER0^SORZ!IOi;$AGl{OE`+OUtxC{Gf&FeSX`wWJ|$-3NOq zbn(cS4=* zNYJ%w=P%6b+_x_`W@&2YV#Dsm7?n>>yft$5(YAf8aHZ$;)a_0Oj}yP{pTROqP>LFr zZux@NdRf}v<%6p73|A>pxhnTbX%M+#03x(RNX&Gn?=u#WE8KwAM7%dW-E|#P>Alt$ z;_ml%-+e5 z(^s86%1$3BI^GN$pl+0ahaU05N^y>alH{GqCT#v)b)1@rzt**jZMR%b<;X4w@k9*ZANa+Q{5 zifdfZ;;uT;VS}k!a;<5@F&j&(pVP|R>XCHokUtI;+2&fm9M#5%0&B}tTXO2?@>gW1 zz90qQD2B@nZQtRt$5$m>X-jE7`cT}EL*!O(ErP9Db5j*^SfC$kzv3OLt=s>`^lbqN zlQu_-O(tq~^DN+W8F(T{bErP-XcQejx_tX5C0kZ=PlqxH@7k|Q#o0*)$!igdr(of7 zlz`o-O67(cA3;yKv;ZQsP^)w5Yxl5933u^ERg3@6nV;Y~ zL#=hz?}bC2n`wvt=v9~d8@Hw#YUQMZz&?D#z-6`JsN(ZCHb_r0k2dev``r8S8fl%X zHf6cOIL(kBKXq47cLtfKgrT7R_RGX~X$>Qc_(Cn5D#hsX{ltlR7J9)F%})$FzqwWY z!ZssQL0RT+ZJJph5GkR}SaLv-*^rg0MBr?exg0aIyPS8MRaL72vLb1@MbN|$%c!K! z0qrwf%n)yD9((ufM;FzD0FUw7H+>MLLK#(~xDtePVvRAMT2n1OjMyLRnwl&N8=VFr z?}uAlT1n0zq{E)yvJT(sRrmYBUJw7RPP556m7f}$fSY%@ZK36pd_EhJ5=OtXyO1~m zDmLoN+kC@|=B)25Q9H--G2?T9{Y2l*XEo}@KvCoHsO-s-xY!Eovbez04_cZUbb zmFHu3+;IGH5|_dY`&$*!u}|4;a|qa1UVPlw->M*!*qcAD3x!!_W$lHuYOwu!)jp`P z{?P^&*%F3NxsnGw;j4i9A?eU-=#|SLOcRL(jWSw{L%=;CrFEbO^g(UFCIF8^ZzLmQ z@PXTkO^;R^rECX7R6+ZZ-CW-W!hqo+;y4BEOLo;P4VDfkwgPNOdmO=M%Ok^#gT2I_ za2kqtN*8OsBx9StsQTYr?~?y9b}ie@FNiZz+cj==fvqK%4m{ksC@gvU%f~ z6A<(!>GCuPuK)D$|dB)&x{I0r~ zD9@JoHEpzmOI9X{)weO^*C6lOx~ETmz)B0+DTT3Zzt)@0d0R`x~zf(fr9XcQ?xGWc!GaNa{p)w$x| zv4q(W`N`jSxo$@bKlP2r!#-oOEO|eqQi_VHR6+fp&@-|7NX8lzPTlET4E+T4Ma#m! z#@$d;@X$8?PLex|QZsRP;IQl)d1T;^;iYB(a8xU5F>r;&>Jk<6LB3x_K+};Hxz^I} zo5BWIWpxEQ53t|Hb<0@;|Kh@B7o-#0*ta;nEQWRe-Jl#Fui^-pv6{L~ zt8(wMFzLApT8O3ychPPmcvqR$=C%c@|2w@S2Rt(E%SJ?@HEcMZ?W+*`D2?b}z?X8s za=|@eZyD<m~FAVA=U~JoNbmZ~ z9Fy)!HTvowTS`iMzC_AZ{G}b39+@6MPjBG9*bXCMx2q~8;1t!{Vj0nE-BZ4?b7#n7 zu}8OCEh10Eb+N1}2s^*G_I+WFY>E8%GMG6=@~D2d=V(xQ2CCW6s3%Uf<0zD_1pRs2 z8H_qxOA~kTO}h_vqfpj(YX1pYHF4vqQ-f76LH!rli#bZBZ>*=#k{XYrS2apnk1A5j zSzhBkh31|6^E*6?9Mu&}6a0h&#k)tXX6Dw4*|Pg?h5a&%^ocjL^)5w^?FwK#KC?QLB&*R4Gc=0AAqz-;E$ik(AI(;S?u6YJ#t5Qtn=7>YAN;;|5rhdl$u-Db4&sN~%~-W6m~bxq=Q1r~ z$=Hu)SDAK>SPf^IbpVgqHRC4Fw$9iAuI>WeS*8MfJQ@_!2fu}Z>NXl8$f8|^`l{U# z#n%B833C!USv*+OHoQk7&(M7yiYzB?c@>@k;P4k_>)8yQIePwm3zM#YhlxPJ^td7w~7-{m-8*Q2p#_5p4W<_`2Jm20uxx%;tu&tG{gK zNx;LBNBqH$dalF>?q?m*fs?O6n0|BYwiu>$|EoJYO>HOGEc+;BmraYo1ES%`6ZUsL zdWOU*kh%RoJF)I1{~Bla=G)S{Rt2jnIfEW_OrEuAWIRB|_tbA=PA~ayJHJ8CpQ0Br zm>GCpPj>Z%mye&mxf1CGz4#k_saP$z?U$v>+u)?x=qs-4Q;oC+8kiuhWxsi)(H;O` zb&iS#%|_2z#HKHFg(vl~J8@bo<3vOQn@V2g>-IK4zUIT-+)H)G>~Id()vSyzn2nBz zHeSgZ8#+HAOZPGi=$nb=aAzV~wpc4FSqgR)D|5PMIL!^+kj;_}+4%+-G&`U6?$XS3 z95@sdZw;0mx($aNl!cv;er}KCC;S60oai10=k$aOq15_&i9}8CX5DZM~ zL=6kZgI81HpSChGnc;KCyu5aCLMuuDOGSn*muTxcwN2F(2>3&lN*>|aWdVO>3b1z| z-b$WQ1?;^BpG%5q18_OcwX*++&;1Y|Wix-hGj6OCj=?6GWAdB@Ji zKRxc30GtZ=f)+}f>lj@k2EbCPSHAwT7xJcfsCU2cl9J%~mo6rT{7xait=RM`J-TIb zGAgC?_KQMyTe0DlE0B0qMi$Tp9D`%eCd_?um`${5G+C?&fJP2Aj^%Y_N@u`#mJ{7UR7bfhtf-?<6 zBOZtBXJe%yt_@dChxx?fTy5<*Zyg~fbzO9g*-eN>3H~0=QyVKG$xkp&RRuV(=LORW z5h$xN22CuX8*SU_r8^Yc{eAj$keT+8)3;>5bla0`#633^^>kOPzIX}mUCARF-eN*C zkbI#is|&B~ALj;GWbZHVGH-G@gtUE@8>intuAb~St@O2MG1(vUwTT;P8- zTS_kXD7ck*Rz&^oR4o+MXem&Ya6t0Sr(SK-A{+3b^F=MS2Oiq6vjmzt8?E0WQO0Hx zSKzRud_JY*`H6%@{A=}E?xpTrO4COit63tRiwqaiMyey^6So1#UBf}^u$^~PhHI|7 zhtDt8{BS#hl^69xjY++wI_7x>0fW?e1KW1G723FNWWM^$J@@W{qh!qb8IejLRJLLd zeg676vpG|dC}b6iuk95@8W)aw)SS7nxwjZvzFC-1^N#Rpg@)&3$Y&`jYA$wec&}mV zxt)q2IHAM3V6T!SF=ydVRB1@vZ&6%VcU{NktdDJ7nf6P2wcF-Iim~`sYX3eftf9Vea8(0iE;I0{Mzw^6l8DTsv|bMjr!Jm zc7-PUst(%o;s<5lmQN;qY;)aty1LYkbwR!1g)%EL1ihGvis>jAXtm|T&Ane5_$s*l zGj3pel60}5MfLjV0`BJJspC~qR|Vqa$y4t0x>9pGLYJ*Qtt1NNGzhZKah46W+kKgQ zWaE6u$%Ef8S$%=FD(~JaMHj`Fgpn9(&7felOPfS&?+yMVpa09M(s3Y9U12(?; zA1^ChqpfK|qzrPg(kK~Kl!hVTHpj;!2|!8r?8v=4@xHZQZOiD-mQ!cHj}Vhq{DBqA za)N>HF);f9uD8(h;ZLWX!I>LzZy}OI4XJU)*xZIsgYW-mn<^^ORGBXqdAtdT<82Y7 z_1-b6e27Mu8<*}08wiv}q-33Tm9yT@RsSu<2L@2X*}U;0+1@+#`Iso^N;tTEj3YV; zVWo#RYsb@33+iyb6qOnFez@}ZnJd$~!8^i}TU43>5t|cDvM7v&qT(nU=N1n*cDe_w z((3NF@>dvh$rpB)xwlMeEHv0SSs@|9oID4zR0(TSVOMVJu#+>5lRskeg9Bw<#UUAp zmF-By@$cSeJn@m8G$eU6HpVK@^#8_!tI z^WvfwqG7_Z?LBO#ucuB0!x6vHWh@mR3xp|$v2t+zK0;r0f#~s?jB)p6732&t{+osj z7#Y~!&G;`tDzCvGstvp&oy;RrwpeHhnoZci2yAc;A3o@d;mQzHf|vXoZx-c-j8Zp# zf?eq%d7cqxvPY}q!+klH!+uKq-%rHxSiJC8Uk)@P`wfu-m;aE(FI(baIhKW`@MQI! z&%S&iDHBFqRJJ*e%*$U_TiCo`g|nO1EDPgUy>Rwz;t#>K^8@OQB~#1D}exrG_R zL7v=dZ)4IT_E3_xV&>D5Td3&ta`6lc6uU9x?gE{Mfx+m`kKATfh;^4$jipX8ty-L( zy0EmQ2Hj~g01>TU4Ad>P8bB~@JiJaLnQT?yJhYsy_?s)jVZV& z=9N-KM0|1*az-NH$>oN3Ajp-zuZeheOLxcIeZfE|qlB-iB3_!t&KunVZ#|tHKY#kQ z#cFN6i!8m8hT#Npfr2eoOt!Yfyyt_7${WJ5kp3-&fjkJrI(DbYH2%IH^1K1rqAiG( zm)35LuN#yfg?zA>D$*xtfWux-?rBR1o>a0UOwQjK`~~MQE$H>6IW?MLB$Ee{4wAWd z@}-ex4*tP&;h^|?yRB3v8C5fZD=`YMU2fT~;_@Er2-e!+^{h;K(#o4E_wjIzWR#V@ zgb-NrIXP?CaNr^e+0m}nExHC+RU{`N>hnRZHnZDPF^r>2x{RN5CpPNQtJCD9MC?^= zgC6>yCTWBI#L2@NvK;jU+AiGU7yBXC8&O&D$8t=WAs5fbKAg|R|Eh;N%weSSeyb_+ z`*757a&5(K!IoM$Ic0?k_phEUdji9oJr>|y}_AgGc-cw!PR*S>mBD@Mufh?+65{+W zmmMh?hvSb}^}+2w7ue*{X5{woR!V~=Px#O}lH?4~iGG}qjHD&KrLremnYQlO$poGI zKrhitr_gh$Jjo84wx<2mxcRZ7SVJS6 z>mophBuhT2a9g{F#Y8ba*m7}qxz=N5z4_>xlTW%1Ghe{`X21gu-fV-;j6{)ZzyO=hWAHUw?rKV|2NPne`Vq^ z@trDV30-mW<(MgQZw!XEhrU5z@;>eHn|O8VNHCs~gL31alZu~r?N)Dbdt;S|c)p!h z@d*G)Z-=Y3&hS41xi>z>~Av2;0MAj3`3pgpp~zhuc_T1fNQuK_W!t2hg#GCr-h?O{DH zcyHz0^#fXa5ppX2L>&(agH@>KFEN^S)jZ!u=K5H`>^k6OzJn~XT0R8FNnU^mbTNrC z(~W*E0o*F)KM<0XD6~KgxYs#!^trw5ZPnIeos&6}QOUB+c@TJ3)A%ci{({|S)@LdF zq|Y@otfD~>=gLVX#hd(+TEBN<=^za`+=gAvZee$bH3^;PMX3d|7L|+|ekaFmJstXM ziP2&atB)@&iEd2!raxI5v33rQChV0`MUYDRxnw!(l`#6>9Mtpxt)G3?lU%DBz7+nwazQEK-so zNi^uWod<|kG`*LK)Yr~!=D;6HRWGSfvpXS~v!!9Eh8wq0?3J#fzv8IqPJ;5&WR=2b zdc#2)!Od#Grn19CC9Cbv+H9W`^EK*b5;hlKOPrP@@-@WGT7cB3fh;3k#cM#cx*j*l ziVaRNcV3QwoD->zfF^;;CKsbuxkWskI0&(~8iZN9;2t3Cx9P@6Q>aNxhecHpFSrpn z2}D5^bSVA0KkWdbK~7^7B38^%ntraJee)byA`n+a#4-hn%oi+XlmR-zQ4r83n}8Sw zQGjsH(dKh5TGa~XGD$V0DP?R#i6S;Lu`EjFA#|sEd+xT3n6*iL3i9mVczT9CYyF_u ziXO!l(=!9Mmn$@}z0o>*x0K6;qnb6HhjXc8Qma-DFqc^g7FPNyiu}i=zFv-?C)j~! zaY2xi@3|$0-jG6NdwMA~21$=EESH=nwP9k6CQ1jS3+9#WVW?WC^F2OMOnX>@0?SeS3Ch%pro~yh3IX zdE-7!^$v^!goyEO=m)hwnyFwY^VZ|e7iU+?PE|LV)JMFDj8ywcMmjH#gZ=-ES6r=& zB=l+FQOef4F$09;$WCr1I@c^1S5{i5f5x&f;cCEfrDt{(Cq3KUUe7M4gQD}gYOMp} zn5KQ{2=(?9Cj}Sd9gq8z2QYog^1Z32M;ieJIoS>T%osLbY|AmIf%R0ic+^0{48^Sd zR}*YP8HBj2%Sj57-dsP{t$NcFu9!j0#D5v0P$iXR*8QSodYXJRm_&R#3YuD5bRMAaLRK3Az)*F3CFXVn_Oh>Qc?! zbjJj`-nTQgkTTsZ^RJ9=d0k_9vsm@S@37P{G$Q(+vYZNd;S}o7E)J*Sqb(;ypMUGC zF2F2-lkVhE1ETUY5>Cq|anB=THe+#vRM)e*t+&SaR9K8R#eh>aT$W0;2@DN`T^ibRpaX1!OuKB(vjkkNkq zr6f}#cWp{cSAj6B9hW?yU|Z*~3lg~=k`q(;1)eXt+yR~V{sk6L;e)?QE&Av&5Pw&H z8|?6-nIV654BaF>3Rfyq6|^K<7042W1Lrht67KA7vQZ7f{ufvZ)G}k~_0->U$ql*} zy>bY+)KkMrPNee#vn$q+q(qdetHR+)q2_z!p@{Dt#5JUyAYBCm1$3Oy@&dpoYV460 z^^1H+)(R-wu%rUy%-3oIDG_IjL-fuB>uYE5tQkz84Sqxv1XpJ8KKOY`1`4Vi!ZQ}d zd0=IX1+P!Eo}|}w;;tBIbj@bp<)E`o5ygnV%b=aR=H+uM;;&u44&%>V9#@~Gc~hix zsYW~ho@)*W%nq2f={rzI9DN2r2M1=*(Z#1XHp3CT$;|jAq}Cif+u$z&$w&pPfO@r3 z7|drER>Yp&M8Je4^S6-BfMjbk+>=h`?XRkwUUrtB5%ce}B0cGijG1D;IM*(k1izH! zRz#X5tWA`pr)GDA^8FqN-E^sy{w~~WdOt%LWmV7^e+q;Qss750e{~VhPcB(w|GIoa zWf{lU?8P!w73}SbUm*FoD*wk;EVJ2Ak+Oq!<;#z5RV@2NTzhaFz&L0e`qgSGOPM>w z$OkoWl`gB({5}b!8^c+zDH->WzlYQQb)St5Wg0{PFS1q`MyrZSl)JJxTGiBiT$xy4 zUzvDc9}D|PZf@lyVp?aj>l`8&&Y3?9GjeE$P;x`P4hjVqV@&Tv{snqh9BMZ|;i>L(Mm>X5k8CN+em$P3sLWKoxfl zE5D5!+jYiTs-MfqM0MI}{9&zsONIC>oI9KuI*T{^k$4wUQ*w)WpauVjr?U==B5dEb zq9ToSgMf4+EDh4#EZyDRjdUyBN_Vq#NO!YzNOyOCimaY=+pp*_JqF^q8+ZVUDiov}x6s^Jt!(o%MeJD- zIz!c{c<`0E6Z8myC;Ofp|o; ziOF!WRm7}dIQuC7y~`AO|K5gnkHZs~lyA%ns3TGutrj|O;^7Lov5-DiVy+^|kfxk` z=z}vsODTUd4L6&Qr}$@sC8_8SYnTau($rjLa)2KuQ%yD%c`FSM1@<(4GcO`aYeA_k ze%tYzl>va696Vg9cqy$XT4r%ASrO;9U70IMg5_9++H;|{$v+pq6tks;6IcMm=7dYx zX9||;J3!GW?*y~?7=LOcz1B|9N%yV=$DS$4^G7w;A zRJ4+J!C-UuI*kE42~QX6<$7ing9p_(kWXx$y$JiZHa8l!(NGRv$%;Zhh_NAW|RwX z9(+OTf=B_Ds`tmi6r1hJSeKtNN1FD4P;+SZm6RN0s zsjwH@<&Kc6bW&wzEWj*{fP;><_r&iPA*+utNU(vJMW?o?j!bZxZq*wcL zZ8&fWcJm?a*W@(b&FgXFlN0gjh%M*+blIJ9M>fCd09TcmHAL`YzHji{u(%c&-HT5l z#~)r~MOiooyew+h0M&inc65dxx%zRfOXvhyxZ$8$jo%+Ql5+@BNoT@UjY4XQ00~0+ zh^jCr(7bP!EQ!`c_ORbJK3@PUIl14@5ICz1R3G4xs>83YqkkSiozF*`fKC z8DmLxvW*5?c5Uh^)qBrdx21EyA44QCJZPi*hMB&o9rO60dh1+8yX#NQnNof`%yZ{G zt>3>Uy{;lx;tTGCUIyLEr5Am$c!(mNs&4;C{^#rjt8LZx9hb6DFK|TS2M(Z-Rni2G z*&fwS3c7sUwR5}HMlW{m{hMv7EX%gEz3x$`()@oh@u+6vQ;Po#)RWSMdjHxMpz8(l zK^MIJSO<-(6sam|lus?Iz8KlrjfKy$(oxdlVW|8VdOCuY<`<*A5ZLvorEDq}(sHZd zZbo$njoR#wS>${Jsia$`pS)wm&Ex16V=uPo7q-MBcEVg6WE@d*_S;Rfd5Y2u5hodi z@h@>mlzh6gf6PoqI<<{7$K9R8rP5SE`pyZ+SBb$L&&jfKzW;Yq7<}q+VKAWORKu<*6uQuFg4S-T&9{(!3(rr_i7{^xN7IX(EEO_bv`+!N}~m? z@40`Y=5svvhs>>eTB`dwJlkdWvhH}^u4zV8rlxyQ0gv_}d0)+<*Z&r`x1_Q~IXlzh zZifO?$jHE~KySM}6#LveQS^U`gwe94K=CaNc^lCwO5NYGyd1I-!%wu3#zY06OikY! zs<2*G-#FU)9vFLfM(uerAD;&?wo~bL2}eVRI(?!a6xPpj=L_}2krNXY{U}Onv3l2n zGO=)&UA;DIKy}ndQ7?nXGVD|!%dj5N-c{t$)h3o_xkP98Qmn*56RrispCQ5yvrtIe z>bMFblZ#08FN=o>5{4xY`C-@R=56sE&lFQ(*#^a7*H{}DI_o;?-K6J{RU__3M<1RN z!x;6pMQrfzeV&Ha$lH|NsamRs@674!N32a_*@-+2IkC4XAHUk7h-nb3U(CQC&o?C! z$q(>lM(X*R702f-G=Hmgv4zgI^|M`lp1?x;<}*7a(>9+o9LS>hROAPbWRl4K{HKxn z1il7X9uM8r7@X;U$L{dggAryi))8mcddl$x#3?@xFF{jAG*HV{Oj@FTpx|Qw>;dno zkLi$*!^WEE)J_6RJ-{2YsYbtqfVdrgXwv;V(5Q)l@x9I)VT%nFab_z56JfT^9XX)g z6e6)`O_sB24=i1kfK{Lk=MtTb`KG2p_N;vcPE!78)i(<`sYeRrhMYJm99m zGqaU?6_YQBE0rI%SF#!p6>9Yk8e2sAe#$ueu2&FcPp;RG@-)c;*C=~`IVyLd@)7UaZ~EU=qKRlhvm({eUp}m5x&?c^BRMM`JGJ_ANi3aatb^g1jcDpu|1mEFgPjgjKZ-LQvd%Gx?^36TGxB_d zDk19*E{!Dlk!F03$X$ad$5WtwGBk~e*6AKnC$`$@0g0iDqkyUhQnt9*W{`yvYGY#()EwcSI@ zkP#3>R|_a-+-QVATZBfuyO z`yWo#Cr%cOtsxm;X7l)FRGItq4xExrhXyrMBXL`?I1Qp=BcBJG=bQ=Q+^t;K2)Mi8 zU<2~1-70-QH_nGDEGbx$twFt#kz|{HL1l2ByEK+Z$Los^3uG}^8Nk(|r~6D`Tje2gGO8b|9 zZdC5Sx=|#C%6FP@ZxN&o2$*=}s?X~lZdRL*{w!*CZDpvksseg3#l~Ovi5V_I;|R<_ zdaM_6)7Tq#l0olx{6qQveYexM zg-gPT>EcF>=%MdMlAJ2xO4iS*8L|HL4lKB(aBnR+X?XakYOD36x94+^;!8+U80?54 z??Wu54&*4h-;MzKJIEKH=4Tc`a0smHVB_kCF%WQg4}fK%CDFd8!MW@7CyIz1oh$`+ z`oYL&0_>^@e?971L}`sl^SX&|deo~l7VgX#$*o}e5pz$b1fWEj7L7}bLIKnbmr#J^ z;K8)+;)l|8080o``E@fz90`az0jVczTUDcF2(TKwzEC*RKVPu|1Ej%hZ2@K)<6IjA zdOuY8D*#-q)#7BfXZfCEMm8(fdfDk>556cB#05)sWq)I_-8@zEexrLY2z~#?MTP+Nq@l{? zY-`)0eeyHfAubj|F|@;r0C%aVO*Sic z7KTfzO0{4$|3)fHS{x$f5vvbOpft)au1-$tHoFbkVpp5Dwm_*!h@RgO`ZmJighKl5cWt0=j^vpukUvpojE@rsXge4 zTLmBP{>^y5^YLHBAfk`!Y-wTp_h()vFA4?-#lwJf3BGeh!-iJv<;u)z8=Mk4z>vp( z;;4NRO{T_DI1?F({SQQbAgbhDzG5cmVVZz}ViZ@mPi&0RGHQ#Ned)as~rFDVwchanp#g~IRCBcCDA)yzS2m&|a z!?VVSGfJGL(@hGu4s!}7HH|@e>1)5tiqog3EJB((xR2_}H@aLughcW%?%X8fPtMQ* z5D=}~-TPvD&ujfLt5QM-Mk{tX{2pnxu;emH*;KuJ>|4Mj8kkVSjAmhI?m?5eE@?fZ zFLT42gyKGiwUofP4p>A@R@$X}f?#7ExIUNq3tRMF=?xxOORJeVT`oVwA>mf0f{G4P z?wc}YxN3uz1_o!!*P643Ta4?Mik0*+&I6lUA&jFTLuI8}UXXYivy+{stLtxys@mGQ zYAr{5Q2wso(>4)ZIoYmkjh5vC4X?jD6;BfuZwao6>>LknmMrd`QEf_1?vREDxF|eb zk-F`89$Z`t(aV=j21cbjRx z%IFv5@n|A5+OjTf>+9CwM_ilu$r3xgd)Pq_myj;!uYEdBM&6zXi5tyTQj)%4c$BxQ zXx46mbfqFSS?|N)y2Zt#%;VBNb58R<#hEkL4f|!%d3(JsS`G}3i%GEZWBOkNf!~w| zh*|-Wo=R*U!d^a4?}T3hSckS0>OY6*Qr8~8qly?ruvbZnv$e{gQ1pC3=dB#jphV@x z(yWyp1aVJH*^%!2)!y>Lk%oC>3xLW#2g<1edz>n zv?>AH&*TUj7Zq9SwE@~HMM(&2s-8dzsF|v^ECdxYO%EUFrI0G_?K;OU2YbPrB7 z7Nx3~jcz^Z*3VzN!U*yv$dnjCGu(Cde?UBR421*ouErrl+yWjh=Z>|XP%u@7uCfMI z_Z{0(UKA9SAvLvnvAbJOa8l4bof(NC8=7OOhmyZwV|ZiJ_&VxnXFZEA!UFEfFEo^~ zsT1eAma|NULkg7Y+KyE{ArIo0zi1C1?BUFYaORyk6&NihU5b#ITw!$vB+XNSd&bUd zXLk0+y4)eFHz!}H8_b^a?n6#(xWs%{jm(;`*UcAmM z%;4=lw+biO2YwWtmu=eQ*Im@xmg1AU z6?*~RJAsGW>2gp=sCa#)v>8Icb(yG!yF$ixW@Av);^2U#K)|4yPjsfgiZ0&ZLMeB7 zEx+bZUaN1peimu-i#Ogy>aDQ~A|ohdM5*52+DWFI#lG2?UKL2OdX;O#DML}*8X}-4E|3zFM`K=%jZtgBxD6P&w+0` zjdXTFVtOMOqMF(7j0>3k#GQI+Kvz0;3k^2;%7Ao^+0*H&%a`Cyu4nDddQ)I zJfYNIfn|Z!<5Ra_B58%nG?pYDfV z+#jyS=Sp8UyFYfTqh+2S-i%-m!xj>1by7{8s-biAssfDD$k@Q>jo-GrIcv|eI2-;s zRkD?VzaHTuQEMYh3e;zfivJan6T($r{l($e1DB3Fyd5@|b1hfiVVgW7e7%f@d~Yl( zpH-4jkgT_8I>R1s2ip%qYcCH5!;c>KBzwQ};pDBTX0{gujYm_454WhtOWucPV&}PN z5n0AEE)eQ0@m_5u(twP9#MokIVsLp`iO`p)Y|YyVa@Utjj)h0MYphC85inC*|M|RP zO2q4YmT!D{%7c+fF{wz~ZV~^XGB4zD<;;S!_3qs7cH3rU<>g?vYyauRL3>aA$5f%& z>*@V=rFrpmgv@TB-mEVTZTmZ3C1*RJECH~voSWA|U!PW{EjW?Zt6bdNdG&lgyP`f` zzI3bTY_uO$x3|k?ykzD`1XId1-(@+GDiw*Wpt?8RgNdW%L4lgwkHyY+fZ*ypA+Tav znxCz2q%F;-$b6Jn2!7xBHddx_pPYy2G_-54v51IeT+=en2M_bc11gfqeEdmcc4d@V zNFdiQe;_@hO0S!A=7FJ0{SV(a<;~yQ`_Sk0%}+0Do7>5=C@ zcw?wuTY@rbx|-*ih0F?hHW_M)!%+M0R9xM$tex?j=&X=P{(Ol%=`J3KGv?ON2qhxJ zOoU|06%4my8B2{-c9oAvSq)aeA$SQ;mpnl1;hn`2I+mvgbJ?x$e;3(m70D`5!DALYl8oB_iSf#?HRz%x{Iodrulc1A+IC`gKQB4sO+8%^%?;X zyg!6K)}#TGk}hKsdch)FkS4XfCPbE69{>AUV+&y^Fe&MB7GUml&Si@wLYygy`G7nX z@>wZW6$9cawbc|3aSV*)_Yg)euqjOqa||5TRsX)IdiiM^R?X)kV<81{)6Ne-9yT~Mt1_h;pucr>jE5wCv?@v8pWn3vX?)V z$uBAdEdrbRp!Wc*{XcjYp(`o;h%i$<9L-ib(#HTv)g$@pKf#8=Mf@7VKTUV%_R1=P zPDG(Hr#S)5=mlzH=E;8*&ES?IhaihGIYiCqE4B)C@@Qp~cub3#bdrw&4y)7{mRIa* zHPgrul!n2IeK6Pv$P1F@K`79&=&(6+`HDOsIDZ*Klb9RKD(uQV#T-Ptihu|XQ33V| zx63I>hmaQbCCJ&l0oXOSaGI=Z&*eO=D`BO^8-*|lfG>_us_ElZBw}2+i9&E+sA8Cn zqF9HMq+eb&fu>z7*H4rr0bCbw*v66!O_GeA9{$XW1sjZ-)KyxZScz(GIIZX)kN_zL zd4ZzE)}#Q&a*V=~b)7ZZ#nX-Y6L1V!<9iYj2+_PGWaB zt0?d$)(~M2VU~Lu&;UQeB;tfznK#K57^VS=XK03Dlud9ntLPH2baYsQ8F5|FjN&Y zj>MN~(hHXT_kW5j%d3EwUBegg7#*wj2wnYe{jVW1l(j~?BdL*!R##@bAbQqr$q?GF ztURnWB}IiKpLr#?9Xr$g-)Y#_KZs!tTE?xx5~|P7tG9%^a_RQLj zcq1BRGgSp@HRIRunIMT_N)Fl{U*R0+a`n6_s1{U>vw$Zwi2)P9GL2g^1>}CR-2DA4 z_qU|6Q6HW#ANV_loh!iNjG(dNK(ci%wIke4$VU!by36S>9Z+=8XfSZ3O8c4n*~%#Y znQ*>}oF}y`hgwhDF3HFiW$BD*kr{OFdG3|{(G8NVU;o07pLx!IV8{j{~i`N-A z=Bi<;<_{`%DduYKJ?~57C7W8NkhFe)0>m3O4rgaWWzwZ*)L(tmcaN7%oQ#uL?Bgu@ z=`e2$1Zyph-REWliRD`^YSpK-7JoO?xo(&dxoG){=-lB>xM_Bjo&uUIGRl9NEM5Ln zxtG&sZK9UQmf1VpCi4S0#cIRfuXU~^dVXM54)HEKj6Wul?hNtvMZ5n*S<&T<3YI2j zbg@)sShU}t_FFez-pKxfSmi95?v%9XY!!RjNYq|-)yg+uGZDjb6?NUH@gH%cv}|i| z5J*mI1%^y5F32vl#F?GJb;u(v@v8%LFed|U7r=hC5}IQ*=r@INWeiD}uef5z8#@w4}hjLBl{ zQ=w*m@*oJFqUqVW6Ib>i-(N`$f|SoW$Pc3Ff_60pLryK(PwifBwaDxD)jKvg2_&$S z?dWCH1MOWmuK`IGFN%K|oPX~dh1gXTTW-#7er-&={lu9gIOgRO(Yd}5X3!}VZ%ZJS z_^EkD{?HdL9A(Hu)a)Gz?Do#_VaN#emureNH3EL?tB8?!c@)E7D`D2`u$|cu4k_w~ z%m-FtsY#ijB%0GHbL!JOQvxVgZ-Hl&-3o57wm|0O`z8A(4d=>@<5uxC)0@z0 zv@8#Yu=QfLek$-Nt>~8imiIRFABBX$+N~d{X5CkSW z%&Ky<#J4YBHuGEAD}K4lgcVVhl)<4L2(ELp_dy%vPOR`ZLy9=@;6)U_Iw^b}l6(H% zbdR5OKAhIrBN?`CO7XBMN`;5RmdH^mv#r&$on}*s5EW&;ctOjdb5Vn*vmcF_$)CFp z(yNFw($SZ}#I>+AMT(H4c@z;Vs{C3&#^&IrmIc)@M}P@|6)m-n8)^09)`|J0`%70Z z>B4ifb9v2&&6U{%M$FxqW&Dsvw|XciwEd^2^ao3&p!C9fJc?4S%l9FTMauaLckUhR zLw_~YK#Ur(VW20m#c0#2cTLfRYzY-VH1?o&Uu>)j#4AU+zIuGXVN5j>jG7NoQZ^3;Ixv4oC>D&b>X=6&YM_(n52L%l}uLvkeNE^Qm@et%%bP|YeAX+ z5{YxRb~^UjO;fUNiGmB#ifWQK{i6LGj+;BwRNR#*N6Qz_A0ZOR+y^WW2EH8+otbsv zb6#DbPAXV1Vj8-*deSO|ZiGShJr~_-x=7y}m*iPM|27$hnYgTJ_x4c{`{TE9DWKry zmSb3vOQyV}WE_|B>2f66-ot5y(nB$hrs1BHiqgh;b&SA4O6*O3s;%R`7bpMAhqLF; zN15Q>zaZ9WDy`}YBfIyx9F$WTYjrOBe7pZH?&RW?jC*W=>q{$|4*UYWeb#&N;(~40 zP8;JMYtd08@yYs<>aNF8do1)3N?MnJjcwM!NGaLF=$JZ$@5`7C#=mfX60)a*mMG?a zdO^0?od`wK>$TE18EYUr9udLmUzljwWVML)&vHVgN^ht{{+)frwbLZwGl<>H?&v{( zq`tfzCyjHnk1OTRO_qu!?eql zA+Oc%_+mC|WrM}KV)w#;f&styU4{)wpO8%2sO-_WkFTR#T<2+`gjkCuw%Dhfz0hOG zLPL<0s;=OduV(Y>UGoOr%MK#XW1O_V z5}AaGs%9^WgtStREY@|p7iNR1kBx~vJo6OuG#~~S^QsfGgq+nFA=OLG=PDsICOMK> z>{EkVcsCu)uC+K>w65L5&`nmF>8iIO)vn!JUvie+M~_kK|1i61abym8dKl(5$Z3#g zj$|3EAx;;Z_O?XTnXn$DBsaxSnc&~FG21-owrY>{ck4ATL%n~H-1i&0rs2?4$a9d5EZe;eQrNnU8n?Tj&07aElxom%=n^9~!WKzN5 zs;2@c1mrrsUy!QfdZ9ANhVRXbNRIe*YqX6Z6H)S(pQW*(aR zsx0JkfPnaMG&QAd0`a&DQhN7EVY1vZjD_QRvxjd>M1%k`hek$Gd(U?sii{^aJTmD7pS65t!ygd~`@k+hWm-!u-RO zs5OqIu*v+7>11keuzby>JB^ncb6|l2B*ya}XKiLmAfqDLBo_0z@cdSqCI!#={KF*- zZb_c%G1;uYELd7}v;Y8LerjUmJ9?KiJ=%xZ8}rqt>dU6X5)=s7u}9QG)G-%lwfzc_ zq)`fHJdNQIu_AJH)rZ&!7yu{l10CSxovIA!UGYo)^DS-OU=I!(+PS0gO8>*a>I2W2 z?jbC4{iICK>IYZw>32$X2T3!mq;K>KW-CB>b+qb>VKGpz1$8Th<$IOmXNQ|Fe`q&_ zPDq$O{G^eK2ALjx(Eqpue65VMB|8R#p&}DKL9FU1+m{~4wpnB)0BH&BqiuMmR3EGF z5@PaM8j|kto}BP~bc`+_<=)p~dh(yAv!xh>9j~P*fS| z)xD@F)jicc-N=yektoYqAvVE=uB)!J_8ZFSPc9)1cwjdRljESisee8j4OrAb@dM8Cx-f{V_3|ps%x`gwakI)W^l-|Dv;Lp1T;d9!b7@;A?v^? ztRf zJzAFtXrjU-SN~mzqHLU`2x~aHD!B5Ta=r)f9Fr)w1RVR?&bDXQ`Z;S_$bo$C5&E0%i_>4zUEBNuNDk4iT>0?qR2$rF5=_ zxaPu$dP;T?lvD2MTiH+rkUgV86pwKM)f}V-XEy!&bed!YOmB&U z9HdaHM8c*BsZ#{P_;b-2xbSU?48ZBqXrTWrTna$OKB+SFeDmdcT}i^!uqGmxmOEF| zu?;q=2y6rInWH&ZSl@$-I)#83EmwZ1thG_y2rRpWdctiOlL`zv@zZ{5QUMEK3t)7i z;821yOTg5PPmf8PiKM`n1TIJTJ@E$0J#8iFq5Pr}2z=W@IU|i65P-_w;LcYrQ=2Y7 z@t*h$<(@;7MgdYH`4h}nT}mZCc@VNWXpsSBmC0fqKEst*zCkW+FDoGSLhMNbgjzP+ zCE|OTQh^7-+eLUuLS=Ha!MHg8sq8D!^aN$A(&Y=5MVDY2D%I2e71jbD7?&PYJ8K^+ z{FE2h0+%#^buuZ)Ol?X_n4MKA_^@B@jlB7mR871TnoJsSyQCGh1*}sADy2D?Y@QUwp0Y|SWn;+Ex{?RF>h(l`am>Qg zpvm-up83VU@A+wMzT+NDS^4FkKWeiTEQp)-C+;Xu=?g~lKRX#a@D`R=5dz0HfN==m zlcN<4*OiXg2JUP5)J;%|-ueWulyUa9ONls z#@GKl1OfhXpE^S|4RWRSjfoGd+1N`m9Lz}Mkit19m zbYY@|uTl6?eTo1~lXl(-=@LuK;VH%(4RZW9n@O-V(y)3rYwN~K#MGignii9`Gy5Z3 zq4*~0I#fu$-p|+fuBIiCsvYwj4^+AXXVZJh8z77Ri9))3u#6CP^X;?1pVw6r-sCO^ zu%^WZK-6RyQSnrY4sEl{GHk;TN8qey-0?%umZtjF3#wy^*JZEP#M} zta;{jaPAEE)}6Ec54Tstt2+mZ5>_Ccj`nN~AY|%C0!RfVjUg@pgwZy|(bdO1KbJ0S zO91m#LexAnS1};CDu`NUZo=qw4FC=nMlI4eU0Z3^o)S_dPXdr$p}MqV>cPdkqjroY zTwpw+`qdRMKuM;S13^nOb3l&-B5<0q@3Tqq7A-$S=d$GFu}%TBS4J_b9me+|gXNZD zG5BME6+Awnd_b{Vqv^jxmJlm_vet{^LW;g&tvkk_*ihs}1? zgZ-oxmPizL0XbLsDDf}tfFjUB62%SPUam_!q3#;6Ny%s+7f0I(0ip`oSX^nK_)Vap zb3CBf137njQEmQF^5f#~t>y171e%Q(Z`o~AW()fnd)r$4vG{a$3I_|v8GAWEu~ktl zAse3?;^f)AHSM%T3COH67MPoAfx19f)2I|Dy05I(Br`jJnHZY{bnGn)zzZ9-F3Eyz zg!FtiE(uPKe{ZFgrU>QWCSDJ2%pmmBiat<^F@e81#owGVpo7zGj zgoX@8TZ>iv(6&oiJ}}+F9|R(@RCY6zTd;%2A%jHh?21yQ2f}gDW9}YmNBO zquru)_so#ThZesEz}UX6G%33Wk+P@20X8eas;eZr{CrP(9ekO79v-V}v4GfWx)62x z_3z=h?pQKvW%6eCaHwA2rG@u=oA;_fY|HNDbpK|zdwV;v(z?TjfH%JU=IQwERMp>X-Ic*to#gYY3+GjxeJMlZC*#z936(FjlflalD?7t?t$qu7jKQ0y3mY5Z zWkQ#9K(Q!AYg^RUgL}>IrOM0G7ruMonbFy2#IwWCo!V>UVE^ifQc}{?M%0r?c96)9 zYynv0y0x77o!lfpj{Bm=`l1UQHC7u)`@J{$wR?bh+J%G&cM)l=4*at2Kn zIKW9%SYIWyRC{X8n}2zTZhyB5Dd}S2j=_C3E7cn*#&ll}X%xGC{8b%JtcH_6cOBSue5V{8bv7cat%z0E z%XiU1gv5WZ?0(+)hXv#Qb$5GMn^iAF>`tyZD;!6D*L2@hPzHtFyC`jDg7zF;vRn5) z$zftBY0#cMXxbRlxZ?7A#@)B4a5$6njq73m)~vcL-DlXU76w?+9}(fHh%ui=BBC(2 zkw20u)|5LQ`nAmJ#0wvuvQ5*8Lzn87gDTDii^M&ZwN{S~)88Y(!QxS8hUkLku7hb{P4C zWHBY;bFR7;wC*?5CK+w5v}kN|``UZ)x!KR1!NTu%7YoP}p5o|WxheM3LEF&FNA?Dt zw=u&P@=;V+#2_yF=3Sk_>`J#xtA1S+U4rwy948le2w|1h_vvR_?n?V496KW3=j~jC zne^6uqlm-c4qeBo{ObO2nnMCSt@_`4qSz-Q_wB0WvuNMp$@9Y-rx+rtGIn>Gr5eg54VrI zH+L(46jK99Wh#|lNF&PKvAZ(oRJPihH`SB|YF&XeR*&d4q=cetzvspI!_#BOV?*KE zi;3T=0B;oPt21x(*Xzt|y`0_r>f zkDD2L8{DaAOH7!3|FEaO32WvNyH^Cbt=8tF3!hiI-KnEuG=8!rOTtIA5oKWcO^CD8 zT&_G%Z*Cs$@4d!Qk<{-p6+S+ORx0mVNMWC!{bjY5Su2=6aq#x$_M?f?IzroVA1xEo zG1{Jm5%)}UwCk>ST$Ig6p@3vHa2i}Gpf25xh_y%U>h#8mV)GhXKRvUF|2voM|eUsxT9nAbM?JY}dudLV*V-!WjS`l6|N~TTn zX+c3`E1eE$ZPdb1Lb+jHPN}YJBpqn-#)=#{@tkPpM8>Gn8`jkF9#gECy8`=O0^zh) zshq2kURdmyo&v{OP1gL~YvDxzw%nR4yG`X%6jQ6%`?d0qC|`XExR)oU!jx9&bQuiL zSaYr+{>gLG?q|7ocev`;5W=(b>QA-@W$sI!p;}JgA@0=m1I~Wm{|byr3i$?(G#|IF zfBq6tG31KjqE&35*xj4)5sm{+M0j6h=KQUYf9=ln+&P5061 z#DnMO`iVq|i^*JkL3_;_q>-q0rqE`oA!gvZELW97GEy=V`KX64h)Ij`P`Z6F$IfGJ zKvF!QFs1$$f{#<#CyqI>ZL)7Rdv6dq-oFmSQJ{|&@t-IwO3Cf%_&62;qr8UbF1s*-aCVuU$Pp+-rx}G|aS5D0) zrm{cGz$TAThT0$DS2)yhj{B|wqjZB{V@V^Y9_(mr`u#3&pG`jT@YF}*snOvuVUQqL zAEC$k3dxW*n}$FTBQeF3lcomSD84o9yXhxlIRMh)>vQl>^XihJ%bTE0aX`we>RPL$ z`BN>lo;d`8Wo|DQ_$YOEyFYK^Fnv6&Y#913pIjL1?ldkxRyIn|o5%Y728Gxzn$@$J z7(WWChf&?RTe>&@>5r*Ahlg!>grpRi`Rd=MBTL58cXRH|e%w)_5{`>R?eIaZLh$h_ z0uzaybrFavJ}H{d+5 z>Fm7%I^^FUhuxhY;~ORmPb(M>2wpxWM2#YPRvgB`ubp0cAiW-~Yzj*TXYaf?gRE+^ zN6R~IQH8p677@DvxXMN>YIyuy*|IeCC8OqaW7Nov%UR+0qQ5maVbRaVWu-W<6W0BL zF@J39Pg15KO5I2Qb@|tqarxc;%$i_zTh+!~3UcKD$eE?!dOWXZuK* ze6ldGoXtR6#tikB+1f9o-Qmvm#3WFT?Q!0+rLR@NrT}ASyJK2D3d@Z+YG}V^)hCgT z^oLVss`vNr4&yLI`Zh_G4kz!jkoq3=d%5XJkm!O&Y`ark>kYedyD&|)FjiU8GEtwa z$xcOyDNK;F=P_J2yZP9A?jr1riG5jj#fuIW>kQnPywPHQdM9}owicoy))KJ;vOS}4 z>8NxJF4OgGOAr6Zq5P%(@w_JRVMUs8;j1|iDVu>oUVsc)w-4Q~?JtCVS<>{r%p!P3eiuw|E;oKYf zfU!NtT%P0v9TbyfYqFM#ouJd{R~nH&=uGXg+F@^KD^-2)gmlX=M?_(xJ>~`w^^1!0 z4nOQPBnV>G(`&sKKF`Cyf5_@vW6IaRymbL{D4kVZc+9)lHJ&-{+VA{fM2j`)5mpE)I+VXt;8JO5=T!Lz!-($d zs!#Rhg1;gv{!($JFH&cJKdlN$3oVjOIR0pA$P9iP5@!T%34lEe(Z}qNN5@j9=2V4X zn1A241}YQ;rHgQE>KtDPGHio-6|Kt-K2N-tE&^H`>~(t(a|ue>_o~$+PM8GcWjAyF z#f_iq4B5A+IqD8-ttARvfVyr|whI&eCNO$koG6&95nQg*1SwdVFCh*W1Lt7V#9K~g z!jC|9Xmc2419~1h0?fqnB06tFEW43>l90C>wpBMN6adK?qV%HbTJkrDfygftVHPZQ zklK}In2o$vsvF4lvprbapOCP0c z_xZMNPfJ4(w?ne|4?|3sl}cUS^@cdKReb@b#7f<+E#i|eB9hVkOyP#z7cu%G(MiJL zj@=QuhkXRn*Ad~=ini(th{Iw`{G|n?L&&9`3C1guJv*+{?Uj;3|=`Sd}>wVohQNQa3(BWbQ)kduV~+|q;sjhX0y*=Y8}Z#kiERst|GlpYTu z7ZJmEP9Q8I zrIqDL#pAw}=f306(Z!L@W`I~oH zD#M`>_FUv-sic`3jEc(VdmLY?F9P;H%F3^|yu%V(J{E(#qz~FolVG!u;iHwyX{W>? zXBm;u<1&V?`=O(gsOgbeWYa8MjT=^4QV}v&O*=xiH9Px@&P!N0v;afy2D8KnDhM^%(%g=j>-Jwgmp2vPzuv~2oNoSU0L77cZ zD-gx$99b@s_O|JBJu1uKsZW^OZ6#B3VZYFjhX+-`QgQ~Q;YrRLero+mH<1gG(gd=(wXL}4SV_SO03_9f3h%AhU`Zd4{3sfqry z%8Tl(oAOs)UH-d!zSMXEJf+2Hn0Cw0?Bw@4zwSmg&5D_*;(iyk=UKj^twi>n`-Bfl z;mUUQ2pXg(NKsj}GT{<~}(WF+Q zk9w-J$Dt~JvMXb5RBAaC^ybAh3T{>>d6+-7ebb6_E(x#FAXNq8KG81!6ZbjF&_*US zND3)E783S@gs*p__CIC)iaufN=7ztLACUYb%BtMmcmd99th@~W>5omCjy-Hc`?_G3 z3Y!XEti?yV`nusI1mSApnjan3<@L#$%s2B1qDs2Cts1-guhwhMC!LbBw2b?@EtAd~ zSz~NEM%O&YEiV-v5#*PJK2M2w`@*WL6+<kqB4~Anw>hv02LCFW( z*(-lg)vndZw|_OuEOoHz-07jqA^s}$IH63zG*HYs;u(2+QN(%WecZpu2Y`&T&Bh}j zRl|}c&Fh?1#ek3bIqovW4@?<8c!eu<7WNuR-+~!v`2b7&X`A1}8v$yNaBu#HI5bpo zD9GJxd{ABHPh(=n((1D!4BIJ+^a>{NOe+c>?1{|&o_9}oS1<0@k+&0!xy#MW$U-|G zx;1@NW@fiM7G_1p>NJyc26aobV7bvH3OE6iKwok;^;-3P^*1a3Dw{T_hdMg8;*WvB}g`kR6eYou!xO92#v{YcDtUc$hP;!WaL6P2&WFMc`7rsOF{LroU zetrDr$nmzo`@%?|Ewhj*{b+VQ7nVaol5nWDTlTa(0nArqC(D^K=|{v?f!P~xdbt=h z29vDb7<&fYc8~S@!}FQ7&-;j~F~)YT{^v|5qK6Mt!}Rbj{D;sin4xPQGeXw3`gdHcMYBEqRj;m~IMbO*pVuaX19zwa?|#D;!Z zL9?}ZM$2+-W-I^c7V<5b+e&u;!a8-ZspnFC@}6K}!L1VN^o!oPr5-7md|?`G1B>n# z5Oc8H#ssrH4ux6^BY> zPm(&tK>xOUI2Zr6d@#fkRM>F$FlO`9gA*&Qo-f^)IX~3r`1M@gZ!Q?LeIEOcyPkiE z`N^>22D%1KTpB9(U4Qm-rHD{=l6P&!#{o8c4pp0w=2KmSzl6OWDd^dXV^W|sNH3Ji zkjeh@cmX+0-L48<=2u+9?xhQ!sq5QcXuVfEMimoB&hfSM0;b+xiwYvnf-7Xap%QV(Zgi zdo8%=*s2~<5PSkbInbc+-6%kJhUCRrq=x7iL6Uq%j?q?I}C3a}=?<<16^nL_HK;&H2W=oq3 zT7KlrRtk)RjA?p; zObFFp=8FK|Y@AQ|=9-jWBqcAd?*Khjz#(+JYWkN<&C(V0k*NNMWz*c(v!qmxwy(yD z@J&KjtjOaQ(Q7xQPdyI|yiXlZ4cjB^9Oyx8bM$Y6jVqZ5T=XmAruizRHS)4&PHJ=a zrQci>-r7aP3#<(B{*X>e0dA`=(2SN6PGWtEv$Nzj8rq$#zb#gzjh$Gb8{fIt-T>fgy~h zGI#5%P`HP->nmbcVB*x=n-+b1k9QLN-4*4&UYpc+_{&i_L(_?%`5brNyiwq6fnX?S zgpEWY<o?4rCN8BMo|YmPkP?N`+*p@Z(-$<=0*KO!$yczIeNU zoL~K7`h<_I@%^_F?KfkUllQxu6&z}0!mx(`f{yb{QB&S+st>|XIe0q6FobN5Q)jul zTNFQ|(V)c9&lDh3UQct@M3Zv{Sh>%?5|UO(SMm9Ody1+h+DxgaX<<@lN?Bv1?899O z{h39DYOD}udUBDT`XMWitd|U4ptbO{fAhhfgWz17etWa$+NwCcz0E>5j+L#VBJ4eA zT&7|oFgm+vj&x#02VKBFMt<_y2RV2@Jrm`Pz_o<@4>t*46g?L~N#V0avagOc{wuaK z?>dICXpOI>nYkVzh(aRp7zu~9&-e|e<+8TJ0~0Z@YE$uyRs7Hk$EghWEz8E7)BDV? zV(kAL$)X&XF|FeeOGzU0Al$l3a5bszAYgmE_E=Fy*lgWBSFa@Ry5J(b29^>Q3 zT7EeV1(1UZzS%2G2(di!w7e*tbhio@7u7qhm1^B2Oh;K42#H;apKue-7BIz;{Z!TR z4*17CFQ|9guxwmVuYW)`{)kbR5c6s|9gd`JAuKI6Uj)OAsv+*wAO;)PEn=;~S&}>3 z>mNta9Cy|b@6KsdJZtL)u!&}+(X@z;XagY9oocES!od%+P<4kemk#RCffwT?&R(ug z^A6a_CjsB92m@qSz^}}qSbfA2;L?+efS^u_{aVUMM_)t-*%PzVIru(WSn753S4Jv6Op(L*pc)z|*L zmp|T4-SK+V70~3XX)e<_U~1g4UtB9uE7OFGt4=x8q8viOGWWQYuY9L7FDxYEs%|=dLNf5 z=82&%%GsJV3?=@`SdO7krU6bo`;>1*OiyBr%e9`3>CE2pwERP)kODT_G=blkwnX(M z5i{NC4pk5tL1_t$06nHPop!}MH(GreD%6LW!>K;^l$9)zGGqDIft&71gt0gbxh}AT z6OYAK>{?e-qz=-}Plf~y>5l!I$onS9EJIAliHymDLkz_7XL0gJQhEC6rwkgKC2HX( z3BiwsCn6Ek+>HriopK+_j$AJ8X^PbT>CUcjEMWo!RU^*hz1oavIteXvS(H9u=Ojv8-~SXtl7QI?{rhhh96<~(2ert2l#lk=&Dq0=Deq4!t}*Wx za9^6P`5-AJtwuGe&i3mKg6U4S zLN`(?$0WF+DdXD7cZ$UyNA{rpZFQ>*-Kw0j)#8-C?jlRexqSA6%P92vH)pcwY)C|% z807NhuKQ>9f1v;`H3Z*BS6dNV1x$#sSq46xmR8S)Zp|<06v28L4r@YQ@voW_Ia0=W zRV#kD4|k%guEN6k6ShXxAN_lw;HsrQ1zC_o(1&6SK%OthRZ{K(hh``zZ zSxGr}ZoUE7b0=3v7LxL_y7!PAMN(1qM*8a>-ACL{hSPAVjD!3($=U%59Vrd#gYLa8 zEDNk#Hp4e;7wYBvf#{qTPHbk{{;mI})(zL&-qaI4GDqx|3*UojlTB0!lfyHl4W00` zQdR?MSBCdPDr9Usmc(YESx@G_KVF<^vn#~L6eD}xdwM^)dN!^Rg~=9pvp@0eZV@ZK z!HvR+`vg4^6TaWk=f# z``Baz*ZK?)+#^THd-2r#=Dp`eh4}WVY@=(is;Z0@7k&cgKdzUjK6iWK*S{ zfd2;85B~<%4+^PMeRYMfszr{7Ys|&(? z@@*Q_Z8v5W@^Pbd%QWh7`?g}rDzxE3DNIj;q$M#gDd=dOD1WC0(myX2rp9ISY0Zvj+@k8Adkk*Gc^Pt5^NQnU8kU(f#a}_q*c%A<;tN|HbZ4+i4ZChi`I1+g{C!WQ{3SZ2EqOB7*n6AHfOZHCdJfehUmb za_}YM*#56S%X8z0T#bg#=_RqY|I}+B22@Uk|HZZAtbziO1@D`AFLeu6XRN-$2?r^^ zc2cajP|XX}P9-!?+z!n#>(pY?qhdG5PJWX!`89kF%-HMOL@dq*bvV>1SRB0sh*2-` z`lFr~f+Yx(k#nSYwX;|1X3H0T^&yIt>=A~-&xl$6>^GvOajZxvh+X_6sX7M(Ad}3l z?)D!K-KOld>@9BfD5!;R7H1-7v!undqv}|y7f9-=<+?Hi-p$Pv8~Ws#*bbDhQR{ve z&k?Z&`(J_jy*rb_pGcI)glCBhl%xJ&w}Xz?)`HIRzfF!GDfu;=KKVHXYR^wEMmnu+ z>hbSrrRB$v16*WZ{gl>t1hTqw#d+E~9b-wo+iPULVa%DGAxBqUd(MCl+_*Y)A=acW z+uxNK8^ftRiu`cnBk_Q8sFI!33pqu0}wN0`WKrFg++0K z=NzUg0fnED)L}cuX(_v)#0A-jM$}u?)+Ee3lEeyD&21oKfoUz+xHRAu{^_Y0SCm8Z zBWv(qwBZ%q)9Uc+TFo@ob#q_qYFFlT6Nb`T0D;LUt zi#mQJ~uafC4PoN zi<$a=!|R;f_8p=Ul{M6l;jmQ9N6U+}7g!3OGKDedb1<~v-4=Dlj^oOXCd+v=oloWs zF04gw{Hnb>!JGd#+E?PSawe{VOg!M4=bQ&tW0KvEJ~r8;>G8)vY7*S>x{nJGq}`u? zMmWpJsA!{Vl08bQ{u#PLJdb#2Iko?`Rp@2rGd1JdY0%6 zG7!14j@56>TX)M=R`(n$1sJ_2zPMW=+HMjLZxR$AT!iTGXLZkFmV3^#UlChn!%^d{s@6 zoSMlPY?QXLIR?w>)ggreUTw751G_S)^{Th-nqqy#{J^2my*Y4%+bvguj_X@vOV%dZ z$8VUwSl!Q;)wlc?;0dg`4(qJkF?Vjp)jwNuZ&D$Wdwf*`eCu!BEix6)*LvU- z807msjpqLyUXwRRl7mSWPOb$jn<|wBiDW>qRjm8amwHmCzNu3__A2Y3 z|8Uh@$kX-|XdB^GMYLyZ#f}@RCVh(n&xFj>3>CJjQSV;3u$m_S0&tL&yC z(=zXaPfzf2k^wgq0f%*J_PAd539Uw)qqz>^jnNd`@mm1Jylyyv^WzcXWJ$36Sh(Ur z!rlv^9%n^}^K2-aoUV7G`s{4Vh(|t51u0L%?k=Q|SdDq0@m%Og`GO*6(iS@3fDQos z>{H^q%@$mqM8i0vtIP)U-W8@U1>JeEh-WA6GfeSLqIIa6an7rbk``2D+T#N{ zQO`Li&6|?P_5-_yJ^F$38{(G7^>fe##1cx$D)EVQd;BuCq&o@NG|3m{&gH2z64`2KhXpW}wpo>Ah&%+mQY1s2BsB8WbZ_0gwd&{N;d#HK@PUbN`t8RByJp?Cbz4`+oli()dxgP;Ep3U>8}I(zjj}K0gvSBm zL(CA(B_&E{M;0bu*qrB`ULLuFeD2R`J8*qy6(;Q7DYD_1$CY{^g$r;&bsO!c9eLOD zzYWj6;jPS34ct9CKfk|a`YdI>k}>nX%v`dZP2_Wx8#&Lvi#(DtI%E`nb-RnC?n`ji z)bAPP|KVlT{?^0LXgJRsO{DoDxbIds?ACsfb!Yp32I_X{h&}hj zVZ)~`ZK%+r-r{Y=th2!QI%kA?IWIx@lLzV8Gvafm&i&huYn|td0Z&&REuiMRoK(?I zLrPec{d4D;Q5uqfNeu}VHS_9q1VV6p>(CJ`la9owC&i9it3P<{?eZRA#k?g}jdBh3 zCqi^-upIaIkUC(PrdN>Mwp?D=3QTM^4*LJoTurJ>TOH=!Hf33Dw7D`VS+_sSG3R4py1+g|~8#-xk4k|&?h6<84 zur`NAGxjYQz%~}mD7)RsK%)GYr1F1or8Sx5JmHEGR`OD2X7rDpr|)ImpaRq9KQGX! zdzB0}%VCRfi#kaGS{SfIa->JGaggO9zdkSwK$R&0H0X15?wtEMRoene7ug8%vjrLZ zmv#;Ndu-Ot^K?hm3PrblZ{lhp8bS4@GYJsb7uL@0(;}F!Gb| z-P=WPT#4+d2anA7>^|V#eV0vfagW06w5%$54fv&7R8@P>Jd89`vy!NLrpatg0j>qc z>VuGBVQP+jv+}zGv7#ioVc60oXSYkeOAH<^z{$5SGX+2`;*rDV&u0=Nf!^mCN3~6kw7j{d4nm23T9Fo9= zTY*;oZs%17BQfdy?QR@h*~G(M;VsSkE3Q(4_15ou`=v~J`b{LwzdlWAD3NNp@z32Q z2r-twTWQ_KigI_DddR4+cR0>%orDT5u+==xKk&*inr|{+pvST>qP+n+Hl9ahXCJi!z%)8P}F#3M&3A z;bc8I%f!d;Kc??+<#F{XgGBQLn^N{F*hi8}CbXi9Sp}S8&w`!dWfm0ttDY?AK&``c zoNS*N@XAVs)Fi@xf{85Wvy@pak~&Kfbhi)R4jIsymWuisMxVE0AfQ{ADGWS#4Pjgr z-=rnNZW4o#i==#l%ofoVe{CTAmz(lyaplT`v5os-?3Ht9ENQPL@&&)(bmY3H$~0s% zX6mHrBb)YB(OjJ%_6mK`@Ez>Np4A{#n^bmN#@#+qi|ke?ygwCsEsM{&%pi7 zu`4eD;`T_{BE90X*Lo%b;x^8SfHnu$FR09nQkQ&*UJ8d&Q=!sA7PF#An2yVfT0Ylw zS=B47Uvnp={mJ7JVncaXT~M&YAa~hju5L$sndg?^OIglrE61|rTSZFMk*BUKJ@se*UBa6lkg67`Q7%wOmN9HaXj z=3A;mps?gNWvK&E{;r>dz3sTYOB~`l)7c-7%b!qDLR8xM64m90d2dA~tNCm4W!5xv z)6s}5PW*^Ib6>wHG-Dn}%^-SpWsglJu$0JBuOl^eSVir+5JoqVijmP{b*7Y^Wux4= zY|PjWX)W=C2E+g_=zt8E$~k+P3;(2DKIgPX*c; zkvCDY#!T_dF`_wv3ENF;K;FA--%DBC@bRCRc2Ryl&s|f6#x!9l&3Y*Gz-R|N9HQU0 zOnkVnnf8}DKiuXB#JZqTNaJcZLeP{xL)XS@@BZPt58Yn~kf89OB~f4&gx7Z;d@hRB zJn*eJ=D8>&)1&TW8S4_7H)#C&v5Va=#Cz|}cl>JWtsG$Od=0RWFYvnk=t^vs zYtVkWB8I?s#?KLFLjoa+SjmQ;68kWI!Ro?v0njLG!^@cvNQMaAg4phRU3+19(~qOy zlTN=BY~j}^el$i32d8!gU+>Z9d-xmn7c1*v5+;=N<@|wcev`&Zptdoo2?#_EMD!Ao zcr+^%$7{f-oTSutSce^fYo0RyeRq)(rmdRbSTZGGR6YFG*42=o6kC9X4vr9Cxp%R@ zBrRV0#)na?N;!q3U11+!!yv{QTd-uBgRHjOxBhv=6hMMI4N`r%B~xW#=@CHdE}n?V zd5xI{3V6^iE1L47sjX%asv>-jw4BALJwi28LLCmYu0SM<%({r(DA%qDJqIHpdKU0I ze$5kS!|yS_P3He8D^|Ep5yL7seRWPcDGgn5W67P}rHYNKjugWtrm8kXQ%!Q^VglP${cpe`Zr|EC;}_ zhMwffncCA?63R_ltB*v8$Ju@y!bx|Z)Kr&Pvj_zjad((U<_JXt6mzrSKxE-%?f?F| z5TfFR&@IDorJ8~)k!YMbib(jWnrQH*P)H7^80tWyd4SPmof`GOAR2(pl8-wG%y(m^ zQKSUNirY1Kk4XUtCyF|t_J|Ncg$38lU@<3JP-N?Eq3EVR>8w`bo{SuN|9|3LlD*fn z7ceYw0A3Qj%K4$p_1Ec=<%{ZoQdYL6T%CR2J8Z`t)_;bpP#L>^6PI1T5blN&!^?dB z34=1t0c>GNvM>&d5HW0A92WNZ=8zTbi)QyiWMP62XprAW9`y)69Qc+x#j;6cV?H@T zBLNjeO=OX<|2DTxb$v#kfJUKH?IKWe>x+k!*r5nsejx9FZF1G1l4o9#V>AQWc+x=q zjl~RT<6)^7&wB0`mDB>AIQjayq}-F~`qUiMQFaY*JYW=ZGCTSyQjLWLE(5I(oU>?X zxuFdp0~_2KV1qmUKO0=v40tQtd}{CWO!UPA&(bkx(j-H=b|V!uz~Vd#{GiWmZlC!0 z#11sMw}g~+FQM8 zdfJ)B^bbQt#Md$M?H5^8aJ!WR;@u`zy>=57U{rWlw|cIpcaOZ5NGMb}fTN-#%a@Op z;o|Irp4391*ayNke55gT){=kEaxgeKGPsn_LE$muNFs zv(~sB)@iNFIqB`lj;p;kD4koB-lnQ*42L<%Yvi!j)$`Qt&fPygJiN#vqw+BD+NNSZrkFHPHXe9t_xE=bSzup^Zj?Dp_vuW#;wLIh z7o2D%Khq<&$7`;F)^lWg%lS3geJIM45h&n`hv2O$5w(t9*-3lO(bmw$KXs*rgf}?N zduKYXgAQ8D#9l|qY}D7(N!P%3a1M${_;DF|Evl_WPLpN2f z*Sgmb#D_8>YE4slgysCq)>8HR<@rg|eQyl^cxJ;y%gueMQJu3F1(IQa4W|yXNm|4d ze{}Fl@C6vcl_~SCS#+-7ly4n(P3CK;G&@$X30&*;hG|74bjk{HOd*bjK#%?lW)hOO zD0*6qxz3uE8s7>{ShWGTsjmsM1#{d&AzO}#3+VU~hyc6-EtI*faug@E7{Gr+h8`Qi z6?erH8+Xd4u^)Ze)31aX^W|M!ZsI+LN}`)9#mQnH1sd*KvoNq@C1ah>r8q%i>u_Pj z3BWxAwXPfa_gqO&@Ryn0H$e$q6=x)yRePmt!mRR}2A zW~*=Unc%e`h7rjv$9VkffYza(YYd!SI&!DhuvAM$aURiH17-vry~e5=#w_t|A4sPY zUJ=yWh)qQ#;y901leTCBYYOW-W?y7o|Izj4^xNurb{FnPN2J4pDX<(ge; zE6O{@yW)riuY|KtYjdbG!1>4=|FSizkBoY0DtNW@itt<=;A%40FnyHP_BQMbh^ad> z)wd3KSd!rM3b%BuAkkC~h*4TN2(}J5Y3OyYZ+y32&yJ2U;xP@i2APMRRi#sQC}?zw z@TggYYRA7b`q?!>(DCTVNx{@y!u>(~^_QB=iSt7dPT=dOFwXoInDE{^4NT+|HGA8h zQt(&6hA>4!4@j=G*33wND34AU_e)-aP>C}!=iLRGh$o*!+Q7*1V{OZPMts2FlfO_L z?+$AVZm1l`&B`uBDlOknl4legM`yN}dtA>au-!ZY5B%tIQCFRs4+4LfE3t3~ptwSP zCNbXqrfIL9E7uxr9}6*Hz@>5W)DaNTY#kr_@~_%;I{0?)b8qAGbnnxi@m&ikp08{a z<|^;Klo~v_X89(azE!xP7}6)fW-aQ|lGO+Z7%y(F}G z${Ufm23TnCkLWC=6RTvZ0WpHlg&lPq+>Vl?<58^JZ8M$Pk0{=Ik@mt+&qbfh!l0G) z%ZH;+Z64l>I<4-WaM$Ng%H8if4X=-~n5aw}PKpP%S;a(D6vQe^I~XFnPd$g|FpN=s z)&#@NVMIi^TUC?80)`>5iHZrPl{U+mCj^mE5;^YNi~rD0w5|Tv2Wbk$ke2{2sqp{| z>Nlfrc`lsUeK@>5yfxzZ{FaAx0=m^TuA0)Ag&qN<9*A+U+gV&vQOe;>J9JlGJqUGexvJUio;}){6nt*WwBx= zhJA)aDo5h1nkLgwAjgk6<}W{kr0AJLBYFPaO9T{+j}dn$@)}cwKkTMfr>{r5F;JZ^ zRDKSEk(A@BWLs!s)uqUbJ65EWOn_&^toR_9ofjObOA06=dJjs6Eo38u=4A zr2)fp-8{AbRv@Oi;bu#?$EGC*7HadAIV$f|7+~(=+C7I5xW1rMVi0#i4`+q^e3Koed@3kHdcEKI_;$Zb zv84CQvMbJUGghK2(^emRN8+Sx#H_lL3Qi)sU5h~zS~W9mA8??{asuk*T37erMDlPk z^s+bq*`3WzSaq35E!}#$nh#j6sDeN%giEm&gzE4-FnIDnL%)7;SU&`}?i+xA)L00| z-9=8e<|;MxHwUH4Aw{45>^G=xJr0Cqi4(ReZP+ks7O(hXRB{;F9I`566_lpme`HUZ zHji5bUNuh7*EFSW5uhR;nyOi0Z`ZRIZRYMuBNL^ZAD(TQ)g3Y;vsy)N@PkF0r;<2- zQ|6*WeN34axTE}li5{mT?Zm2j<*FX9V|{2?Mz8Llsx<#M71K$<+P@OGseW+S+hrPY{xNid=oE-6OdxP}3)`4%E&pB2zuANBR zeb(m^v&h9t6E`f3YIH;xWF-Qiw%ZeywkEb1v={8hg`&P=|5HS5YR|^g486DtZ}ur` z^?<{qwEP_5g3T4=B7WHw{jC3*LLGhY_H{~)o?pwwbUk(X)?1!)LIpg&|xytJ1=_WNP2<_c%tAy#iLN!?QCT9XgpP;Xm52U^RM+F~dDeX$53?kh_($ zNAYV^pd%Gn@UPl<&cBZ~s>UwlhWNslR<(Pm@Cgf=Q_gEA{O|9jkBN)Zm{R$_JtNECL6rn`2d$!gpW zU~E*Hy2*d$GgE(I_SPBUs7dxurZMF=aUDrjjCCe#keU-yAw3 z0Z}nndlck;T8|T^Q<#Qz1sL_o^%c|j3DKd8SG5BWxG>abZ{i>ms)Jwct!P)ofe!P?~J8q7LvwqxK-4!fF+83@%xD}A{{OER6W5GPw) zW1nW{X$s)o)tYrwFI~O@VZh~sf9ZLk(BQH)yI42lf+)yr2iVsQ6e6qBgrrU zI~m?QEoZ65Cdirto#<~Ptxo<7(hs-!VS%>UyB~3P-A!VHe4e+^Vy#b7H6f3LBKeC*R8lFW11GABff^LA)bD`U1_M z5vc5ndZkv3gz$~vYZ##XBz~g?n$?K)17Jru;&kQm|sM~lb8g{WS4V*I6GO4gcUL#-UK2T>L0uAr&8mD0lK?>p|+n+NWH zY&gW-dM$QLh`(EJd#oRS#OE|T{hIvRBlK8v2WihTSf2uDh2i_6S`z=cN~^{esz1I& z@cHz~2hpu4kBlKS-40h^aZr(!HMe5HYsQGOg#op#q#Kz>*9+|UK@z?aW!ry?xLajv zobz~APJEd@m2z%adY+@ArrK9E(Y4a17^z^$z?6c_w;|Kta+>RX#Y7@S_qE5WA%B-N z?JUAWAeLl@lgs0G{T3MWH{*tC0}Od7AIkolc*M!OUj{N)lZkVzeDd1Z&TQ*mec zPIg1H6%#$KZrb-JoE=7(*t^;!SDKw{e{2~tHl|v?JC>0j-fTza&6cJ2r|=w<+Ushe zs&0U+1@@d>#I2>G=Nj+7^A_pc2DQ`Or0BlHONm7a3X8JkWBVVGYU&>oGb$*^Bi7sz z2HWaV{-AyQv1z)lz|PBy*B`9GwR@~+s}dN!=p!LO^o7i1p^Up0%!bC#pKrQ6J1mnV zG3HPxG}M+;jj-}j=Nft=30Tu530=Ed_}sZW_r1~;!ZIVm&V153C_7ah!=Kc*s7vFD z`1c0fEoHW(XniH4sK-+W)^B_s7F^0T9-!h-oKOFJHOphxH7RQbCH4(vq?U0&3h7*i z{I1Z#GogSR9y5Nn!~-SA)i~G{Q*U(;e}j+ zTq0sdgISVcxSY`PJ!&-KGyU77?FtvZj#rw?1mg3^K&si$ZCSwkkj?XTHUpV8Itryj z;*6uLtWf#YH9g$$ZE(dMtv-I}+AY76+z(V7VGiaCm#bV$Q z6b?i(lRmT*yI9r{B_@?1sZTVAyfQlwNvZzuZkZM0>r@6ZA0&8Ue`QD`?#}(7qC~2q z{YBbxOK#5#K^FO|{PzbK_8e*YA?_r!>bc1rXyOIL@U0wt?T_DfuE9S%azqX zNZ`ugoqySLEGhmy|2iK+7eyXt?_~&`OJY(z}7Q1?a#aY7IAt9l@%_5-M2w<^};P;<&qcdF@mB+Y0 zH}UsOnyh{A&$q6%&O+ga2W~62%~Lc&@6OonkL0cleNMT%-_};l{@`_OX=|f>VPG*W za|!^Y$@X{1i;=cz=`-=w(+Y3N`i=51RXRb{=z*5-7Ewwus)UFg&f!p8sB z4r6(K$}N9kFHwf&I-)o8@%AAlAVzwoUJAv`j*p#RHkB0|cznA#zqr$-<4NJ~Vxqa_k+Is$( zc!G2=Ig>sMO8>%L|F>_Q3%G@n#-AmpgKW||s{?kXJ%tI2N9Si|g3PM)$wc)BI?o#nV>G)9v*uk_GSIplg-J6-j^jUL=8jbEJ`p`MK(uZ zR-VZt`5F`&Yy{C7g+S_}aHO)y1b3QD<|p zE81!fl}ZI@#>%20WjA19cD3t-_}{`TrQu10iDRXYy+f(u1(T^*ev&ssd1;_SYrVWM z(#dsr5?3arbS!Ly1V6M=33N3Bdd(ad`NG#i&Idy*cxA5Mq=JyAj8r_R0TnZTfsnpw z7S9YwM>%WU8Kf*%4U(oAZ|4eGGQ!BYbZgv%>6f+eMNg?AvCKZ%( zn4yf0gi==~T*&IyFAL;46gHh=&VYL#vXU$_ z=5#+-uoDmsc45lV5gE!&elU}q7x@k>wnm#d>lRj$)E#CxHbmA-rSG|F%?dL>r@mwH z`&vRN@Q`aFR?9r~%6(@y5{pG=lChpE6$6(I9j2;f0o8#RR0%H&uU`2WlE&GE>C$*9 zjS4s@_xC>vH=Pyk%R1G5!#FB>2YFxdM1G!`k5jI~Oh*4$geNsnz?U%wtBq?7C{M9W=V0Db!#*+>4w#VrEl~sDGLB1E zV$2XChjb7vMNM&Goye)f}Qv{v4PcmV6f!6V~!oyD^maI{_%1vP6ypM z!Py=C!mYSCPuSS&v7Qbp?uZa>TCu`(lz;4O+QFtYi>3Le`cV<*5TbKpF>86#Rq5I{ zeb#wRP&8bQZNp`oLO+R;l8^x$Eb#Jl^yPMZ(7>ED15u9SQ% zd2M20hi*R~g6CgzniXU`pIF9ZZn6cx+**>lGCOojZ>fpe5l+^;nRL?;={z>h@$6ib zOkddK_$`^`dahb4a`Uz00jYtvwULy$<;NZXc+d41k+$GDQFLRPy3moK(KpsnBaK9r zye)9=oYTJ0fiE+`ZOgGOu6U9ComhoAtRsFvdq(-ixR23p-3R~Nhcctrj{JNmb#tIr zEHH5VY<76b>(!J~!*Y|u_XGY@ivqRJJ!|5lbPeH^RvEwG?M}+hj;?c1pXoilj>%;v zw@WRJS=qh)IogZYCVXp@NSgbE{eddX7cez>LlgFMO)XW2yL5%}0j`Yn?W=c>2Kpxax42JKyG!J-&ED=hnPP@mHQaTqda^h1-fZT-Uid~U4MnM zlVjpI;z_G-HF*XaV?{}t1ECxfA~`P-n!2C7c7itdmyO0&!a753vjW?2TsM*}7m{@7 zN+nE<&eheHDh6VWBMTk-n!_URtpB8{yU;2`3zm#3ypyR_`0?Ib%eDn8Bzg!-fB#+h zO~ysjg_hawi;Q+xLG;**=5e_Z=l$HxTWs*9#`TCp=`>)+^V zPgp5LGB82;GAO0Z$K4gP;@uzP?mZoG+l~9B!cjzc)u)x(oy`Y6DD+uRxm5gM{@fJ@ zXQgM3?!rh?7V){w`B~pwzM7q~`9}m*XzHowL`DKL%Iz_@Nmn$=r(t;eeRrnE8qD>^ zz#AU*R`GV~N*#%`8F9L@oJ{oh?^x-6#dsVO+F(&SyOPIO$?~IJWe62+W)H@_Bu2F* zozziK)>y~36t|T}y8;cDsHUK}GroMh$|v&~Y6vhhqh%3#&oz~?Nt7F{f*Y#{=+Req z<|Fyh7|7IKXw?gWUPk;-^U@;r-*UPv#94-lFL6wMEXUJrT|1q{(RtD0@4LzQX~Onk zmF1YqAqM7P)#b+gys;It^PYb5^3(oe6Fe-F=I{ZDf2l5m!qGo72?ik@>vEsA` zZ$37IMu0FDq_>A=F*nBTX!Nsk%+F%RIQ!NAoSJ*=bHPUBF3+`#Se>62dRms$DY`4g zR{ByDW8$r(Es>zMWRZZSa}hkwNvm7(kOQgXP>Z}}=ih);n&#^R&$9zv;XWGCuavX( z#!Ut(6UR4F>z@J*7a)VRFw!P*@Xd2ggUTsw6390Q^-Un}%hS5NLEW}5CA@%aSe9zE%51r?{Qs5s;d`mHmG6~t@*)aXb03;x|+vIz{ z@WeeIupI^hikw=WxXw|}GjB7BDqHPmmF;cf{~TFA0^dxdMSu#HCNvt1+~pVU<(Gn} z@(NaeP0q(+$M=##8HD!UpLFYbrko%9VFp)ag?xXnI>-BJWgmlq7^!lJF0 z8HKHrB$33szs4|ETR;Yba1luY4i_y+f@ZdPq2sTb!nU$j?G`#gqkj)5*`o#~wzC;P zoM5Be(8(-@_^l{Ob`_j?x9aT8Cw?#Z<^TQXT`T=dA-^-Q9^CeX(V~6ob>yMq4S&i{4$PIbP zzr|H43Xe8L0Ls3#(L{ni>h!?ofluNerBJCbFV}Dtx{WCDd|eT6=tCAnLVTMRWJh!O zDjqD#kD@@dnlP!{>qf^I*twG0x>KnFi*__!<9XPwHSNMT%u$jqSqt%nGMkb3aghWJ zLHsnpeW|D@xPqNOAEDv-*^f7pNOwW>LkmCq+>!8qo-FC=3j}i{xVf|(Z(S0J7G^rX zY;=W)VJI1Gk$AtaNF68pXoeKoaVMf=`R1$`a-S)c*6z4|X6i^RK#i~zcP~_h{WE3V zssg60K=WJQY$3V1(|xO=)s{DaF>N5otzNx%EfA7pNlzD=nWX@U4il#gk1|{nWFT-1 z=&Sld@Sl9e@^N4h`_@IY8z7k8{F4VY_2+1HGUwNUl5V4a?3MXjFtY21{`+EO-#Qb`o-=}h{rmpxRKuex0Jc;##uSj}6M z-qFNkE!(x6T}$zVbn0kTZ7E7ZeEk3lQfe&y)WM%fpa-;Wj-NAL*}SljZxEXT10OZN zGoGTIYorOJ4zTKHLV_-uD%Cr zi0B<7l#_%TtK`sEs1T!4DiM2{Z{*Sq(N>Ku)Ig!}RjtNIu=`(J zon=%U!J@5WKyZRP2?_4*5Zv88xDM``;O_434DJ@(b#M*tu0daubI)COy?+C%>8a_i zS#<5%dw=B-s%yCRFw`?t`HhY5Jw^f78$jF&rulxLG^BZY{BuP--?UG;M%)}__@)ar z2PZ+88YmEFEp4AFQg9)Q&q=l`FWE*YK_6>KQK&UzNr6^|1JT%$QhgOM3;z`&i^MR;~P7TGVkwZaQ+b%dnYy0Whkv|Ev&Y@NX-pKWyk*=6``|dzy-ai46 zS@ERj<#699|E(L)c4EKMAKydzfIoGGsK#f}CZX6UtTihr7b+aIB}^ z2R97(Uq}r^h*&b>JH0>(&zZfvcoPGJh4j|d9UW-*`*-D9VQ1?0v-)GHB;2$VirC{! z1zyT>!80Keg;)JQ?~k=T3%yY=Q^JlP4PE~lIbV3sZXe8RFW2_<52O@%W|jthlHk#E zcT{PsZYshJG&xq*p6VF~8i9?l2^wlQzHJX>sKg{CO+xuHD>HS-R}YfLfOg88mxL2a z=B${xvV}5LXmmJSlquo4bpKYCCa+1`pvJjED7RgQVWvZ4tcRAB;fzgYk@J#AngdcN zP_T`1^6pQA@T#gaGvmULFVSeg)q5^6Ncmal>A3e$^cIpVC$DBzD1brTAn6@5xB!J# zoVwi$)ZfUH&8$ImDUXJP^fD2Yyzrfp5x7D|!8+sbp-S(%NX-#yI{X=$UA3ruNC5qfAr1H~&@jE$_k!*5taLP~ZAh4b$7<#{ zd|%2$)(@rA8O*JY$c%@Sox(IC;v64Kok_@VQGQX34#n|ZB9UKYGbEyp#akkD{oGCK zy}aO8ZqJcY_!#OFr6&$@zNsxmF$%zxJDxUnpDvzfh-AvPC}5&wH)0Kyv0P1yR6=B@ zWHJIUHAyk{4*TX4@{JS?>JAun!GA`!Xinkx$X8XGEZMm5-=eVIzyF(A;APa;r`620_vrVT9){0er z)HGl14+;IUEP}5)=D52#jNVzyX7lRK%AL(Rgb!lRcA5sSO}Mk-rOKP68^=mlXR|YR zlOi+o)I)j+m*MB%vE=Trk*bvxqn-3B0{iRMn}6@lCFR4|?THUM+nOsVu!jXPtFm(kA@wiOEz*aAl8>VV5s~c&G365>j#T8660y6OyXwYT;W_|K2zIy*6Atl zLFE%=EM3T8GAvdHffZP~id;N=Nl80pQc4I9-R#oNM57{Gs;;{a=CM2+-e}Mvx=b*x zNR?*o;Jl7OUX@v2r1)AYdy7rN4%wa1q=K325@B~jA)d$nM zb3BjVVcE|;wblCH8b-`NM#P&KgPGY67+L_1RnI8)V=5s;-A#)0I!TCUCtwt*_Ur+& zH_^Y9O_rY|Krvgu)A_I5;`a%i{||0#&+*gSTymsetdnn%E0T`kNRpQlzS&P9SCf~U zsEG3y$VG8f{e7D#B?6V>svJdGJdA$8IJebxYvb_<|L5V?NP6@u$||M7RdofPi2x&I zDM7$KBzORdtMs88pjnYmEY^wxG%FP;PGt|of|y87^aEy-dU&81SZgT-Cn5%M zw!Ub=r0p?Z7DI=F4#%=v&pDAI@6n&h)*Tyy*g}7%H&5FbvfNu&oU}e)^b6U;f@xXU zf5nwai|p{alK(xCY3X~={PaS-Wx!#cOgAQy2g(vu;lPo`VG0gyl!xZ7afYgBFCO<{ zc(V*)$&XtY-lAiqTJ`fGO|osAo4`Myd%@OW@KW^`JHy%>;}8p>wRwJxGmZ31xQyOX zNGr7KaX=uaxx?6HwTnWQo;xgWWvVdev@L5ytV`M_sf!~7Jl!+aaJp5a zJPyUlnDhqy)T{5gVw(V&ij|m+MN{U;qqAvg7N1Pyyt8o(cYkXir@rM6v!zpBaPR;# zqy0Z9Rm-0qHYxB|NpS-zFh|uU6xre|K9=PHmlC;(<;5FBJZ<0|XjhGje8UrIGqzX( z_7w!m8nVB!ZO2RaJhctJ`1}uJ#X&{0ZCS*j(P@R1HeFxPbmey`SX*`pmC7yHjfvGN z9UAJ4d(c1|9Tz`gsZgvJ3%^=0*xOQdxR;%qpJExIAAVF{;JVjL7{9T7EMR%@8F5MT zjP;mi)vOXDckeE4cLp?{r_+su<)IuHs?ryazM4%C@$3vcQ@o9YEquB52L1yJq3FE;Oj|nrE~C`tEQ~d;yCZx!kwwF1twvJz>Ug zM`gb?9aYH3aU#z7<8P!j-w7HK8;R26{o044N5@yV7RQT#{UqCy@>Z~|s>FmJjTUF_ zbk^es5DTs&02Ukq7-CGXY2Fkl=1#^E983ws{d*(CB_zPZf_wjqV+y2%u7~vo?2=g9 z88|@LVAVRYlu32q&*FJZqhfTmy({4$jz=gd#{}#NmxciVUhx@A)SPKkqg>rIX6~dI z0L)bvFa;33u7Y}!Q@#i`WlLqYb|#a|nUm%$%K`3YCcxcnMLtJnjj~yuC1<{ujfGx^ zDz~RHPPKACr2x&aj+-w~8@!uxZ!10{hLy9;HJ2mX_j%S*SOne~Y(z)NR4ajFIx$vv z5YJd<3E+(c4_{$G-2&m+?%G*ra^n4(+X6~Bi#P96%hFQ62~OiQk0XZk=Kuhx_y8O? zy}?EcgI;E#SbMAc#}=g+k4(Tq|m`Q^T^qAEW=Xq zAPJy}^SivI+w#f>Af-L?^joa9L`QJb#ENSrle~j^SY?J~?`)*}xHmsV*)`jnsR69I zIssUvLJ--mx)?`85GQ?-xmM{c)F9@q6Kcs^fJIZNR1^J5ZU+pZ3As6}wqnsCX9HF~ zy{R*}Ifo3+>0o*0uXDfxF#yt5X;_12bVa)ZUSbLHg4i{P2xhY|IM)*;1(#TuOH@qy zC2`GBf#!|t0!$gCx+e}F?0^N=Jq%=G|3`OaHUXw6^?^T0Iw+2L0xAi55?)er$-MT1 zz9Z-S8_^|P>R>hV(Bs1Q^`YEi=9q7oFY>b?7@v!1{=l3R$F3W5e?b7Ljedom8zz zw(;1XrB2Vx$N%2%c9IM|?F4Xl31ovP(IaV6!b$H3P|tN@Yqc3D-Fi>~teaqYiOvLE zg4k78b&0Yv&V4KDpbkav0uXIiFioZOX9s{~q$TJFxeDBv&cH;^kJ|Sq*$^MHu!9>y zuWoDHAbq1;jA{hu7(;4ZmvA{hBTM2K+Es5Md}S z0&t9$izK4M44EvID5e0wbQfzka4?9DnqcjI&chuz#i75Ep9PCXk;3!@RsOsRhVDCU zMe+0U0(2}@zkN91&(gJ&#j6I%D+Wz-B#NDtwLK;BlITYVkOQymQh@14Y1C_m$y^T6* z`T%l`vKOhXGS5^A^mSr8-jXbSBT3
    #gC}EO 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

    dcZCxWoda7iUEg#!ghw^ z*fjB!_CR?z!ZI)re_Z3DyZ~**ie+j&ahBu>7QYx2w8){7It|NR2QGxR z+;WnP)aM1_uh_`0*yc+@Cv>Ws-3u>-2;Lz(dF-kOqX7O6_jM(7FUYd-%sX^SKV~~4XJ-;%i7q-vJifj(Vw=_V>t7qt# z=WnlDrl>ETi$^{Fm=$ae6xEn8<^GwTJ@+brGj)8uGv|rS%$&%#n<{Ce#3sc{fW=Fw zXVaFJqj3SGDUYx>wc7AIDQBemO9mb{%>@JJH4qCk?!j# z4#JAAFga9!F5$#}_!bJ?R225T^ma?=z17}EnI%u!;R=Hr7x)^yrBFq9nXX}fHu*x#bfVaeTlmD2Kog}-wp+8;}5UmlOqaJPDQv?NU}PHX@>kO)*NT~;kM z@rAtEmhXdlX7pEa1GJDlcec#SU)3?+7StV?#Dj^d67(JIE}P$(2%RrkO!K8oVr!r} zjk%API(-|H%rFLZu-F&v4nFZ7dPQD8fpkNzfA7R_3!@uGPRF`SjFcW;o}b@mlTbM8 zv2Zi~&2H3G5tCvfp`b1!{Zu0(F4e^uuUw9*}XAAs@M1GaPKVIm7$lL z#c7)^?#rCVK>Ab^GV2F)){-{zGy#}$&WRfdvU*C$U(kXJhG;=&NZJQa9C#t?)S8P= zlfA8kTwezd+{DFiK?1iR(4OgyYi;aQnMb?s6Z7R?0Z%zE?3upJG5@jYRwD@`P;e|A zB!CXGyvX;(CSzo*Ibdu{qJ*_>Yrg+ls{susY~4Z{s0}cUe9?4qy?h_S4ORY6wALEr zMo!EUO&W$&kpwKV>h1S+dh-oh8RXvwF_lhdd$c2IymM%~d+~gauoI{J+*R=SMC9K{ z%77-I;zD_Qqo#6Z(A@efkjOM)#rY%6anidtpaIB0Iw=@~?L?_>^P9r38?6s z8+bGexHA|F6KnewEG{Dgc~s;`43n$Q`KUJ{-=N4=V8z^WsE%60s+lb;u*!=An0#(d zZ{&?2#rCQufP^m5du?&N(H-!%|I1B4yvAlgXJ0M;+P)`Pp1yxmH;SFP>_og2E;GBl zG%h>BlNDjjShjIE;V~Jj(OU73sNZJ5v086-f8*nOf!?a?El*T!h28mgc^`j4&$C!H z#6sdUh5JxIzHcHsAi-?L>5{Jg9aD^sU8DE3TiFvq!_G01Z;7P{5$PVMmQML+#qTyn z!q$H^Y*dRF=%uJ&^O-XTjGD)$ra_BnQ{_V$)+#07~L|)#ta}dqB9B%4R|Ety0K~Uy~NYB|0J;8)IMC~g^&nXs~&uu zVf8>}c_Le@ituv5FBE^8lAS(vN}sK+P+Uzo`GQ+poAi;Ww)X)|1A#-LPg!MKyOayU zK#%(O<|gZ4fKVKxH8+ye?z&dhiHmP�E@LdV7KfAMrIzy5iATZK6NeASo~O!;+kh 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

    A=swtU&Br{rj{CiQVppfl|-iIk9&yrtY@x=V&S# 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

    a@Ww0W~xTbS`b)PgS~z=;)qdzVe~CC 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

  1. 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%0D>v42lV|8pvnKw8wrXCnWO`^~#S#DIQ! z&B32@4aTpa|fE zGB2aNrUr7L;jtFRu0dTj!6YBl3b0rnA^t2kT6ZryJ%A2~tdyC_zVQdQUi7TwTvRVv zSYTNAnpKuRXGtp{=e@q-R&`s<0HpXd#HceP?cFTL -s*HDCNGpF`FK>(YW0Vj{ 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 Date: Thu, 9 Jul 2026 14:58:27 -0400 Subject: [PATCH 26/50] reorder graph events to match capture event ordering --- .../trace_capture_merge_experimental.py | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py index 0c910ec5f..7bcce2180 100644 --- a/TraceLens/Trace2Tree/trace_capture_merge_experimental.py +++ b/TraceLens/Trace2Tree/trace_capture_merge_experimental.py @@ -98,14 +98,13 @@ def _align_capture_to_graph(capture_events, graph_events): return None return aligned -def _align_capture_to_graph_by_group(capture_events, graph_events): +def _align_graph_to_capture_by_group(capture_events, graph_events): """ Align capture dispatch events to graph kernel events by grouping on kernel name and matching positionally within each group. - Returns the capture events reordered to match graph_events order, or None + Returns the graph_events reordered to match capture_events order, or None if any kernel name has a count mismatch between capture and graph. """ - capture_groups = defaultdict(list) for e in capture_events: capture_groups[_capture_kernel_name(e)].append(e) @@ -126,13 +125,13 @@ def _align_capture_to_graph_by_group(capture_events, graph_events): ) return None - # Reassemble capture events in graph order using per-group position + # Reassemble graph events in capture order using per-group position group_idx = defaultdict(int) aligned = [] - for g_event in graph_events: - name = g_event["name"] + for c_event in capture_events: + name = _capture_kernel_name(c_event) idx = group_idx[name] - aligned.append(capture_groups[name][idx]) + aligned.append(graph_groups[name][idx]) group_idx[name] += 1 return aligned @@ -230,13 +229,12 @@ def verify_subtree_events(capture_events, graph_events): in the same order (return code 1). 2. Greedy forward-scan by name — handles count mismatches by discarding extra capture dispatches (return code 2). - 3. Group-by-name positional match — handles cases where the HIP graph - scheduler reorders independent nodes relative to CPU dispatch order - (return code 3). See docs/capture_merge_error.md. + 3. Group-by-name positional match — handles cases graph replay events + and capture events are in different order (return code 3). Returns: - (success, aligned_capture_events) where success is 1, 2, or 3 on - success and 0 on failure. + (success, aligned_capture_events, aligned_graph_events) where success + is 1, 2, or 3 on success and 0 on failure. """ if len(capture_events) != len(graph_events): print( @@ -254,8 +252,8 @@ def verify_subtree_events(capture_events, graph_events): len(capture_events) - len(aligned), ) ) - return 2, aligned - return 0, capture_events + return 2, aligned, graph_events + return 0, capture_events, graph_events for j, i in zip(capture_events, graph_events): if "kernel" not in j.get("args", {}).keys(): @@ -268,13 +266,16 @@ def verify_subtree_events(capture_events, graph_events): ) continue if i["name"] != _capture_kernel_name(j): - aligned = _align_capture_to_graph_by_group(capture_events, graph_events) - if aligned is not None: + # Counts match but order differs + aligned_graph = _align_graph_to_capture_by_group( + capture_events, graph_events + ) + if aligned_graph is not None: print("Group-by-name alignment succeeded.") - return 3, aligned - return 0, capture_events + return 3, capture_events, aligned_graph + return 0, capture_events, graph_events - return 1, capture_events + return 1, capture_events, graph_events def update_subtree_uids_and_timestamps( @@ -762,7 +763,11 @@ def merge_capture_trace_into_graph( continue capture_filtered_events = aligned else: - verify_success, capture_filtered_events = verify_subtree_events( + ( + verify_success, + capture_filtered_events, + graph_filtered_events, + ) = verify_subtree_events( capture_filtered_events, graph_filtered_events ) From aeea45e68b63a557a1f38bc58c38d7153fb64a88 Mon Sep 17 00:00:00 2001 From: Arseny Date: Thu, 9 Jul 2026 14:28:52 -0700 Subject: [PATCH 27/50] Initial basic eval scripts --- .../compare_results/compare_diff_stats.py | 132 +++++++++++++ .../compare_results/random_baselines.py | 175 ++++++++++++++++++ 2 files changed, 307 insertions(+) create mode 100644 tests/traces/semantic/deepseek_R1/compare_results/compare_diff_stats.py create mode 100644 tests/traces/semantic/deepseek_R1/compare_results/random_baselines.py diff --git a/tests/traces/semantic/deepseek_R1/compare_results/compare_diff_stats.py b/tests/traces/semantic/deepseek_R1/compare_results/compare_diff_stats.py new file mode 100644 index 000000000..6bee4fe34 --- /dev/null +++ b/tests/traces/semantic/deepseek_R1/compare_results/compare_diff_stats.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +"""Compare LCA assignments between the "with capture" (gold standard) and +"no capture" comparative analyses of the same DeepSeek-R1 decode traces. + +Both analyses emit a ``diff_stats.csv`` in which every row is a single GPU +kernel (identified by ``source`` = trace1/trace2 and ``gpu_op_uid``) tagged with +a ``lowest_common_ancestor_id`` (LCA). LCA ids are opaque cluster labels: their +numeric value is only meaningful within a single analysis, so we never compare +ids across analyses directly. Instead we measure how well the two LCA +*partitions* of the shared kernel set agree, using bidirectional cluster purity. + +Forward purity (gold -> no-capture): + For every gold LCA group, take the majority no-capture LCA among its + kernels and count how many kernels in the group carry that majority label. + Sum across groups and divide by the number of matched kernels. + +Reverse purity (no-capture -> gold): the same metric with the roles swapped. + +Reporting both catches degenerate collapses: if the no-capture analysis dumped +every kernel into one LCA, forward purity stays high (each gold group trivially +agrees with the single label) but reverse purity collapses. +""" + +import argparse +from pathlib import Path + +import pandas as pd + +KEY_COLS = ["source", "gpu_op_uid"] +LCA_COL = "lowest_common_ancestor_id" + + +def load(path: Path, lca_out: str) -> pd.DataFrame: + df = pd.read_csv(path) + missing = [c for c in KEY_COLS + [LCA_COL, "name"] if c not in df.columns] + if missing: + raise ValueError(f"{path} is missing required columns: {missing}") + df = df.copy() + df["key"] = df["source"].astype(str) + ":" + df["gpu_op_uid"].astype(str) + if df["key"].duplicated().any(): + n = int(df["key"].duplicated().sum()) + raise ValueError(f"{path}: {n} duplicate (source, gpu_op_uid) keys; not a unique kernel id") + return df[["key", "name", LCA_COL]].rename(columns={LCA_COL: lca_out}) + + +def purity(df: pd.DataFrame, group_col: str, label_col: str): + """Sum over each group of the majority-label count within that group. + + Returns (matched_count, total, fraction, per_group_records).""" + total = len(df) + matched = 0 + records = [] + for gid, grp in df.groupby(group_col, sort=True): + counts = grp[label_col].value_counts() # sorted desc by count + majority_label = counts.index[0] + majority_count = int(counts.iloc[0]) + matched += majority_count + records.append( + { + "group_id": gid, + "group_size": len(grp), + "majority_label": majority_label, + "majority_count": majority_count, + "group_purity": majority_count / len(grp), + } + ) + frac = matched / total if total else float("nan") + return matched, total, frac, records + + +def main() -> None: + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument("with_capture", type=Path, help="path to with-capture (GOLD) diff_stats.csv") + ap.add_argument("no_capture", type=Path, help="path to no-capture diff_stats.csv") + args = ap.parse_args() + + gold = load(args.with_capture, "lca_gold") + ncap = load(args.no_capture, "lca_nc") + + print("=" * 78) + print("LCA assignment agreement: with-capture (GOLD) vs no-capture") + print("=" * 78) + print(f"with-capture kernels : {len(gold)} | distinct gold LCAs: {gold['lca_gold'].nunique()}") + print(f"no-capture kernels : {len(ncap)} | distinct nc LCAs: {ncap['lca_nc'].nunique()}") + + # Match kernels on identity (source, gpu_op_uid); keep only the intersection. + merged = gold.merge(ncap[["key", "lca_nc", "name"]], on="key", suffixes=("_gold", "_nc")) + name_agree = (merged["name_gold"] == merged["name_nc"]).mean() if len(merged) else float("nan") + + gold_only = len(gold) - len(merged) + nc_only = len(ncap) - len(merged) + print("-" * 78) + print(f"matched kernels (in both) : {len(merged)}") + print(f"gold-only (unmatched) : {gold_only}") + print(f"no-capture-only (unmatched) : {nc_only}") + print(f"kernel-name agreement on matched keys: {name_agree:.4f} (sanity: should be 1.0)") + + df = merged[["key", "lca_gold", "lca_nc"]] + print("-" * 78) + print(f"matched-set distinct gold LCAs: {df['lca_gold'].nunique()}") + print(f"matched-set distinct nc LCAs: {df['lca_nc'].nunique()}") + + # Forward purity: gold groups -> majority no-capture LCA. + f_matched, f_total, f_frac, f_recs = purity(df, "lca_gold", "lca_nc") + # Reverse purity: no-capture groups -> majority gold LCA. + r_matched, r_total, r_frac, r_recs = purity(df, "lca_nc", "lca_gold") + + print("=" * 78) + print("RESULTS") + print("=" * 78) + print( + f"Forward purity (gold group -> majority no-capture LCA): " + f"{f_matched}/{f_total} = {f_frac:.4f}" + ) + print( + f"Reverse purity (no-capture group -> majority gold LCA): " + f"{r_matched}/{r_total} = {r_frac:.4f}" + ) + print("=" * 78) + + # Extra context: the largest no-capture groups (where collapse would show up). + top_nc = ( + pd.DataFrame(r_recs) + .sort_values("group_size", ascending=False) + .head(5) + ) + print("Largest no-capture LCA groups (matched set):") + print(top_nc.to_string(index=False)) + + +if __name__ == "__main__": + main() diff --git a/tests/traces/semantic/deepseek_R1/compare_results/random_baselines.py b/tests/traces/semantic/deepseek_R1/compare_results/random_baselines.py new file mode 100644 index 000000000..92a983788 --- /dev/null +++ b/tests/traces/semantic/deepseek_R1/compare_results/random_baselines.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python3 +"""Random baselines for the no-capture LCA partition, evaluated with the same +bidirectional purity metric used in ``compare_diff_stats.py``. + +Both real and baseline purities are computed over the SAME 636 matched kernels +(kernels present in both the with-capture/GOLD and no-capture analyses, matched +by identity ``(source, gpu_op_uid)``). The baselines preserve the no-capture +bucket sizes *as observed on the matched set*, so the total number of matched +kernels (636) and each bucket's size are identical to the real no-capture +partition -- only the kernel->bucket assignment changes. + +Baseline 1 (random): randomly shuffle which matched kernels fall into each + bucket, preserving bucket sizes. Reported as mean +/- std over many seeds. + +Baseline 2 (sequential blocks, key string order): order buckets from most to + least popular, then walk the matched kernels ordered by the lexicographic key + string ("source:uid"), assigning the first k1 to bucket 1 (largest), the next + k2 to bucket 2, and so on. + +Baseline 3 (sequential blocks, integer uid order): identical block assignment, + but kernels are ordered by (source, integer gpu_op_uid). This respects the + numeric ordering of gpu_op_uid (e.g. 999 before 1000) that the string sort in + Baseline 2 breaks. + +Purpose: show what forward/reverse purity a semantics-free assignment achieves, +so the real no-capture purity can be judged against that floor. +""" + +import argparse +from pathlib import Path + +import numpy as np +import pandas as pd + +LCA_ID = "lowest_common_ancestor_id" +LCA_NAME = "lowest_common_ancestor_name" +N_TRIALS = 2000 +SEED = 0 + + +def load(path: Path): + df = pd.read_csv(path) + df = df.copy() + df["key"] = df["source"].astype(str) + ":" + df["gpu_op_uid"].astype(str) + return df + + +def purity_frac(labels_a: np.ndarray, labels_b: np.ndarray) -> float: + """Fraction of items whose A-group carries the A-group's majority B-label. + + Sum over groups of A of the modal B-count, divided by the total item count. + """ + df = pd.DataFrame({"a": labels_a, "b": labels_b}) + matched = 0 + for _, grp in df.groupby("a", sort=False): + matched += int(grp["b"].value_counts().iloc[0]) + return matched / len(df) + + +def both_purities(gold: np.ndarray, nc: np.ndarray): + """Return (forward, reverse). + + forward = gold group -> majority nc label + reverse = nc group -> majority gold label + """ + return purity_frac(gold, nc), purity_frac(nc, gold) + + +def run(merged: pd.DataFrame, title: str) -> None: + """Compute real + baseline purities for a given matched-kernel frame. + + ``merged`` must have columns: lca_gold, lca_nc, nc_name, source, gpu_op_uid. + Bucket sizes are recomputed from ``merged`` so the "total matched preserved" + property holds for whatever subset is passed in. + """ + merged = merged.sort_values("key").reset_index(drop=True) + n = len(merged) + + gold = merged["lca_gold"].to_numpy() + nc_real = merged["lca_nc"].to_numpy() + + # No-capture bucket sizes on this (sub)set (sum == n). + sizes = merged["lca_nc"].value_counts() # sorted desc by count + bucket_ids = sizes.index.to_numpy() + bucket_sizes = sizes.to_numpy() + names = ( + merged.drop_duplicates("lca_nc").set_index("lca_nc")["nc_name"].to_dict() + ) + assert bucket_sizes.sum() == n, (bucket_sizes.sum(), n) + + # Label pool: bucket id repeated by its size (length == n). + pool = np.repeat(bucket_ids, bucket_sizes) + assert len(pool) == n + + # ---- Real no-capture ---- + real_fwd, real_rev = both_purities(gold, nc_real) + + # ---- Baseline 1: random shuffle of the pool over matched kernels ---- + rng = np.random.default_rng(SEED) + fwds = np.empty(N_TRIALS) + revs = np.empty(N_TRIALS) + for t in range(N_TRIALS): + shuffled = pool.copy() + rng.shuffle(shuffled) + fwds[t], revs[t] = both_purities(gold, shuffled) + b1_fwd_m, b1_fwd_s = fwds.mean(), fwds.std() + b1_rev_m, b1_rev_s = revs.mean(), revs.std() + + # ---- Baseline 2: sequential blocks, buckets ordered most->least popular ---- + # Kernels ordered by key (lexicographic string: source then string uid). + seq = pool.copy() + b2_fwd, b2_rev = both_purities(gold, seq) + + # ---- Baseline 3: sequential blocks, kernels ordered by INT gpu_op_uid ---- + order3 = np.lexsort((merged["gpu_op_uid"].to_numpy(), merged["source"].to_numpy())) + gold3 = gold[order3] + b3_fwd, b3_rev = both_purities(gold3, pool) + + # ---------------- report ---------------- + print("=" * 74) + print(f"{title}") + print("Matched kernels:", n, "| no-capture buckets:", len(bucket_ids)) + print("Distinct gold LCAs:", merged["lca_gold"].nunique()) + print("=" * 74) + print("No-capture bucket sizes (preserved by all baselines):") + for bid, sz in zip(bucket_ids, bucket_sizes): + print(f" LCA {bid:>3} {names.get(bid, '?'):<18} {sz:>4}") + print("-" * 74) + hdr = f"{'partition':<26}{'forward (gold->nc)':>24}{'reverse (nc->gold)':>24}" + print(hdr) + print("-" * 74) + print(f"{'Real no-capture':<26}{real_fwd:>24.4f}{real_rev:>24.4f}") + print( + f"{'Baseline 1 (random)':<26}" + f"{f'{b1_fwd_m:.4f} +/- {b1_fwd_s:.4f}':>24}" + f"{f'{b1_rev_m:.4f} +/- {b1_rev_s:.4f}':>24}" + ) + print(f"{'Baseline 2 (seq, key str)':<26}{b2_fwd:>24.4f}{b2_rev:>24.4f}") + print(f"{'Baseline 3 (seq, int uid)':<26}{b3_fwd:>24.4f}{b3_rev:>24.4f}") + print("=" * 74) + + +def main() -> None: + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument("with_capture", type=Path, help="path to with-capture (GOLD) diff_stats.csv") + ap.add_argument("no_capture", type=Path, help="path to no-capture diff_stats.csv") + args = ap.parse_args() + + gold_df = load(args.with_capture) + nc_df = load(args.no_capture) + + # Matched set: identity present in both. Deterministic order by key. + merged = gold_df[["key", LCA_ID]].rename(columns={LCA_ID: "lca_gold"}).merge( + nc_df[["key", "source", "gpu_op_uid", LCA_ID, LCA_NAME]].rename( + columns={LCA_ID: "lca_nc", LCA_NAME: "nc_name"} + ), + on="key", + ) + + run(merged, "ALL MATCHED KERNELS") + + # Exclude singleton gold groups: gold LCAs with exactly one matched kernel. + gsz = merged.groupby("lca_gold")["key"].transform("size") + merged_ns = merged[gsz > 1].copy() + n_dropped = len(merged) - len(merged_ns) + print() + run( + merged_ns, + f"EXCLUDING SINGLETON GOLD GROUPS (dropped {n_dropped} kernels)", + ) + print(f"(Baseline 1 over {N_TRIALS} random seeds; Baselines 2 & 3 deterministic.)") + + +if __name__ == "__main__": + main() From d5af6690ac832044efb2a769e48ba86fc43bfa2d Mon Sep 17 00:00:00 2001 From: Arseny Date: Fri, 10 Jul 2026 09:37:37 -0700 Subject: [PATCH 28/50] Minor refactor --- .../eval_utils/compare_lca_partitions.py | 307 ++++++++++++++++++ .../compare_results/compare_diff_stats.py | 132 -------- .../compare_results/random_baselines.py | 175 ---------- 3 files changed, 307 insertions(+), 307 deletions(-) create mode 100755 agent_evals/Analysis/eval_utils/compare_lca_partitions.py delete mode 100644 tests/traces/semantic/deepseek_R1/compare_results/compare_diff_stats.py delete mode 100644 tests/traces/semantic/deepseek_R1/compare_results/random_baselines.py diff --git a/agent_evals/Analysis/eval_utils/compare_lca_partitions.py b/agent_evals/Analysis/eval_utils/compare_lca_partitions.py new file mode 100755 index 000000000..21901da00 --- /dev/null +++ b/agent_evals/Analysis/eval_utils/compare_lca_partitions.py @@ -0,0 +1,307 @@ +#!/usr/bin/env python3 +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Compare LCA (lowest-common-ancestor) partitions between the "with capture" +(gold standard) and "no capture" comparative analyses of the same traces, and +score the no-capture partition against semantics-free baselines. + +Both analyses emit a ``diff_stats.csv`` in which every row is a single GPU kernel +(identified by ``source`` = trace1/trace2 and ``gpu_op_uid``) tagged with a +``lowest_common_ancestor_id`` (LCA). LCA ids are opaque cluster labels: their +numeric value is only meaningful within a single analysis, so we never compare +ids across analyses directly. Instead we measure how well the two LCA +*partitions* of the shared kernel set agree, using bidirectional cluster purity. + +Forward purity (gold -> no-capture): + For every gold LCA group, take the majority no-capture LCA among its kernels + and count how many kernels in the group carry that majority label. Sum across + groups and divide by the number of matched kernels. + +Reverse purity (no-capture -> gold): the same metric with the roles swapped. + +Reporting both catches degenerate collapses: if the no-capture analysis dumped +every kernel into one LCA, forward purity stays high (each gold group trivially +agrees with the single label) but reverse purity collapses. + +Random baselines +---------------- +To judge whether the real no-capture purity reflects genuine semantic signal or +is merely an artifact of the bucket-size distribution and the metric's structure, +we compare against semantics-free baselines. All are evaluated on the SAME +matched kernels and PRESERVE the no-capture bucket sizes as observed on the +matched set -- only the kernel->bucket assignment changes. + +Baseline 1 (random): randomly shuffle which matched kernels fall into each + bucket, preserving bucket sizes. Reported as mean +/- std over many seeds. +Baseline 2 (sequential blocks, key string order): order buckets from most to + least popular, then walk the matched kernels ordered by the lexicographic key + string ("source:uid"), assigning the first k1 to bucket 1 (largest), the next + k2 to bucket 2, and so on. +Baseline 3 (sequential blocks, integer uid order): identical block assignment, + but kernels are ordered by (source, integer gpu_op_uid). + +Usage: + compare_lca_partitions.py +""" + +import argparse +from pathlib import Path + +import numpy as np +import pandas as pd + +KEY_COLS = ["source", "gpu_op_uid"] +LCA_COL = "lowest_common_ancestor_id" +LCA_NAME = "lowest_common_ancestor_name" + +# Number of random-baseline seeds (Baseline 1). Kept modest by default; the +# baseline loop is O(trials * kernels), so for large kernel sets it is capped to +# REDUCED_TRIALS (see the guard in main()). +DEFAULT_TRIALS = 200 +LARGE_KERNEL_THRESHOLD = 5000 +REDUCED_TRIALS = 2 +SEED = 0 + + +def load(path: Path) -> pd.DataFrame: + """Load a diff_stats.csv, validate identity columns, and add a unique key.""" + df = pd.read_csv(path) + missing = [c for c in KEY_COLS + [LCA_COL, LCA_NAME, "name"] if c not in df.columns] + if missing: + raise ValueError(f"{path} is missing required columns: {missing}") + df = df.copy() + df["key"] = df["source"].astype(str) + ":" + df["gpu_op_uid"].astype(str) + if df["key"].duplicated().any(): + n = int(df["key"].duplicated().sum()) + raise ValueError(f"{path}: {n} duplicate (source, gpu_op_uid) keys; not a unique kernel id") + return df + + +def purity(df: pd.DataFrame, group_col: str, label_col: str): + """Sum over each group of the majority-label count within that group. + + Returns (matched_count, total, fraction, per_group_records).""" + total = len(df) + matched = 0 + records = [] + for gid, grp in df.groupby(group_col, sort=True): + counts = grp[label_col].value_counts() # sorted desc by count + majority_label = counts.index[0] + majority_count = int(counts.iloc[0]) + matched += majority_count + records.append( + { + "group_id": gid, + "group_size": len(grp), + "majority_label": majority_label, + "majority_count": majority_count, + "group_purity": majority_count / len(grp), + } + ) + frac = matched / total if total else float("nan") + return matched, total, frac, records + + +def purity_frac(labels_a: np.ndarray, labels_b: np.ndarray) -> float: + """Fraction of items whose A-group carries the A-group's majority B-label. + + Sum over groups of A of the modal B-count, divided by the total item count. + """ + df = pd.DataFrame({"a": labels_a, "b": labels_b}) + matched = 0 + for _, grp in df.groupby("a", sort=False): + matched += int(grp["b"].value_counts().iloc[0]) + return matched / len(df) + + +def both_purities(gold: np.ndarray, nc: np.ndarray): + """Return (forward, reverse). + + forward = gold group -> majority nc label + reverse = nc group -> majority gold label + """ + return purity_frac(gold, nc), purity_frac(nc, gold) + + +def agreement_report(gold: pd.DataFrame, ncap: pd.DataFrame) -> None: + """Print the LCA-partition agreement (forward/reverse purity) section.""" + print("=" * 78) + print("LCA assignment agreement: with-capture (GOLD) vs no-capture") + print("=" * 78) + print(f"with-capture kernels : {len(gold)} | distinct gold LCAs: {gold[LCA_COL].nunique()}") + print(f"no-capture kernels : {len(ncap)} | distinct nc LCAs: {ncap[LCA_COL].nunique()}") + + g = gold[["key", "name", LCA_COL]].rename(columns={LCA_COL: "lca_gold", "name": "name_gold"}) + n = ncap[["key", "name", LCA_COL]].rename(columns={LCA_COL: "lca_nc", "name": "name_nc"}) + merged = g.merge(n, on="key") + name_agree = (merged["name_gold"] == merged["name_nc"]).mean() if len(merged) else float("nan") + + gold_only = len(gold) - len(merged) + nc_only = len(ncap) - len(merged) + print("-" * 78) + print(f"matched kernels (in both) : {len(merged)}") + print(f"gold-only (unmatched) : {gold_only}") + print(f"no-capture-only (unmatched) : {nc_only}") + print(f"kernel-name agreement on matched keys: {name_agree:.4f} (sanity: should be 1.0)") + + df = merged[["key", "lca_gold", "lca_nc"]] + print("-" * 78) + print(f"matched-set distinct gold LCAs: {df['lca_gold'].nunique()}") + print(f"matched-set distinct nc LCAs: {df['lca_nc'].nunique()}") + + # Forward purity: gold groups -> majority no-capture LCA. + f_matched, f_total, f_frac, _ = purity(df, "lca_gold", "lca_nc") + # Reverse purity: no-capture groups -> majority gold LCA. + r_matched, r_total, r_frac, r_recs = purity(df, "lca_nc", "lca_gold") + + print("=" * 78) + print("RESULTS") + print("=" * 78) + print( + f"Forward purity (gold group -> majority no-capture LCA): " + f"{f_matched}/{f_total} = {f_frac:.4f}" + ) + print( + f"Reverse purity (no-capture group -> majority gold LCA): " + f"{r_matched}/{r_total} = {r_frac:.4f}" + ) + print("=" * 78) + + # Extra context: the largest no-capture groups (where collapse would show up). + top_nc = pd.DataFrame(r_recs).sort_values("group_size", ascending=False).head(5) + print("Largest no-capture LCA groups (matched set):") + print(top_nc.to_string(index=False)) + + +def baseline_report(merged: pd.DataFrame, title: str, n_trials: int) -> None: + """Compute real + baseline purities for a given matched-kernel frame. + + ``merged`` must have columns: lca_gold, lca_nc, nc_name, source, gpu_op_uid, + key. Bucket sizes are recomputed from ``merged`` so the "total matched + preserved" property holds for whatever subset is passed in. + """ + merged = merged.sort_values("key").reset_index(drop=True) + n = len(merged) + + gold = merged["lca_gold"].to_numpy() + nc_real = merged["lca_nc"].to_numpy() + + # No-capture bucket sizes on this (sub)set (sum == n). + sizes = merged["lca_nc"].value_counts() # sorted desc by count + bucket_ids = sizes.index.to_numpy() + bucket_sizes = sizes.to_numpy() + names = merged.drop_duplicates("lca_nc").set_index("lca_nc")["nc_name"].to_dict() + assert bucket_sizes.sum() == n, (bucket_sizes.sum(), n) + + # Label pool: bucket id repeated by its size (length == n). + pool = np.repeat(bucket_ids, bucket_sizes) + assert len(pool) == n + + # ---- Real no-capture ---- + real_fwd, real_rev = both_purities(gold, nc_real) + + # ---- Baseline 1: random shuffle of the pool over matched kernels ---- + rng = np.random.default_rng(SEED) + fwds = np.empty(n_trials) + revs = np.empty(n_trials) + for t in range(n_trials): + shuffled = pool.copy() + rng.shuffle(shuffled) + fwds[t], revs[t] = both_purities(gold, shuffled) + b1_fwd_m, b1_fwd_s = fwds.mean(), fwds.std() + b1_rev_m, b1_rev_s = revs.mean(), revs.std() + + # ---- Baseline 2: sequential blocks, buckets ordered most->least popular ---- + # Kernels ordered by key (lexicographic string: source then string uid). + seq = pool.copy() + b2_fwd, b2_rev = both_purities(gold, seq) + + # ---- Baseline 3: sequential blocks, kernels ordered by INT gpu_op_uid ---- + order3 = np.lexsort((merged["gpu_op_uid"].to_numpy(), merged["source"].to_numpy())) + gold3 = gold[order3] + b3_fwd, b3_rev = both_purities(gold3, pool) + + # ---------------- report ---------------- + print("=" * 74) + print(f"{title}") + print("Matched kernels:", n, "| no-capture buckets:", len(bucket_ids)) + print("Distinct gold LCAs:", merged["lca_gold"].nunique()) + print("=" * 74) + print("No-capture bucket sizes (preserved by all baselines):") + for bid, sz in zip(bucket_ids, bucket_sizes): + print(f" LCA {bid:>3} {names.get(bid, '?'):<18} {sz:>4}") + print("-" * 74) + hdr = f"{'partition':<26}{'forward (gold->nc)':>24}{'reverse (nc->gold)':>24}" + print(hdr) + print("-" * 74) + print(f"{'Real no-capture':<26}{real_fwd:>24.4f}{real_rev:>24.4f}") + print( + f"{'Baseline 1 (random)':<26}" + f"{f'{b1_fwd_m:.4f} +/- {b1_fwd_s:.4f}':>24}" + f"{f'{b1_rev_m:.4f} +/- {b1_rev_s:.4f}':>24}" + ) + print(f"{'Baseline 2 (seq, key str)':<26}{b2_fwd:>24.4f}{b2_rev:>24.4f}") + print(f"{'Baseline 3 (seq, int uid)':<26}{b3_fwd:>24.4f}{b3_rev:>24.4f}") + print("=" * 74) + + +def main() -> None: + ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + ap.add_argument("with_capture", type=Path, help="path to with-capture (GOLD) diff_stats.csv") + ap.add_argument("no_capture", type=Path, help="path to no-capture diff_stats.csv") + ap.add_argument( + "--trials", + type=int, + default=DEFAULT_TRIALS, + help=f"random-baseline seeds (default: {DEFAULT_TRIALS}; auto-capped to " + f"{REDUCED_TRIALS} when matched kernels > {LARGE_KERNEL_THRESHOLD})", + ) + args = ap.parse_args() + + gold = load(args.with_capture) + ncap = load(args.no_capture) + + # ---- Part 1: LCA-partition agreement ---- + agreement_report(gold, ncap) + print() + + # Matched set for the baselines: identity present in both. Deterministic by key. + merged = gold[["key", LCA_COL]].rename(columns={LCA_COL: "lca_gold"}).merge( + ncap[["key", "source", "gpu_op_uid", LCA_COL, LCA_NAME]].rename( + columns={LCA_COL: "lca_nc", LCA_NAME: "nc_name"} + ), + on="key", + ) + + # Guard: the random baseline is O(trials * kernels); cap trials on large sets. + n_trials = args.trials + if len(merged) > LARGE_KERNEL_THRESHOLD: + n_trials = REDUCED_TRIALS + print( + f"[guard] matched kernels = {len(merged)} > {LARGE_KERNEL_THRESHOLD}; " + f"reducing random-baseline trials {args.trials} -> {n_trials}" + ) + print() + + # ---- Part 2: random / sequential baselines ---- + baseline_report(merged, "ALL MATCHED KERNELS", n_trials) + + # Exclude singleton gold groups: gold LCAs with exactly one matched kernel. + gsz = merged.groupby("lca_gold")["key"].transform("size") + merged_ns = merged[gsz > 1].copy() + n_dropped = len(merged) - len(merged_ns) + print() + baseline_report( + merged_ns, + f"EXCLUDING SINGLETON GOLD GROUPS (dropped {n_dropped} kernels)", + n_trials, + ) + print(f"(Baseline 1 over {n_trials} random seeds; Baselines 2 & 3 deterministic.)") + + +if __name__ == "__main__": + main() diff --git a/tests/traces/semantic/deepseek_R1/compare_results/compare_diff_stats.py b/tests/traces/semantic/deepseek_R1/compare_results/compare_diff_stats.py deleted file mode 100644 index 6bee4fe34..000000000 --- a/tests/traces/semantic/deepseek_R1/compare_results/compare_diff_stats.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env python3 -"""Compare LCA assignments between the "with capture" (gold standard) and -"no capture" comparative analyses of the same DeepSeek-R1 decode traces. - -Both analyses emit a ``diff_stats.csv`` in which every row is a single GPU -kernel (identified by ``source`` = trace1/trace2 and ``gpu_op_uid``) tagged with -a ``lowest_common_ancestor_id`` (LCA). LCA ids are opaque cluster labels: their -numeric value is only meaningful within a single analysis, so we never compare -ids across analyses directly. Instead we measure how well the two LCA -*partitions* of the shared kernel set agree, using bidirectional cluster purity. - -Forward purity (gold -> no-capture): - For every gold LCA group, take the majority no-capture LCA among its - kernels and count how many kernels in the group carry that majority label. - Sum across groups and divide by the number of matched kernels. - -Reverse purity (no-capture -> gold): the same metric with the roles swapped. - -Reporting both catches degenerate collapses: if the no-capture analysis dumped -every kernel into one LCA, forward purity stays high (each gold group trivially -agrees with the single label) but reverse purity collapses. -""" - -import argparse -from pathlib import Path - -import pandas as pd - -KEY_COLS = ["source", "gpu_op_uid"] -LCA_COL = "lowest_common_ancestor_id" - - -def load(path: Path, lca_out: str) -> pd.DataFrame: - df = pd.read_csv(path) - missing = [c for c in KEY_COLS + [LCA_COL, "name"] if c not in df.columns] - if missing: - raise ValueError(f"{path} is missing required columns: {missing}") - df = df.copy() - df["key"] = df["source"].astype(str) + ":" + df["gpu_op_uid"].astype(str) - if df["key"].duplicated().any(): - n = int(df["key"].duplicated().sum()) - raise ValueError(f"{path}: {n} duplicate (source, gpu_op_uid) keys; not a unique kernel id") - return df[["key", "name", LCA_COL]].rename(columns={LCA_COL: lca_out}) - - -def purity(df: pd.DataFrame, group_col: str, label_col: str): - """Sum over each group of the majority-label count within that group. - - Returns (matched_count, total, fraction, per_group_records).""" - total = len(df) - matched = 0 - records = [] - for gid, grp in df.groupby(group_col, sort=True): - counts = grp[label_col].value_counts() # sorted desc by count - majority_label = counts.index[0] - majority_count = int(counts.iloc[0]) - matched += majority_count - records.append( - { - "group_id": gid, - "group_size": len(grp), - "majority_label": majority_label, - "majority_count": majority_count, - "group_purity": majority_count / len(grp), - } - ) - frac = matched / total if total else float("nan") - return matched, total, frac, records - - -def main() -> None: - ap = argparse.ArgumentParser(description=__doc__) - ap.add_argument("with_capture", type=Path, help="path to with-capture (GOLD) diff_stats.csv") - ap.add_argument("no_capture", type=Path, help="path to no-capture diff_stats.csv") - args = ap.parse_args() - - gold = load(args.with_capture, "lca_gold") - ncap = load(args.no_capture, "lca_nc") - - print("=" * 78) - print("LCA assignment agreement: with-capture (GOLD) vs no-capture") - print("=" * 78) - print(f"with-capture kernels : {len(gold)} | distinct gold LCAs: {gold['lca_gold'].nunique()}") - print(f"no-capture kernels : {len(ncap)} | distinct nc LCAs: {ncap['lca_nc'].nunique()}") - - # Match kernels on identity (source, gpu_op_uid); keep only the intersection. - merged = gold.merge(ncap[["key", "lca_nc", "name"]], on="key", suffixes=("_gold", "_nc")) - name_agree = (merged["name_gold"] == merged["name_nc"]).mean() if len(merged) else float("nan") - - gold_only = len(gold) - len(merged) - nc_only = len(ncap) - len(merged) - print("-" * 78) - print(f"matched kernels (in both) : {len(merged)}") - print(f"gold-only (unmatched) : {gold_only}") - print(f"no-capture-only (unmatched) : {nc_only}") - print(f"kernel-name agreement on matched keys: {name_agree:.4f} (sanity: should be 1.0)") - - df = merged[["key", "lca_gold", "lca_nc"]] - print("-" * 78) - print(f"matched-set distinct gold LCAs: {df['lca_gold'].nunique()}") - print(f"matched-set distinct nc LCAs: {df['lca_nc'].nunique()}") - - # Forward purity: gold groups -> majority no-capture LCA. - f_matched, f_total, f_frac, f_recs = purity(df, "lca_gold", "lca_nc") - # Reverse purity: no-capture groups -> majority gold LCA. - r_matched, r_total, r_frac, r_recs = purity(df, "lca_nc", "lca_gold") - - print("=" * 78) - print("RESULTS") - print("=" * 78) - print( - f"Forward purity (gold group -> majority no-capture LCA): " - f"{f_matched}/{f_total} = {f_frac:.4f}" - ) - print( - f"Reverse purity (no-capture group -> majority gold LCA): " - f"{r_matched}/{r_total} = {r_frac:.4f}" - ) - print("=" * 78) - - # Extra context: the largest no-capture groups (where collapse would show up). - top_nc = ( - pd.DataFrame(r_recs) - .sort_values("group_size", ascending=False) - .head(5) - ) - print("Largest no-capture LCA groups (matched set):") - print(top_nc.to_string(index=False)) - - -if __name__ == "__main__": - main() diff --git a/tests/traces/semantic/deepseek_R1/compare_results/random_baselines.py b/tests/traces/semantic/deepseek_R1/compare_results/random_baselines.py deleted file mode 100644 index 92a983788..000000000 --- a/tests/traces/semantic/deepseek_R1/compare_results/random_baselines.py +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/env python3 -"""Random baselines for the no-capture LCA partition, evaluated with the same -bidirectional purity metric used in ``compare_diff_stats.py``. - -Both real and baseline purities are computed over the SAME 636 matched kernels -(kernels present in both the with-capture/GOLD and no-capture analyses, matched -by identity ``(source, gpu_op_uid)``). The baselines preserve the no-capture -bucket sizes *as observed on the matched set*, so the total number of matched -kernels (636) and each bucket's size are identical to the real no-capture -partition -- only the kernel->bucket assignment changes. - -Baseline 1 (random): randomly shuffle which matched kernels fall into each - bucket, preserving bucket sizes. Reported as mean +/- std over many seeds. - -Baseline 2 (sequential blocks, key string order): order buckets from most to - least popular, then walk the matched kernels ordered by the lexicographic key - string ("source:uid"), assigning the first k1 to bucket 1 (largest), the next - k2 to bucket 2, and so on. - -Baseline 3 (sequential blocks, integer uid order): identical block assignment, - but kernels are ordered by (source, integer gpu_op_uid). This respects the - numeric ordering of gpu_op_uid (e.g. 999 before 1000) that the string sort in - Baseline 2 breaks. - -Purpose: show what forward/reverse purity a semantics-free assignment achieves, -so the real no-capture purity can be judged against that floor. -""" - -import argparse -from pathlib import Path - -import numpy as np -import pandas as pd - -LCA_ID = "lowest_common_ancestor_id" -LCA_NAME = "lowest_common_ancestor_name" -N_TRIALS = 2000 -SEED = 0 - - -def load(path: Path): - df = pd.read_csv(path) - df = df.copy() - df["key"] = df["source"].astype(str) + ":" + df["gpu_op_uid"].astype(str) - return df - - -def purity_frac(labels_a: np.ndarray, labels_b: np.ndarray) -> float: - """Fraction of items whose A-group carries the A-group's majority B-label. - - Sum over groups of A of the modal B-count, divided by the total item count. - """ - df = pd.DataFrame({"a": labels_a, "b": labels_b}) - matched = 0 - for _, grp in df.groupby("a", sort=False): - matched += int(grp["b"].value_counts().iloc[0]) - return matched / len(df) - - -def both_purities(gold: np.ndarray, nc: np.ndarray): - """Return (forward, reverse). - - forward = gold group -> majority nc label - reverse = nc group -> majority gold label - """ - return purity_frac(gold, nc), purity_frac(nc, gold) - - -def run(merged: pd.DataFrame, title: str) -> None: - """Compute real + baseline purities for a given matched-kernel frame. - - ``merged`` must have columns: lca_gold, lca_nc, nc_name, source, gpu_op_uid. - Bucket sizes are recomputed from ``merged`` so the "total matched preserved" - property holds for whatever subset is passed in. - """ - merged = merged.sort_values("key").reset_index(drop=True) - n = len(merged) - - gold = merged["lca_gold"].to_numpy() - nc_real = merged["lca_nc"].to_numpy() - - # No-capture bucket sizes on this (sub)set (sum == n). - sizes = merged["lca_nc"].value_counts() # sorted desc by count - bucket_ids = sizes.index.to_numpy() - bucket_sizes = sizes.to_numpy() - names = ( - merged.drop_duplicates("lca_nc").set_index("lca_nc")["nc_name"].to_dict() - ) - assert bucket_sizes.sum() == n, (bucket_sizes.sum(), n) - - # Label pool: bucket id repeated by its size (length == n). - pool = np.repeat(bucket_ids, bucket_sizes) - assert len(pool) == n - - # ---- Real no-capture ---- - real_fwd, real_rev = both_purities(gold, nc_real) - - # ---- Baseline 1: random shuffle of the pool over matched kernels ---- - rng = np.random.default_rng(SEED) - fwds = np.empty(N_TRIALS) - revs = np.empty(N_TRIALS) - for t in range(N_TRIALS): - shuffled = pool.copy() - rng.shuffle(shuffled) - fwds[t], revs[t] = both_purities(gold, shuffled) - b1_fwd_m, b1_fwd_s = fwds.mean(), fwds.std() - b1_rev_m, b1_rev_s = revs.mean(), revs.std() - - # ---- Baseline 2: sequential blocks, buckets ordered most->least popular ---- - # Kernels ordered by key (lexicographic string: source then string uid). - seq = pool.copy() - b2_fwd, b2_rev = both_purities(gold, seq) - - # ---- Baseline 3: sequential blocks, kernels ordered by INT gpu_op_uid ---- - order3 = np.lexsort((merged["gpu_op_uid"].to_numpy(), merged["source"].to_numpy())) - gold3 = gold[order3] - b3_fwd, b3_rev = both_purities(gold3, pool) - - # ---------------- report ---------------- - print("=" * 74) - print(f"{title}") - print("Matched kernels:", n, "| no-capture buckets:", len(bucket_ids)) - print("Distinct gold LCAs:", merged["lca_gold"].nunique()) - print("=" * 74) - print("No-capture bucket sizes (preserved by all baselines):") - for bid, sz in zip(bucket_ids, bucket_sizes): - print(f" LCA {bid:>3} {names.get(bid, '?'):<18} {sz:>4}") - print("-" * 74) - hdr = f"{'partition':<26}{'forward (gold->nc)':>24}{'reverse (nc->gold)':>24}" - print(hdr) - print("-" * 74) - print(f"{'Real no-capture':<26}{real_fwd:>24.4f}{real_rev:>24.4f}") - print( - f"{'Baseline 1 (random)':<26}" - f"{f'{b1_fwd_m:.4f} +/- {b1_fwd_s:.4f}':>24}" - f"{f'{b1_rev_m:.4f} +/- {b1_rev_s:.4f}':>24}" - ) - print(f"{'Baseline 2 (seq, key str)':<26}{b2_fwd:>24.4f}{b2_rev:>24.4f}") - print(f"{'Baseline 3 (seq, int uid)':<26}{b3_fwd:>24.4f}{b3_rev:>24.4f}") - print("=" * 74) - - -def main() -> None: - ap = argparse.ArgumentParser(description=__doc__) - ap.add_argument("with_capture", type=Path, help="path to with-capture (GOLD) diff_stats.csv") - ap.add_argument("no_capture", type=Path, help="path to no-capture diff_stats.csv") - args = ap.parse_args() - - gold_df = load(args.with_capture) - nc_df = load(args.no_capture) - - # Matched set: identity present in both. Deterministic order by key. - merged = gold_df[["key", LCA_ID]].rename(columns={LCA_ID: "lca_gold"}).merge( - nc_df[["key", "source", "gpu_op_uid", LCA_ID, LCA_NAME]].rename( - columns={LCA_ID: "lca_nc", LCA_NAME: "nc_name"} - ), - on="key", - ) - - run(merged, "ALL MATCHED KERNELS") - - # Exclude singleton gold groups: gold LCAs with exactly one matched kernel. - gsz = merged.groupby("lca_gold")["key"].transform("size") - merged_ns = merged[gsz > 1].copy() - n_dropped = len(merged) - len(merged_ns) - print() - run( - merged_ns, - f"EXCLUDING SINGLETON GOLD GROUPS (dropped {n_dropped} kernels)", - ) - print(f"(Baseline 1 over {N_TRIALS} random seeds; Baselines 2 & 3 deterministic.)") - - -if __name__ == "__main__": - main() From b9992a6120352e68f04a1de2f1cb21a1e78d13d3 Mon Sep 17 00:00:00 2001 From: Arseny Date: Fri, 10 Jul 2026 11:40:29 -0700 Subject: [PATCH 29/50] Replace block harmonization with name-first kernel-name unification for graph-mode semantic comparison Graph-mode traces collapse the CPU->GPU call stack under hip/cudaGraphLaunch, so nn_module/cpu_op context is unavailable and the block-alignment harmonization cannot work. The only reliable cross-trace signal is the raw GPU kernel name. This reworks Step 2 of the semantic comparison workflow into two LLM-assisted, name-first passes writing the unified name into semantic_block (consumed unchanged by the downstream diff/comparison scripts). Pass 1 (kernel_unification.py): unify raw kernel names across traces to establish certain anchors. prepare-context aggregates unique names with stats; apply-map writes the unified name (default = raw name). For >5000 unique names, an LLM-driven stem preprocessing step (kernel-stem-preprocessing-agent) authors custom regex rules (collapse/preserve/drop) applied by apply-stem-rules. Pass 2 (kernel_coherence.py + kernel_runlength.py): refine one-sided buckets using first-pass shared buckets as positional anchors. prepare-context derives each one-sided bucket's shared-neighbor context; the coherence agent pairs same-context buckets across traces into new shared names (e.g. cross-vendor GEMM projections) and splits names that occur in different contexts; apply resolves each kernel via context_renames -> fallback_remap -> keep. Adds agents kernel-unification-agent, kernel-stem-preprocessing-agent, kernel-coherence-agent and updates semantic-comparison-agent Steps 2.1-2.6. --- .../.cursor/agents/kernel-coherence-agent.md | 136 +++++ .../agents/kernel-stem-preprocessing-agent.md | 127 +++++ .../agents/kernel-unification-agent.md | 124 ++++ .../agents/semantic-comparison-agent.md | 175 ++++-- .../semantic_analyses/kernel_coherence.py | 450 +++++++++++++++ .../semantic_analyses/kernel_runlength.py | 80 +++ .../semantic_analyses/kernel_unification.py | 538 ++++++++++++++++++ 7 files changed, 1592 insertions(+), 38 deletions(-) create mode 100644 TraceLens/Agent/Analysis/.cursor/agents/kernel-coherence-agent.md create mode 100644 TraceLens/Agent/Analysis/.cursor/agents/kernel-stem-preprocessing-agent.md create mode 100644 TraceLens/Agent/Analysis/.cursor/agents/kernel-unification-agent.md create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/kernel_runlength.py create mode 100644 TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py diff --git a/TraceLens/Agent/Analysis/.cursor/agents/kernel-coherence-agent.md b/TraceLens/Agent/Analysis/.cursor/agents/kernel-coherence-agent.md new file mode 100644 index 000000000..0adffbb7b --- /dev/null +++ b/TraceLens/Agent/Analysis/.cursor/agents/kernel-coherence-agent.md @@ -0,0 +1,136 @@ + + +--- +name: kernel-coherence-agent +description: Second-pass cross-trace refinement. Consumes kernel_coherence_context.json (one-sided kernel buckets with their shared-neighbor context) and writes kernel_coherence_decisions.json, pairing one-sided buckets across traces by position and splitting names that occur in different contexts, so the comparison has no one-sided condensed symbols. +model: claude-opus-4-8 +--- + +# Kernel Coherence Agent + +Second pass over the name-first unification. The first pass leaves **one-sided** +buckets: kernels whose unified name appears in only one trace -- most importantly +vendor GEMM families that could not be paired by name (MI300 `Cijk_*` vs B300 +`nvjet_*`). This pass uses the first-pass **shared** buckets as cross-trace +positional anchors and re-labels the one-sided buckets by their **neighbor +context**. + +Two capabilities: + +1. **Cross-trace pairing by position.** A one-sided bucket in trace A and a + one-sided bucket in trace B that sit in the *same* shared-neighbor context are + the same operation -- give them the **same new shared name**. (The GEMM + between `add_rmsnorm` and `rotary_embedding` is the QKV projection on both + traces, even though the raw kernels are `Cijk_...` vs `nvjet_...`.) +2. **Context-dependent splitting.** One name that appears in *different* contexts + should become *different* buckets (a GEMM between attention and norm vs a GEMM + between embedding and MoE). + +**Scripts directory:** `TraceLens/Agent/Analysis/semantic_analyses/` + +## Input + +The full `kernel_coherence_context.json` is provided inline. Key fields: + +- `condensed_sequence_a` / `_b` -- kernel-order semantic_block values with + consecutive duplicates collapsed (one symbol per run). +- `shared_blocks` -- symbols in both condensed sequences (your stable anchors). +- `one_sided_in_a` / `one_sided_in_b` -- the symbols you must resolve. +- `one_sided_details_a` / `_b` -- per one-sided symbol, a list of `contexts`, + each with `id`, `left_window` / `right_window` (nearest shared symbols), + `kernels_in_run`, `perf_categories`, `sample_input_dims`, and + `top_kernel_names_by_dur`. +- `context_catalog` -- flat list of every context with its `id` (use these ids + verbatim in your output). + +## How to decide + +For each one-sided context, work out the operation from: + +- **`left_window` / `right_window`** -- the primary signal. In a transformer + decoder layer the projections are pinned by their neighbors: + - `(*norm* | rotary_embedding)` -> QKV projection + - `(paged_attention | *norm*)` -> output projection + - `(*norm* | act_and_mul)` -> gate/up projection + - `(act_and_mul | *norm*)` -> down projection +- **kernel name** -- `Cijk_*`, `nvjet_*`, `cublasLt::*`, `_gemm_*` are GEMMs; + `*paged_attention*`, `*fmha*` attention; `*rmsnorm*` norm; `*rope*` rotary. +- **`sample_input_dims`** and **`kernels_in_run`** -- corroborate a pairing + (matching shapes / per-layer counts). + +**Pairing rule:** two contexts on opposite traces with the same +`(left_window, right_window)` and a compatible operation get the **same** final +name. Pick a short, vendor-neutral name (`qkv_projection`, `output_projection`, +`gate_up_projection`, `down_projection`, ...). + +**perf_category caveat:** the regex classifier may tag a vendor kernel as +`Others` (e.g. `nvjet_*`). Do **not** require identical `perf_category` to pair +-- rely on the kernel name and the neighbor context. Still never pair operations +that are clearly different types. + +## Output file: `kernel_coherence_decisions.json` + +```json +{ + "context_renames": { + "MI300:6": "qkv_projection", + "B300:6": "qkv_projection" + }, + "fallback_remap_a": { + "Cijk_..._MT64x16x128_...": "qkv_projection" + }, + "fallback_remap_b": { + "nvjet_sm103_tst_64x16_64x16_4x1_v_bz_TNT": "qkv_projection" + }, + "notes": "optional rationale" +} +``` + +Resolution order applied per kernel (see `apply`): + +1. **`context_renames[context_id]`** -- context-specific; wins. Use it to express + context-dependent behavior: the *same* first-pass symbol with *different* + `(left,right)` windows gets *different* finals via *different* context ids. +2. **`fallback_remap_a` / `_b[symbol]`** -- blanket per-symbol remap, applied when + no context id matched (empty windows at a sequence boundary) or when a symbol + means the same thing everywhere and you don't need to split it by context. +3. Otherwise the first-pass name is kept. + +### Guidance + +- For a GEMM shape that has one dominant role across the trace, a single + `fallback_remap` entry is cleaner than many identical `context_renames`; add + `context_renames` only where a symbol genuinely changes role by context. +- Prefer merging a one-sided bucket into an **existing shared** symbol when the + evidence supports it (e.g. an attention split-K/reduce kernel -> the shared + `paged_attention` bucket). +- When you introduce a new bucket for a paired concept, use the **same** name on + both traces so the condensed sets align. +- **Leave genuine one-offs alone.** Pre/post-layer, framework-specific setup + kernels (index build, dtype copies, prefix-scan) have no counterpart; do not + force them into a shared bucket. Residual one-sided singletons are acceptable. + +## Apply + verify + +```bash +python TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py apply \ + --context /kernel_coherence_context.json \ + --decisions /kernel_coherence_decisions.json \ + --audit-csv-a /per_kernel_final_.csv \ + --audit-csv-b /per_kernel_final_.csv +``` + +Rewrites `semantic_block` on both label files, writes per-kernel audit CSVs, and +prints the residual one-sided condensed symbols. If meaningful (non-singleton) +symbols remain one-sided, revise the decisions and re-run; residual pre/post +singletons may be accepted. + +## Return Value + +Return: `status`, `pairs_created` (new shared names used on both sides), +`context_renames`, `fallback_a`, `fallback_b`, `shared_blocks_after`, and the +residual one-sided symbols with a one-line reason for leaving each. diff --git a/TraceLens/Agent/Analysis/.cursor/agents/kernel-stem-preprocessing-agent.md b/TraceLens/Agent/Analysis/.cursor/agents/kernel-stem-preprocessing-agent.md new file mode 100644 index 000000000..636789e22 --- /dev/null +++ b/TraceLens/Agent/Analysis/.cursor/agents/kernel-stem-preprocessing-agent.md @@ -0,0 +1,127 @@ + + +--- +name: kernel-stem-preprocessing-agent +description: Conditional pre-step for kernel unification when the combined unique kernel-name count is too large (> threshold, default 5000) to fit LLM context. Inspects a sample of names, authors custom regex rules that collapse high-cardinality families to stems, preserve families whose parameters matter for later analysis, and drop noise, then iterates until the stem count is manageable. +model: claude-opus-4-8 +--- + +# Kernel Stem Preprocessing Agent + +Reduce the number of distinct kernel names to a set small enough for the +`kernel-unification-agent` to reason over, **without losing information that +matters**. + +This step runs **only** when `kernel_unification.py prepare-context` reports +`needs_stem_preprocessing: true` (combined unique names exceed the threshold, +default 5000). Otherwise skip it entirely. + +**Scripts directory:** `TraceLens/Agent/Analysis/semantic_analyses/` + +## Why this is needed + +High-cardinality name families blow up the unique count. A single logical GEMM +family can appear as thousands of variants that differ only by an autotuner id +or embedded shape, e.g. `gemm_013123`, `gemm_013124`, ... or +`Cijk_..._MT32x16x512_...`, `Cijk_..._MT64x16x256_...`. These variants are the +same operation for the purpose of establishing cross-trace anchors, so +collapsing them to a **stem** (e.g. `gemm`, `Cijk_..._MT#_...`) drastically +shrinks the set. + +But **not every varying parameter is noise.** Some distinctions should be kept +for later analysis (e.g. GEMM tile / grid dimensions are useful downstream), and +some names are pure noise that should be dropped (profiler markers, one-off +setup kernels). Use judgment. + +## Input + +`prepare-context` output is provided inline. Key fields: + +- `summary.combined_unique`, `threshold` -- the size problem. +- `sample` -- a representative, impact-spanning sample of names, each with + `trace`, `name`, `perf_categories`, `kernel_count`, `total_dur_us`. Use it to + discover the naming families; do **not** assume it is exhaustive. + +## Your job + +1. **Identify families.** Group the sampled names into families that share a + structure (same prefix / vendor scheme, varying only in ids or shapes). +2. **Decide per family** one of three actions: + - **`collapse`** -- the variation is an id or a detail irrelevant to + matching. Author a regex that rewrites the name to a stable stem. + *Prefer collapsing the biggest families first* -- that is where the + cardinality lives. + - **`preserve`** -- the variation carries information a later stage needs + (e.g. GEMM dims). Keep the full name; still list the family so your intent + is explicit. + - **`drop`** -- the name is noise (profiler markers, debug kernels) and + should be excluded from unification. Dropped kernels keep their raw name + and simply will not unify. +3. **Author `stem_rules.json`** (see shape below). Rules are applied **in + order**; the first matching rule wins. Names matching no rule default to + `preserve`. +4. **Iterate.** Run `apply-stem-rules` and read the printed cardinality. If it + is still above threshold, broaden collapse patterns or drop more low-value + families and re-run until it reports `OK` (or is comfortably small). + +### Guidance for writing collapse regexes + +- Anchor to the family so a rule cannot over-match a different family. +- Collapse the varying token, not the whole name: replace digit runs / shape + tokens with a placeholder rather than erasing the identifying prefix. E.g. + `('_MT\d+x\d+x\d+', '_MT#')` keeps `Cijk_..._MT#_...` distinguishable from a + different Cijk variant, while `('_[0-9]+$', '')` strips a trailing id. +- Keep the stem **stable across both traces** where the operation is the same, + but you do not need to make two frameworks' stems identical here -- the + `kernel-unification-agent` maps stems across traces afterward. + +## Output file: `stem_rules.json` + +```json +{ + "rules": [ + {"pattern": "^gemm_[0-9]+$", "replacement": "gemm", + "action": "collapse", "note": "autotuner-id GEMM family"}, + {"pattern": "_MT[0-9]+x[0-9]+x[0-9]+", "replacement": "_MT#", + "action": "collapse", "note": "collapse Cijk tile-size id, keep family"}, + {"pattern": "(?i)profiler|marker|nvtx", "replacement": "", + "action": "drop", "note": "profiler noise"}, + {"pattern": "^(nvjet|cublasLt)", "replacement": "", + "action": "preserve", "note": "keep vendor GEMM dims for later analysis"} + ] +} +``` + +Fields per rule: +- `pattern` -- Python `re` regex, matched with `re.search`. +- `replacement` -- used by `re.sub` for `collapse` (may reference groups); + ignored for `preserve` / `drop`. +- `action` -- `collapse` | `preserve` | `drop`. +- `note` -- short rationale (required; this is the audit trail). + +## Apply loop + +```bash +python TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py apply-stem-rules \ + --labels-a /semantic_labels.json \ + --labels-b /semantic_labels.json \ + --name-a --name-b \ + --rules /stem_rules.json \ + --raw-to-stem /raw_to_stem.json \ + -o /kernel_unification_context.json +``` + +- Emits `raw_to_stem.json` (used later by `apply-map`) and a **stem-level** + `kernel_unification_context.json` for the `kernel-unification-agent`. +- Prints `raw -> stems` counts and per-action tallies. Re-run after editing + rules until the stem count is within budget. + +## Return Value + +Return: `status`, `raw_unique_before`, `stem_unique_after`, `action_counts` +(collapse/preserve/drop), a one-line rationale per family, and the path to +`stem_rules.json` and `raw_to_stem.json`. diff --git a/TraceLens/Agent/Analysis/.cursor/agents/kernel-unification-agent.md b/TraceLens/Agent/Analysis/.cursor/agents/kernel-unification-agent.md new file mode 100644 index 000000000..4b42b2280 --- /dev/null +++ b/TraceLens/Agent/Analysis/.cursor/agents/kernel-unification-agent.md @@ -0,0 +1,124 @@ + + +--- +name: kernel-unification-agent +description: Name-first cross-trace kernel-name unification. Reads kernel_unification_context.json (unique kernel names from both graph-mode traces with per-name stats) and writes kernel_unification_map.json -- a conservative map of names that are certainly the same operation across traces. Establishes matching anchors; does not resolve every ambiguity. +model: claude-opus-4-8 +--- + +# Kernel Unification Agent + +Unify raw GPU **kernel names** across two traces so equivalent kernels can be +matched cross-trace. + +Graph-mode traces collapse the CPU->GPU call stack under +`hip/cudaGraphLaunch`, so `nn_module` / `cpu_op` context is unavailable. The +only reliable cross-trace signal is the raw kernel name. Different frameworks +and vendors name the same operation differently (e.g. `moe_attn_vllm` vs +`sglang_moe_attention`), so this agent proposes a map that unifies such names +to a single shared label -- establishing clear **anchors** for the comparison. + +**Scripts directory:** `TraceLens/Agent/Analysis/semantic_analyses/` + +## Input + +The full `kernel_unification_context.json` is provided inline in your prompt. +Do NOT re-read it from disk. Key fields: + +- `name_a`, `name_b` -- short trace labels. +- `key_level` -- `raw_name` (map raw kernel names) or `stem` (stem + preprocessing was already applied; map the stems shown). +- `only_in_`, `only_in_` -- names present in only one trace. + **These are your unification candidates.** Each entry has `name`, + `kernel_count`, `total_dur_us`, `perf_categories`, and a `sample_input_dims` + (and `sample_raw_names` when `key_level` is `stem`). +- `in_both` -- names already identical in both traces. They are unified by + default; **do not** add map entries for them. +- `summary` -- counts for orientation. + +## Your job + +Produce a map that unifies names in `only_in_` with their counterparts +in `only_in_` when you are **certain** they are the same operation. + +### Signals for matching + +- **`perf_categories`** -- a GEMM only unifies with a GEMM, SDPA with SDPA, + etc. Never unify across different perf categories. +- **Name semantics** -- decode the mangled name. `nvjet_*`, `Cijk_*`, + `cublasLt::*`, `_gemm_a16_w16_*` are vendor GEMM kernels; `*paged_attention*`, + `*fmha*`, `*flash*` are attention; `*rmsnorm*`, `*layer_norm*` are + normalization; `*reduce*`, `*all_reduce*`, `*allgather*` are communication. +- **`sample_input_dims`** -- matching shapes across traces strengthen a pairing. +- **`kernel_count` / `total_dur_us`** -- an operation that runs N times per + layer on one trace usually runs a comparable number of times on the other. + +### Rules + +1. **Certainty only.** Map a pair only when the evidence is strong. When + unsure, leave both names unmapped -- they fall back to their raw name / stem + and simply remain unmatched. This pass builds anchors, not a full + resolution. +2. **Skip identical names.** Anything in `in_both` is already unified. No entry. +3. **Preserve granularity.** Do not merge two functionally distinct kernels + because their names look similar. Do not collapse a family that a later + analysis stage may want to keep separate (e.g. distinct attention variants). +4. **Same value on both sides.** For a matched pair, use the **same** unified + string as the value in both `map_a` and `map_b`. Choose a short, neutral, + vendor-agnostic name (e.g. `moe_attn`, `qkv_projection`, `allreduce`). +5. **Exact keys.** Keys must be copied verbatim from the context lists + (`only_in_` entries' `name` field). Every key must exist in that + trace's list. +6. **perf_category is not yours to change.** You only unify names. + +## Output file: `kernel_unification_map.json` + +Write to the output directory. Exact shape: + +```json +{ + "name_a": "MI300", + "name_b": "B300", + "map_a": { + "moe_attn_vllm": "moe_attn", + "Cijk_Alik_Bljk_..._MT32x16x512_...": "expert_gemm" + }, + "map_b": { + "sglang_moe_attention": "moe_attn", + "nvjet_sm103_tst_128x16_...": "expert_gemm" + } +} +``` + +- `map_a` keys are `name_a` names; `map_b` keys are `name_b` names. +- A pair is unified when a `map_a` value equals a `map_b` value. +- A one-sided rename (a name you want to relabel but that has no counterpart) + is allowed but usually unnecessary -- prefer leaving it unmapped. +- Either map may be empty if no confident unification exists on that side. + +## Apply + verify + +The orchestrator runs: + +```bash +python TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py apply-map \ + --labels-a /semantic_labels.json \ + --labels-b /semantic_labels.json \ + --name-a --name-b \ + --map /kernel_unification_map.json \ + [--raw-to-stem /raw_to_stem.json] # only if stem preprocessing was used +``` + +This writes the unified name into each kernel's `semantic_block` field (default += raw name / stem when the map has no entry) and prints the resulting shared / +one-sided vocabulary counts. + +## Return Value + +Return: `status` (SUCCESS/ERROR), `pairs_unified` (count of matched values), +`names_mapped_a`, `names_mapped_b`, `shared_blocks_after_apply`, and any names +you deliberately left unmapped due to uncertainty (with a one-line reason). diff --git a/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md index 6f29cb2aa..4a5f4062c 100644 --- a/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md +++ b/TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md @@ -6,16 +6,25 @@ See LICENSE for license information. --- name: semantic-comparison-agent -description: End-to-end semantic comparison of two GPU traces. Runs deterministic breakdown per trace (extraction + tree context + classification + pattern finding + label assembly), then a single LLM harmonization pass to assign and unify semantic_block names, followed by a comparison pipeline. -model: claude-opus-4-7-high +description: End-to-end semantic comparison of two graph-mode GPU traces. Runs deterministic breakdown per trace (extraction + tree context + classification + pattern finding + label assembly), then a name-first LLM kernel-name unification pass that establishes cross-trace matching anchors in the semantic_block field, followed by a comparison pipeline. +model: claude-opus-4-8 --- # Semantic Comparison Orchestrate end-to-end semantic comparison of two GPU traces. The user provides two raw trace files and the orchestrator handles everything: -deterministic parallel breakdown (no LLM), single-pass LLM harmonization -that assigns and unifies semantic_block names, and the comparison pipeline. +deterministic parallel breakdown (no LLM), a name-first LLM kernel-name +unification pass that establishes cross-trace matching anchors, and the +comparison pipeline. + +**Why name-first.** In graph mode the CPU->GPU call stack collapses under +`hip/cudaGraphLaunch`, so `nn_module` / `cpu_op` context is unavailable and +block-alignment harmonization cannot work. The only reliable cross-trace +signal is the raw GPU **kernel name**. This workflow unifies kernel names +across the two traces (e.g. `moe_attn_vllm` and `sglang_moe_attention` -> +`moe_attn`) and writes the unified name into each kernel's `semantic_block` +field, which the downstream comparison uses as its matching key. Use vendor-agnostic terminology (GPU kernels, vendor GEMM library, etc.) except when quoting actual kernel names from traces. @@ -27,7 +36,7 @@ except when quoting actual kernel names from traces. ``` 0. Query User Inputs 1. Semantic Breakdown (PARALLEL shell commands, one per trace) -2. Semantic Harmonization (single agent, cross-trace) +2. Kernel-Name Unification (name-first anchors + coherence refinement, LLM) 3. Generate TraceDiff Output (script) 4. Generate Comparison CSV (script) ``` @@ -140,43 +149,125 @@ and stop. --- -## Step 2: Semantic Harmonization (LLM -- Label + Harmonize) +## Step 2: Kernel-Name Unification (Name-First, LLM) -The harmonization agent is the **only LLM call** in the pipeline. It -assigns descriptive `semantic_block` names to each block AND ensures -cross-trace consistency. The enriched context includes `cpu_ops`, -`nn_module`, kernel names, and `perf_category` per block. +Replaces the old block-alignment harmonization. Instead of aligning blocks +via CPU-op / nn_module context (absent in graph mode), the LLM unifies raw +**kernel names** across the two traces. The unified name is written into each +kernel's `semantic_block` field, which Steps 3-4 use as the matching key. +Kernel names already identical in both traces unify by default (no map entry +needed); the LLM only maps names that differ but denote the same operation. -### 2.1 Read the Agent Definition +Scripts: `TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py` -Read: `TraceLens/Agent/Analysis/.cursor/agents/semantic-harmonization-agent.md` +### 2.1 Prepare Unification Context [S] -### 2.2 Launch Harmonization Agent +```bash +KU=TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py +python $KU prepare-context \ + --labels-a /_work//semantic_labels.json \ + --labels-b /_work//semantic_labels.json \ + --name-a --name-b \ + -o /_work/kernel_unification_context.json +``` + +The context lists each trace's unique kernel names with `perf_categories`, +`kernel_count`, `total_dur_us`, and a `sample_input_dims`, split into +`only_in_` / `only_in_` / `in_both`. +### 2.2 Stem Preprocessing (conditional, only if flagged) + +If Step 2.1 prints `STEM PREPROCESSING NEEDED` (combined unique names exceed +the threshold, default 5000), the raw name set is too large for the LLM. +Follow `TraceLens/Agent/Analysis/.cursor/agents/kernel-stem-preprocessing-agent.md`: +the LLM inspects the emitted `sample`, authors `stem_rules.json` (custom +regexes that collapse high-cardinality families to stems, preserve families +whose parameters matter for later analysis, drop noise), then: + +```bash +python $KU apply-stem-rules \ + --labels-a /_work//semantic_labels.json \ + --labels-b /_work//semantic_labels.json \ + --name-a --name-b \ + --rules /_work/stem_rules.json \ + --raw-to-stem /_work/raw_to_stem.json \ + -o /_work/kernel_unification_context.json ``` ----BEGIN AGENT INSTRUCTIONS--- - ----END AGENT INSTRUCTIONS--- - -**Execution Context:** -- Trace A directory: /_work// -- Trace B directory: /_work// -- Output directory: /_work/ -- Name A: -- Name B: - -Follow the agent instructions above to label and harmonize the blocks. -Return the summary described in the "Return Value" section. + +Re-run until the printed stem count is within budget. This rewrites +`kernel_unification_context.json` at the stem level and emits +`raw_to_stem.json` (needed by 2.4). **Skip this step entirely when not flagged.** + +### 2.3 Launch Kernel Unification Agent [LLM] + +Read `TraceLens/Agent/Analysis/.cursor/agents/kernel-unification-agent.md` and +launch it with `kernel_unification_context.json` inline. It writes +`/_work/kernel_unification_map.json` (`map_a` / `map_b`), mapping +only names it is certain are equivalent, using the same unified value on both +sides for a matched pair. For multi-region vLLM: run once per matching region +pair. + +### 2.4 Apply the Map [S] + +```bash +python $KU apply-map \ + --labels-a /_work//semantic_labels.json \ + --labels-b /_work//semantic_labels.json \ + --name-a --name-b \ + --map /_work/kernel_unification_map.json \ + --raw-to-stem /_work/raw_to_stem.json # only if 2.2 ran +``` + +### 2.5 Verify Unification + +Check that `kernel_unification_context.json` and `kernel_unification_map.json` +exist in `/_work/`, and that `apply-map` reported a non-empty +shared vocabulary. Every kernel now carries a `semantic_block` set to its +unified kernel name. + +### 2.6 Coherence Pass (second pass, LLM) + +The first pass leaves **one-sided** buckets -- kernels whose unified name +appears in only one trace (most importantly vendor GEMM families: MI300 +`Cijk_*` vs B300 `nvjet_*`, which cannot be paired by name). This pass uses +the first-pass **shared** buckets as cross-trace positional anchors and +re-labels one-sided buckets by their shared-neighbor context, which (a) pairs +GEMMs across vendors by position and (b) splits a name that occurs in different +contexts. Skip it only if `apply-map` already reported no meaningful one-sided +buckets. + +**2.6a Prepare coherence context [S]** +```bash +KC=TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py +python $KC prepare-context \ + --labels-a /_work//semantic_labels.json \ + --labels-b /_work//semantic_labels.json \ + --name-a --name-b \ + --neighbor-radius 1 \ + -o /_work/kernel_coherence_context.json ``` -For multi-region vLLM: run once per matching region pair. +**2.6b Launch coherence agent [LLM]** -- read +`TraceLens/Agent/Analysis/.cursor/agents/kernel-coherence-agent.md` and launch +it with `kernel_coherence_context.json` inline. It writes +`/_work/kernel_coherence_decisions.json` (`context_renames` + +`fallback_remap_a` / `fallback_remap_b`), pairing same-context one-sided buckets +across traces into new shared names. -### 2.3 Verify Harmonization +**2.6c Apply [S]** +```bash +python $KC apply \ + --context /_work/kernel_coherence_context.json \ + --decisions /_work/kernel_coherence_decisions.json \ + --audit-csv-a /_work/per_kernel_final_.csv \ + --audit-csv-b /_work/per_kernel_final_.csv +``` -Check that `alignment.json`, `harmonization_context.json`, and -`harmonization_corrections.json` exist in `/_work/`. -Verify that `semantic_labels.json` files now contain `semantic_block` -fields on all kernels. +`apply` rewrites `semantic_block` in place and prints any residual one-sided +condensed symbols. If meaningful (non-singleton) symbols remain, revise the +decisions and re-run 2.6b--2.6c; residual pre/post-layer singletons (setup / +copy / prefix-scan kernels with no counterpart) may be accepted. Increase +`--neighbor-radius` in 2.6a if one-sided buckets share an ambiguous context. --- @@ -239,11 +330,13 @@ python TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ 1. **Seamless flow** -- user provides two trace paths, orchestrator handles everything 2. **Parallel breakdown** -- both traces processed as parallel shell jobs -3. **Cross-trace harmonization** -- separate step unifies labels for - consistent comparison -4. **Vendor-agnostic language** -- generic terms for all recommendations -5. **Complete coverage** -- every semantic block is labeled and compared -6. **No script creation** -- subagents use only existing scripts +3. **Name-first unification** -- kernel names are unified across traces to + establish matching anchors; identical names unify by default +4. **Conservative anchors** -- map only certain equivalences; preserve + granularity and leave uncertain names unmapped +5. **Vendor-agnostic language** -- generic terms for all recommendations +6. **No script creation** -- subagents use only existing scripts (the stem + preprocessing authors regex *rules*, not new scripts) --- @@ -252,8 +345,14 @@ python TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ ``` / _work/ - /semantic_labels.json # Per-trace semantic labels + /semantic_labels.json # Per-trace labels (semantic_block = unified kernel name) /semantic_labels.json + kernel_unification_context.json # Pass 1 LLM input: unique kernel names + stats + kernel_unification_map.json # Pass 1 LLM output: cross-trace name map + raw_to_stem.json # Only when stem preprocessing ran + kernel_coherence_context.json # Pass 2 LLM input: one-sided buckets + neighbor context + kernel_coherence_decisions.json # Pass 2 LLM output: context_renames + fallbacks + per_kernel_final_.csv # Pass 2 audit: first_pass -> final block per kernel comparison.csv # Cross-trace comparison tracediff_output/ # TraceDiff-compatible output diff_stats.csv diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py new file mode 100644 index 000000000..599f56984 --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py @@ -0,0 +1,450 @@ +#!/usr/bin/env python3 +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +""" +Second-pass kernel-name coherence (LLM-assisted). + +After the first-pass name-first unification (``kernel_unification.py``), the +comparison still has **one-sided** buckets: kernels whose unified name appears +in only one trace (e.g. vendor GEMM families -- MI300 ``Cijk_*`` vs B300 +``nvjet_*`` -- that could not be paired by name alone). + +This pass uses the first-pass **shared** buckets as cross-trace-stable +positional anchors. For each one-sided bucket it derives the *neighbor context* +(nearest shared symbols to its left and right in the run-length-collapsed kernel +sequence) and lets an LLM: + + * pair a one-sided bucket in trace A with a one-sided bucket in trace B that + occupies the **same** neighbor context (e.g. the GEMM between ``add_rmsnorm`` + and ``rotary_embedding`` is the QKV projection on both traces), assigning + both a new shared name; and + * split a single name that occurs in **different** contexts into different + buckets (context-dependent granularity). + +Two subcommands: + + prepare-context Build the LLM packet: condensed sequences, shared vs + one-sided symbol sets, and per one-sided symbol the unique + neighbor contexts with evidence (perf_category, kernels in + the run, duration, sample input_dims, raw name). Emits a flat + ``context_catalog`` with stable ids. + + apply Apply the LLM decisions (``context_renames`` + + ``fallback_remap_a`` / ``fallback_remap_b``) to recompute each + kernel's ``semantic_block`` in place, emit an audit CSV, and + warn about any residual one-sided condensed symbols. + +Usage: + python kernel_coherence.py prepare-context \ + --labels-a /semantic_labels.json \ + --labels-b /semantic_labels.json \ + --name-a MI300 --name-b B300 \ + --neighbor-radius 1 \ + -o kernel_coherence_context.json + + python kernel_coherence.py apply \ + --context kernel_coherence_context.json \ + --decisions kernel_coherence_decisions.json \ + [--audit-csv-a per_kernel_final_MI300.csv] \ + [--audit-csv-b per_kernel_final_B300.csv] +""" + +import argparse +import csv +import json +import os +import sys +from collections import OrderedDict, defaultdict + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from kernel_runlength import ( + collapse_consecutive, + load_sequence, + run_index_per_kernel, + shared_neighbor_windows_skip_non_shared, +) + + +DEFAULT_RADIUS = 1 +DEFAULT_TOP_KERNELS = 5 + + +def _load(path): + with open(path) as f: + return json.load(f) + + +def _dims_repr(dims, limit=160): + if not dims: + return "" + s = json.dumps(dims, separators=(",", ":")) + return s[:limit] + "..." if len(s) > limit else s + + +# =========================================================================== +# prepare-context +# =========================================================================== + + +def _run_to_kernel_indices(run_per_kernel): + """Map run index -> list of kernel positions in that run.""" + run_to_k = defaultdict(list) + for ki, rj in enumerate(run_per_kernel): + run_to_k[rj].append(ki) + return run_to_k + + +def _symbol_evidence(kernels, indices, top_kernels): + """Aggregate evidence for the kernels of one run (or symbol).""" + by_name_dur = defaultdict(float) + by_name_cnt = defaultdict(int) + cats = set() + sample_dims = "" + for ki in indices: + k = kernels[ki] + nm = k.get("name", "") + by_name_dur[nm] += k.get("dur", 0.0) or 0.0 + by_name_cnt[nm] += 1 + pc = k.get("perf_category") + if pc: + cats.add(pc) + if not sample_dims: + sample_dims = _dims_repr(k.get("input_dims")) + ranked = sorted(by_name_dur.items(), key=lambda x: -x[1])[:top_kernels] + top = [ + {"kernel_name": n, "total_us": round(d, 3), "kernel_count": by_name_cnt[n]} + for n, d in ranked + ] + return sorted(cats), sample_dims, top + + +def _collect_contexts(name, kernels, condensed, run_per_kernel, shared, problematic, + radius, top_kernels): + """Per one-sided symbol, the unique (left,right) shared-neighbor contexts.""" + run_to_k = _run_to_kernel_indices(run_per_kernel) + out = OrderedDict() + ctr = 0 + for sym in sorted(problematic): + seen = set() + contexts = [] + for j, c in enumerate(condensed): + if c != sym: + continue + left, right = shared_neighbor_windows_skip_non_shared( + condensed, j, shared, radius + ) + key = (tuple(left), tuple(right)) + if key in seen: + continue + seen.add(key) + indices = run_to_k.get(j, []) + cats, dims, top = _symbol_evidence(kernels, indices, top_kernels) + contexts.append( + OrderedDict( + id=f"{name}:{ctr}", + first_pass_block=sym, + left_window=list(left), + right_window=list(right), + kernels_in_run=len(indices), + perf_categories=cats, + sample_input_dims=dims, + top_kernel_names_by_dur=top, + ) + ) + ctr += 1 + out[sym] = {"contexts": contexts, "context_count": len(contexts)} + return out + + +def cmd_prepare_context(args): + labels_a = _load(args.labels_a) + labels_b = _load(args.labels_b) + kernels_a = labels_a["labeled_kernels"] + kernels_b = labels_b["labeled_kernels"] + + seq_a = [k.get("semantic_block", "") for k in kernels_a] + seq_b = [k.get("semantic_block", "") for k in kernels_b] + cond_a = collapse_consecutive(seq_a) + cond_b = collapse_consecutive(seq_b) + set_a, set_b = set(cond_a), set(cond_b) + shared = set_a & set_b + prob_a = set_a - set_b + prob_b = set_b - set_a + + run_a = run_index_per_kernel(seq_a) + run_b = run_index_per_kernel(seq_b) + + detail_a = _collect_contexts( + args.name_a, kernels_a, cond_a, run_a, shared, prob_a, + args.neighbor_radius, args.top_kernels, + ) + detail_b = _collect_contexts( + args.name_b, kernels_b, cond_b, run_b, shared, prob_b, + args.neighbor_radius, args.top_kernels, + ) + + catalog = [] + for detail, wl in ((detail_a, args.name_a), (detail_b, args.name_b)): + for sym, pack in detail.items(): + for c in pack["contexts"]: + catalog.append( + OrderedDict( + id=c["id"], + workload=wl, + first_pass_block=sym, + left_window=c["left_window"], + right_window=c["right_window"], + ) + ) + + out = OrderedDict() + out["name_a"] = args.name_a + out["name_b"] = args.name_b + out["definitions"] = { + "condensed_sequence": "Kernel-order semantic_block values with consecutive " + "duplicates removed (one symbol per contiguous run).", + "shared_block": "semantic_block present in the condensed sequence of both traces.", + "one_sided_block": "semantic_block present in only one trace's condensed sequence.", + "neighbor_context": "left_window/right_window: nearest `neighbor_radius` shared " + "symbols on each side of the run, skipping non-shared symbols.", + } + out["hyperparameters"] = { + "neighbor_radius": args.neighbor_radius, + "top_kernels": args.top_kernels, + } + out["inputs"] = {"labels_a": args.labels_a, "labels_b": args.labels_b} + out["condensed_sequence_a"] = cond_a + out["condensed_sequence_b"] = cond_b + out["shared_blocks"] = sorted(shared) + out["one_sided_in_a"] = sorted(prob_a) + out["one_sided_in_b"] = sorted(prob_b) + out["one_sided_details_a"] = detail_a + out["one_sided_details_b"] = detail_b + out["llm_task"] = ( + "Re-label one-sided blocks so the comparison has no one-sided condensed " + "symbols. Pair a one-sided block in A with a one-sided block in B that has " + "the SAME (left_window,right_window) and perf_category by giving both the " + "same new shared name. Split a block that appears in different contexts via " + "distinct context ids. See the kernel-coherence agent for the output schema." + ) + out["llm_output_schema"] = { + "context_renames": "{context_id -> final_block}", + "fallback_remap_a": "{first_pass_block -> final_block} for trace A", + "fallback_remap_b": "{first_pass_block -> final_block} for trace B", + "notes": "optional string", + } + out["context_catalog"] = catalog + + with open(args.output, "w") as f: + json.dump(out, f, indent=2) + + nca = sum(v["context_count"] for v in detail_a.values()) + ncb = sum(v["context_count"] for v in detail_b.values()) + print( + f"Wrote {args.output}: shared={len(shared)} " + f"one_sided_a={len(prob_a)} one_sided_b={len(prob_b)} " + f"contexts_a={nca} contexts_b={ncb}", + file=sys.stderr, + ) + + +# =========================================================================== +# apply +# =========================================================================== + + +def _context_lookup(catalog): + """(workload, symbol, left, right) -> context_id.""" + out = {} + for row in catalog: + out[ + ( + row["workload"], + row["first_pass_block"], + tuple(row.get("left_window") or []), + tuple(row.get("right_window") or []), + ) + ] = row["id"] + return out + + +def _final_blocks(workload, kernels, shared, problematic, radius, + lookup, context_renames, fallback): + """Compute the final semantic_block for each kernel; return (finals, audit).""" + seq = [k.get("semantic_block", "") for k in kernels] + cond = collapse_consecutive(seq) + run_per_kernel = run_index_per_kernel(seq) + + finals = [] + audit = [] + for i, k in enumerate(kernels): + fp = seq[i] + j = run_per_kernel[i] + sym = cond[j] + cid = "" + if sym not in problematic: + final = fp + else: + left, right = shared_neighbor_windows_skip_non_shared( + cond, j, shared, radius + ) + cid = lookup.get((workload, sym, tuple(left), tuple(right)), "") + if cid and cid in context_renames: + final = context_renames[cid] + elif sym in fallback: + final = fallback[sym] + else: + final = fp + finals.append(final) + audit.append( + { + "kernel_index": k.get("index", i), + "name": k.get("name", ""), + "first_pass_block": fp, + "final_block": final, + "context_id": cid, + } + ) + return finals, audit + + +def _write_audit(path, rows): + with open(path, "w", newline="") as f: + w = csv.DictWriter( + f, + fieldnames=["kernel_index", "name", "first_pass_block", + "final_block", "context_id"], + ) + w.writeheader() + w.writerows(rows) + + +def _residual_one_sided(labels_a, labels_b): + """Return one-sided condensed symbols remaining after apply.""" + ca = set(collapse_consecutive([k.get("semantic_block", "") for k in labels_a["labeled_kernels"]])) + cb = set(collapse_consecutive([k.get("semantic_block", "") for k in labels_b["labeled_kernels"]])) + return sorted(ca - cb), sorted(cb - ca) + + +def cmd_apply(args): + ctx = _load(args.context) + dec = _load(args.decisions) + name_a = ctx["name_a"] + name_b = ctx["name_b"] + radius = int(ctx.get("hyperparameters", {}).get("neighbor_radius", DEFAULT_RADIUS)) + labels_a_path = ctx["inputs"]["labels_a"] + labels_b_path = ctx["inputs"]["labels_b"] + + context_renames = {str(k): str(v) for k, v in (dec.get("context_renames") or {}).items()} + fb_a = {str(k): str(v) for k, v in (dec.get("fallback_remap_a") or {}).items()} + fb_b = {str(k): str(v) for k, v in (dec.get("fallback_remap_b") or {}).items()} + + labels_a = _load(labels_a_path) + labels_b = _load(labels_b_path) + ka = labels_a["labeled_kernels"] + kb = labels_b["labeled_kernels"] + + cond_a = collapse_consecutive([k.get("semantic_block", "") for k in ka]) + cond_b = collapse_consecutive([k.get("semantic_block", "") for k in kb]) + shared = set(cond_a) & set(cond_b) + prob_a = set(cond_a) - set(cond_b) + prob_b = set(cond_b) - set(cond_a) + lookup = _context_lookup(ctx.get("context_catalog", [])) + + finals_a, audit_a = _final_blocks( + name_a, ka, shared, prob_a, radius, lookup, context_renames, fb_a + ) + finals_b, audit_b = _final_blocks( + name_b, kb, shared, prob_b, radius, lookup, context_renames, fb_b + ) + + changed_a = 0 + for k, fin in zip(ka, finals_a): + if k.get("semantic_block") != fin: + changed_a += 1 + k["semantic_block"] = fin + changed_b = 0 + for k, fin in zip(kb, finals_b): + if k.get("semantic_block") != fin: + changed_b += 1 + k["semantic_block"] = fin + + with open(labels_a_path, "w") as f: + json.dump(labels_a, f, indent=2) + with open(labels_b_path, "w") as f: + json.dump(labels_b, f, indent=2) + + if args.audit_csv_a: + _write_audit(args.audit_csv_a, audit_a) + if args.audit_csv_b: + _write_audit(args.audit_csv_b, audit_b) + + blocks_a = set(k["semantic_block"] for k in ka) + blocks_b = set(k["semantic_block"] for k in kb) + res_a, res_b = _residual_one_sided(labels_a, labels_b) + + print( + f"Applied: {name_a} {changed_a} kernels relabeled, " + f"{name_b} {changed_b} kernels relabeled.", + file=sys.stderr, + ) + print( + f"Shared blocks now: {len(blocks_a & blocks_b)} " + f"({name_a}-only {len(blocks_a - blocks_b)}, " + f"{name_b}-only {len(blocks_b - blocks_a)}).", + file=sys.stderr, + ) + if res_a or res_b: + print( + f"WARNING: condensed one-sided symbols remain -- " + f"{name_a}: {res_a} {name_b}: {res_b}", + file=sys.stderr, + ) + else: + print("No one-sided condensed symbols remain.", file=sys.stderr) + + +# =========================================================================== +# CLI +# =========================================================================== + + +def main(): + parser = argparse.ArgumentParser( + description="Second-pass kernel-name coherence (prepare-context / apply)" + ) + sub = parser.add_subparsers(dest="command", required=True) + + p_prep = sub.add_parser("prepare-context", help="Build the coherence LLM context") + p_prep.add_argument("--labels-a", required=True) + p_prep.add_argument("--labels-b", required=True) + p_prep.add_argument("--name-a", default="trace_a") + p_prep.add_argument("--name-b", default="trace_b") + p_prep.add_argument( + "--neighbor-radius", type=int, default=DEFAULT_RADIUS, + help=f"Shared symbols to collect on each side (default {DEFAULT_RADIUS})", + ) + p_prep.add_argument( + "--top-kernels", type=int, default=DEFAULT_TOP_KERNELS, + help=f"Top kernel names by duration per context (default {DEFAULT_TOP_KERNELS})", + ) + p_prep.add_argument("-o", "--output", required=True) + p_prep.set_defaults(func=cmd_prepare_context) + + p_apply = sub.add_parser("apply", help="Apply coherence decisions to labels in place") + p_apply.add_argument("--context", required=True, help="kernel_coherence_context.json") + p_apply.add_argument("--decisions", required=True, help="LLM decisions JSON") + p_apply.add_argument("--audit-csv-a", help="Per-kernel audit CSV for trace A") + p_apply.add_argument("--audit-csv-b", help="Per-kernel audit CSV for trace B") + p_apply.set_defaults(func=cmd_apply) + + args = parser.parse_args() + args.func(args) + + +if __name__ == "__main__": + main() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_runlength.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_runlength.py new file mode 100644 index 000000000..d6fa690d2 --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_runlength.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Run-length helpers over per-kernel ``semantic_block`` sequences. + +Shared by the kernel-name coherence (second) pass. Operates purely on the +``semantic_block`` field of ``semantic_labels.json`` -- no ``nn_module`` / +tree_context is required, so it works on graph-mode traces. + +Terminology: + sequence -- kernel-order list of semantic_block values (one per kernel). + condensed -- the sequence with consecutive duplicates collapsed + (``A A B D D`` -> ``A B D``); one symbol per contiguous run. + shared -- a symbol present in the condensed sets of BOTH traces. + one-sided -- a symbol present in only one trace's condensed set. +""" + +import json + + +def load_sequence(labels_path): + """Return the kernel-order list of semantic_block values for a labels file.""" + with open(labels_path) as f: + data = json.load(f) + return [k.get("semantic_block", "") for k in data.get("labeled_kernels", [])] + + +def collapse_consecutive(seq): + """Collapse consecutive duplicates: ``A A B D D`` -> ``A B D``.""" + if not seq: + return [] + out = [seq[0]] + for s in seq[1:]: + if s != out[-1]: + out.append(s) + return out + + +def run_index_per_kernel(seq): + """Map each kernel position to the index of its run in ``collapse_consecutive(seq)``.""" + if not seq: + return [] + out = [] + run_idx = 0 + prev = None + for s in seq: + if prev is not None and s != prev: + run_idx += 1 + out.append(run_idx) + prev = s + return out + + +def shared_neighbor_windows_skip_non_shared(condensed, center_j, shared, radius): + """Nearest ``radius`` *shared* symbols on each side of ``condensed[center_j]``. + + Walks outward from the center, skipping any symbol not in ``shared`` + (including other one-sided symbols), so the windows are always expressed + in cross-trace-stable anchors. Nearest-to-center first on each side. + Returns ``(left_window, right_window)`` as lists. + """ + left = [] + i = center_j - 1 + while i >= 0 and len(left) < radius: + if condensed[i] in shared: + left.append(condensed[i]) + i -= 1 + + right = [] + i = center_j + 1 + while i < len(condensed) and len(right) < radius: + if condensed[i] in shared: + right.append(condensed[i]) + i += 1 + + return left, right diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py new file mode 100644 index 000000000..948622ef2 --- /dev/null +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py @@ -0,0 +1,538 @@ +#!/usr/bin/env python3 +############################################################################### +# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +""" +Name-first cross-trace kernel-name unification (LLM-assisted). + +Graph-mode traces collapse the CPU->GPU call stack under ``hip/cudaGraphLaunch``, +so ``nn_module`` / ``cpu_op`` context is unavailable and the block-alignment +harmonization cannot work. The only reliable cross-trace signal is the raw GPU +**kernel name**. This module unifies kernel names across two traces so that the +downstream comparison (which matches on the per-kernel ``semantic_block`` field) +can pair equivalent kernels. + +The approach is *name-first*: an LLM inspects the unique kernel names from both +traces and writes a conservative map of names it is **certain** are equivalent +(e.g. ``moe_attn_vllm`` and ``sglang_moe_attention`` -> ``moe_attn``). Names +that are already identical need no entry -- they unify by default. The goal is +to establish clear anchors, not to resolve every ambiguity. + +Three subcommands: + + prepare-context Aggregate the unique kernel names from both traces (with + per-name stats) into a compact LLM packet. When the + combined unique-name count exceeds ``--threshold`` it emits + a representative *sample* plus ``needs_stem_preprocessing: + true`` instead of the full lists (see apply-stem-rules). + + apply-stem-rules Apply an LLM-authored ``stem_rules.json`` (custom regexes + + collapse/preserve/drop actions) to the full unique-name set, + emitting a ``raw_to_stem`` map and a reduced, + stem-level context. Prints resulting cardinality so the + model can iterate. + + apply-map Apply the LLM's ``kernel_unification_map.json`` back onto + both ``semantic_labels.json`` files, writing the unified + name into ``semantic_block`` (default = raw name / stem when + the map has no entry). + +Usage: + python kernel_unification.py prepare-context \ + --labels-a /semantic_labels.json \ + --labels-b /semantic_labels.json \ + --name-a MI300 --name-b B300 \ + -o kernel_unification_context.json + + python kernel_unification.py apply-stem-rules \ + --labels-a /semantic_labels.json \ + --labels-b /semantic_labels.json \ + --name-a MI300 --name-b B300 \ + --rules stem_rules.json \ + --raw-to-stem raw_to_stem.json \ + -o kernel_unification_context.json + + python kernel_unification.py apply-map \ + --labels-a /semantic_labels.json \ + --labels-b /semantic_labels.json \ + --name-a MI300 --name-b B300 \ + --map kernel_unification_map.json \ + [--raw-to-stem raw_to_stem.json] +""" + +import argparse +import json +import re +import sys +from collections import OrderedDict + + +DEFAULT_THRESHOLD = 5000 +DEFAULT_SAMPLE_SIZE = 300 + + +# =========================================================================== +# shared helpers +# =========================================================================== + + +def _load(path): + with open(path) as f: + return json.load(f) + + +def _dims_repr(dims, limit=160): + """Compact, length-capped string form of an input_dims value.""" + if not dims: + return "" + s = json.dumps(dims, separators=(",", ":")) + if len(s) > limit: + s = s[:limit] + "..." + return s + + +def aggregate_names(labels, key_fn=None): + """Aggregate a labels file's kernels by name (or by ``key_fn(name)``). + + Returns an OrderedDict ``{key: entry}`` where entry carries count, + total duration, the set of perf_categories seen, and one sample + input_dims. Order is by descending total duration then key, so the + most impactful kernels come first for the LLM. + """ + acc = {} + for k in labels.get("labeled_kernels", []): + name = k.get("name", "") + key = key_fn(name) if key_fn else name + if key is None: + continue # dropped by stem rules -> excluded from the unification set + entry = acc.get(key) + if entry is None: + entry = acc[key] = { + "name": key, + "kernel_count": 0, + "total_dur_us": 0.0, + "perf_categories": set(), + "sample_input_dims": "", + "sample_raw_names": set(), + } + entry["kernel_count"] += 1 + entry["total_dur_us"] += k.get("dur", 0.0) or 0.0 + pc = k.get("perf_category") + if pc: + entry["perf_categories"].add(pc) + if not entry["sample_input_dims"]: + entry["sample_input_dims"] = _dims_repr(k.get("input_dims")) + if key_fn and len(entry["sample_raw_names"]) < 5 and name != key: + entry["sample_raw_names"].add(name) + + ordered = sorted( + acc.values(), key=lambda e: (-e["total_dur_us"], e["name"]) + ) + out = OrderedDict() + for e in ordered: + e["total_dur_us"] = round(e["total_dur_us"], 3) + e["perf_categories"] = sorted(e["perf_categories"]) + e["sample_raw_names"] = sorted(e["sample_raw_names"]) + if not e["sample_raw_names"]: + del e["sample_raw_names"] + out[e["name"]] = e + return out + + +def _entry_list(agg, keys): + """Materialize entries for *keys* preserving *agg* ordering.""" + keyset = set(keys) + return [e for name, e in agg.items() if name in keyset] + + +UNIFICATION_RULES = [ + "Map ONLY names you are confident are the same operation across traces.", + "Names already identical in both traces are unified by default -- do NOT " + "add map entries for them.", + "Prefer preserving granularity: do not merge two functionally distinct " + "kernels just because names look similar.", + "This pass establishes clear anchors, not a full resolution of every " + "ambiguity; leave uncertain names unmapped (they fall back to their raw " + "name / stem).", + "Values are short shared unified names; use the SAME value on both sides " + "for a matched pair.", + "Keys must be exact names (or stems, when stem preprocessing was applied) " + "taken verbatim from the context lists.", +] + + +def _build_context(agg_a, agg_b, name_a, name_b, level, extra=None): + """Assemble the unification-context dict from two aggregations.""" + set_a = set(agg_a) + set_b = set(agg_b) + only_a = [n for n in agg_a if n not in set_b] + only_b = [n for n in agg_b if n not in set_a] + in_both = sorted(set_a & set_b) + + ctx = OrderedDict() + ctx["name_a"] = name_a + ctx["name_b"] = name_b + ctx["key_level"] = level # "raw_name" or "stem" + ctx["summary"] = { + f"unique_{name_a}": len(set_a), + f"unique_{name_b}": len(set_b), + "combined_unique": len(set_a | set_b), + "in_both": len(in_both), + f"only_in_{name_a}": len(only_a), + f"only_in_{name_b}": len(only_b), + } + ctx["rules"] = UNIFICATION_RULES + ctx[f"only_in_{name_a}"] = _entry_list(agg_a, only_a) + ctx[f"only_in_{name_b}"] = _entry_list(agg_b, only_b) + ctx["in_both"] = in_both + if extra: + ctx.update(extra) + return ctx + + +# =========================================================================== +# prepare-context +# =========================================================================== + + +def _sample_names(agg_a, agg_b, name_a, name_b, sample_size): + """Deterministic representative sample across both traces. + + Interleaves the two per-trace aggregations (already ordered by impact) + and takes evenly-spaced picks so the sample spans high- and low-impact + kernels rather than only the top-N. + """ + def _spaced(agg, budget): + items = list(agg.values()) + if len(items) <= budget: + return items + step = len(items) / float(budget) + return [items[int(i * step)] for i in range(budget)] + + half = max(1, sample_size // 2) + sample = [] + for e in _spaced(agg_a, half): + row = dict(e) + row["trace"] = name_a + sample.append(row) + for e in _spaced(agg_b, sample_size - half): + row = dict(e) + row["trace"] = name_b + sample.append(row) + return sample + + +def cmd_prepare_context(args): + labels_a = _load(args.labels_a) + labels_b = _load(args.labels_b) + agg_a = aggregate_names(labels_a) + agg_b = aggregate_names(labels_b) + + combined = len(set(agg_a) | set(agg_b)) + needs_stem = combined > args.threshold + + if needs_stem: + ctx = OrderedDict() + ctx["name_a"] = args.name_a + ctx["name_b"] = args.name_b + ctx["key_level"] = "raw_name" + ctx["summary"] = { + f"unique_{args.name_a}": len(agg_a), + f"unique_{args.name_b}": len(agg_b), + "combined_unique": combined, + } + ctx["needs_stem_preprocessing"] = True + ctx["threshold"] = args.threshold + ctx["instructions"] = ( + "Combined unique kernel-name count exceeds the threshold and will " + "likely overwhelm the context. Inspect the sample below, author a " + "stem_rules.json (see the kernel-stem-preprocessing agent), and run " + "'kernel_unification.py apply-stem-rules' to reduce the name set " + "before unification." + ) + ctx["sample"] = _sample_names( + agg_a, agg_b, args.name_a, args.name_b, args.sample_size + ) + else: + ctx = _build_context( + agg_a, agg_b, args.name_a, args.name_b, "raw_name", + extra={"needs_stem_preprocessing": False}, + ) + + with open(args.output, "w") as f: + json.dump(ctx, f, indent=2) + + if needs_stem: + print( + f"Wrote {args.output}: {combined} combined unique names > " + f"threshold {args.threshold} -> STEM PREPROCESSING NEEDED " + f"({len(ctx['sample'])} sampled names emitted).", + file=sys.stderr, + ) + else: + print( + f"Wrote {args.output}: {combined} combined unique names " + f"({ctx['summary']['in_both']} shared, " + f"{ctx['summary'][f'only_in_{args.name_a}']} {args.name_a}-only, " + f"{ctx['summary'][f'only_in_{args.name_b}']} {args.name_b}-only).", + file=sys.stderr, + ) + + +# =========================================================================== +# apply-stem-rules +# =========================================================================== + + +def _compile_rules(rules): + """Compile stem_rules entries; validate shape and actions.""" + compiled = [] + for i, r in enumerate(rules): + action = r.get("action", "collapse") + if action not in ("collapse", "preserve", "drop"): + raise SystemExit( + f"rule {i}: invalid action {action!r} " + f"(expected collapse/preserve/drop)" + ) + pattern = r.get("pattern", "") + try: + rx = re.compile(pattern) + except re.error as e: + raise SystemExit(f"rule {i}: bad regex {pattern!r}: {e}") + compiled.append( + { + "regex": rx, + "action": action, + "replacement": r.get("replacement", ""), + "note": r.get("note", ""), + } + ) + return compiled + + +def stem_for(name, compiled): + """Return (stem, action) for *name* using the first matching rule. + + Unmatched names default to (name, "preserve"). + """ + for r in compiled: + if r["regex"].search(name): + if r["action"] == "collapse": + return r["regex"].sub(r["replacement"], name), "collapse" + if r["action"] == "preserve": + return name, "preserve" + return name, "drop" + return name, "preserve" + + +def cmd_apply_stem_rules(args): + labels_a = _load(args.labels_a) + labels_b = _load(args.labels_b) + rules_doc = _load(args.rules) + rules = rules_doc["rules"] if isinstance(rules_doc, dict) else rules_doc + compiled = _compile_rules(rules) + + agg_a_raw = aggregate_names(labels_a) + agg_b_raw = aggregate_names(labels_b) + all_names = set(agg_a_raw) | set(agg_b_raw) + + raw_to_stem = {} + dropped = set() + action_counts = {"collapse": 0, "preserve": 0, "drop": 0} + for name in all_names: + stem, action = stem_for(name, compiled) + action_counts[action] += 1 + if action == "drop": + dropped.add(name) + raw_to_stem[name] = name # falls back to raw; excluded from context + else: + raw_to_stem[name] = stem + + if args.raw_to_stem: + with open(args.raw_to_stem, "w") as f: + json.dump(raw_to_stem, f, indent=2) + + def _stem_key(name): + if name in dropped: + return None # exclude dropped kernels from the stem aggregation + return raw_to_stem.get(name, name) + + agg_a = aggregate_names(labels_a, key_fn=lambda n: _stem_key(n)) + agg_b = aggregate_names(labels_b, key_fn=lambda n: _stem_key(n)) + agg_a.pop(None, None) + agg_b.pop(None, None) + + combined_stems = len(set(agg_a) | set(agg_b)) + ctx = _build_context( + agg_a, agg_b, args.name_a, args.name_b, "stem", + extra={ + "needs_stem_preprocessing": False, + "stem_preprocessing_applied": True, + "raw_unique_before": len(all_names), + "stem_unique_after": combined_stems, + "action_counts": action_counts, + "dropped_count": len(dropped), + }, + ) + + with open(args.output, "w") as f: + json.dump(ctx, f, indent=2) + + status = "OK" if combined_stems <= args.threshold else "STILL ABOVE THRESHOLD" + print( + f"Stem rules: {len(all_names)} raw -> {combined_stems} stems " + f"(collapse {action_counts['collapse']}, preserve " + f"{action_counts['preserve']}, drop {action_counts['drop']}). " + f"threshold {args.threshold}: {status}.", + file=sys.stderr, + ) + if combined_stems > args.threshold: + print( + " Reduce further: broaden collapse rules or drop more low-value " + "families, then re-run apply-stem-rules.", + file=sys.stderr, + ) + + +# =========================================================================== +# apply-map +# =========================================================================== + + +def _load_map_side(map_doc, side, name): + """Extract one trace's {key: unified} map from the LLM map document. + + Accepts either ``map_`` / ``map_`` keys or a nested + ``{trace_a: {map: {...}}}`` shape. + """ + for cand in (f"map_{side}", f"map_{name}", side, name): + if cand in map_doc: + val = map_doc[cand] + if isinstance(val, dict) and "map" in val: + return val["map"] + if isinstance(val, dict): + return val + return {} + + +def _apply_side(labels, unified_map, raw_to_stem): + """Write semantic_block = unified name for every kernel; return stats.""" + n_mapped = 0 + n_stemmed = 0 + for k in labels.get("labeled_kernels", []): + raw = k.get("name", "") + base = raw + if raw_to_stem is not None: + base = raw_to_stem.get(raw, raw) + if base != raw: + n_stemmed += 1 + unified = unified_map.get(base, base) + if base in unified_map: + n_mapped += 1 + k["semantic_block"] = unified + return {"kernels": len(labels.get("labeled_kernels", [])), + "mapped": n_mapped, "stemmed": n_stemmed} + + +def cmd_apply_map(args): + labels_a = _load(args.labels_a) + labels_b = _load(args.labels_b) + map_doc = _load(args.map) + raw_to_stem = _load(args.raw_to_stem) if args.raw_to_stem else None + + map_a = _load_map_side(map_doc, "a", args.name_a) + map_b = _load_map_side(map_doc, "b", args.name_b) + + stats_a = _apply_side(labels_a, map_a, raw_to_stem) + stats_b = _apply_side(labels_b, map_b, raw_to_stem) + + with open(args.labels_a, "w") as f: + json.dump(labels_a, f, indent=2) + with open(args.labels_b, "w") as f: + json.dump(labels_b, f, indent=2) + + blocks_a = set(k["semantic_block"] for k in labels_a["labeled_kernels"]) + blocks_b = set(k["semantic_block"] for k in labels_b["labeled_kernels"]) + shared = blocks_a & blocks_b + + print(f"Applied to {args.name_a}: {stats_a}", file=sys.stderr) + print(f"Applied to {args.name_b}: {stats_b}", file=sys.stderr) + print( + f"Unified vocabulary: {len(shared)} shared blocks, " + f"{len(blocks_a - shared)} {args.name_a}-only, " + f"{len(blocks_b - shared)} {args.name_b}-only.", + file=sys.stderr, + ) + + +# =========================================================================== +# CLI +# =========================================================================== + + +def _add_common(p): + p.add_argument("--labels-a", required=True, help="Trace A semantic_labels.json") + p.add_argument("--labels-b", required=True, help="Trace B semantic_labels.json") + p.add_argument("--name-a", default="trace_a", help="Short name for trace A") + p.add_argument("--name-b", default="trace_b", help="Short name for trace B") + + +def main(): + parser = argparse.ArgumentParser( + description="Name-first cross-trace kernel-name unification " + "(prepare-context / apply-stem-rules / apply-map)" + ) + sub = parser.add_subparsers(dest="command", required=True) + + p_prep = sub.add_parser( + "prepare-context", help="Build the LLM unification context" + ) + _add_common(p_prep) + p_prep.add_argument("-o", "--output", required=True, help="Output context JSON") + p_prep.add_argument( + "--threshold", type=int, default=DEFAULT_THRESHOLD, + help=f"Combined-unique count above which stem preprocessing is flagged " + f"(default {DEFAULT_THRESHOLD})", + ) + p_prep.add_argument( + "--sample-size", type=int, default=DEFAULT_SAMPLE_SIZE, + help=f"Names to sample when over threshold (default {DEFAULT_SAMPLE_SIZE})", + ) + p_prep.set_defaults(func=cmd_prepare_context) + + p_stem = sub.add_parser( + "apply-stem-rules", + help="Apply LLM-authored stem_rules.json and emit a reduced context", + ) + _add_common(p_stem) + p_stem.add_argument("--rules", required=True, help="stem_rules.json from the LLM") + p_stem.add_argument( + "--raw-to-stem", help="Output path for the raw-name -> stem map" + ) + p_stem.add_argument("-o", "--output", required=True, help="Reduced context JSON") + p_stem.add_argument( + "--threshold", type=int, default=DEFAULT_THRESHOLD, + help=f"Target combined-stem count (default {DEFAULT_THRESHOLD})", + ) + p_stem.set_defaults(func=cmd_apply_stem_rules) + + p_apply = sub.add_parser( + "apply-map", + help="Apply kernel_unification_map.json onto both label files", + ) + _add_common(p_apply) + p_apply.add_argument("--map", required=True, help="kernel_unification_map.json") + p_apply.add_argument( + "--raw-to-stem", help="raw-name -> stem map (if stem preprocessing was used)" + ) + p_apply.set_defaults(func=cmd_apply_map) + + args = parser.parse_args() + args.func(args) + + +if __name__ == "__main__": + main() From 5a748a869295a771f5cd9c5ab40fcad8c5e540d8 Mon Sep 17 00:00:00 2001 From: Arseny Date: Fri, 10 Jul 2026 13:04:43 -0700 Subject: [PATCH 30/50] Add strict consistency metric to compare_lca_partitions All-or-nothing variant of purity: a kernel counts only if its entire group maps to a single group on the other side (no partial credit for the majority). Reports strict forward/reverse consistency with random and sequential baselines, alongside the existing majority-based purity. Always <= the matching purity. --- .../eval_utils/compare_lca_partitions.py | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/agent_evals/Analysis/eval_utils/compare_lca_partitions.py b/agent_evals/Analysis/eval_utils/compare_lca_partitions.py index 21901da00..19d9fc024 100755 --- a/agent_evals/Analysis/eval_utils/compare_lca_partitions.py +++ b/agent_evals/Analysis/eval_utils/compare_lca_partitions.py @@ -27,6 +27,14 @@ every kernel into one LCA, forward purity stays high (each gold group trivially agrees with the single label) but reverse purity collapses. +Strict consistency +------------------ +An all-or-nothing variant of purity: a kernel is *consistent* iff its ENTIRE +group maps to a single group on the other side (no partial credit for the +majority). Strict forward = fraction of kernels whose whole gold group lands in +one no-capture LCA; strict reverse swaps the roles. Always <= the matching +purity, with equality only when every multi-kernel group is perfectly pure. + Random baselines ---------------- To judge whether the real no-capture purity reflects genuine semantic signal or @@ -127,6 +135,35 @@ def both_purities(gold: np.ndarray, nc: np.ndarray): return purity_frac(gold, nc), purity_frac(nc, gold) +def strict_consistency_frac(group_labels: np.ndarray, other_labels: np.ndarray) -> float: + """Fraction of items whose entire group is homogeneous in ``other_labels``. + + Group items by ``group_labels``; an item is *consistent* iff every item that + shares its group carries the same ``other_labels`` value (so the whole group + maps to a single other-bin). Report the fraction of consistent items. + + This is an all-or-nothing variant of ``purity_frac``: a group contributes its + full size when perfectly pure, else 0 (no partial credit for the majority). + Hence ``strict_consistency_frac <= purity_frac`` always, with equality only + when every multi-item group is perfectly pure. + """ + df = pd.DataFrame({"g": group_labels, "o": other_labels}) + consistent = 0 + for _, grp in df.groupby("g", sort=False): + if grp["o"].nunique() == 1: + consistent += len(grp) + return consistent / len(df) + + +def both_strict(gold: np.ndarray, nc: np.ndarray): + """Return (strict_forward, strict_reverse). + + strict_forward = fraction of items whose gold group is fully pure in nc + strict_reverse = fraction of items whose nc group is fully pure in gold + """ + return strict_consistency_frac(gold, nc), strict_consistency_frac(nc, gold) + + def agreement_report(gold: pd.DataFrame, ncap: pd.DataFrame) -> None: """Print the LCA-partition agreement (forward/reverse purity) section.""" print("=" * 78) @@ -158,6 +195,13 @@ def agreement_report(gold: pd.DataFrame, ncap: pd.DataFrame) -> None: # Reverse purity: no-capture groups -> majority gold LCA. r_matched, r_total, r_frac, r_recs = purity(df, "lca_nc", "lca_gold") + # Strict consistency (all-or-nothing per group; no partial credit). + gold_lbl = df["lca_gold"].to_numpy() + nc_lbl = df["lca_nc"].to_numpy() + sf = strict_consistency_frac(gold_lbl, nc_lbl) # gold groups fully pure in nc + sr = strict_consistency_frac(nc_lbl, gold_lbl) # nc groups fully pure in gold + n_tot = len(df) + print("=" * 78) print("RESULTS") print("=" * 78) @@ -169,6 +213,14 @@ def agreement_report(gold: pd.DataFrame, ncap: pd.DataFrame) -> None: f"Reverse purity (no-capture group -> majority gold LCA): " f"{r_matched}/{r_total} = {r_frac:.4f}" ) + print( + f"Strict forward consistency (whole gold group -> one nc LCA): " + f"{int(round(sf * n_tot))}/{n_tot} = {sf:.4f}" + ) + print( + f"Strict reverse consistency (whole nc group -> one gold LCA): " + f"{int(round(sr * n_tot))}/{n_tot} = {sr:.4f}" + ) print("=" * 78) # Extra context: the largest no-capture groups (where collapse would show up). @@ -203,27 +255,35 @@ def baseline_report(merged: pd.DataFrame, title: str, n_trials: int) -> None: # ---- Real no-capture ---- real_fwd, real_rev = both_purities(gold, nc_real) + real_sfwd, real_srev = both_strict(gold, nc_real) # ---- Baseline 1: random shuffle of the pool over matched kernels ---- rng = np.random.default_rng(SEED) fwds = np.empty(n_trials) revs = np.empty(n_trials) + sfwds = np.empty(n_trials) + srevs = np.empty(n_trials) for t in range(n_trials): shuffled = pool.copy() rng.shuffle(shuffled) fwds[t], revs[t] = both_purities(gold, shuffled) + sfwds[t], srevs[t] = both_strict(gold, shuffled) b1_fwd_m, b1_fwd_s = fwds.mean(), fwds.std() b1_rev_m, b1_rev_s = revs.mean(), revs.std() + b1_sfwd_m, b1_sfwd_s = sfwds.mean(), sfwds.std() + b1_srev_m, b1_srev_s = srevs.mean(), srevs.std() # ---- Baseline 2: sequential blocks, buckets ordered most->least popular ---- # Kernels ordered by key (lexicographic string: source then string uid). seq = pool.copy() b2_fwd, b2_rev = both_purities(gold, seq) + b2_sfwd, b2_srev = both_strict(gold, seq) # ---- Baseline 3: sequential blocks, kernels ordered by INT gpu_op_uid ---- order3 = np.lexsort((merged["gpu_op_uid"].to_numpy(), merged["source"].to_numpy())) gold3 = gold[order3] b3_fwd, b3_rev = both_purities(gold3, pool) + b3_sfwd, b3_srev = both_strict(gold3, pool) # ---------------- report ---------------- print("=" * 74) @@ -246,6 +306,19 @@ def baseline_report(merged: pd.DataFrame, title: str, n_trials: int) -> None: ) print(f"{'Baseline 2 (seq, key str)':<26}{b2_fwd:>24.4f}{b2_rev:>24.4f}") print(f"{'Baseline 3 (seq, int uid)':<26}{b3_fwd:>24.4f}{b3_rev:>24.4f}") + print("-" * 74) + print("Strict consistency (fraction of items in a FULLY pure group):") + sh = f"{'partition':<26}{'strict fwd (gold pure)':>24}{'strict rev (nc pure)':>24}" + print(sh) + print("-" * 74) + print(f"{'Real no-capture':<26}{real_sfwd:>24.4f}{real_srev:>24.4f}") + print( + f"{'Baseline 1 (random)':<26}" + f"{f'{b1_sfwd_m:.4f} +/- {b1_sfwd_s:.4f}':>24}" + f"{f'{b1_srev_m:.4f} +/- {b1_srev_s:.4f}':>24}" + ) + print(f"{'Baseline 2 (seq, key str)':<26}{b2_sfwd:>24.4f}{b2_srev:>24.4f}") + print(f"{'Baseline 3 (seq, int uid)':<26}{b3_sfwd:>24.4f}{b3_srev:>24.4f}") print("=" * 74) From ca07e750940142c9e82afb9d9478eef811006933 Mon Sep 17 00:00:00 2001 From: Arseny Date: Tue, 4 Aug 2026 23:33:49 -0700 Subject: [PATCH 31/50] Current semantic with tests but no test traces yet --- agent_evals/Analysis/README.md | 40 +++- .../combined_traces_comparative.csv | 4 +- .../generate_semantic_gold_ref.sh | 151 +++++++++++++++ .../run_repeatability_parallel.sh | 31 ++- .../semantic_partition_scripted_evals.py | 159 ++++++++++++++++ .../eval_utils/semantic_purity_aggregate.py | 179 ++++++++++++++++++ tests/test_compare_lca_partitions.py | 141 ++++++++++++++ 7 files changed, 702 insertions(+), 3 deletions(-) create mode 100755 agent_evals/Analysis/eval_scripts/generate_semantic_gold_ref.sh create mode 100644 agent_evals/Analysis/eval_utils/semantic_partition_scripted_evals.py create mode 100644 agent_evals/Analysis/eval_utils/semantic_purity_aggregate.py create mode 100644 tests/test_compare_lca_partitions.py diff --git a/agent_evals/Analysis/README.md b/agent_evals/Analysis/README.md index 2ae4248e4..710c7b122 100644 --- a/agent_evals/Analysis/README.md +++ b/agent_evals/Analysis/README.md @@ -211,10 +211,11 @@ gemm_01_compute_few_tiles,gemm,agent_evals/Analysis/analysis_tests/unit_tests/ge For each test case in the traces CSV, the scripts run two phases: 1. **Phase 1 -- Analysis:** Invokes the Analysis agent on the trace file. Output is written to `analysis_output/`. Agent output is logged as stream JSON (`.ndjson`). The orchestrator includes targeted subagent retry (1 retry per failed subagent in Steps 6, 7, and 9) to reduce flaky pipeline failures. -2. **Phase 2 -- Workflow + Quality Evals (4 parallel tasks):** Launches four tasks concurrently: +2. **Phase 2 -- Workflow + Quality Evals (5 parallel tasks):** Launches five tasks concurrently: - Scripted workflow evals — 13 evals with per-item sub-scoring (via `docker exec`) - LLM workflow eval — 1 eval with multi-dimensional weighted scoring (via `agent`) - Scripted quality evals — 1 eval (via `docker exec`) + - Scripted semantic-purity eval — 1 eval, self-gated to only the two semantic-purity test cases (see [Semantic-Purity Eval](#semantic-purity-eval)) - LLM quality evals — 2 evals with multi-dimensional weighted scoring (via `agent`) 3. **Merge Results:** Runs `eval_utils/merge_results.py` to combine per-eval CSVs into a single `eval_summary.csv`. @@ -251,6 +252,41 @@ All scripted evals include **pre-check gates** that immediately FAIL all evals w LLM evals (2–3) run via `.cursor/skills/quality-llm-eval.md`. System-level P-items are skipped (no Impact field to compare). +### Semantic-Purity Eval + +`eval_utils/semantic_partition_scripted_evals.py` computes the LCA-partition purity of the semantic kernel-bucketing method (`_semantic/tracediff_output/diff_stats.csv` in the run's output) against a with-capture ("gold") reference, using the forward/reverse purity and strict forward/reverse consistency metrics from `eval_utils/compare_lca_partitions.py`. **Its own PASS/FAIL is informational only** -- see "Two-stage design" below for why, and `eval_utils/semantic_purity_aggregate.py` for the eval that actually gates. + +**Self-gating:** this eval is a no-op (writes an empty results CSV, always exits 0) for every test case except the two whose `reference_dir` contains a `semantic_purity_gold_diff_stats.csv` file: `semantic_purity_deepseek_r1` and `semantic_purity_qwen3_30b_a3b` in `analysis_tests/combined_traces_comparative.csv`. No other test case is affected by this eval. + +**Fixtures:** `analysis_tests/semantic_purity_deepseek_r1.tar.gz` and `analysis_tests/semantic_purity_qwen3_30b_a3b.tar.gz` each contain only the with-capture trace pair (`with_capture/MI300`, `with_capture/B300`) plus the pre-generated `analysis_output_ref/semantic_purity_gold_diff_stats.csv` gold reference -- the no-capture trace pair fed to Phase 1 as `trace1_path`/`trace2_path` is **not** stored redundantly in the tarball. Instead, `run_repeatability_parallel.sh` derives `no_capture/` from `with_capture/` on first use (copy the tree, then strip `torch_trace/capture_traces/` under each device folder), matching what `generate_semantic_gold_ref.sh` does for one-off gold regeneration. + +**Regenerating gold:** the gold `diff_stats.csv` is produced once (not per-repeat, since the with-capture path has no LLM involved and is deterministic) by running the same full agentic orchestrator on the **with-capture** trace pair and keeping `perf_report_trace1_csvs/diff_stats.csv` from that run's output -- same mechanism `generate_ref.sh` uses for the standard references. Regenerate with: + +```bash +bash agent_evals/Analysis/eval_scripts/generate_semantic_gold_ref.sh [semantic_purity_deepseek_r1 semantic_purity_qwen3_30b_a3b] +``` + +**Two-stage design.** The semantic-bucketing method has real run-to-run variance -- most visibly on Qwen3-30B-A3B, where five independently-observed runs ranged strict_forward 0.4677-0.7304 (DeepSeek-R1 was tight: 0.9748-0.9780 across three runs). A single run's metrics are therefore not a trustworthy regression signal on their own, so the gate is split in two: + +1. **Per-run (`semantic_partition_scripted_evals.py`):** always records forward_purity / reverse_purity / strict_forward / strict_reverse in `details`, and always reports PASS as long as the metrics were computed (result only turns FAIL for genuine pipeline errors -- candidate output missing, no matched keys). This is what makes it safe to run `NUM_REPEATS=1`: nothing downstream expects a per-run verdict to mean anything about quality. +2. **Post-repeat (`semantic_purity_aggregate.py`):** runs once after all `NUM_REPEATS` complete (wired into `run_repeatability_parallel.sh` right after the main `wait`, comparative mode only). It averages **strict_forward** specifically (chosen over forward_purity because it's all-or-nothing per gold group, so it doesn't give partial credit the way majority-vote purity does -- more discriminating) across whatever runs it finds, and compares that average against a fixed floor: + + | Test case | Floor (avg strict_forward) | Derivation | + |---|---|---| + | `semantic_purity_deepseek_r1` | 0.92 | mean(0.9748, 0.9748, 0.9780) = 0.9759, minus ~5% | + | `semantic_purity_qwen3_30b_a3b` | 0.55 | mean(0.5671, 0.4677, 0.7304, 0.5691, 0.5677) = 0.5804, minus ~5% | + + These floors are not derived from `compare_lca_partitions.py`'s random-shuffle baseline (Baseline 1, ~0.04-0.06 strict_forward for both models) -- they're set directly from currently-observed real performance with a small buffer. The intent is regression detection ("don't get worse than today"), not an absolute quality bar; raise them if the method is deliberately improved, don't lower them without a documented reason. Writes `semantic_purity_aggregate_verdict.csv` under each test case's results directory and exits non-zero if either test case fails. + +**Repeatability:** `NUM_REPEATS=3` is the intended setting for this eval, since the aggregate gate needs several runs to average over -- `NUM_REPEATS=1` still works (the per-run eval never gates), but the aggregate step then warns it's averaging over fewer runs than intended and the resulting verdict is a weaker estimate. + +```bash +NUM_REPEATS=3 TEST_IDS="semantic_purity_deepseek_r1 semantic_purity_qwen3_30b_a3b" \ + CONTAINER=my_container bash agent_evals/Analysis/eval_scripts/run_repeatability_parallel.sh +``` + +**STABLE/FLAKY does not apply to this eval's quality signal.** Because `semantic_purity_1`'s per-run result is always PASS (informational only), its row in `stability_summary.csv` will show `STABLE_PASS` regardless of the actual metric values or of whether `semantic_purity_aggregate.py` failed the case -- this is by design (the per-run/aggregate split was chosen specifically because averaging-then-gating is incompatible with independent per-run STABLE/FLAKY classification), not a bug. Look at `semantic_purity_aggregate_verdict.csv` for the real verdict; `stability_summary.csv`'s row for `semantic_purity_1` on these two test cases only tells you whether the pipeline itself completed each repeat, nothing about quality. + ## Results Results are written to `agent_evals/Analysis/repeatability_results//run_/` and include: @@ -259,6 +295,8 @@ Results are written to `agent_evals/Analysis/repeatability_results//run_/ - `workflow_scripted_eval.log` / `workflow_scripted_results.csv` -- scripted workflow eval output. - `workflow_llm_eval.ndjson` / `workflow_llm_results.csv` -- LLM workflow eval output. - `quality_scripted_eval.log` / `quality_scripted_results.csv` -- scripted quality eval output. +- `semantic_purity_eval.log` / `semantic_purity_results.csv` -- scripted semantic-purity eval output (empty/no-op for all test cases except the two described in [Semantic-Purity Eval](#semantic-purity-eval)). +- `semantic_purity_aggregate_verdict.csv` -- written once per test case (not per-repeat) under `repeatability_results//` (one level up from `run_/`) by `semantic_purity_aggregate.py` after all repeats finish; this is the actual pass/fail verdict for the two semantic-purity test cases (see [Semantic-Purity Eval](#semantic-purity-eval)). - `quality_llm_eval.ndjson` / `quality_llm_results.csv` -- LLM quality eval output. - `eval_summary.csv` -- merged results for the test case. diff --git a/agent_evals/Analysis/analysis_tests/combined_traces_comparative.csv b/agent_evals/Analysis/analysis_tests/combined_traces_comparative.csv index aeb3add1b..773c63540 100644 --- a/agent_evals/Analysis/analysis_tests/combined_traces_comparative.csv +++ b/agent_evals/Analysis/analysis_tests/combined_traces_comparative.csv @@ -7,4 +7,6 @@ test05_gemm_identical_runtime_roofline,gemm,agent_evals/Analysis/analysis_tests/ test06_conv_gap_exceeds_roofline,conv,agent_evals/Analysis/analysis_tests/unit_tests_comparative/test06_conv_gap_exceeds_roofline/trace1.json,agent_evals/Analysis/analysis_tests/unit_tests_comparative/test06_conv_gap_exceeds_roofline/trace2.json,agent_evals/Analysis/analysis_tests/unit_tests_comparative/test06_conv_gap_exceeds_roofline/analysis_output_ref,MI300X,H100 bert_small,full_model,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/bert_small/gaunernst_bert-small-uncased__1016001_mi300.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/bert_small/gaunernst_bert-small-uncased__1016001_h100.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/bert_small/analysis_output_ref,MI300X,H100 llama3_2,full_model,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/llama3_2/llama3_2_mi300.pt.trace_mi300.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/llama3_2/llama3_2_h100.pt.trace_h100.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/llama3_2/analysis_output_ref,MI300X,H100 -timesformer,full_model,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/timesformer/facebook_timesformer-base-finetuned-k400__1016002_mi300.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/timesformer/facebook_timesformer-base-finetuned-k400__1016002_h100.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/timesformer/analysis_output_ref,MI300X,H100 \ No newline at end of file +timesformer,full_model,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/timesformer/facebook_timesformer-base-finetuned-k400__1016002_mi300.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/timesformer/facebook_timesformer-base-finetuned-k400__1016002_h100.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/timesformer/analysis_output_ref,MI300X,H100 +semantic_purity_deepseek_r1,semantic_purity,agent_evals/Analysis/analysis_tests/semantic_purity_deepseek_r1/no_capture/MI300,agent_evals/Analysis/analysis_tests/semantic_purity_deepseek_r1/no_capture/B300,agent_evals/Analysis/analysis_tests/semantic_purity_deepseek_r1/analysis_output_ref,MI300,B300 +semantic_purity_qwen3_30b_a3b,semantic_purity,agent_evals/Analysis/analysis_tests/semantic_purity_qwen3_30b_a3b/no_capture/MI300,agent_evals/Analysis/analysis_tests/semantic_purity_qwen3_30b_a3b/no_capture/B300,agent_evals/Analysis/analysis_tests/semantic_purity_qwen3_30b_a3b/analysis_output_ref,MI300,B300 diff --git a/agent_evals/Analysis/eval_scripts/generate_semantic_gold_ref.sh b/agent_evals/Analysis/eval_scripts/generate_semantic_gold_ref.sh new file mode 100755 index 000000000..1f19082ad --- /dev/null +++ b/agent_evals/Analysis/eval_scripts/generate_semantic_gold_ref.sh @@ -0,0 +1,151 @@ +#!/usr/bin/env bash +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +# --------------------------------------------------------------------------- +# One-time gold-reference generation for the semantic-purity comparative test +# cases (semantic_purity_deepseek_r1, semantic_purity_qwen3_30b_a3b). +# +# For each test case this: +# 1. Expands the with-capture-only fixture tarball if not already expanded. +# 2. Derives a sibling no-capture trace pair (copy + strip +# torch_trace/capture_traces/) -- this is what Phase 1 of +# run_repeatability_parallel.sh feeds to the candidate agent runs. +# 3. Runs the full analysis orchestrator once on the WITH-CAPTURE trace pair +# (same agent invocation as run_repeatability_parallel.sh/generate_ref.sh) +# and copies the resulting perf_report_trace1_csvs/diff_stats.csv into +# the test case's reference_dir as semantic_purity_gold_diff_stats.csv. +# This file's presence is what self-gates semantic_partition_scripted_evals.py +# onto these two test cases (see that script and the "Adding a semantic-purity +# test case" section of README.md). +# +# This is a manual, one-time step (like generate_ref.sh) -- not part of the +# repeated Phase 1/2 test loop, since gold has no LLM involved and doesn't +# vary across repeats. +# +# Usage: bash generate_semantic_gold_ref.sh [test_id ...] +# With no arguments, generates gold for both semantic-purity test cases. +# --------------------------------------------------------------------------- +set -uo pipefail + +REPO_ROOT="${REPO_ROOT:-$(pwd)}" +ANALYSIS_DIR="$REPO_ROOT/TraceLens/Agent/Analysis" +EVALS_DIR="$REPO_ROOT/agent_evals/Analysis" +TESTS_DIR="$EVALS_DIR/analysis_tests" +GOLD_FILENAME="semantic_purity_gold_diff_stats.csv" + +# id -> "with_capture_subdir platform1 platform2" +declare -A CASES=( + [semantic_purity_deepseek_r1]="with_capture MI300 B300" + [semantic_purity_qwen3_30b_a3b]="with_capture MI300 B300" +) + +ts() { date "+%H:%M:%S"; } + +expand_archive() { + local name="$1" + local archive="$TESTS_DIR/${name}.tar.gz" + local target="$TESTS_DIR/$name" + if [[ -f "$archive" ]] && [[ ! -d "$target" ]]; then + echo "Expanding ${name}.tar.gz..." + tar xzf "$archive" -C "$REPO_ROOT" + fi +} + +# Derive a no-capture trace tree from a with-capture one: identical file tree, +# minus torch_trace/capture_traces/ under each device folder. +derive_no_capture() { + local with_capture_dir="$1" + local no_capture_dir="$2" + if [[ -d "$no_capture_dir" ]]; then + echo " no-capture dir already exists, skipping derivation: $no_capture_dir" + return + fi + echo " Deriving no-capture trace tree: $no_capture_dir" + cp -r "$with_capture_dir" "$no_capture_dir" + find "$no_capture_dir" -type d -name capture_traces -prune -exec rm -rf {} \; +} + +generate_one() { + local id="$1" + local subdir platform1 platform2 + read -r subdir platform1 platform2 <<< "${CASES[$id]}" + + local case_dir="$TESTS_DIR/$id" + local with_capture_dir="$case_dir/$subdir" + local no_capture_dir="$case_dir/no_capture" + local reference_dir="$case_dir/analysis_output_ref" + + expand_archive "$id" + + if [[ ! -d "$with_capture_dir" ]]; then + echo "ERROR [$id]: with-capture trace dir not found: $with_capture_dir" >&2 + return 1 + fi + + local trace1="$with_capture_dir/MI300" + local trace2="$with_capture_dir/B300" + derive_no_capture "$with_capture_dir" "$no_capture_dir" + + local scratch_dir="$case_dir/_gold_generation_scratch" + local output_dir="$scratch_dir/analysis_output" + rm -rf "$scratch_dir" + mkdir -p "$output_dir" + + echo "[$id] [$(ts)] Running full orchestrator on WITH-CAPTURE trace pair (gold generation)..." + local agent_success=false + local attempts=0 + while [ "$agent_success" = false ] && [ "$attempts" -lt 3 ]; do + attempts=$((attempts + 1)) + ( + cd "$ANALYSIS_DIR" || exit + agent --model claude-opus-4-8-thinking-medium --print --force --trust --output-format stream-json \ + "Follow the analysis orchestrator installed with the TraceLens pip package (look under TraceLens/Agent/Analysis/.cursor/skills/ in the package installation directory) and run the full agentic analysis workflow on $trace1 and $trace2 with platform $platform1 (trace1) and $platform2 (trace2), analysis mode default, output to $output_dir" + ) < /dev/null > "$scratch_dir/gold_generation_stream.ndjson" 2>&1 + + if head -c 2048 "$scratch_dir/gold_generation_stream.ndjson" | grep -qiE 'Error:.*unavailable|Service Unavailable'; then + echo "[$id] Attempt $attempts/3 failed (agent unavailable). Backing off 30s..." + sleep 30 + else + agent_success=true + fi + done + + if [ "$agent_success" = false ]; then + echo "ERROR [$id]: FAILED after 3 attempts (agent unavailable)." >&2 + return 1 + fi + + local gold_src="$output_dir/perf_report_trace1_csvs/diff_stats.csv" + if [[ ! -f "$gold_src" ]]; then + echo "ERROR [$id]: expected gold source not found: $gold_src" >&2 + return 1 + fi + + mkdir -p "$reference_dir" + cp "$gold_src" "$reference_dir/$GOLD_FILENAME" + rm -rf "$scratch_dir" + + echo "[$id] [$(ts)] Gold reference saved: $reference_dir/$GOLD_FILENAME" +} + +if [[ $# -gt 0 ]]; then + ids=("$@") +else + ids=("${!CASES[@]}") +fi + +status=0 +for id in "${ids[@]}"; do + if [[ -z "${CASES[$id]:-}" ]]; then + echo "ERROR: unknown test id '$id'" >&2 + status=1 + continue + fi + generate_one "$id" || status=1 +done + +exit $status diff --git a/agent_evals/Analysis/eval_scripts/run_repeatability_parallel.sh b/agent_evals/Analysis/eval_scripts/run_repeatability_parallel.sh index 9b8e8125d..d0749dd08 100644 --- a/agent_evals/Analysis/eval_scripts/run_repeatability_parallel.sh +++ b/agent_evals/Analysis/eval_scripts/run_repeatability_parallel.sh @@ -126,7 +126,7 @@ run_single_job() { log_status " $tag [$(ts)] Phase 1 complete." sleep "$SLEEP_BETWEEN" - # -- Phase 2: 4 parallel evals ------------------------------------------ + # -- Phase 2: 5 parallel evals ------------------------------------------ log_status " $tag [$(ts)] Phase 2: evals starting" local eval_pids=() @@ -151,6 +151,13 @@ run_single_job() { > "$CASE_RESULTS/quality_scripted_eval.log" 2>&1 & eval_pids+=($!) + "${DEXEC[@]}" python3 "$EVALS_DIR/eval_utils/semantic_partition_scripted_evals.py" \ + --output-dir "$OUTPUT_DIR" --reference-dir "$reference_dir" \ + --results "$CASE_RESULTS/semantic_purity_results.csv" \ + --comparison-scope "$COMPARISON_SCOPE" \ + > "$CASE_RESULTS/semantic_purity_eval.log" 2>&1 & + eval_pids+=($!) + ( cd "$EVALS_DIR" || exit agent --model claude-opus-4-8-thinking-medium --print --force --trust --output-format stream-json \ @@ -197,6 +204,17 @@ mkdir -p "$RESULTS_ROOT" if [[ "$COMPARISON_SCOPE" == "comparative" ]]; then expand_archive unit_tests_comparative expand_archive e2e_tests_comparative + expand_archive semantic_purity_deepseek_r1 + expand_archive semantic_purity_qwen3_30b_a3b + for case_id in semantic_purity_deepseek_r1 semantic_purity_qwen3_30b_a3b; do + wc_dir="$EVALS_DIR/analysis_tests/$case_id/with_capture" + nc_dir="$EVALS_DIR/analysis_tests/$case_id/no_capture" + if [[ -d "$wc_dir" ]] && [[ ! -d "$nc_dir" ]]; then + echo "Deriving no-capture trace tree for $case_id..." + cp -r "$wc_dir" "$nc_dir" + find "$nc_dir" -type d -name capture_traces -prune -exec rm -rf {} \; + fi + done else expand_archive unit_tests_standalone expand_archive e2e_tests_standalone @@ -261,6 +279,17 @@ echo " Repeatability test finished." echo " Results in: $RESULTS_ROOT" echo "=========================================" +# --------------------------------------------------------------------------- +# Semantic-purity regression gate: averages strict_forward across the +# NUM_REPEATS runs just produced and compares to a fixed, observed- +# performance-derived floor. Per-run PASS/FAIL from +# semantic_partition_scripted_evals.py is informational only (see that +# script's docstring); this is the actual gate. Comparative mode only. +# --------------------------------------------------------------------------- +if [[ "$COMPARISON_SCOPE" == "comparative" ]]; then + "${DEXEC[@]}" python3 "$EVALS_DIR/eval_utils/semantic_purity_aggregate.py" --results-root "$RESULTS_ROOT" || true +fi + # --------------------------------------------------------------------------- # Post-processing: aggregate results and generate reports via Cursor agent # --------------------------------------------------------------------------- diff --git a/agent_evals/Analysis/eval_utils/semantic_partition_scripted_evals.py b/agent_evals/Analysis/eval_utils/semantic_partition_scripted_evals.py new file mode 100644 index 000000000..e4409b7c0 --- /dev/null +++ b/agent_evals/Analysis/eval_utils/semantic_partition_scripted_evals.py @@ -0,0 +1,159 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Scripted eval: LCA-partition purity vs. a with-capture (gold) reference. + +Self-gating: only test cases whose reference_dir contains a +``semantic_purity_gold_diff_stats.csv`` (produced once by +``generate_semantic_gold_ref.sh``) are scored. All other comparative test +cases produce zero rows here, so this eval is a no-op for the existing +MI300-vs-H100 suite. + +For gated test cases, this reuses compare_lca_partitions.py's forward/reverse +purity and strict forward/reverse consistency metrics, computed between the +gold partition and the candidate's semantic-bucketing output +(``_semantic/tracediff_output/diff_stats.csv``), and records them. + +IMPORTANT: this per-run result is informational only. Because the semantic +method has real run-to-run variance (observed on Qwen3-30B-A3B), a single +run's metrics are not a reliable regression signal by themselves -- the +actual pass/fail decision is made by semantic_purity_aggregate.py, which +averages strict_forward across NUM_REPEATS runs (intended: 3) and compares +against a floor derived from currently-observed performance. See that +script and the "Semantic-purity quality gate" section of README.md. + +Consequently the "result" written here is PASS whenever the metrics were +computed at all; it only turns FAIL for genuine pipeline errors (candidate +output missing, no matched keys). Do not read STABLE/FLAKY classification +of this eval's row (via aggregate_repeatability.py) as a quality signal -- +it is dropped from that role by design and only reflects whether the +per-run pipeline itself succeeded. +""" + +import argparse +import csv +import os +import sys + +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from compare_lca_partitions import LCA_COL, both_purities, both_strict, load # noqa: E402 + +CSV_COLUMNS = [ + "index", + "category", + "issue_summary", + "result", + "details", + "root_cause", + "recommended_fix", +] + +GOLD_FILENAME = "semantic_purity_gold_diff_stats.csv" +CANDIDATE_RELPATH = os.path.join("_semantic", "tracediff_output", "diff_stats.csv") + + +def _write(results_path: str, rows: list[dict]) -> None: + with open(results_path, "w", newline="") as f: + writer = csv.DictWriter(f, fieldnames=CSV_COLUMNS) + writer.writeheader() + writer.writerows(rows) + + +def run(output_dir: str, reference_dir: str, results_path: str) -> list[dict]: + gold_path = os.path.join(reference_dir, GOLD_FILENAME) + if not os.path.isfile(gold_path): + # Not a semantic-purity test case; self-gate to a no-op. + _write(results_path, []) + return [] + + candidate_path = os.path.join(output_dir, CANDIDATE_RELPATH) + if not os.path.isfile(candidate_path): + rows = [ + { + "index": "semantic_purity_1", + "category": "Quality", + "issue_summary": "LCA-partition purity vs with-capture gold", + "result": "FAIL", + "details": f"Candidate semantic diff-stats not found: {candidate_path}", + "root_cause": "pipeline", + "recommended_fix": "Analysis run did not produce a semantic-bucketing output; check the run log", + } + ] + _write(results_path, rows) + return rows + + gold = load(gold_path) + cand = load(candidate_path) + + merged = gold[["key", LCA_COL]].rename(columns={LCA_COL: "lca_gold"}).merge( + cand[["key", LCA_COL]].rename(columns={LCA_COL: "lca_cand"}), + on="key", + ) + + if merged.empty: + rows = [ + { + "index": "semantic_purity_1", + "category": "Quality", + "issue_summary": "LCA-partition purity vs with-capture gold", + "result": "FAIL", + "details": "No matched (source, gpu_op_uid) keys between gold and candidate", + "root_cause": "data", + "recommended_fix": "Check that candidate and gold were generated from the same trace pair", + } + ] + _write(results_path, rows) + return rows + + gold_lbl = merged["lca_gold"].to_numpy() + cand_lbl = merged["lca_cand"].to_numpy() + fwd, rev = both_purities(gold_lbl, cand_lbl) + sfwd, srev = both_strict(gold_lbl, cand_lbl) + + # Informational only -- see module docstring. The regression gate is + # applied post-hoc, across repeats, by semantic_purity_aggregate.py. + details = ( + f"matched={len(merged)} forward_purity={fwd:.4f} reverse_purity={rev:.4f} " + f"strict_forward={sfwd:.4f} strict_reverse={srev:.4f} " + f"(informational only -- see semantic_purity_aggregate.py for the actual gate)" + ) + rows = [ + { + "index": "semantic_purity_1", + "category": "Quality", + "issue_summary": "LCA-partition purity vs with-capture gold", + "result": "PASS", + "details": details, + "root_cause": "", + "recommended_fix": "", + } + ] + _write(results_path, rows) + return rows + + +def main(): + parser = argparse.ArgumentParser(description="LCA-partition purity vs with-capture gold") + parser.add_argument("--output-dir", required=True) + parser.add_argument("--reference-dir", required=True) + parser.add_argument("--results", required=True) + parser.add_argument( + "--comparison-scope", + choices=["standalone", "comparative"], + default="comparative", + help="Only comparative mode is supported; accepted for CLI consistency with other evals", + ) + args = parser.parse_args() + + rows = run(args.output_dir, args.reference_dir, args.results) + if not rows: + sys.exit(0) + passed = sum(1 for r in rows if r["result"] == "PASS") + sys.exit(0 if passed == len(rows) else 1) + + +if __name__ == "__main__": + main() diff --git a/agent_evals/Analysis/eval_utils/semantic_purity_aggregate.py b/agent_evals/Analysis/eval_utils/semantic_purity_aggregate.py new file mode 100644 index 000000000..98d27f82e --- /dev/null +++ b/agent_evals/Analysis/eval_utils/semantic_purity_aggregate.py @@ -0,0 +1,179 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Aggregate the semantic-purity regression gate across repeated runs. + +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. + +This script is the actual gate. For each semantic-purity test case it: + 1. Scans results_root//run_*/semantic_purity_results.csv, + parsing out each run's strict_forward value (the "strict forward + consistency" metric from compare_lca_partitions.py: the fraction of + gold groups that map, in their entirety, to a single candidate LCA). + strict_forward is used as the sole gating metric -- it is more + discriminating than forward_purity because it does not give partial + credit to a majority-only match. + 2. Averages strict_forward across however many runs were found (intended: + NUM_REPEATS=3; a smaller N is honored but is a weaker estimate and is + flagged as such). + 3. Compares that average against MIN_STRICT_FORWARD_AVG[test_id] -- a + floor derived directly from currently-observed performance (mean of + all independently-verified runs collected during method validation), + minus a 5% buffer, sanity-checked to stay far above the random-shuffle + baseline (Baseline 1 in compare_lca_partitions.py, ~0.04-0.06 for + both models). The intent is regression detection ("don't get worse + than today"), not an absolute quality bar. + +Writes one verdict row (7-column eval schema) per test id to +results_root//semantic_purity_aggregate_verdict.csv, and prints a +summary table. + +Usage: python3 semantic_purity_aggregate.py --results-root +""" + +import argparse +import csv +import glob +import os +import re +import statistics +import sys + +CSV_COLUMNS = [ + "index", + "category", + "issue_summary", + "result", + "details", + "root_cause", + "recommended_fix", +] + +# Floor = mean(observed strict_forward across all independently-verified +# runs collected during method validation) * 0.95, rounded down slightly. +# Observed data (via compare_lca_partitions.py against the committed gold +# reference): +# deepseek_r1: 0.9748, 0.9748, 0.9780 -> mean 0.9759 -> floor 0.92 +# qwen3_30b_a3b: 0.5671, 0.4677, 0.7304, 0.5691, 0.5677 +# -> mean 0.5804 -> floor 0.55 +# Both floors sit far above the random-shuffle baseline (Baseline 1) of +# ~0.04-0.06 strict_forward for both models -- i.e. nowhere near "no better +# than chance". Revisit these floors if the method is intentionally +# improved (raise them) -- do not lower them without a documented reason. +MIN_STRICT_FORWARD_AVG = { + "semantic_purity_deepseek_r1": 0.92, + "semantic_purity_qwen3_30b_a3b": 0.55, +} + +DETAILS_RE = re.compile(r"strict_forward=([0-9.]+)") +FORWARD_RE = re.compile(r"forward_purity=([0-9.]+)") + + +def find_run_csvs(results_root: str, test_id: str) -> list[str]: + pattern = os.path.join(results_root, test_id, "run_*", "semantic_purity_results.csv") + return sorted(glob.glob(pattern)) + + +def parse_run(csv_path: str): + with open(csv_path, newline="") as f: + rows = list(csv.DictReader(f)) + if not rows: + return None # self-gated no-op for this test id (shouldn't happen here) + row = rows[0] + details = row.get("details", "") + m_sfwd = DETAILS_RE.search(details) + m_fwd = FORWARD_RE.search(details) + if not m_sfwd: + return None # pipeline failure row, no metrics to parse + return { + "strict_forward": float(m_sfwd.group(1)), + "forward_purity": float(m_fwd.group(1)) if m_fwd else None, + "source": csv_path, + } + + +def aggregate_one(results_root: str, test_id: str) -> dict: + run_csvs = find_run_csvs(results_root, test_id) + parsed = [p for p in (parse_run(c) for c in run_csvs) if p is not None] + + if not parsed: + return { + "index": "semantic_purity_aggregate", + "category": "Quality", + "issue_summary": f"Semantic-purity regression gate ({test_id})", + "result": "FAIL", + "details": f"No usable runs found under {results_root}/{test_id}/run_*/semantic_purity_results.csv", + "root_cause": "pipeline", + "recommended_fix": "Ensure Phase 1+2 completed for this test id before aggregating", + } + + values = [p["strict_forward"] for p in parsed] + avg = statistics.mean(values) + floor = MIN_STRICT_FORWARD_AVG.get(test_id) + if floor is None: + return { + "index": "semantic_purity_aggregate", + "category": "Quality", + "issue_summary": f"Semantic-purity regression gate ({test_id})", + "result": "FAIL", + "details": f"No floor configured for test id {test_id}; add one to MIN_STRICT_FORWARD_AVG", + "root_cause": "config", + "recommended_fix": "Add this test id to MIN_STRICT_FORWARD_AVG in semantic_purity_aggregate.py", + } + + passed = avg >= floor + n_note = "" if len(parsed) >= 3 else f" (WARNING: only {len(parsed)} run(s) found; intended N=3, this is a weaker estimate)" + details = ( + f"n_runs={len(parsed)} strict_forward_values={[round(v, 4) for v in values]} " + f"avg_strict_forward={avg:.4f} floor={floor}{n_note}" + ) + return { + "index": "semantic_purity_aggregate", + "category": "Quality", + "issue_summary": f"Semantic-purity regression gate ({test_id})", + "result": "PASS" if passed else "FAIL", + "details": details, + "root_cause": "" if passed else "quality", + "recommended_fix": "" if passed else "Semantic-bucketing quality regressed below the observed-performance floor; investigate the clustering change", + } + + +def main(): + parser = argparse.ArgumentParser(description="Aggregate semantic-purity gate across repeats") + parser.add_argument("--results-root", required=True) + parser.add_argument( + "--test-ids", + default=",".join(MIN_STRICT_FORWARD_AVG.keys()), + help="Comma-separated test ids to aggregate (default: all known semantic-purity test ids)", + ) + args = parser.parse_args() + + test_ids = [t.strip() for t in args.test_ids.split(",") if t.strip()] + overall_pass = True + for test_id in test_ids: + case_dir = os.path.join(args.results_root, test_id) + if not os.path.isdir(case_dir): + print(f"[{test_id}] skipped (no results directory found)") + continue + result = aggregate_one(args.results_root, test_id) + out_path = os.path.join(case_dir, "semantic_purity_aggregate_verdict.csv") + with open(out_path, "w", newline="") as f: + writer = csv.DictWriter(f, fieldnames=CSV_COLUMNS) + writer.writeheader() + writer.writerow(result) + print(f"[{test_id}] {result['result']}: {result['details']}") + print(f" -> {out_path}") + if result["result"] != "PASS": + overall_pass = False + + sys.exit(0 if overall_pass else 1) + + +if __name__ == "__main__": + main() diff --git a/tests/test_compare_lca_partitions.py b/tests/test_compare_lca_partitions.py new file mode 100644 index 000000000..43081e8ed --- /dev/null +++ b/tests/test_compare_lca_partitions.py @@ -0,0 +1,141 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Fast, no-agent unit tests for agent_evals/Analysis/eval_utils/compare_lca_partitions.py. + +Uses small synthetic diff_stats.csv fixtures (no traces, no LLM) to pin down +the purity/strict-consistency metric semantics. +""" + +import os +import sys + +import pandas as pd +import pytest + +sys.path.insert( + 0, + os.path.join( + os.path.dirname(os.path.abspath(__file__)), + "..", + "agent_evals", + "Analysis", + "eval_utils", + ), +) +from compare_lca_partitions import both_purities, both_strict, load # noqa: E402 + +COLUMNS = ["source", "gpu_op_uid", "name", "lowest_common_ancestor_id", "lowest_common_ancestor_name"] + + +def _write_csv(path, rows): + pd.DataFrame(rows, columns=COLUMNS).to_csv(path, index=False) + + +def _row(source, uid, name, lca_id): + return [source, uid, name, lca_id, f"lca_{lca_id}"] + + +def test_load_requires_key_columns(tmp_path): + path = tmp_path / "bad.csv" + pd.DataFrame({"foo": [1, 2]}).to_csv(path, index=False) + with pytest.raises(ValueError, match="missing required columns"): + load(path) + + +def test_load_rejects_duplicate_keys(tmp_path): + path = tmp_path / "dup.csv" + _write_csv( + path, + [ + _row("trace1", 1, "kernelA", 0), + _row("trace1", 1, "kernelA", 0), + ], + ) + with pytest.raises(ValueError, match="duplicate"): + load(path) + + +def test_perfect_agreement_gives_purity_one(): + gold = ["g0", "g0", "g1", "g1"] + cand = ["c0", "c0", "c1", "c1"] + fwd, rev = both_purities(gold, cand) + sfwd, srev = both_strict(gold, cand) + assert fwd == 1.0 + assert rev == 1.0 + assert sfwd == 1.0 + assert srev == 1.0 + + +def test_candidate_collapse_hurts_reverse_purity_not_forward(): + # Every gold group maps entirely into one giant candidate bucket: forward + # purity is trivially perfect (each gold group agrees with the sole label + # it sees), but reverse purity collapses because that one candidate bucket + # disagrees with most of the gold labels it swallowed. + gold = ["g0", "g0", "g1", "g1", "g2", "g2"] + cand = ["c0"] * 6 + fwd, rev = both_purities(gold, cand) + assert fwd == 1.0 + assert rev == pytest.approx(2 / 6) # majority gold label (any of the 3) covers 2/6 + + +def test_partial_split_purity_between_zero_and_one(): + # gold group g0 (4 items) splits 3-1 across two candidate buckets. + gold = ["g0", "g0", "g0", "g0", "g1", "g1"] + cand = ["c0", "c0", "c0", "c1", "c2", "c2"] + fwd, rev = both_purities(gold, cand) + sfwd, srev = both_strict(gold, cand) + # forward: g0 majority=3/4, g1 majority=2/2 -> (3+2)/6 + assert fwd == pytest.approx(5 / 6) + # strict forward: g0 not fully pure (0 credit), g1 fully pure (2 credit) -> 2/6 + assert sfwd == pytest.approx(2 / 6) + assert sfwd <= fwd + assert srev <= rev + + +def test_strict_never_exceeds_matching_purity_on_random_like_partition(): + gold = ["g0"] * 5 + ["g1"] * 3 + ["g2"] * 2 + cand = ["c0", "c0", "c1", "c1", "c1", "c2", "c0", "c1", "c2", "c2"] + fwd, rev = both_purities(gold, cand) + sfwd, srev = both_strict(gold, cand) + assert sfwd <= fwd + assert srev <= rev + + +def test_end_to_end_via_csv_files(tmp_path): + gold_path = tmp_path / "gold.csv" + cand_path = tmp_path / "cand.csv" + _write_csv( + gold_path, + [ + _row("trace1", 1, "kernelA", 0), + _row("trace1", 2, "kernelB", 0), + _row("trace2", 1, "kernelC", 1), + _row("trace2", 2, "kernelD", 1), + ], + ) + _write_csv( + cand_path, + [ + _row("trace1", 1, "kernelA", 10), + _row("trace1", 2, "kernelB", 10), + _row("trace2", 1, "kernelC", 11), + _row("trace2", 2, "kernelD", 11), + ], + ) + gold = load(gold_path) + cand = load(cand_path) + merged = gold[["key", "lowest_common_ancestor_id"]].rename( + columns={"lowest_common_ancestor_id": "lca_gold"} + ).merge( + cand[["key", "lowest_common_ancestor_id"]].rename( + columns={"lowest_common_ancestor_id": "lca_cand"} + ), + on="key", + ) + assert len(merged) == 4 + fwd, rev = both_purities(merged["lca_gold"].to_numpy(), merged["lca_cand"].to_numpy()) + assert fwd == 1.0 and rev == 1.0 From 1018b587044a77af765230c30cd7d0d2c0e7069d Mon Sep 17 00:00:00 2001 From: Arseny Date: Fri, 7 Aug 2026 20:05:48 -0700 Subject: [PATCH 32/50] Current semantic analysis with test, slimmed down. --- agent_evals/Analysis/README.md | 40 +--- .../combined_traces_comparative.csv | 4 +- .../generate_semantic_gold_ref.sh | 151 -------------- .../run_repeatability_parallel.sh | 31 +-- agent_evals/Analysis/partial_tests/.gitignore | 8 + agent_evals/Analysis/partial_tests/README.md | 115 +++++++++++ .../semantic_partition_scripted_evals.py | 44 ++-- .../eval_utils/semantic_purity_aggregate.py | 48 ++--- .../semantic_purity_deepseek_r1.tar.gz | Bin 0 -> 144919 bytes .../semantic_purity_qwen3_30b_a3b.tar.gz | Bin 0 -> 181094 bytes .../generate_updated_semantic_gold.sh | 105 ++++++++++ .../partial_tests/partial_test_cases.csv | 3 + .../partial_tests/run_partial_tests.sh | 191 ++++++++++++++++++ 13 files changed, 470 insertions(+), 270 deletions(-) delete mode 100755 agent_evals/Analysis/eval_scripts/generate_semantic_gold_ref.sh create mode 100644 agent_evals/Analysis/partial_tests/.gitignore create mode 100644 agent_evals/Analysis/partial_tests/README.md rename agent_evals/Analysis/{ => partial_tests}/eval_utils/semantic_partition_scripted_evals.py (77%) rename agent_evals/Analysis/{ => partial_tests}/eval_utils/semantic_purity_aggregate.py (79%) create mode 100644 agent_evals/Analysis/partial_tests/fixtures/semantic_purity_deepseek_r1.tar.gz create mode 100644 agent_evals/Analysis/partial_tests/fixtures/semantic_purity_qwen3_30b_a3b.tar.gz create mode 100755 agent_evals/Analysis/partial_tests/generate_updated_semantic_gold.sh create mode 100644 agent_evals/Analysis/partial_tests/partial_test_cases.csv create mode 100755 agent_evals/Analysis/partial_tests/run_partial_tests.sh diff --git a/agent_evals/Analysis/README.md b/agent_evals/Analysis/README.md index 710c7b122..2ae4248e4 100644 --- a/agent_evals/Analysis/README.md +++ b/agent_evals/Analysis/README.md @@ -211,11 +211,10 @@ gemm_01_compute_few_tiles,gemm,agent_evals/Analysis/analysis_tests/unit_tests/ge For each test case in the traces CSV, the scripts run two phases: 1. **Phase 1 -- Analysis:** Invokes the Analysis agent on the trace file. Output is written to `analysis_output/`. Agent output is logged as stream JSON (`.ndjson`). The orchestrator includes targeted subagent retry (1 retry per failed subagent in Steps 6, 7, and 9) to reduce flaky pipeline failures. -2. **Phase 2 -- Workflow + Quality Evals (5 parallel tasks):** Launches five tasks concurrently: +2. **Phase 2 -- Workflow + Quality Evals (4 parallel tasks):** Launches four tasks concurrently: - Scripted workflow evals — 13 evals with per-item sub-scoring (via `docker exec`) - LLM workflow eval — 1 eval with multi-dimensional weighted scoring (via `agent`) - Scripted quality evals — 1 eval (via `docker exec`) - - Scripted semantic-purity eval — 1 eval, self-gated to only the two semantic-purity test cases (see [Semantic-Purity Eval](#semantic-purity-eval)) - LLM quality evals — 2 evals with multi-dimensional weighted scoring (via `agent`) 3. **Merge Results:** Runs `eval_utils/merge_results.py` to combine per-eval CSVs into a single `eval_summary.csv`. @@ -252,41 +251,6 @@ All scripted evals include **pre-check gates** that immediately FAIL all evals w LLM evals (2–3) run via `.cursor/skills/quality-llm-eval.md`. System-level P-items are skipped (no Impact field to compare). -### Semantic-Purity Eval - -`eval_utils/semantic_partition_scripted_evals.py` computes the LCA-partition purity of the semantic kernel-bucketing method (`_semantic/tracediff_output/diff_stats.csv` in the run's output) against a with-capture ("gold") reference, using the forward/reverse purity and strict forward/reverse consistency metrics from `eval_utils/compare_lca_partitions.py`. **Its own PASS/FAIL is informational only** -- see "Two-stage design" below for why, and `eval_utils/semantic_purity_aggregate.py` for the eval that actually gates. - -**Self-gating:** this eval is a no-op (writes an empty results CSV, always exits 0) for every test case except the two whose `reference_dir` contains a `semantic_purity_gold_diff_stats.csv` file: `semantic_purity_deepseek_r1` and `semantic_purity_qwen3_30b_a3b` in `analysis_tests/combined_traces_comparative.csv`. No other test case is affected by this eval. - -**Fixtures:** `analysis_tests/semantic_purity_deepseek_r1.tar.gz` and `analysis_tests/semantic_purity_qwen3_30b_a3b.tar.gz` each contain only the with-capture trace pair (`with_capture/MI300`, `with_capture/B300`) plus the pre-generated `analysis_output_ref/semantic_purity_gold_diff_stats.csv` gold reference -- the no-capture trace pair fed to Phase 1 as `trace1_path`/`trace2_path` is **not** stored redundantly in the tarball. Instead, `run_repeatability_parallel.sh` derives `no_capture/` from `with_capture/` on first use (copy the tree, then strip `torch_trace/capture_traces/` under each device folder), matching what `generate_semantic_gold_ref.sh` does for one-off gold regeneration. - -**Regenerating gold:** the gold `diff_stats.csv` is produced once (not per-repeat, since the with-capture path has no LLM involved and is deterministic) by running the same full agentic orchestrator on the **with-capture** trace pair and keeping `perf_report_trace1_csvs/diff_stats.csv` from that run's output -- same mechanism `generate_ref.sh` uses for the standard references. Regenerate with: - -```bash -bash agent_evals/Analysis/eval_scripts/generate_semantic_gold_ref.sh [semantic_purity_deepseek_r1 semantic_purity_qwen3_30b_a3b] -``` - -**Two-stage design.** The semantic-bucketing method has real run-to-run variance -- most visibly on Qwen3-30B-A3B, where five independently-observed runs ranged strict_forward 0.4677-0.7304 (DeepSeek-R1 was tight: 0.9748-0.9780 across three runs). A single run's metrics are therefore not a trustworthy regression signal on their own, so the gate is split in two: - -1. **Per-run (`semantic_partition_scripted_evals.py`):** always records forward_purity / reverse_purity / strict_forward / strict_reverse in `details`, and always reports PASS as long as the metrics were computed (result only turns FAIL for genuine pipeline errors -- candidate output missing, no matched keys). This is what makes it safe to run `NUM_REPEATS=1`: nothing downstream expects a per-run verdict to mean anything about quality. -2. **Post-repeat (`semantic_purity_aggregate.py`):** runs once after all `NUM_REPEATS` complete (wired into `run_repeatability_parallel.sh` right after the main `wait`, comparative mode only). It averages **strict_forward** specifically (chosen over forward_purity because it's all-or-nothing per gold group, so it doesn't give partial credit the way majority-vote purity does -- more discriminating) across whatever runs it finds, and compares that average against a fixed floor: - - | Test case | Floor (avg strict_forward) | Derivation | - |---|---|---| - | `semantic_purity_deepseek_r1` | 0.92 | mean(0.9748, 0.9748, 0.9780) = 0.9759, minus ~5% | - | `semantic_purity_qwen3_30b_a3b` | 0.55 | mean(0.5671, 0.4677, 0.7304, 0.5691, 0.5677) = 0.5804, minus ~5% | - - These floors are not derived from `compare_lca_partitions.py`'s random-shuffle baseline (Baseline 1, ~0.04-0.06 strict_forward for both models) -- they're set directly from currently-observed real performance with a small buffer. The intent is regression detection ("don't get worse than today"), not an absolute quality bar; raise them if the method is deliberately improved, don't lower them without a documented reason. Writes `semantic_purity_aggregate_verdict.csv` under each test case's results directory and exits non-zero if either test case fails. - -**Repeatability:** `NUM_REPEATS=3` is the intended setting for this eval, since the aggregate gate needs several runs to average over -- `NUM_REPEATS=1` still works (the per-run eval never gates), but the aggregate step then warns it's averaging over fewer runs than intended and the resulting verdict is a weaker estimate. - -```bash -NUM_REPEATS=3 TEST_IDS="semantic_purity_deepseek_r1 semantic_purity_qwen3_30b_a3b" \ - CONTAINER=my_container bash agent_evals/Analysis/eval_scripts/run_repeatability_parallel.sh -``` - -**STABLE/FLAKY does not apply to this eval's quality signal.** Because `semantic_purity_1`'s per-run result is always PASS (informational only), its row in `stability_summary.csv` will show `STABLE_PASS` regardless of the actual metric values or of whether `semantic_purity_aggregate.py` failed the case -- this is by design (the per-run/aggregate split was chosen specifically because averaging-then-gating is incompatible with independent per-run STABLE/FLAKY classification), not a bug. Look at `semantic_purity_aggregate_verdict.csv` for the real verdict; `stability_summary.csv`'s row for `semantic_purity_1` on these two test cases only tells you whether the pipeline itself completed each repeat, nothing about quality. - ## Results Results are written to `agent_evals/Analysis/repeatability_results//run_/` and include: @@ -295,8 +259,6 @@ Results are written to `agent_evals/Analysis/repeatability_results//run_/ - `workflow_scripted_eval.log` / `workflow_scripted_results.csv` -- scripted workflow eval output. - `workflow_llm_eval.ndjson` / `workflow_llm_results.csv` -- LLM workflow eval output. - `quality_scripted_eval.log` / `quality_scripted_results.csv` -- scripted quality eval output. -- `semantic_purity_eval.log` / `semantic_purity_results.csv` -- scripted semantic-purity eval output (empty/no-op for all test cases except the two described in [Semantic-Purity Eval](#semantic-purity-eval)). -- `semantic_purity_aggregate_verdict.csv` -- written once per test case (not per-repeat) under `repeatability_results//` (one level up from `run_/`) by `semantic_purity_aggregate.py` after all repeats finish; this is the actual pass/fail verdict for the two semantic-purity test cases (see [Semantic-Purity Eval](#semantic-purity-eval)). - `quality_llm_eval.ndjson` / `quality_llm_results.csv` -- LLM quality eval output. - `eval_summary.csv` -- merged results for the test case. diff --git a/agent_evals/Analysis/analysis_tests/combined_traces_comparative.csv b/agent_evals/Analysis/analysis_tests/combined_traces_comparative.csv index 773c63540..aeb3add1b 100644 --- a/agent_evals/Analysis/analysis_tests/combined_traces_comparative.csv +++ b/agent_evals/Analysis/analysis_tests/combined_traces_comparative.csv @@ -7,6 +7,4 @@ test05_gemm_identical_runtime_roofline,gemm,agent_evals/Analysis/analysis_tests/ test06_conv_gap_exceeds_roofline,conv,agent_evals/Analysis/analysis_tests/unit_tests_comparative/test06_conv_gap_exceeds_roofline/trace1.json,agent_evals/Analysis/analysis_tests/unit_tests_comparative/test06_conv_gap_exceeds_roofline/trace2.json,agent_evals/Analysis/analysis_tests/unit_tests_comparative/test06_conv_gap_exceeds_roofline/analysis_output_ref,MI300X,H100 bert_small,full_model,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/bert_small/gaunernst_bert-small-uncased__1016001_mi300.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/bert_small/gaunernst_bert-small-uncased__1016001_h100.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/bert_small/analysis_output_ref,MI300X,H100 llama3_2,full_model,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/llama3_2/llama3_2_mi300.pt.trace_mi300.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/llama3_2/llama3_2_h100.pt.trace_h100.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/llama3_2/analysis_output_ref,MI300X,H100 -timesformer,full_model,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/timesformer/facebook_timesformer-base-finetuned-k400__1016002_mi300.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/timesformer/facebook_timesformer-base-finetuned-k400__1016002_h100.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/timesformer/analysis_output_ref,MI300X,H100 -semantic_purity_deepseek_r1,semantic_purity,agent_evals/Analysis/analysis_tests/semantic_purity_deepseek_r1/no_capture/MI300,agent_evals/Analysis/analysis_tests/semantic_purity_deepseek_r1/no_capture/B300,agent_evals/Analysis/analysis_tests/semantic_purity_deepseek_r1/analysis_output_ref,MI300,B300 -semantic_purity_qwen3_30b_a3b,semantic_purity,agent_evals/Analysis/analysis_tests/semantic_purity_qwen3_30b_a3b/no_capture/MI300,agent_evals/Analysis/analysis_tests/semantic_purity_qwen3_30b_a3b/no_capture/B300,agent_evals/Analysis/analysis_tests/semantic_purity_qwen3_30b_a3b/analysis_output_ref,MI300,B300 +timesformer,full_model,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/timesformer/facebook_timesformer-base-finetuned-k400__1016002_mi300.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/timesformer/facebook_timesformer-base-finetuned-k400__1016002_h100.json.gz,agent_evals/Analysis/analysis_tests/e2e_tests_comparative/timesformer/analysis_output_ref,MI300X,H100 \ No newline at end of file diff --git a/agent_evals/Analysis/eval_scripts/generate_semantic_gold_ref.sh b/agent_evals/Analysis/eval_scripts/generate_semantic_gold_ref.sh deleted file mode 100755 index 1f19082ad..000000000 --- a/agent_evals/Analysis/eval_scripts/generate_semantic_gold_ref.sh +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/env bash -############################################################################### -# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. -# -# See LICENSE for license information. -############################################################################### - -# --------------------------------------------------------------------------- -# One-time gold-reference generation for the semantic-purity comparative test -# cases (semantic_purity_deepseek_r1, semantic_purity_qwen3_30b_a3b). -# -# For each test case this: -# 1. Expands the with-capture-only fixture tarball if not already expanded. -# 2. Derives a sibling no-capture trace pair (copy + strip -# torch_trace/capture_traces/) -- this is what Phase 1 of -# run_repeatability_parallel.sh feeds to the candidate agent runs. -# 3. Runs the full analysis orchestrator once on the WITH-CAPTURE trace pair -# (same agent invocation as run_repeatability_parallel.sh/generate_ref.sh) -# and copies the resulting perf_report_trace1_csvs/diff_stats.csv into -# the test case's reference_dir as semantic_purity_gold_diff_stats.csv. -# This file's presence is what self-gates semantic_partition_scripted_evals.py -# onto these two test cases (see that script and the "Adding a semantic-purity -# test case" section of README.md). -# -# This is a manual, one-time step (like generate_ref.sh) -- not part of the -# repeated Phase 1/2 test loop, since gold has no LLM involved and doesn't -# vary across repeats. -# -# Usage: bash generate_semantic_gold_ref.sh [test_id ...] -# With no arguments, generates gold for both semantic-purity test cases. -# --------------------------------------------------------------------------- -set -uo pipefail - -REPO_ROOT="${REPO_ROOT:-$(pwd)}" -ANALYSIS_DIR="$REPO_ROOT/TraceLens/Agent/Analysis" -EVALS_DIR="$REPO_ROOT/agent_evals/Analysis" -TESTS_DIR="$EVALS_DIR/analysis_tests" -GOLD_FILENAME="semantic_purity_gold_diff_stats.csv" - -# id -> "with_capture_subdir platform1 platform2" -declare -A CASES=( - [semantic_purity_deepseek_r1]="with_capture MI300 B300" - [semantic_purity_qwen3_30b_a3b]="with_capture MI300 B300" -) - -ts() { date "+%H:%M:%S"; } - -expand_archive() { - local name="$1" - local archive="$TESTS_DIR/${name}.tar.gz" - local target="$TESTS_DIR/$name" - if [[ -f "$archive" ]] && [[ ! -d "$target" ]]; then - echo "Expanding ${name}.tar.gz..." - tar xzf "$archive" -C "$REPO_ROOT" - fi -} - -# Derive a no-capture trace tree from a with-capture one: identical file tree, -# minus torch_trace/capture_traces/ under each device folder. -derive_no_capture() { - local with_capture_dir="$1" - local no_capture_dir="$2" - if [[ -d "$no_capture_dir" ]]; then - echo " no-capture dir already exists, skipping derivation: $no_capture_dir" - return - fi - echo " Deriving no-capture trace tree: $no_capture_dir" - cp -r "$with_capture_dir" "$no_capture_dir" - find "$no_capture_dir" -type d -name capture_traces -prune -exec rm -rf {} \; -} - -generate_one() { - local id="$1" - local subdir platform1 platform2 - read -r subdir platform1 platform2 <<< "${CASES[$id]}" - - local case_dir="$TESTS_DIR/$id" - local with_capture_dir="$case_dir/$subdir" - local no_capture_dir="$case_dir/no_capture" - local reference_dir="$case_dir/analysis_output_ref" - - expand_archive "$id" - - if [[ ! -d "$with_capture_dir" ]]; then - echo "ERROR [$id]: with-capture trace dir not found: $with_capture_dir" >&2 - return 1 - fi - - local trace1="$with_capture_dir/MI300" - local trace2="$with_capture_dir/B300" - derive_no_capture "$with_capture_dir" "$no_capture_dir" - - local scratch_dir="$case_dir/_gold_generation_scratch" - local output_dir="$scratch_dir/analysis_output" - rm -rf "$scratch_dir" - mkdir -p "$output_dir" - - echo "[$id] [$(ts)] Running full orchestrator on WITH-CAPTURE trace pair (gold generation)..." - local agent_success=false - local attempts=0 - while [ "$agent_success" = false ] && [ "$attempts" -lt 3 ]; do - attempts=$((attempts + 1)) - ( - cd "$ANALYSIS_DIR" || exit - agent --model claude-opus-4-8-thinking-medium --print --force --trust --output-format stream-json \ - "Follow the analysis orchestrator installed with the TraceLens pip package (look under TraceLens/Agent/Analysis/.cursor/skills/ in the package installation directory) and run the full agentic analysis workflow on $trace1 and $trace2 with platform $platform1 (trace1) and $platform2 (trace2), analysis mode default, output to $output_dir" - ) < /dev/null > "$scratch_dir/gold_generation_stream.ndjson" 2>&1 - - if head -c 2048 "$scratch_dir/gold_generation_stream.ndjson" | grep -qiE 'Error:.*unavailable|Service Unavailable'; then - echo "[$id] Attempt $attempts/3 failed (agent unavailable). Backing off 30s..." - sleep 30 - else - agent_success=true - fi - done - - if [ "$agent_success" = false ]; then - echo "ERROR [$id]: FAILED after 3 attempts (agent unavailable)." >&2 - return 1 - fi - - local gold_src="$output_dir/perf_report_trace1_csvs/diff_stats.csv" - if [[ ! -f "$gold_src" ]]; then - echo "ERROR [$id]: expected gold source not found: $gold_src" >&2 - return 1 - fi - - mkdir -p "$reference_dir" - cp "$gold_src" "$reference_dir/$GOLD_FILENAME" - rm -rf "$scratch_dir" - - echo "[$id] [$(ts)] Gold reference saved: $reference_dir/$GOLD_FILENAME" -} - -if [[ $# -gt 0 ]]; then - ids=("$@") -else - ids=("${!CASES[@]}") -fi - -status=0 -for id in "${ids[@]}"; do - if [[ -z "${CASES[$id]:-}" ]]; then - echo "ERROR: unknown test id '$id'" >&2 - status=1 - continue - fi - generate_one "$id" || status=1 -done - -exit $status diff --git a/agent_evals/Analysis/eval_scripts/run_repeatability_parallel.sh b/agent_evals/Analysis/eval_scripts/run_repeatability_parallel.sh index d0749dd08..9b8e8125d 100644 --- a/agent_evals/Analysis/eval_scripts/run_repeatability_parallel.sh +++ b/agent_evals/Analysis/eval_scripts/run_repeatability_parallel.sh @@ -126,7 +126,7 @@ run_single_job() { log_status " $tag [$(ts)] Phase 1 complete." sleep "$SLEEP_BETWEEN" - # -- Phase 2: 5 parallel evals ------------------------------------------ + # -- Phase 2: 4 parallel evals ------------------------------------------ log_status " $tag [$(ts)] Phase 2: evals starting" local eval_pids=() @@ -151,13 +151,6 @@ run_single_job() { > "$CASE_RESULTS/quality_scripted_eval.log" 2>&1 & eval_pids+=($!) - "${DEXEC[@]}" python3 "$EVALS_DIR/eval_utils/semantic_partition_scripted_evals.py" \ - --output-dir "$OUTPUT_DIR" --reference-dir "$reference_dir" \ - --results "$CASE_RESULTS/semantic_purity_results.csv" \ - --comparison-scope "$COMPARISON_SCOPE" \ - > "$CASE_RESULTS/semantic_purity_eval.log" 2>&1 & - eval_pids+=($!) - ( cd "$EVALS_DIR" || exit agent --model claude-opus-4-8-thinking-medium --print --force --trust --output-format stream-json \ @@ -204,17 +197,6 @@ mkdir -p "$RESULTS_ROOT" if [[ "$COMPARISON_SCOPE" == "comparative" ]]; then expand_archive unit_tests_comparative expand_archive e2e_tests_comparative - expand_archive semantic_purity_deepseek_r1 - expand_archive semantic_purity_qwen3_30b_a3b - for case_id in semantic_purity_deepseek_r1 semantic_purity_qwen3_30b_a3b; do - wc_dir="$EVALS_DIR/analysis_tests/$case_id/with_capture" - nc_dir="$EVALS_DIR/analysis_tests/$case_id/no_capture" - if [[ -d "$wc_dir" ]] && [[ ! -d "$nc_dir" ]]; then - echo "Deriving no-capture trace tree for $case_id..." - cp -r "$wc_dir" "$nc_dir" - find "$nc_dir" -type d -name capture_traces -prune -exec rm -rf {} \; - fi - done else expand_archive unit_tests_standalone expand_archive e2e_tests_standalone @@ -279,17 +261,6 @@ echo " Repeatability test finished." echo " Results in: $RESULTS_ROOT" echo "=========================================" -# --------------------------------------------------------------------------- -# Semantic-purity regression gate: averages strict_forward across the -# NUM_REPEATS runs just produced and compares to a fixed, observed- -# performance-derived floor. Per-run PASS/FAIL from -# semantic_partition_scripted_evals.py is informational only (see that -# script's docstring); this is the actual gate. Comparative mode only. -# --------------------------------------------------------------------------- -if [[ "$COMPARISON_SCOPE" == "comparative" ]]; then - "${DEXEC[@]}" python3 "$EVALS_DIR/eval_utils/semantic_purity_aggregate.py" --results-root "$RESULTS_ROOT" || true -fi - # --------------------------------------------------------------------------- # Post-processing: aggregate results and generate reports via Cursor agent # --------------------------------------------------------------------------- diff --git a/agent_evals/Analysis/partial_tests/.gitignore b/agent_evals/Analysis/partial_tests/.gitignore new file mode 100644 index 000000000..314eaa1e0 --- /dev/null +++ b/agent_evals/Analysis/partial_tests/.gitignore @@ -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/ +/semantic_purity_qwen3_30b_a3b/ +# Run outputs and scratch +/partial_results/ +_gold_scratch_*/ +eval_utils/__pycache__/ diff --git a/agent_evals/Analysis/partial_tests/README.md b/agent_evals/Analysis/partial_tests/README.md new file mode 100644 index 000000000..b2f347288 --- /dev/null +++ b/agent_evals/Analysis/partial_tests/README.md @@ -0,0 +1,115 @@ + + +# Partial-workflow tests + +This folder holds tests that run only **part** of an analysis workflow — just +far enough to produce an artifact that a scripted eval scores against a +pre-baked reference. This is deliberately lighter than +`../eval_scripts/run_repeatability_parallel.sh`, which runs the full 11-step +analysis orchestrator per case. + +The first (and currently only) partial-workflow test is **`semantic_purity`**. +The folder is named generically so other partial-workflow tests can be added +beside it (give them a new value in the `workflow` column of +`partial_test_cases.csv` and a matching branch in `run_partial_tests.sh`). + +## Layout + +``` +partial_tests/ +├── run_partial_tests.sh # the runner +├── generate_updated_semantic_gold.sh # OPTIONAL, rare: regenerate gold +├── partial_test_cases.csv # manifest (id,workflow,trace_a,trace_b,reference_dir,platform_a,platform_b) +├── eval_utils/ +│ ├── semantic_partition_scripted_evals.py # per-run purity metrics (informational) +│ └── semantic_purity_aggregate.py # the regression gate +├── fixtures/*.tar.gz # DECODE trace pair + pre-baked gold (small) +└── / # expanded fixture (MI300/, B300/, analysis_output_ref/) +``` + +`compare_lca_partitions.py` — the shared purity/consistency math — lives in +`../eval_utils/` (it is also imported by `tests/test_compare_lca_partitions.py`). + +## What `semantic_purity` does + +For each model (DeepSeek-R1, Qwen3-30B-A3B) the fixture ships: +- the **DECODE** trace for MI300 and B300 (single batch-16 decode execution — the + only trace kind these tests use), and +- a pre-baked **gold** `analysis_output_ref/semantic_purity_gold_diff_stats.csv`. + +The runner invokes the **semantic-comparison workflow** (the no-capture, +name-first + coherence bucketing method) on the DECODE pair, running only +through its "Generate TraceDiff Output" step — equivalent to the main +orchestrator through Step 1.S. That produces +`analysis_output/tracediff_output/diff_stats.csv`, whose LCA partition is then +compared to gold. + +Gold itself is the *with-capture* TraceDiff partition on the same DECODE pair. +Because both sides derive from the same single-execution DECODE trace, their +`gpu_op_uid` numbering lines up, so the `(source, gpu_op_uid)` join used by +`compare_lca_partitions.py` is meaningful. + +## Running + +```bash +# from the repo root +bash agent_evals/Analysis/partial_tests/run_partial_tests.sh + +# one model, single run (quick check) +TEST_IDS=semantic_purity_deepseek_r1 NUM_REPEATS=1 \ + bash agent_evals/Analysis/partial_tests/run_partial_tests.sh + +# variance study +NUM_REPEATS=5 bash agent_evals/Analysis/partial_tests/run_partial_tests.sh +``` + +Env knobs: `NUM_REPEATS` (default 1), `TEST_IDS` (space-separated whitelist), +`MAX_PARALLEL` (default 3), `CONTAINER` (docker container to exec python in), +`AGENT_MODEL`. Results land under `partial_tests/partial_results//run_*/`. + +## Semantic-purity quality gate + +The semantic bucketing method uses an LLM for its unification/coherence steps, +so it has **real run-to-run variance**. Therefore: + +- `semantic_partition_scripted_evals.py` writes each run's metrics + (`forward_purity`, `strict_forward`, etc.) but is **informational only** — its + per-run `result` is PASS unless the pipeline itself failed (missing candidate, + no matched keys). +- `semantic_purity_aggregate.py` is the **actual gate**. It averages + `strict_forward` across the runs found and compares to a per-model floor. + The floors — and the observed-run data they're derived from — live in that + script's `MIN_STRICT_FORWARD_AVG` and its module docstring, which are the + single source of truth (not duplicated here). The floors are set below the + worst single observed run with margin, so a quick `NUM_REPEATS=1` check does + not false-alarm, while staying well above the random-shuffle baseline. Raise + them if the method is intentionally improved; do not lower them without a + documented reason. + +## Regenerating gold (optional, rare — maintainer only) + +Gold ships **pre-baked** inside the fixture tarballs, so normal test runs never +need this. Regenerate only after an intentional, reviewed change to the +with-capture TraceDiff path. + +**Precondition — not runnable from a clean clone.** Regeneration needs the +original **full-capture** traces (the DECODE traces *and* their +`capture_traces/` folders). Those are large and are **not committed to the +repo** — only the slimmed DECODE-only traces ship in the fixtures. You must +already have the full-capture traces available locally (on the machine where +they were captured). The script's source paths default to +`tests/traces/semantic/...` and are set in the `SEM_ROOT` / `SOURCES` entries at +the top of the script; edit them to point at wherever you keep the traces. The +script fails with a clear "missing source" error if they aren't present. + +```bash +bash agent_evals/Analysis/partial_tests/generate_updated_semantic_gold.sh +``` + +It runs the with-capture perf-report / TraceDiff path on the DECODE pair, writes +the refreshed CSV into each `analysis_output_ref/`, and repacks the fixture +tarball. diff --git a/agent_evals/Analysis/eval_utils/semantic_partition_scripted_evals.py b/agent_evals/Analysis/partial_tests/eval_utils/semantic_partition_scripted_evals.py similarity index 77% rename from agent_evals/Analysis/eval_utils/semantic_partition_scripted_evals.py rename to agent_evals/Analysis/partial_tests/eval_utils/semantic_partition_scripted_evals.py index e4409b7c0..db5d47eb5 100644 --- a/agent_evals/Analysis/eval_utils/semantic_partition_scripted_evals.py +++ b/agent_evals/Analysis/partial_tests/eval_utils/semantic_partition_scripted_evals.py @@ -7,30 +7,29 @@ """Scripted eval: LCA-partition purity vs. a with-capture (gold) reference. Self-gating: only test cases whose reference_dir contains a -``semantic_purity_gold_diff_stats.csv`` (produced once by -``generate_semantic_gold_ref.sh``) are scored. All other comparative test -cases produce zero rows here, so this eval is a no-op for the existing -MI300-vs-H100 suite. +``semantic_purity_gold_diff_stats.csv`` (which ships pre-baked in each +partial-test fixture; regenerated only rarely by +``generate_updated_semantic_gold.sh``) are scored. Any other test case +produces zero rows here, so this eval is inert unless a gold reference is +present. For gated test cases, this reuses compare_lca_partitions.py's forward/reverse purity and strict forward/reverse consistency metrics, computed between the gold partition and the candidate's semantic-bucketing output -(``_semantic/tracediff_output/diff_stats.csv``), and records them. +(``tracediff_output/diff_stats.csv``, produced by the semantic-comparison +workflow through its "Generate TraceDiff Output" step), and records them. IMPORTANT: this per-run result is informational only. Because the semantic method has real run-to-run variance (observed on Qwen3-30B-A3B), a single run's metrics are not a reliable regression signal by themselves -- the actual pass/fail decision is made by semantic_purity_aggregate.py, which -averages strict_forward across NUM_REPEATS runs (intended: 3) and compares -against a floor derived from currently-observed performance. See that -script and the "Semantic-purity quality gate" section of README.md. +averages strict_forward across NUM_REPEATS runs and compares against a +floor derived from currently-observed performance. See that script and the +partial_tests/README.md "Semantic-purity quality gate" section. Consequently the "result" written here is PASS whenever the metrics were computed at all; it only turns FAIL for genuine pipeline errors (candidate -output missing, no matched keys). Do not read STABLE/FLAKY classification -of this eval's row (via aggregate_repeatability.py) as a quality signal -- -it is dropped from that role by design and only reflects whether the -per-run pipeline itself succeeded. +output missing, no matched keys). """ import argparse @@ -38,7 +37,12 @@ import os import sys -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +# compare_lca_partitions.py is the shared metric implementation; it stays in +# agent_evals/Analysis/eval_utils/ (also imported by tests/test_compare_lca_partitions.py). +# This eval now lives in partial_tests/eval_utils/, so reach two levels up. +_HERE = os.path.dirname(os.path.abspath(__file__)) +_ANALYSIS_EVAL_UTILS = os.path.abspath(os.path.join(_HERE, "..", "..", "eval_utils")) +sys.path.insert(0, _ANALYSIS_EVAL_UTILS) from compare_lca_partitions import LCA_COL, both_purities, both_strict, load # noqa: E402 CSV_COLUMNS = [ @@ -52,7 +56,7 @@ ] GOLD_FILENAME = "semantic_purity_gold_diff_stats.csv" -CANDIDATE_RELPATH = os.path.join("_semantic", "tracediff_output", "diff_stats.csv") +CANDIDATE_RELPATH = os.path.join("tracediff_output", "diff_stats.csv") def _write(results_path: str, rows: list[dict]) -> None: @@ -65,7 +69,7 @@ def _write(results_path: str, rows: list[dict]) -> None: def run(output_dir: str, reference_dir: str, results_path: str) -> list[dict]: gold_path = os.path.join(reference_dir, GOLD_FILENAME) if not os.path.isfile(gold_path): - # Not a semantic-purity test case; self-gate to a no-op. + # No gold reference here; self-gate to a no-op. _write(results_path, []) return [] @@ -79,7 +83,7 @@ def run(output_dir: str, reference_dir: str, results_path: str) -> list[dict]: "result": "FAIL", "details": f"Candidate semantic diff-stats not found: {candidate_path}", "root_cause": "pipeline", - "recommended_fix": "Analysis run did not produce a semantic-bucketing output; check the run log", + "recommended_fix": "Semantic workflow did not produce tracediff_output/diff_stats.csv; check the run log", } ] _write(results_path, rows) @@ -102,7 +106,7 @@ def run(output_dir: str, reference_dir: str, results_path: str) -> list[dict]: "result": "FAIL", "details": "No matched (source, gpu_op_uid) keys between gold and candidate", "root_cause": "data", - "recommended_fix": "Check that candidate and gold were generated from the same trace pair", + "recommended_fix": "Check that candidate and gold were generated from the same DECODE trace pair", } ] _write(results_path, rows) @@ -140,12 +144,6 @@ def main(): parser.add_argument("--output-dir", required=True) parser.add_argument("--reference-dir", required=True) parser.add_argument("--results", required=True) - parser.add_argument( - "--comparison-scope", - choices=["standalone", "comparative"], - default="comparative", - help="Only comparative mode is supported; accepted for CLI consistency with other evals", - ) args = parser.parse_args() rows = run(args.output_dir, args.reference_dir, args.results) diff --git a/agent_evals/Analysis/eval_utils/semantic_purity_aggregate.py b/agent_evals/Analysis/partial_tests/eval_utils/semantic_purity_aggregate.py similarity index 79% rename from agent_evals/Analysis/eval_utils/semantic_purity_aggregate.py rename to agent_evals/Analysis/partial_tests/eval_utils/semantic_purity_aggregate.py index 98d27f82e..37ec3d1b6 100644 --- a/agent_evals/Analysis/eval_utils/semantic_purity_aggregate.py +++ b/agent_evals/Analysis/partial_tests/eval_utils/semantic_purity_aggregate.py @@ -19,16 +19,15 @@ strict_forward is used as the sole gating metric -- it is more discriminating than forward_purity because it does not give partial credit to a majority-only match. - 2. Averages strict_forward across however many runs were found (intended: - NUM_REPEATS=3; a smaller N is honored but is a weaker estimate and is - flagged as such). + 2. Averages strict_forward across however many runs were found. 3. Compares that average against MIN_STRICT_FORWARD_AVG[test_id] -- a - floor derived directly from currently-observed performance (mean of - all independently-verified runs collected during method validation), - minus a 5% buffer, sanity-checked to stay far above the random-shuffle - baseline (Baseline 1 in compare_lca_partitions.py, ~0.04-0.06 for - both models). The intent is regression detection ("don't get worse - than today"), not an absolute quality bar. + floor set BELOW the worst single independently-observed run (with + margin), so that even a quick NUM_REPEATS=1 check does not + false-alarm on ordinary variance, while still sitting far above the + random-shuffle baseline (Baseline 1 in compare_lca_partitions.py, + ~0.04-0.06 strict_forward for both models). The intent is regression + detection ("don't get materially worse than today"), not an absolute + quality bar. Writes one verdict row (7-column eval schema) per test id to results_root//semantic_purity_aggregate_verdict.csv, and prints a @@ -55,20 +54,21 @@ "recommended_fix", ] -# Floor = mean(observed strict_forward across all independently-verified -# runs collected during method validation) * 0.95, rounded down slightly. -# Observed data (via compare_lca_partitions.py against the committed gold -# reference): -# deepseek_r1: 0.9748, 0.9748, 0.9780 -> mean 0.9759 -> floor 0.92 -# qwen3_30b_a3b: 0.5671, 0.4677, 0.7304, 0.5691, 0.5677 -# -> mean 0.5804 -> floor 0.55 -# Both floors sit far above the random-shuffle baseline (Baseline 1) of -# ~0.04-0.06 strict_forward for both models -- i.e. nowhere near "no better -# than chance". Revisit these floors if the method is intentionally -# improved (raise them) -- do not lower them without a documented reason. +# Floors are set below the worst single strict_forward run observed during +# decode-only method validation (with margin), NOT at the mean -- so a +# one-off NUM_REPEATS=1 quick check cannot false-alarm on ordinary +# variance. Averaging across repeats leaves even more headroom. +# +# Observed decode-only strict_forward (compare_lca_partitions.py vs the +# pre-baked gold): +# deepseek_r1: 0.7280, 0.9780, 0.9748, 0.9748, 0.9780 (worst 0.7280) +# qwen3_30b_a3b: 0.3710, 0.5671, 0.4677, 0.7304, 0.5691 (worst 0.3710) +# Both floors sit far above the random-shuffle baseline (~0.04-0.06). If the +# method is intentionally improved, raise these; do not lower them without a +# documented reason. MIN_STRICT_FORWARD_AVG = { - "semantic_purity_deepseek_r1": 0.92, - "semantic_purity_qwen3_30b_a3b": 0.55, + "semantic_purity_deepseek_r1": 0.60, + "semantic_purity_qwen3_30b_a3b": 0.30, } DETAILS_RE = re.compile(r"strict_forward=([0-9.]+)") @@ -110,7 +110,7 @@ def aggregate_one(results_root: str, test_id: str) -> dict: "result": "FAIL", "details": f"No usable runs found under {results_root}/{test_id}/run_*/semantic_purity_results.csv", "root_cause": "pipeline", - "recommended_fix": "Ensure Phase 1+2 completed for this test id before aggregating", + "recommended_fix": "Ensure the run(s) completed for this test id before aggregating", } values = [p["strict_forward"] for p in parsed] @@ -128,7 +128,7 @@ def aggregate_one(results_root: str, test_id: str) -> dict: } passed = avg >= floor - n_note = "" if len(parsed) >= 3 else f" (WARNING: only {len(parsed)} run(s) found; intended N=3, this is a weaker estimate)" + n_note = "" if len(parsed) > 1 else " (single run; a multi-run average is a stronger estimate)" details = ( f"n_runs={len(parsed)} strict_forward_values={[round(v, 4) for v in values]} " f"avg_strict_forward={avg:.4f} floor={floor}{n_note}" diff --git a/agent_evals/Analysis/partial_tests/fixtures/semantic_purity_deepseek_r1.tar.gz b/agent_evals/Analysis/partial_tests/fixtures/semantic_purity_deepseek_r1.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..69c88671f00070e4bf59301d4bb823be3fe45d69 GIT binary patch literal 144919 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

    }u+~$A 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 z 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

    _Z^XGbD=vH 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%0A{XrG{-%9X` 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 ". +SEM_ROOT="tests/traces/semantic" +declare -A SOURCES=( + [semantic_purity_deepseek_r1]="\ +$SEM_ROOT/deepseek_R1/Deepseek-R1-Distill-LLama-8B/MI300/torch_trace/1782841132.2905657-TP-0-DECODE.trace.json.gz \ +$SEM_ROOT/deepseek_R1/Deepseek-R1-Distill-LLama-8B/MI300/torch_trace/capture_traces \ +$SEM_ROOT/deepseek_R1/Deepseek-R1-Distill-LLama-8B/B300/torch_trace/1782843274.7730265-TP-0-DECODE.trace.json.gz \ +$SEM_ROOT/deepseek_R1/Deepseek-R1-Distill-LLama-8B/B300/torch_trace/capture_traces" + [semantic_purity_qwen3_30b_a3b]="\ +$SEM_ROOT/qwen3_30b_a3b/Qwen3-30B-A3B/MI300/torch_trace/1782859605.7198358-TP-0-DECODE.trace.json.gz \ +$SEM_ROOT/qwen3_30b_a3b/Qwen3-30B-A3B/MI300/torch_trace/capture_traces \ +$SEM_ROOT/qwen3_30b_a3b/Qwen3-30B-A3B/B300/torch_trace/1782799835.6885648-TP-0-DECODE.trace.json.gz \ +$SEM_ROOT/qwen3_30b_a3b/Qwen3-30B-A3B/B300/torch_trace/capture_traces" +) + +generate_one() { + local id="$1" + local spec="${SOURCES[$id]:-}" + if [[ -z "$spec" ]]; then + echo "ERROR: unknown test id '$id' (no source mapping)" >&2 + return 1 + fi + # shellcheck disable=SC2086 + set -- $spec + local decode_a="$REPO_ROOT/$1" cap_a="$REPO_ROOT/$2" decode_b="$REPO_ROOT/$3" cap_b="$REPO_ROOT/$4" + + for p in "$decode_a" "$cap_a" "$decode_b" "$cap_b" "$ARCH_JSON"; do + [[ -e "$p" ]] || { echo "ERROR [$id]: missing source $p" >&2; return 1; } + done + + local scratch="$PARTIAL_DIR/_gold_scratch_$id" + local out_csvs="$scratch/perf_report_trace1_csvs" + rm -rf "$scratch"; mkdir -p "$scratch" + + echo "[$id] running with-capture TraceDiff on the DECODE pair..." + # trace1 (MI300) with capture + comparison against trace2 (B300) with its + # capture triggers TraceDiff internally and writes diff_stats.csv into + # perf_report_trace1_csvs/. Only platform1's arch JSON is needed. + "$PERF_CLI" \ + --profile_json_path "$decode_a" --capture_folder "$cap_a" \ + --gpu_arch_json_path "$ARCH_JSON" \ + --group_by_parent_module --enable_pseudo_ops --group_by_num_kernels --include_call_stack \ + --comparison_json_path "$decode_b" --comparison_capture_folder "$cap_b" \ + --output_xlsx_path "$scratch/perf_report_trace1.xlsx" \ + --output_csvs_dir "$out_csvs" \ + || { echo "ERROR [$id]: perf-report CLI failed" >&2; return 1; } + + local gold_src="$out_csvs/diff_stats.csv" + [[ -f "$gold_src" ]] || { echo "ERROR [$id]: $gold_src not produced" >&2; return 1; } + + local ref_dir="$PARTIAL_DIR/$id/analysis_output_ref" + mkdir -p "$ref_dir" + cp "$gold_src" "$ref_dir/$GOLD_FILENAME" + echo "[$id] gold -> $ref_dir/$GOLD_FILENAME ($(wc -l < "$ref_dir/$GOLD_FILENAME") lines)" + + # Re-pack the fixture tarball so the refreshed gold ships with it. + tar czf "$PARTIAL_DIR/fixtures/${id}.tar.gz" -C "$REPO_ROOT" "agent_evals/Analysis/partial_tests/$id" + echo "[$id] fixture repacked -> fixtures/${id}.tar.gz" + rm -rf "$scratch" +} + +ids=("$@") +if [[ ${#ids[@]} -eq 0 ]]; then + ids=("${!SOURCES[@]}") +fi + +rc=0 +for id in "${ids[@]}"; do + generate_one "$id" || rc=1 +done +exit "$rc" diff --git a/agent_evals/Analysis/partial_tests/partial_test_cases.csv b/agent_evals/Analysis/partial_tests/partial_test_cases.csv new file mode 100644 index 000000000..a00b6bbee --- /dev/null +++ b/agent_evals/Analysis/partial_tests/partial_test_cases.csv @@ -0,0 +1,3 @@ +id,workflow,trace_a,trace_b,reference_dir,platform_a,platform_b +semantic_purity_deepseek_r1,semantic_comparison,agent_evals/Analysis/partial_tests/semantic_purity_deepseek_r1/MI300/1782841132.2905657-TP-0-DECODE.trace.json.gz,agent_evals/Analysis/partial_tests/semantic_purity_deepseek_r1/B300/1782843274.7730265-TP-0-DECODE.trace.json.gz,agent_evals/Analysis/partial_tests/semantic_purity_deepseek_r1/analysis_output_ref,MI300,B300 +semantic_purity_qwen3_30b_a3b,semantic_comparison,agent_evals/Analysis/partial_tests/semantic_purity_qwen3_30b_a3b/MI300/1782859605.7198358-TP-0-DECODE.trace.json.gz,agent_evals/Analysis/partial_tests/semantic_purity_qwen3_30b_a3b/B300/1782799835.6885648-TP-0-DECODE.trace.json.gz,agent_evals/Analysis/partial_tests/semantic_purity_qwen3_30b_a3b/analysis_output_ref,MI300,B300 diff --git a/agent_evals/Analysis/partial_tests/run_partial_tests.sh b/agent_evals/Analysis/partial_tests/run_partial_tests.sh new file mode 100755 index 000000000..60a33ecd5 --- /dev/null +++ b/agent_evals/Analysis/partial_tests/run_partial_tests.sh @@ -0,0 +1,191 @@ +#!/usr/bin/env bash +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +set -uo pipefail + +# --------------------------------------------------------------------------- +# Partial-workflow test runner. +# +# Unlike run_repeatability_parallel.sh (which runs the FULL 11-step analysis +# orchestrator per case), this harness runs only PART of a workflow -- just +# far enough to produce the artifact a scripted eval scores against a +# pre-baked reference. The first such test is semantic_purity, which runs the +# semantic-comparison workflow through its "Generate TraceDiff Output" step +# (== main orchestrator through Step 1.S) to produce +# /tracediff_output/diff_stats.csv +# and scores its LCA-partition purity against the committed gold. +# +# New partial-workflow tests can be added by giving them a distinct value in +# the `workflow` column of partial_test_cases.csv and a matching branch in +# run_single_job below. +# +# Usage: bash run_partial_tests.sh +# NUM_REPEATS repeats per case (default 1; raise for a variance study) +# TEST_IDS space-separated id whitelist (default: all) +# MAX_PARALLEL concurrent jobs (default 3) +# CONTAINER optional docker container to exec python in +# --------------------------------------------------------------------------- + +MAX_PARALLEL="${MAX_PARALLEL:-3}" +NUM_REPEATS="${NUM_REPEATS:-1}" +TEST_IDS="${TEST_IDS:-}" +CONTAINER="${CONTAINER:-}" +AGENT_MODEL="${AGENT_MODEL:-claude-opus-4-8-thinking-medium}" + +REPO_ROOT="${REPO_ROOT:-$(pwd)}" +ANALYSIS_DIR="$REPO_ROOT/TraceLens/Agent/Analysis" +EVALS_DIR="$REPO_ROOT/agent_evals/Analysis" +PARTIAL_DIR="$EVALS_DIR/partial_tests" +TEST_CASES_CSV="${TEST_CASES_CSV:-$PARTIAL_DIR/partial_test_cases.csv}" +RESULTS_ROOT="${RESULTS_ROOT:-$PARTIAL_DIR/partial_results}" + +if [[ -n "$CONTAINER" ]]; then + DEXEC=(docker exec -w "$REPO_ROOT" "$CONTAINER") +else + DEXEC=() +fi + +ts() { date "+%H:%M:%S"; } +log_status() { flock 1 echo "$@"; } + +# Expand a fixture tarball (paths inside are repo-relative) if not already present. +expand_fixture() { + local id="$1" + local archive="$PARTIAL_DIR/fixtures/${id}.tar.gz" + local target="$PARTIAL_DIR/$id" + if [[ -f "$archive" ]] && [[ ! -d "$target" ]]; then + echo "Expanding fixtures/${id}.tar.gz..." + tar xzf "$archive" -C "$REPO_ROOT" + fi +} + +# --------------------------------------------------------------------------- +# One (test_case, repeat) iteration. +# Args: id workflow repeat trace_a trace_b reference_dir platform_a platform_b +# --------------------------------------------------------------------------- +run_single_job() { + local id="$1" workflow="$2" repeat="$3" trace_a="$4" trace_b="$5" reference_dir="$6" platform_a="$7" platform_b="$8" + local tag="[$id|run_$repeat]" + + local CASE_RESULTS="$RESULTS_ROOT/$id/run_${repeat}" + local OUTPUT_DIR="$CASE_RESULTS/analysis_output" + rm -rf "$CASE_RESULTS" 2>/dev/null || true + mkdir -p "$OUTPUT_DIR" + + local abs_a="$REPO_ROOT/$trace_a" + local abs_b="$REPO_ROOT/$trace_b" + local abs_ref="$REPO_ROOT/$reference_dir" + + log_status " $tag [$(ts)] workflow=$workflow starting" + + case "$workflow" in + semantic_comparison) + local agent_success=false + local attempts=0 + while [ "$agent_success" = false ] && [ "$attempts" -lt 3 ]; do + attempts=$((attempts + 1)) + ( + cd "$ANALYSIS_DIR" || exit + timeout 1800 agent --model "$AGENT_MODEL" --print --force --trust --output-format stream-json \ + "Follow the semantic-comparison-agent workflow (TraceLens/Agent/Analysis/.cursor/agents/semantic-comparison-agent.md). Run it on trace A=$abs_a (platform $platform_a) and trace B=$abs_b (platform $platform_b), output to $OUTPUT_DIR. Run only through Step 3 'Generate TraceDiff Output' so that $OUTPUT_DIR/tracediff_output/diff_stats.csv is produced; do NOT run the full analysis orchestrator or any downstream report/category steps." + ) < /dev/null > "$CASE_RESULTS/semantic_stream.ndjson" 2>&1 + + if head -c 2048 "$CASE_RESULTS/semantic_stream.ndjson" | grep -qiE 'Error:.*unavailable|Service Unavailable'; then + log_status " $tag Attempt $attempts/3 failed (agent unavailable). Backing off 30s..." + sleep 30 + else + agent_success=true + fi + done + if [ "$agent_success" = false ]; then + log_status " $tag FAILED after 3 attempts (agent unavailable). Skipping eval." + return 1 + fi + + "${DEXEC[@]}" python3 "$PARTIAL_DIR/eval_utils/semantic_partition_scripted_evals.py" \ + --output-dir "$OUTPUT_DIR" --reference-dir "$abs_ref" \ + --results "$CASE_RESULTS/semantic_purity_results.csv" \ + > "$CASE_RESULTS/semantic_purity_eval.log" 2>&1 || true + ;; + *) + log_status " $tag ERROR: unknown workflow '$workflow'" + return 1 + ;; + esac + + log_status " $tag [$(ts)] done -> $CASE_RESULTS/semantic_purity_results.csv" +} + +# --------------------------------------------------------------------------- +# FIFO semaphore for concurrency control +# --------------------------------------------------------------------------- +FIFO="$RESULTS_ROOT/.job_fifo" +cleanup() { rm -f "$FIFO"; } +setup_semaphore() { + rm -f "$FIFO"; mkfifo "$FIFO"; exec 4<>"$FIFO" + for ((t = 0; t < MAX_PARALLEL; t++)); do echo >&4; done + trap cleanup EXIT +} + +# --------------------------------------------------------------------------- +# Main +# --------------------------------------------------------------------------- +mkdir -p "$RESULTS_ROOT" + +# Expand every fixture referenced by the manifest. +while IFS=, read -r id workflow trace_a trace_b reference_dir platform_a platform_b <&3; do + [[ -z "$id" ]] && continue + expand_fixture "$id" +done 3< <(tail -n +2 "$TEST_CASES_CSV"; echo) + +echo "=========================================" +echo " Partial-workflow tests" +echo " Repeats: $NUM_REPEATS" +echo " Max parallel: $MAX_PARALLEL" +echo " CSV: $TEST_CASES_CSV" +if [[ -n "$TEST_IDS" ]]; then echo " Test filter: $TEST_IDS"; fi +echo "=========================================" +echo "" + +_spawn_jobs() { + local id="$1" workflow="$2" trace_a="$3" trace_b="$4" reference_dir="$5" platform_a="$6" platform_b="$7" + if [[ -n "$TEST_IDS" ]]; then + case " $TEST_IDS " in + *" $id "*) ;; + *) return ;; + esac + fi + for ((i = 0; i < NUM_REPEATS; i++)); do + read -r -u4 + ( + run_single_job "$id" "$workflow" "$i" "$trace_a" "$trace_b" "$reference_dir" "$platform_a" "$platform_b" || true + echo >&4 + sleep 2 # stagger agent startup to avoid ~/.cursor/cli-config.json rename race + ) & + sleep 2 + done +} + +setup_semaphore + +# manifest: id,workflow,trace_a,trace_b,reference_dir,platform_a,platform_b +while IFS=, read -r id workflow trace_a trace_b reference_dir platform_a platform_b <&3; do + [[ -z "$id" ]] && continue + _spawn_jobs "$id" "$workflow" "$trace_a" "$trace_b" "$reference_dir" "$platform_a" "$platform_b" +done 3< <(tail -n +2 "$TEST_CASES_CSV"; echo) + +wait + +echo "" +echo "=========================================" +echo " Runs finished. Applying regression gate..." +echo "=========================================" +"${DEXEC[@]}" python3 "$PARTIAL_DIR/eval_utils/semantic_purity_aggregate.py" \ + --results-root "$RESULTS_ROOT" || true + +echo "" +echo " Results in: $RESULTS_ROOT" From f71bf5ebbab4e8efb96e628efeff112d7f831f26 Mon Sep 17 00:00:00 2001 From: Arseny Date: Wed, 26 Aug 2026 21:34:25 -0700 Subject: [PATCH 33/50] PR fixes (removing prompt duplication) --- .../semantic_analyses/kernel_unification.py | 17 ----------------- .../agents/kernel-unification-agent.md | 3 ++- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py index 948622ef2..3b816a9ab 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py @@ -148,22 +148,6 @@ def _entry_list(agg, keys): return [e for name, e in agg.items() if name in keyset] -UNIFICATION_RULES = [ - "Map ONLY names you are confident are the same operation across traces.", - "Names already identical in both traces are unified by default -- do NOT " - "add map entries for them.", - "Prefer preserving granularity: do not merge two functionally distinct " - "kernels just because names look similar.", - "This pass establishes clear anchors, not a full resolution of every " - "ambiguity; leave uncertain names unmapped (they fall back to their raw " - "name / stem).", - "Values are short shared unified names; use the SAME value on both sides " - "for a matched pair.", - "Keys must be exact names (or stems, when stem preprocessing was applied) " - "taken verbatim from the context lists.", -] - - def _build_context(agg_a, agg_b, name_a, name_b, level, extra=None): """Assemble the unification-context dict from two aggregations.""" set_a = set(agg_a) @@ -184,7 +168,6 @@ def _build_context(agg_a, agg_b, name_a, name_b, level, extra=None): f"only_in_{name_a}": len(only_a), f"only_in_{name_b}": len(only_b), } - ctx["rules"] = UNIFICATION_RULES ctx[f"only_in_{name_a}"] = _entry_list(agg_a, only_a) ctx[f"only_in_{name_b}"] = _entry_list(agg_b, only_b) ctx["in_both"] = in_both diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md index 4b42b2280..b47b679bf 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md @@ -63,7 +63,8 @@ in `only_in_` when you are **certain** they are the same operation. unsure, leave both names unmapped -- they fall back to their raw name / stem and simply remain unmatched. This pass builds anchors, not a full resolution. -2. **Skip identical names.** Anything in `in_both` is already unified. No entry. +2. **Skip identical names.** Anything in `in_both` is already unified. Do NOT + add map entries for them. 3. **Preserve granularity.** Do not merge two functionally distinct kernels because their names look similar. Do not collapse a family that a later analysis stage may want to keep separate (e.g. distinct attention variants). From 093bb6b3842cc670f05209058b20d2eea8400225 Mon Sep 17 00:00:00 2001 From: Arseny Date: Wed, 26 Aug 2026 22:40:50 -0700 Subject: [PATCH 34/50] Debloat partial --- .../Analysis/semantic_analyses/_helpers.py | 11 ++++- .../semantic_analyses/extract_trace_data.py | 49 +++++-------------- .../semantic_analyses/extract_tree_context.py | 11 ++--- .../semantic_analyses/kernel_unification.py | 7 ++- .../semantic_analyses/match_and_compare.py | 5 +- .../semantic_analyses/trace_split_adapter.py | 31 ++---------- .../agents/semantic-comparison-agent.md | 37 +++----------- 7 files changed, 46 insertions(+), 105 deletions(-) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/_helpers.py b/TraceLens/Agent/Analysis/semantic_analyses/_helpers.py index 09d1fb028..ec44863bd 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/_helpers.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/_helpers.py @@ -11,6 +11,7 @@ and trace_comparison/_helpers.py (load_labels). """ +import gzip import json @@ -67,7 +68,13 @@ def detect_period(rle_groups): return n +def load_json(path): + """Load a JSON file, transparently decompressing .gz input.""" + opener = gzip.open if path.endswith(".gz") else open + with opener(path, "rt") as f: + return json.load(f) + + def load_labels(path): """Load a semantic_labels.json file.""" - with open(path) as f: - return json.load(f) + return load_json(path) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py index 8b190a981..c2e5e98ca 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py @@ -21,7 +21,6 @@ """ import argparse -import gzip import json import logging import os @@ -30,11 +29,9 @@ from trace_split_adapter import split_vllm_trace, get_steady_state_key from annotation_metadata import gather_metadata +from _helpers import load_json -try: - from TraceLens import GPUEventAnalyser -except ImportError: - GPUEventAnalyser = None +from TraceLens import GPUEventAnalyser logger = logging.getLogger(__name__) @@ -44,9 +41,7 @@ def load_trace(path_or_data): if isinstance(path_or_data, dict): data = path_or_data else: - opener = gzip.open if path_or_data.endswith(".gz") else open - with opener(path_or_data, "rt") as f: - data = json.load(f) + data = load_json(path_or_data) events = data.get("traceEvents", []) by_cat = {} for e in events: @@ -182,10 +177,8 @@ def run_assertions(data, by_cat, kernels, is_graph_mode, strict=True): def compute_gpu_timeline_metrics(events): """ Run GPUEventAnalyser on events and return gpu_timeline dict for metadata. - Returns None if GPUEventAnalyser unavailable or fails. + Returns None on failure. """ - if GPUEventAnalyser is None: - return None try: # Ensure events have UID (required by GPUEventAnalyser for overlap computation) for i, e in enumerate(events): @@ -199,14 +192,14 @@ def compute_gpu_timeline_metrics(events): if total <= 0: return None return { - "busy_time_us": round(metrics.get("busy_time", 0), 2), - "idle_time_us": round(metrics.get("idle_time", 0), 2), - "total_time_us": round(total, 2), - "computation_time_us": round(metrics.get("computation_time", 0), 2), - "exposed_comm_time_us": round(metrics.get("exposed_comm_time", 0), 2), - "exposed_memcpy_time_us": round(metrics.get("exposed_memcpy_time", 0), 2), - "idle_pct": round(100 * idle / total, 1), - "busy_pct": round(100 * busy / total, 1), + "busy_time_us": metrics.get("busy_time", 0), + "idle_time_us": metrics.get("idle_time", 0), + "total_time_us": total, + "computation_time_us": metrics.get("computation_time", 0), + "exposed_comm_time_us": metrics.get("exposed_comm_time", 0), + "exposed_memcpy_time_us": metrics.get("exposed_memcpy_time", 0), + "idle_pct": 100 * idle / total, + "busy_pct": 100 * busy / total, } except Exception as e: logger.warning("GPUEventAnalyser failed: %s", e) @@ -238,22 +231,6 @@ def extract_and_build_result(data, by_cat, source_file, region_metadata=None): return result, kernels -def _resolve_output_dir(output_arg): - """Resolve -o to a directory path, handling the .json suffix case. - - When auto-split detects regions, -o is treated as a directory. If the - caller passed something like ``$DIR/extracted.json`` (intending a file), - strip the trailing ``.json`` component and use the parent directory so - that region subdirs land in ``$DIR/`` rather than inside a rogue - ``extracted.json/`` directory. - """ - if not output_arg: - return "." - if output_arg.endswith(".json") or output_arg.endswith(".json.gz"): - return os.path.dirname(output_arg) or "." - return output_arg - - def _write_split_regions(split_result, trace_path, output_dir): """Write per-region extracted.json + metadata.json files.""" os.makedirs(output_dir, exist_ok=True) @@ -323,7 +300,7 @@ def main(): if not args.no_split: split_result = split_vllm_trace(args.trace) if split_result: - output_dir = _resolve_output_dir(args.output) + output_dir = args.output or "." _write_split_regions(split_result, args.trace, output_dir) return diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py index 389ecb872..b064549fe 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py @@ -35,9 +35,13 @@ _repo_root = os.path.abspath(os.path.join(_this_dir, "..", "..", "..", "..")) if _repo_root not in sys.path: sys.path.insert(0, _repo_root) +if _this_dir not in sys.path: + sys.path.insert(0, _this_dir) from TraceLens.util import DataLoader from TraceLens.Trace2Tree.trace_to_tree import TraceToTree +from TraceLens.Trace2Tree.trace_capture_merge import merge_capture_trace_into_graph +from _helpers import load_json def load_and_build_tree(trace_path, capture_trace_path=None): @@ -49,10 +53,6 @@ def load_and_build_tree(trace_path, capture_trace_path=None): graph-mode traces. """ if capture_trace_path: - from TraceLens.Trace2Tree.trace_capture_merge import ( - merge_capture_trace_into_graph, - ) - print( f"Merging capture trace {capture_trace_path} into {trace_path}...", file=sys.stderr, @@ -290,8 +290,7 @@ def main(): f"Wrote tree_context.json to {len(regions)} region subdirs", file=sys.stderr ) else: - with open(args.extracted_json) as f: - extracted = json.load(f) + extracted = load_json(args.extracted_json) print( f"Matching {len(extracted['kernels'])} kernels to tree events...", diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py index 3b816a9ab..0844d6268 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py @@ -65,10 +65,14 @@ import argparse import json +import os import re import sys from collections import OrderedDict +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from _helpers import load_json + DEFAULT_THRESHOLD = 5000 DEFAULT_SAMPLE_SIZE = 300 @@ -80,8 +84,7 @@ def _load(path): - with open(path) as f: - return json.load(f) + return load_json(path) def _dims_repr(dims, limit=160): diff --git a/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py b/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py index b648ff287..f7b51c231 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py @@ -35,7 +35,7 @@ from collections import OrderedDict sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from _helpers import load_labels +from _helpers import load_labels, load_json @@ -67,8 +67,7 @@ def load_metadata(path): if not path or not os.path.exists(path): return None try: - with open(path) as f: - meta = json.load(f) + meta = load_json(path) return meta.get("gpu_timeline") except (json.JSONDecodeError, OSError): return None diff --git a/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py b/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py index 9c7d9b86a..6a370ba14 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py @@ -19,7 +19,6 @@ key = get_steady_state_key(metadata) """ -import gzip import json import os import subprocess @@ -27,6 +26,9 @@ import tempfile from typing import List, Optional, Tuple +sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) +from _helpers import load_json + def get_steady_state_key(metadata: dict) -> str: """Return a key for grouping by steady-state region. @@ -49,18 +51,6 @@ def get_steady_state_key(metadata: dict) -> str: return f"prefill_decode_{batch}_{batch}" -def _get_tracelens_root() -> str: - """Resolve TraceLens package root (tracelens_private/ or repo root).""" - # trace_split_adapter.py is at TraceLens/AgenticMode/SemanticComparison/trace_breakdown/ - this_file = os.path.abspath(__file__) - trace_breakdown = os.path.dirname(this_file) - semantic = os.path.dirname(trace_breakdown) - agentic = os.path.dirname(semantic) - tracelens_pkg = os.path.dirname(agentic) - root = os.path.dirname(tracelens_pkg) - return root - - def _phase_to_region_meta(phase: dict) -> dict: """Map TraceUtils phase dict to region_meta expected by extract_trace_data.""" num_prefill = phase.get("num_prefill", 0) @@ -102,11 +92,7 @@ def _phase_to_region_meta(phase: dict) -> dict: def _load_trace(path: str) -> dict: """Load trace JSON from .json or .json.gz file.""" - if path.endswith(".gz"): - with gzip.open(path, "rt") as f: - return json.load(f) - with open(path, "r") as f: - return json.load(f) + return load_json(path) def _is_single_iteration(phase: dict) -> bool: @@ -146,13 +132,6 @@ def split_vllm_trace(trace_path: str) -> Optional[List[Tuple[dict, dict]]]: Returns None if no annotation iterations are found (caller should fall back to full trace). """ - root = _get_tracelens_root() - env = os.environ.copy() - if "PYTHONPATH" in env: - env["PYTHONPATH"] = root + os.pathsep + env["PYTHONPATH"] - else: - env["PYTHONPATH"] = root - with tempfile.TemporaryDirectory(prefix="trace_split_") as tmpdir: cmd = [ sys.executable, @@ -168,8 +147,6 @@ def split_vllm_trace(trace_path: str) -> Optional[List[Tuple[dict, dict]]]: ] result = subprocess.run( cmd, - cwd=root, - env=env, capture_output=True, text=True, ) diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md index 088861a75..eff22dc29 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md @@ -60,26 +60,19 @@ Ask the user for: `*_graph*` and `*_capture*` files. **vLLM / annotated traces** are auto-detected by `extract_trace_data.py`. -No special flag is needed -- the script probes for annotation iterations -and splits into per-region subdirectories automatically. +No special flag is needed. --- ## Step 1: Semantic Breakdown (Deterministic, PARALLEL) Breakdown is fully deterministic -- no LLM calls. Run both traces as -**parallel shell commands** (NOT Task subagents) so the orchestrator -blocks until both finish. +parallel shell commands. ### 1.1 Per-trace Pipeline Run the full breakdown for **both traces in a single shell call** using -background jobs + `wait`. The extraction step auto-detects vLLM -annotation regions; no special flag is needed. For vLLM traces the -output directory will contain per-region subdirs; the remaining steps -(`extract_tree_context.py`, `pattern_finder.py`, `classify_kernels.py`, -`build_semantic_labels.py`) support `--regions-dir` / per-region paths -and must be run for **every** region. +background jobs + `wait`. ```bash SCRIPTS=TraceLens/Agent/Analysis/semantic_analyses @@ -151,12 +144,7 @@ and stop. ## Step 2: Kernel-Name Unification (Name-First, LLM) -Replaces the old block-alignment harmonization. Instead of aligning blocks -via CPU-op / nn_module context (absent in graph mode), the LLM unifies raw -**kernel names** across the two traces. The unified name is written into each -kernel's `semantic_block` field, which Steps 3-4 use as the matching key. -Kernel names already identical in both traces unify by default (no map entry -needed); the LLM only maps names that differ but denote the same operation. +The LLM unifies raw **kernel names** across the two traces. The unified name is written into each kernel's `semantic_block` field. Kernel names already identical in both traces unify by default (no map entry needed); the LLM only maps names that differ but denote the same operation Scripts: `TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py` @@ -179,10 +167,7 @@ The context lists each trace's unique kernel names with `perf_categories`, If Step 2.1 prints `STEM PREPROCESSING NEEDED` (combined unique names exceed the threshold, default 5000), the raw name set is too large for the LLM. -Follow `TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md`: -the LLM inspects the emitted `sample`, authors `stem_rules.json` (custom -regexes that collapse high-cardinality families to stems, preserve families -whose parameters matter for later analysis, drop noise), then: +Launch the subagent `TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md`, then: ```bash python $KU apply-stem-rules \ @@ -194,18 +179,12 @@ python $KU apply-stem-rules \ -o /_work/kernel_unification_context.json ``` -Re-run until the printed stem count is within budget. This rewrites -`kernel_unification_context.json` at the stem level and emits -`raw_to_stem.json` (needed by 2.4). **Skip this step entirely when not flagged.** +Re-run until the printed stem count is within budget. -### 2.3 Launch Kernel Unification Agent [LLM] +### 2.3 Launch Kernel Unification Agent Read `TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md` and -launch it with `kernel_unification_context.json` inline. It writes -`/_work/kernel_unification_map.json` (`map_a` / `map_b`), mapping -only names it is certain are equivalent, using the same unified value on both -sides for a matched pair. For multi-region vLLM: run once per matching region -pair. +launch it with `kernel_unification_context.json` inline. For multi-region vLLM: run once per matching region pair. ### 2.4 Apply the Map [S] From c9b3f371fb650791177aa44da418087c7f625d68 Mon Sep 17 00:00:00 2001 From: Arseny Date: Wed, 26 Aug 2026 23:23:59 -0700 Subject: [PATCH 35/50] More debloat --- .../agents/semantic-comparison-agent.md | 58 +++++++------------ .../skills/analysis-orchestrator/reference.md | 20 +++---- .../templates/analysis_template.md | 2 +- 3 files changed, 30 insertions(+), 50 deletions(-) diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md index eff22dc29..2e33596cb 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md @@ -201,19 +201,16 @@ python $KU apply-map \ Check that `kernel_unification_context.json` and `kernel_unification_map.json` exist in `/_work/`, and that `apply-map` reported a non-empty -shared vocabulary. Every kernel now carries a `semantic_block` set to its -unified kernel name. +shared vocabulary. ### 2.6 Coherence Pass (second pass, LLM) The first pass leaves **one-sided** buckets -- kernels whose unified name -appears in only one trace (most importantly vendor GEMM families: MI300 -`Cijk_*` vs B300 `nvjet_*`, which cannot be paired by name). This pass uses -the first-pass **shared** buckets as cross-trace positional anchors and -re-labels one-sided buckets by their shared-neighbor context, which (a) pairs -GEMMs across vendors by position and (b) splits a name that occurs in different -contexts. Skip it only if `apply-map` already reported no meaningful one-sided -buckets. +appears in only one trace (e.g. vendor GEMM families that use different +naming conventions per platform). This pass uses the first-pass **shared** +buckets as cross-trace positional anchors and re-labels one-sided buckets +by their shared-neighbor context. Skip it only if `apply-map` already +reported no meaningful one-sided buckets. **2.6a Prepare coherence context [S]** ```bash @@ -244,9 +241,8 @@ python $KC apply \ `apply` rewrites `semantic_block` in place and prints any residual one-sided condensed symbols. If meaningful (non-singleton) symbols remain, revise the -decisions and re-run 2.6b--2.6c; residual pre/post-layer singletons (setup / -copy / prefix-scan kernels with no counterpart) may be accepted. Increase -`--neighbor-radius` in 2.6a if one-sided buckets share an ambiguous context. +decisions and re-run 2.6b--2.6c, or increase `--neighbor-radius` in 2.6a; +residual singletons with no counterpart may be accepted. --- @@ -269,16 +265,12 @@ Produces in `/tracediff_output/`: This is a **final deliverable** directory for downstream TraceDiff consumers. **Perf-report enrichment compatibility:** `diff_stats.csv` carries a -per-kernel `gpu_op_uid` (the TraceTree UID, identical to the perf report's -`kernel_details[].gpu_op_uid`) and a per-LCA `busy_time`. This makes it +per-kernel `gpu_op_uid` (identical to the perf report's +`kernel_details[].gpu_op_uid`) and a per-LCA `busy_time`, making it consumable by `enrich_perf_report_dict_inplace` in `TraceLens/Reporting/tracediff_comparison_extension.py`, which matches diff rows to `unified_perf_summary` rows via `gpu_op_uid` and adds the -speedup / delta / LCA columns. The enrichment is invoked at the -orchestrator layer (passing the semantic `diff_stats` plus the trace-1 -`df_unified_perf`); `generate_perf_report_pytorch.py` is unchanged and -retains its own in-memory TraceDiff path for the `--comparison_json_path` -flow. +speedup / delta / LCA columns. --- @@ -306,15 +298,9 @@ python TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ ## Key Principles -1. **Seamless flow** -- user provides two trace paths, orchestrator handles - everything -2. **Parallel breakdown** -- both traces processed as parallel shell jobs -3. **Name-first unification** -- kernel names are unified across traces to - establish matching anchors; identical names unify by default -4. **Conservative anchors** -- map only certain equivalences; preserve +1. **Conservative anchors** -- map only certain equivalences; preserve granularity and leave uncertain names unmapped -5. **Vendor-agnostic language** -- generic terms for all recommendations -6. **No script creation** -- subagents use only existing scripts (the stem +2. **No script creation** -- subagents use only existing scripts (the stem preprocessing authors regex *rules*, not new scripts) --- @@ -324,16 +310,16 @@ python TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ ``` / _work/ - /semantic_labels.json # Per-trace labels (semantic_block = unified kernel name) + /semantic_labels.json /semantic_labels.json - kernel_unification_context.json # Pass 1 LLM input: unique kernel names + stats - kernel_unification_map.json # Pass 1 LLM output: cross-trace name map - raw_to_stem.json # Only when stem preprocessing ran - kernel_coherence_context.json # Pass 2 LLM input: one-sided buckets + neighbor context - kernel_coherence_decisions.json # Pass 2 LLM output: context_renames + fallbacks - per_kernel_final_.csv # Pass 2 audit: first_pass -> final block per kernel - comparison.csv # Cross-trace comparison - tracediff_output/ # TraceDiff-compatible output + kernel_unification_context.json + kernel_unification_map.json + raw_to_stem.json + kernel_coherence_context.json + kernel_coherence_decisions.json + per_kernel_final_.csv + comparison.csv + tracediff_output/ diff_stats.csv diff_stats_unique_args_summary.csv cpu_op_map.json diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md index a0fb49ccf..a40ababdd 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md @@ -164,9 +164,9 @@ Do NOT proceed to Step 1 until validation passes. ## Step 0.5: Comparison Method Detection (comparative only) -For `standalone`, skip this step — `` is unused. +For `standalone`, skip this step. -For `comparative`, auto-detect the comparison path (structural **TraceDiff** vs **semantic**). Pass `--capture{1,2}-available` for any trace that had a capture folder collected, so a graph-mode trace with capture is not needlessly routed to semantic: +For `comparative`, auto-detect the comparison path (structural **TraceDiff** vs **semantic**). Pass `--capture{1,2}-available` for any trace that had a capture folder collected: ```bash python3 TraceLens/Agent/Analysis/utils/comparison_routing.py \ @@ -175,7 +175,7 @@ For `comparative`, auto-detect the comparison path (structural **TraceDiff** vs [--capture1-available] [--capture2-available] ``` -Set `` to the printed `method` field and echo `reasons`. The script routes to `semantic` only when the frameworks differ or a trace is graph-mode with no capture available; otherwise `tracediff`. +Set `` to the printed `method` field and echo `reasons`. If `method` is `semantic` and a graph-mode trace is involved but capture folders were not collected in Step 0, ask for them now: `` (trace1) and `` (trace2). @@ -212,8 +212,6 @@ All commands below append `` and ``, resolved by `` provided | `--comparison_json_path --comparison_capture_folder ` | | `comparative` trace2 | none | -> **Semantic comparison method** (`` = `semantic`, decided in Step 0.5): the `` values above are the `tracediff` path. For the semantic method, trace1's report instead consumes a precomputed diff via `--precomputed_diff_stats_csv /_semantic/tracediff_output/diff_stats.csv` — see **Step 1.S** for the required ordering. - **``** — graph capture flags: | scope | value | @@ -276,13 +274,11 @@ All commands below append `` and ``, resolved by ` ``` -(For comparative graph mode, the trace2 report uses `--capture_folder `.) - --- ## Step 1.S: Semantic Comparative Ordering (`` = `semantic` only) -When `` = `comparative` and `` = `semantic`, run Step 1 in this order so the trace1 report can consume the semantic diff: +When `` = `comparative` and `` = `semantic`, run Step 1 in this order: 1. **Trace2 report** — run the analysis-mode CLI above for trace2 using the `comparative` trace2 `` and empty `` (identical to the TraceDiff path). For graph mode add `--capture_folder `. @@ -306,12 +302,10 @@ Run the full semantic comparison through "Generate TraceDiff Output" so that Verify `/_semantic/tracediff_output/diff_stats.csv` exists before continuing. If it is missing, retry the subagent once; if it still fails, stop and report. -3. **Trace1 report** — run the analysis-mode CLI for trace1 with the `comparative` trace1 `` and `` = `--precomputed_diff_stats_csv /_semantic/tracediff_output/diff_stats.csv`. For graph mode also add `--capture_folder `. This produces the enriched `unified_perf_summary` and the `diff_stats` sheet in `perf_report_trace1_csvs` (same enrichment as the tracediff path). +3. **Trace1 report** — run the analysis-mode CLI for trace1 with the `comparative` trace1 `` and `` = `--precomputed_diff_stats_csv /_semantic/tracediff_output/diff_stats.csv`. For graph mode also add `--capture_folder `. 4. **Confirm** `/perf_report_trace1_csvs/diff_stats.csv` exists (written by the report script). If absent, copy `/_semantic/tracediff_output/diff_stats.csv` to that path so the comparative fusion step (Steps 2-5) can read it. -After Step 1.S, proceed to Steps 2-5 unchanged. - --- ## Steps 2-5: Prepare Category Data @@ -707,6 +701,6 @@ If the plot is skipped, the `{{PERF_PLOT}}` placeholder is removed so the report If Steps 1 or many of Steps 2-5 fail or produce unexpected results, check whether the trace uses the following features before retrying: - **GPU Graph Replay**: raw trace JSON contains `hipGraphLaunch` or `cudaGraphLaunch`. - - **Comparative scope** (`` = `comparative`): graph replay is **supported — do not abort**. Step 0.5 routes on capture availability: graph traces **with** capture folders use the direct capture-folder comparison path (tracediff + `--comparison_capture_folder`); graph traces **without** capture use the **semantic** comparison path (follow Step 1.S). Ensure capture folders were collected for both traces when available. + - **Comparative scope**: graph replay is **supported**; routing (tracediff+capture vs semantic) was already decided in Step 0.5. Ensure capture folders were collected for both traces when available. - **Default mode, standalone** (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, standalone** (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. + - **Inference mode, standalone**: graph launches are expected and supported; continue whether or not a capture folder was provided (eager mode has none). diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/templates/analysis_template.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/templates/analysis_template.md index a6a59aaf1..fb962e0ea 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/templates/analysis_template.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/templates/analysis_template.md @@ -146,7 +146,7 @@ One row per entry in `priority_data.json::priorities[]`, in array order (no mani `Trace 2 Time (ms)` = matching `manifest.trace2_ops_summary_by_category[]["total_direct_kernel_time_ms"]` where `"op category"` matches the row Category **case-insensitively**; use — if no match. This field is the semantic-aligned trace2 total (trace2 kernel time rolled up to trace1 categories via the LCA alignment), so it is consistent with the Detailed Analysis cards' per-op Trace 2 times. (`manifest.trace2_ops_summary_by_category_raw` holds the legacy per-framework breakdown for reference only — do NOT use it here.) `Difference (ms)` = Trace 2 Time − Trace 1 Time. -Note: `% of Compute Time` is Trace 1 kernel time / Trace 1 compute-only time; for communication categories (e.g. collectives) this can exceed 100% because the kernel time is not compute-bound — report the value as computed. +Note: for communication categories (e.g. collectives), `% of Compute Time` can exceed 100% because the kernel time is not compute-bound — report the value as computed. | Rank | Category | Trace 1 Time (ms) | Trace 2 Time (ms) | % of Compute Time | Ops | Difference (ms) | |------|----------|-------------------|-------------------|-------------------|-----|-----------------| From de9d01bc46267afc040d882f38c7db576eb37792 Mon Sep 17 00:00:00 2001 From: Arseny Date: Thu, 27 Aug 2026 02:03:48 -0700 Subject: [PATCH 36/50] Vendor anonymization, tested to retain performance. --- .../semantic_analyses/extract_tree_context.py | 2 +- .../agents/kernel-unification-agent.md | 10 ++++++++-- .../agents/semantic-comparison-agent.md | 18 +++++++++++------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py index b064549fe..62bcfc8a2 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py @@ -40,7 +40,7 @@ from TraceLens.util import DataLoader from TraceLens.Trace2Tree.trace_to_tree import TraceToTree -from TraceLens.Trace2Tree.trace_capture_merge import merge_capture_trace_into_graph +from TraceLens.Trace2Tree.trace_capture_merge_experimental import merge_capture_trace_into_graph from _helpers import load_json diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md index b47b679bf..52c393f04 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md @@ -86,15 +86,21 @@ Write to the output directory. Exact shape: "name_b": "B300", "map_a": { "moe_attn_vllm": "moe_attn", - "Cijk_Alik_Bljk_..._MT32x16x512_...": "expert_gemm" + "(vendor1_gemm_name)_(shape1)": "expert_gemm" }, "map_b": { "sglang_moe_attention": "moe_attn", - "nvjet_sm103_tst_128x16_...": "expert_gemm" + "(vendor2_gemm_name)_(shape1)": "expert_gemm" } } ``` +Using the same `(shape1)` on both sides shows *why* this pairs: two vendors' +differently-mangled names for the same GEMM tile shape/role -- not license to +collapse every GEMM in a trace into one bucket; kernels with distinct shapes +or otherwise clearly serving distinct per-layer roles should stay separate +keys. + - `map_a` keys are `name_a` names; `map_b` keys are `name_b` names. - A pair is unified when a `map_a` value equals a `map_b` value. - A one-sided rename (a name you want to relabel but that has no counterpart) diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md index 2e33596cb..ddce88cc6 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md @@ -206,11 +206,14 @@ shared vocabulary. ### 2.6 Coherence Pass (second pass, LLM) The first pass leaves **one-sided** buckets -- kernels whose unified name -appears in only one trace (e.g. vendor GEMM families that use different -naming conventions per platform). This pass uses the first-pass **shared** -buckets as cross-trace positional anchors and re-labels one-sided buckets -by their shared-neighbor context. Skip it only if `apply-map` already -reported no meaningful one-sided buckets. +appears in only one trace (most importantly vendor GEMM families: e.g. +`(vendor1_gemm_name)_*` on one platform vs `(vendor2_gemm_name)_*` on the +other, which cannot be paired by name). This pass uses +the first-pass **shared** buckets as cross-trace positional anchors and +re-labels one-sided buckets by their shared-neighbor context, which (a) +pairs GEMMs across vendors by position and (b) splits a name that occurs in +different contexts. Skip it only if `apply-map` already reported no +meaningful one-sided buckets. **2.6a Prepare coherence context [S]** ```bash @@ -241,8 +244,9 @@ python $KC apply \ `apply` rewrites `semantic_block` in place and prints any residual one-sided condensed symbols. If meaningful (non-singleton) symbols remain, revise the -decisions and re-run 2.6b--2.6c, or increase `--neighbor-radius` in 2.6a; -residual singletons with no counterpart may be accepted. +decisions and re-run 2.6b--2.6c; residual pre/post-layer singletons (setup / +copy / prefix-scan kernels with no counterpart) may be accepted. Increase +`--neighbor-radius` in 2.6a if one-sided buckets share an ambiguous context. --- From 17276f5c4bd119d8c2dcd1539ab3bd83c9fb1822 Mon Sep 17 00:00:00 2001 From: Arseny Date: Mon, 31 Aug 2026 19:50:11 -0700 Subject: [PATCH 37/50] Reduction in the number of changes and cleanup --- .../build_semantic_labels.py | 7 +- .../semantic_analyses/extract_trace_data.py | 25 +++- .../semantic_analyses/trace_split_adapter.py | 1 + .../agents/semantic-comparison-agent.md | 44 ++++-- .../templates/analysis_template.md | 4 +- .../Analysis/utils/orchestrator_prepare.py | 48 +------ .../Reporting/generate_perf_report_pytorch.py | 14 -- .../generate_perf_report_pytorch_inference.py | 14 -- .../tracediff_comparison_extension.py | 129 +----------------- .../split_inference_trace_annotation.py | 16 +++ 10 files changed, 91 insertions(+), 211 deletions(-) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py index 717164b1e..0bcaf4418 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py @@ -149,11 +149,16 @@ def build_labels(extracted, classified, pattern, tree_context=None): c = cls_by_idx.get(i, {}) tc = tree_by_idx.get(i, {}) + tree_uid = tc.get("gpu_op_uid") entry = { "index": i, "name": k["name"], "dur": k["dur"], - "gpu_op_uid": tc.get("gpu_op_uid"), + # Prefer the tree-built UID when tree-context ran (e.g. + # capture-augmented); fall back to the raw-index UID + # extract_trace_data.py already stamps on single-trace kernels + # when tree-context was skipped entirely (no-capture graph mode). + "gpu_op_uid": tree_uid if tree_uid is not None else k.get("gpu_op_uid"), "perf_category": c.get("perf_category", "Others"), "nn_module": _deepest_module(tc.get("nn_module_stack", [])), "cpu_op": tc.get("cpu_op_name", ""), diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py index c2e5e98ca..af97d8bae 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py @@ -9,7 +9,7 @@ Step 1+3: Load a Chrome trace JSON and extract structured data. Outputs a JSON with: - - ordered kernel list (name, duration, timestamp) + - ordered kernel list (name, duration, timestamp, gpu_op_uid) - python call stack (nested) - metadata (categories, graph mode detection, total kernel time) @@ -54,6 +54,22 @@ def load_trace(path_or_data): return data, by_cat +def _stamp_raw_uid(data): + """Tag each event with its position in the raw traceEvents array. + + This mirrors the UID scheme TraceToTree/TreePerfAnalyzer assign + (enumerate() over the full, unfiltered traceEvents list), so a kernel's + ``_gpu_op_uid`` here lines up with the same kernel's UID in a perf report + built from the same trace file -- without ever building a tree. Only + valid for a single, non-split trace file; do not call this on a + per-region slice produced by vLLM trace splitting, since a region's + traceEvents subset does not share the original file's indexing. + """ + for i, e in enumerate(data.get("traceEvents", [])): + if isinstance(e, dict): + e["_gpu_op_uid"] = i + + def get_stream_id(event): """Get stream from args['stream'] or tid (fallback for magic-trace style).""" stream = event.get("args", {}).get("stream") @@ -115,6 +131,12 @@ def extract_kernel_sequence(by_cat): "ts": k["ts"], "args": k.get("args", {}), "stream_id": get_stream_id(k), + # Single-trace path: _stamp_raw_uid() sets "_gpu_op_uid" in-memory. + # Split path: split_inference_trace_annotation.py (invoked with + # --emit-gpu-op-uid) already persisted "gpu_op_uid" onto the event + # before writing the per-region file, so it survives the subprocess + # boundary as literal JSON content. + "gpu_op_uid": k.get("_gpu_op_uid", k.get("gpu_op_uid")), } for k in combined ] @@ -306,6 +328,7 @@ def main(): # --- Single-trace extraction ------------------------------------------- data, by_cat = load_trace(args.trace) + _stamp_raw_uid(data) kernels = extract_kernel_sequence(by_cat) is_graph_mode, graph_launches = detect_graph_mode(by_cat) callstack = extract_python_callstack(by_cat) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py b/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py index 6a370ba14..58b369561 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py @@ -144,6 +144,7 @@ def split_vllm_trace(trace_path: str) -> Optional[List[Tuple[dict, dict]]]: "--store-single-iteration", "--iterations", "all", + "--emit-gpu-op-uid", ] result = subprocess.run( cmd, diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md index ddce88cc6..8d0d94e9f 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md @@ -89,28 +89,54 @@ run_breakdown() { # Check whether extraction produced region subdirs or a flat file if ls $DIR/*/extracted.json >/dev/null 2>&1; then - # Multi-region: tree context once, then per-region steps - python $SCRIPTS/extract_tree_context.py $TRACE --regions-dir $DIR/ + # Multi-region. Skip extract_tree_context.py entirely for no-capture + # graph-mode traces, same reasoning as the single-trace branch below: + # cpu_op/nn_module ancestry is always empty under cudaGraphLaunch, and + # gpu_op_uid is already populated per-region by extract_trace_data.py + # (split_inference_trace_annotation.py persists it onto each event via + # --emit-gpu-op-uid before writing the per-region file, so it survives + # the split subprocess -- no tree build needed to recover it). + FIRST_REGION=$(ls -d $DIR/*/ | head -1) + IS_GRAPH_MODE=$(python -c "import json; print(json.load(open('${FIRST_REGION}extracted.json'))['metadata']['is_graph_mode'])") for REGION in $DIR/*/; do python $SCRIPTS/pattern_finder.py $REGION/extracted.json -o $REGION/pattern.json & python $CLASSIFY $REGION/extracted.json -o $REGION/classified.json & done + if [ "$IS_GRAPH_MODE" != "True" ]; then + python $SCRIPTS/extract_tree_context.py $TRACE --regions-dir $DIR/ + fi wait for REGION in $DIR/*/; do + TREE_ARGS="" + if [ -f "$REGION/tree_context.json" ]; then + TREE_ARGS="--tree-context $REGION/tree_context.json" + fi python $SCRIPTS/build_semantic_labels.py \ $REGION/extracted.json $REGION/classified.json $REGION/pattern.json \ - --tree-context $REGION/tree_context.json \ + $TREE_ARGS \ -o $REGION/semantic_labels.json done else - # Single-trace - python $SCRIPTS/extract_tree_context.py $TRACE $DIR/extracted.json -o $DIR/tree_context.json + # Single-trace. Skip extract_tree_context.py entirely for no-capture + # graph-mode traces: kernels sit directly under cudaGraphLaunch, so + # cpu_op/nn_module ancestry is always empty there anyway, and + # gpu_op_uid is already populated by extract_trace_data.py itself + # (a plain raw-index lookup, no tree build needed). Only build the + # tree when non-graph-mode, or when a companion capture trace is + # available to restore ancestry via --capture-trace. + IS_GRAPH_MODE=$(python -c "import json; print(json.load(open('$DIR/extracted.json'))['metadata']['is_graph_mode'])") python $SCRIPTS/pattern_finder.py $DIR/extracted.json -o $DIR/pattern.json & python $CLASSIFY $DIR/extracted.json -o $DIR/classified.json & + + TREE_ARGS="" + if [ "$IS_GRAPH_MODE" != "True" ]; then + python $SCRIPTS/extract_tree_context.py $TRACE $DIR/extracted.json -o $DIR/tree_context.json + TREE_ARGS="--tree-context $DIR/tree_context.json" + fi wait python $SCRIPTS/build_semantic_labels.py \ $DIR/extracted.json $DIR/classified.json $DIR/pattern.json \ - --tree-context $DIR/tree_context.json \ + $TREE_ARGS \ -o $DIR/semantic_labels.json fi } @@ -120,8 +146,10 @@ run_breakdown $DIR_B & wait ``` -Add `--capture-trace ` to `extract_tree_context.py` when a -companion capture trace is provided. +For multi-region traces, and for single graph-mode traces where a +companion capture trace **is** available, add `--capture-trace +` to the `extract_tree_context.py` call to restore cpu_op +ancestry via the capture/graph-replay merge. **Output directories:** - Trace A: `/_work//` diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/templates/analysis_template.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/templates/analysis_template.md index fb962e0ea..d7d98644a 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/templates/analysis_template.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/templates/analysis_template.md @@ -91,7 +91,7 @@ section that has STANDALONE / COMPARATIVE variants. Delete the unused variant. [1 paragraph comparative overview: summarize which trace is faster overall, by how much, and the dominant gap categories] @@ -144,7 +144,7 @@ One row per entry in `priority_data.json::priorities[]`, in array order (no mani -`Trace 2 Time (ms)` = matching `manifest.trace2_ops_summary_by_category[]["total_direct_kernel_time_ms"]` where `"op category"` matches the row Category **case-insensitively**; use — if no match. This field is the semantic-aligned trace2 total (trace2 kernel time rolled up to trace1 categories via the LCA alignment), so it is consistent with the Detailed Analysis cards' per-op Trace 2 times. (`manifest.trace2_ops_summary_by_category_raw` holds the legacy per-framework breakdown for reference only — do NOT use it here.) +`Trace 2 Time (ms)` = matching `manifest.trace2_ops_summary_by_category[]["total_direct_kernel_time_ms"]` where `"op category"` matches the row Category **case-insensitively**; use — if no match. `Difference (ms)` = Trace 2 Time − Trace 1 Time. Note: for communication categories (e.g. collectives), `% of Compute Time` can exceed 100% because the kernel time is not compute-bound — report the value as computed. diff --git a/TraceLens/Agent/Analysis/utils/orchestrator_prepare.py b/TraceLens/Agent/Analysis/utils/orchestrator_prepare.py index 02c969ed8..a19b8a2de 100644 --- a/TraceLens/Agent/Analysis/utils/orchestrator_prepare.py +++ b/TraceLens/Agent/Analysis/utils/orchestrator_prepare.py @@ -18,7 +18,7 @@ import sys import traceback from collections import defaultdict -from typing import Optional + import pandas as pd sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) @@ -737,26 +737,6 @@ def _build_trace2_ops_summary_by_enhanced_category(trace2_csv_dir: str) -> list: return json.loads(grouped.to_json(orient="records")) -def _load_trace2_aligned_by_category(trace1_csv_dir: str) -> Optional[list]: - """Load the semantic-aligned trace2 per-category summary, if present. - - The perf-report script writes ``trace2_aligned_by_category.csv`` into the - trace1 CSV dir when a precomputed/in-memory diff is enriched. Unlike the - per-framework ``_build_trace2_ops_summary_by_enhanced_category`` (which - categorizes trace2 by its own op names), this rolls trace2 kernel time up - to *trace1* categories via the LCA alignment, so the comparative Top-Ops - table compares like-for-like across frameworks. Returns ``None`` when the - artifact is absent (caller falls back to the per-framework breakdown). - """ - aligned_path = os.path.join(trace1_csv_dir, "trace2_aligned_by_category.csv") - if not os.path.isfile(aligned_path): - return None - df = pd.read_csv(aligned_path) - if df.empty or "op category" not in df.columns: - return None - return json.loads(df.to_json(orient="records")) - - def _gpu_utilization_metrics_from_gpu_timeline_df(gpu_timeline: pd.DataFrame) -> dict: """Build the same gpu_utilization dict used in category_manifest from gpu_timeline.csv rows.""" gpu_data = {} @@ -897,28 +877,9 @@ def main(): os.path.join(output_dir, "metadata", "trace2_gpu_utilization.json"), "w" ) as f: json.dump(trace2_gpu_utilization, f, indent=2) - # Per-framework breakdown (trace2 categorized by its own op names). Kept - # for reference; it mis-compares when frameworks differ (the source of - # the 0 ms Top-Ops artifact). - trace2_ops_summary_by_category_raw = ( - _build_trace2_ops_summary_by_enhanced_category(trace2_csv_dir) + trace2_ops_summary_by_category = _build_trace2_ops_summary_by_enhanced_category( + trace2_csv_dir ) - # Preferred: trace2 time rolled up to trace1 categories via the semantic - # LCA alignment. Falls back to the per-framework breakdown when the - # aligned artifact is unavailable (e.g. no diff was enriched). - trace2_aligned = _load_trace2_aligned_by_category(trace1_csv_dir) - if trace2_aligned is not None: - trace2_ops_summary_by_category = trace2_aligned - print( - " trace2_ops_summary_by_category: using semantic-aligned " - "per-category totals (LCA-mapped to trace1 categories)" - ) - else: - trace2_ops_summary_by_category = trace2_ops_summary_by_category_raw - print( - " trace2_ops_summary_by_category: aligned artifact missing; " - "falling back to per-framework breakdown" - ) print(f"\nGPU Utilization Metrics:") print(f" Total Time: {gpu_utilization_metrics['total_time_ms']:.2f} ms") @@ -1536,9 +1497,6 @@ def main(): if comparison_scope == "comparative" and trace2_gpu_utilization is not None: manifest["trace2_gpu_utilization"] = trace2_gpu_utilization manifest["trace2_ops_summary_by_category"] = trace2_ops_summary_by_category - manifest["trace2_ops_summary_by_category_raw"] = ( - trace2_ops_summary_by_category_raw - ) manifest_file = f"{output_dir}/category_data/category_manifest.json" with open(manifest_file, "w") as f: diff --git a/TraceLens/Reporting/generate_perf_report_pytorch.py b/TraceLens/Reporting/generate_perf_report_pytorch.py index 2ee29b387..d5ef74a95 100644 --- a/TraceLens/Reporting/generate_perf_report_pytorch.py +++ b/TraceLens/Reporting/generate_perf_report_pytorch.py @@ -869,20 +869,6 @@ def generate_perf_report_pytorch( ) dict_name2df["diff_stats"] = _tracediff_diff_stats - from TraceLens.Reporting.tracediff_comparison_extension import ( - aligned_trace2_summary_by_category, - ) - - _aligned_t2 = aligned_trace2_summary_by_category( - _tracediff_diff_stats, - df_unified_perf, - df_unified_perf_summary, - ) - if _aligned_t2: - dict_name2df["trace2_aligned_by_category"] = pd.DataFrame( - _aligned_t2 - ) - if include_overlap_info: df_unified_perf_summary_overlapping_kernels = ( perf_analyzer.summarize_df_unified_perf_table( diff --git a/TraceLens/Reporting/generate_perf_report_pytorch_inference.py b/TraceLens/Reporting/generate_perf_report_pytorch_inference.py index 110fc23a7..7f712b6ca 100644 --- a/TraceLens/Reporting/generate_perf_report_pytorch_inference.py +++ b/TraceLens/Reporting/generate_perf_report_pytorch_inference.py @@ -1015,20 +1015,6 @@ def generate_perf_report_pytorch( ) dict_name2df["diff_stats"] = _tracediff_diff_stats - from TraceLens.Reporting.tracediff_comparison_extension import ( - aligned_trace2_summary_by_category, - ) - - _aligned_t2 = aligned_trace2_summary_by_category( - _tracediff_diff_stats, - df_unified_perf, - df_unified_perf_summary, - ) - if _aligned_t2: - dict_name2df["trace2_aligned_by_category"] = pd.DataFrame( - _aligned_t2 - ) - if include_overlap_info: df_unified_perf_summary_overlapping_kernels = ( perf_analyzer.summarize_df_unified_perf_table( diff --git a/TraceLens/Reporting/tracediff_comparison_extension.py b/TraceLens/Reporting/tracediff_comparison_extension.py index 2e0a2a3d5..c7a99c0f4 100644 --- a/TraceLens/Reporting/tracediff_comparison_extension.py +++ b/TraceLens/Reporting/tracediff_comparison_extension.py @@ -22,7 +22,6 @@ from __future__ import annotations -from collections import defaultdict from typing import Any, Dict, List, Optional, Set import numpy as np @@ -238,22 +237,12 @@ def _build_lca_metadata( return out lca_trace2_time = trace2.groupby("lowest_common_ancestor_id")["busy_time"].first() - # Number of trace2 kernel invocations per LCA group. lca_count_trace2 reports - # the count of the *dominant* mapped LCA (the one contributing the most trace2 - # kernel time) so it is comparable to trace1's op-invocation count -- rather - # than the number of matched LCA groups, which is meaningless as an op count - # for ops that span multiple LCAs (e.g. a custom all-reduce whose op owns both - # a MemCpy and an AllReduce LCA). - lca_trace2_count = trace2.groupby("lowest_common_ancestor_id").size() for lca_id, grp in trace1.groupby("lowest_common_ancestor_id"): t1_total = float(grp["busy_time"].iloc[0]) t2_total = float(lca_trace2_time.get(lca_id, 0.0)) has_trace2_match = bool(_trace2_gpu_op_uid_set_for_lca(trace2, lca_id)) - t2_count_this_lca = ( - int(lca_trace2_count.get(lca_id, 0)) if has_trace2_match else 0 - ) names = grp["lowest_common_ancestor_name"].dropna() lca_display_name = str(names.iloc[0]) if not names.empty else None @@ -272,8 +261,7 @@ def _build_lca_metadata( "lca_names": [lca_display_name], "lca_total_kernel_time_trace1_us": t1_total, "lca_total_kernel_time_trace2_us": t2_total, - "lca_count_trace2": t2_count_this_lca, - "_dominant_t2_time": t2_total, + "lca_count_trace2": 1 if has_trace2_match else 0, } else: existing = out[key] @@ -282,13 +270,8 @@ def _build_lca_metadata( existing["lca_names"].append(lca_display_name) existing["lca_total_kernel_time_trace1_us"] += t1_total existing["lca_total_kernel_time_trace2_us"] += t2_total - if t2_total > existing["_dominant_t2_time"]: - existing["_dominant_t2_time"] = t2_total - existing["lca_count_trace2"] = t2_count_this_lca - - # Drop the private dominant-time helper so the output schema is unchanged. - for meta in out.values(): - meta.pop("_dominant_t2_time", None) + if has_trace2_match: + existing["lca_count_trace2"] += 1 return out @@ -368,112 +351,6 @@ def _ins(name: str, series) -> None: return df -def aligned_trace2_summary_by_category( - diff_stats_df: pd.DataFrame, - df_unified_perf: pd.DataFrame, - unified_perf_summary: pd.DataFrame, - category_col: str = "op category", -) -> List[Dict[str, Any]]: - """Roll trace2 kernel time up to **trace1** categories via the LCA alignment. - - The per-trace ``ops_summary_by_category`` of trace2 is computed from - trace2's *own* categorization, which does not survive a cross-framework - comparison (e.g. a vLLM custom all-reduce attributed to a compute-kernel - category vs. an SGLang NCCL collective counted as exposed communication). - Joining the two per-trace breakdowns by category *name* therefore produces - spurious near-zero trace2 times for categories that exist on only one side. - - This helper instead attributes each diff_stats LCA group's trace2 time to a - single trace1 category -- the category that owns the largest share of that - LCA's trace1 kernel time -- so the resulting per-category totals are aligned - with the same semantic blocks the Detailed Analysis cards already use. - - Returns a list of dicts matching the ``trace2_ops_summary_by_category`` - schema (``op category``, ``Count``, ``total_direct_kernel_time_ms``, - ``Percentage (%)``, ``Cumulative Percentage (%)``), sorted by time desc. - Returns ``[]`` when alignment data is unavailable (caller should fall back). - """ - if ( - diff_stats_df is None - or diff_stats_df.empty - or df_unified_perf is None - or df_unified_perf.empty - or unified_perf_summary is None - or unified_perf_summary.empty - or category_col not in unified_perf_summary.columns - ): - return [] - - uid_to_row_idx = _build_uid_to_row_idx(df_unified_perf, unified_perf_summary) - if not uid_to_row_idx: - return [] - - row_idx_to_cat: Dict[Any, str] = { - idx: str(unified_perf_summary.at[idx, category_col]) - for idx in unified_perf_summary.index - } - - df = diff_stats_df.dropna(subset=["lowest_common_ancestor_id"]) - if df.empty: - return [] - trace1 = df[df["source"] == "trace1"] - trace2 = df[df["source"] == "trace2"] - if trace1.empty: - return [] - - lca_trace2_time = trace2.groupby("lowest_common_ancestor_id")["busy_time"].first() - lca_trace2_count = trace2.groupby("lowest_common_ancestor_id").size() - - cat_time_us: Dict[str, float] = defaultdict(float) - cat_count: Dict[str, int] = defaultdict(int) - - for lca_id, grp in trace1.groupby("lowest_common_ancestor_id"): - # Pick the dominant trace1 category for this LCA, weighting each mapped - # summary row by its diff_stats kernel_time. - cat_weight: Dict[str, float] = defaultdict(float) - for _, row in grp.iterrows(): - key = _resolve_diff_row_to_key(row, uid_to_row_idx) - if key is None: - continue - cat = row_idx_to_cat.get(key) - if cat is None: - continue - try: - kt = float(row.get("kernel_time", 0.0) or 0.0) - except (TypeError, ValueError): - kt = 0.0 - cat_weight[cat] += kt - if not cat_weight: - continue - dominant_cat = max(cat_weight.items(), key=lambda kv: kv[1])[0] - - t2_us = float(lca_trace2_time.get(lca_id, 0.0) or 0.0) - cat_time_us[dominant_cat] += t2_us - cat_count[dominant_cat] += int(lca_trace2_count.get(lca_id, 0)) - - if not cat_time_us: - return [] - - total_ms = sum(cat_time_us.values()) / 1000.0 - rows = sorted(cat_time_us.items(), key=lambda kv: kv[1], reverse=True) - summary: List[Dict[str, Any]] = [] - cumulative = 0.0 - for cat, time_us in rows: - time_ms = time_us / 1000.0 - pct = (time_ms / total_ms * 100.0) if total_ms > 0 else 0.0 - cumulative += pct - summary.append( - { - "op category": cat, - "Count": cat_count.get(cat, 0), - "total_direct_kernel_time_ms": round(time_ms, 10), - "Percentage (%)": round(pct, 10), - "Cumulative Percentage (%)": round(cumulative, 10), - } - ) - return summary - - def enrich_perf_report_dict_inplace( perf_dfs: Dict[str, pd.DataFrame], diff_stats_df: pd.DataFrame, diff --git a/TraceLens/TraceUtils/split_inference_trace_annotation.py b/TraceLens/TraceUtils/split_inference_trace_annotation.py index 10549b118..6027c3cdf 100644 --- a/TraceLens/TraceUtils/split_inference_trace_annotation.py +++ b/TraceLens/TraceUtils/split_inference_trace_annotation.py @@ -1105,6 +1105,18 @@ def main(): "output_dir/decode_only/. Each step is a separate trace file." ), ) + parser.add_argument( + "--emit-gpu-op-uid", + action="store_true", + default=False, + help=( + "Tag each event with a 'gpu_op_uid' field equal to its index in " + "the original (unfiltered) traceEvents array before splitting, " + "so downstream consumers can recover each extracted event's " + "position in the source trace without re-loading it. Off by " + "default to keep existing output byte-for-byte unchanged." + ), + ) args = parser.parse_args() execution_details = [] RUNTIME_EVENT_PATTERN = [ @@ -1117,6 +1129,10 @@ def main(): # Load trace trace_json = DataLoader.load_data(get_filename(args.trace_path)) events = trace_json.get("traceEvents", []) + if args.emit_gpu_op_uid: + for i, e in enumerate(events): + if isinstance(e, dict): + e["gpu_op_uid"] = i gpu_corr_map, flow_corr_map, meta_events = preprocess_trace(events) print(f"Loaded {len(events)} events") From 67a47303d4adfccbb31382e5a7bda35011614a47 Mon Sep 17 00:00:00 2001 From: Arseny Date: Mon, 31 Aug 2026 21:02:14 -0700 Subject: [PATCH 38/50] Cosmetic --- .../build_semantic_labels.py | 17 ++--- .../semantic_analyses/extract_trace_data.py | 12 +--- .../semantic_analyses/extract_tree_context.py | 4 +- .../semantic_analyses/kernel_coherence.py | 71 ++++++++++++++----- .../semantic_analyses/kernel_unification.py | 40 +++++++---- .../semantic_analyses/match_and_compare.py | 1 - .../skills/analysis-orchestrator/reference.md | 1 - .../Agent/Analysis/utils/classify_kernels.py | 24 +++++-- .../Analysis/utils/comparison_routing.py | 4 +- .../eval_utils/compare_lca_partitions.py | 56 +++++++++++---- .../semantic_partition_scripted_evals.py | 21 ++++-- .../eval_utils/semantic_purity_aggregate.py | 20 ++++-- tests/test_compare_lca_partitions.py | 28 +++++--- 13 files changed, 206 insertions(+), 93 deletions(-) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py index 0bcaf4418..3bcbd9b89 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py @@ -48,7 +48,7 @@ def _deepest_module(nn_module_stack): parts = last_entry.split(" > ") deepest = parts[-1] if deepest.startswith("nn.Module: "): - deepest = deepest[len("nn.Module: "):] + deepest = deepest[len("nn.Module: ") :] return deepest @@ -127,16 +127,10 @@ def build_labels(extracted, classified, pattern, tree_context=None): cat_counter = {} - preamble_blocks = _build_region_block_names( - preamble_set, cls_by_idx, cat_counter - ) + preamble_blocks = _build_region_block_names(preamble_set, cls_by_idx, cat_counter) cycle_names = _build_cycle_names(body_rle, period, cat_counter) - epilogue_blocks = _build_region_block_names( - epilogue_set, cls_by_idx, cat_counter - ) - secondary_blocks = _build_region_block_names( - secondary_set, cls_by_idx, cat_counter - ) + epilogue_blocks = _build_region_block_names(epilogue_set, cls_by_idx, cat_counter) + secondary_blocks = _build_region_block_names(secondary_set, cls_by_idx, cat_counter) body_index_to_rle_group = {} for g_idx, (_cat, _count, indices, _types) in enumerate(body_rle): @@ -212,7 +206,8 @@ def main(): parser.add_argument("classified_json", help="Path to classified.json") parser.add_argument("pattern_json", help="Path to pattern.json") parser.add_argument( - "--tree-context", help="Path to tree_context.json (optional, enriches nn_module and cpu_op)" + "--tree-context", + help="Path to tree_context.json (optional, enriches nn_module and cpu_op)", ) parser.add_argument("-o", "--output", help="Output JSON path (default: stdout)") args = parser.parse_args() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py index af97d8bae..0659b5cc7 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py @@ -265,9 +265,7 @@ def _write_split_regions(split_result, trace_path, output_dir): trace_dict.get("traceEvents", []), annotation_meta=region_meta, ) - gpu_timeline = compute_gpu_timeline_metrics( - trace_dict.get("traceEvents", []) - ) + gpu_timeline = compute_gpu_timeline_metrics(trace_dict.get("traceEvents", [])) if gpu_timeline: merged_meta["gpu_timeline"] = gpu_timeline region_meta = {**region_meta, "gpu_timeline": gpu_timeline} @@ -275,9 +273,7 @@ def _write_split_regions(split_result, trace_path, output_dir): filter_to_primary_stream(by_cat) kernels_tmp = extract_kernel_sequence(by_cat) is_graph_tmp, _ = detect_graph_mode(by_cat) - errors = run_assertions( - data, by_cat, kernels_tmp, is_graph_tmp, strict=False - ) + errors = run_assertions(data, by_cat, kernels_tmp, is_graph_tmp, strict=False) if errors: print(f"Skipping {key}: {'; '.join(errors)}", file=sys.stderr) continue @@ -290,9 +286,7 @@ def _write_split_regions(split_result, trace_path, output_dir): json.dump(result, f, indent=2) with open(meta_path, "w") as f: json.dump(merged_meta, f, indent=2) - print( - f"Wrote {extracted_path} ({len(kernels)} kernels)", file=sys.stderr - ) + print(f"Wrote {extracted_path} ({len(kernels)} kernels)", file=sys.stderr) def main(): diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py index 62bcfc8a2..81b727400 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py @@ -40,7 +40,9 @@ from TraceLens.util import DataLoader from TraceLens.Trace2Tree.trace_to_tree import TraceToTree -from TraceLens.Trace2Tree.trace_capture_merge_experimental import merge_capture_trace_into_graph +from TraceLens.Trace2Tree.trace_capture_merge_experimental import ( + merge_capture_trace_into_graph, +) from _helpers import load_json diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py index 599f56984..56fda371d 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py @@ -122,8 +122,9 @@ def _symbol_evidence(kernels, indices, top_kernels): return sorted(cats), sample_dims, top -def _collect_contexts(name, kernels, condensed, run_per_kernel, shared, problematic, - radius, top_kernels): +def _collect_contexts( + name, kernels, condensed, run_per_kernel, shared, problematic, radius, top_kernels +): """Per one-sided symbol, the unique (left,right) shared-neighbor contexts.""" run_to_k = _run_to_kernel_indices(run_per_kernel) out = OrderedDict() @@ -179,12 +180,24 @@ def cmd_prepare_context(args): run_b = run_index_per_kernel(seq_b) detail_a = _collect_contexts( - args.name_a, kernels_a, cond_a, run_a, shared, prob_a, - args.neighbor_radius, args.top_kernels, + args.name_a, + kernels_a, + cond_a, + run_a, + shared, + prob_a, + args.neighbor_radius, + args.top_kernels, ) detail_b = _collect_contexts( - args.name_b, kernels_b, cond_b, run_b, shared, prob_b, - args.neighbor_radius, args.top_kernels, + args.name_b, + kernels_b, + cond_b, + run_b, + shared, + prob_b, + args.neighbor_radius, + args.top_kernels, ) catalog = [] @@ -272,8 +285,9 @@ def _context_lookup(catalog): return out -def _final_blocks(workload, kernels, shared, problematic, radius, - lookup, context_renames, fallback): +def _final_blocks( + workload, kernels, shared, problematic, radius, lookup, context_renames, fallback +): """Compute the final semantic_block for each kernel; return (finals, audit).""" seq = [k.get("semantic_block", "") for k in kernels] cond = collapse_consecutive(seq) @@ -316,8 +330,13 @@ def _write_audit(path, rows): with open(path, "w", newline="") as f: w = csv.DictWriter( f, - fieldnames=["kernel_index", "name", "first_pass_block", - "final_block", "context_id"], + fieldnames=[ + "kernel_index", + "name", + "first_pass_block", + "final_block", + "context_id", + ], ) w.writeheader() w.writerows(rows) @@ -325,8 +344,16 @@ def _write_audit(path, rows): def _residual_one_sided(labels_a, labels_b): """Return one-sided condensed symbols remaining after apply.""" - ca = set(collapse_consecutive([k.get("semantic_block", "") for k in labels_a["labeled_kernels"]])) - cb = set(collapse_consecutive([k.get("semantic_block", "") for k in labels_b["labeled_kernels"]])) + ca = set( + collapse_consecutive( + [k.get("semantic_block", "") for k in labels_a["labeled_kernels"]] + ) + ) + cb = set( + collapse_consecutive( + [k.get("semantic_block", "") for k in labels_b["labeled_kernels"]] + ) + ) return sorted(ca - cb), sorted(cb - ca) @@ -339,7 +366,9 @@ def cmd_apply(args): labels_a_path = ctx["inputs"]["labels_a"] labels_b_path = ctx["inputs"]["labels_b"] - context_renames = {str(k): str(v) for k, v in (dec.get("context_renames") or {}).items()} + context_renames = { + str(k): str(v) for k, v in (dec.get("context_renames") or {}).items() + } fb_a = {str(k): str(v) for k, v in (dec.get("fallback_remap_a") or {}).items()} fb_b = {str(k): str(v) for k, v in (dec.get("fallback_remap_b") or {}).items()} @@ -425,18 +454,26 @@ def main(): p_prep.add_argument("--name-a", default="trace_a") p_prep.add_argument("--name-b", default="trace_b") p_prep.add_argument( - "--neighbor-radius", type=int, default=DEFAULT_RADIUS, + "--neighbor-radius", + type=int, + default=DEFAULT_RADIUS, help=f"Shared symbols to collect on each side (default {DEFAULT_RADIUS})", ) p_prep.add_argument( - "--top-kernels", type=int, default=DEFAULT_TOP_KERNELS, + "--top-kernels", + type=int, + default=DEFAULT_TOP_KERNELS, help=f"Top kernel names by duration per context (default {DEFAULT_TOP_KERNELS})", ) p_prep.add_argument("-o", "--output", required=True) p_prep.set_defaults(func=cmd_prepare_context) - p_apply = sub.add_parser("apply", help="Apply coherence decisions to labels in place") - p_apply.add_argument("--context", required=True, help="kernel_coherence_context.json") + p_apply = sub.add_parser( + "apply", help="Apply coherence decisions to labels in place" + ) + p_apply.add_argument( + "--context", required=True, help="kernel_coherence_context.json" + ) p_apply.add_argument("--decisions", required=True, help="LLM decisions JSON") p_apply.add_argument("--audit-csv-a", help="Per-kernel audit CSV for trace A") p_apply.add_argument("--audit-csv-b", help="Per-kernel audit CSV for trace B") diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py index 0844d6268..984a79665 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py @@ -131,9 +131,7 @@ def aggregate_names(labels, key_fn=None): if key_fn and len(entry["sample_raw_names"]) < 5 and name != key: entry["sample_raw_names"].add(name) - ordered = sorted( - acc.values(), key=lambda e: (-e["total_dur_us"], e["name"]) - ) + ordered = sorted(acc.values(), key=lambda e: (-e["total_dur_us"], e["name"])) out = OrderedDict() for e in ordered: e["total_dur_us"] = round(e["total_dur_us"], 3) @@ -191,6 +189,7 @@ def _sample_names(agg_a, agg_b, name_a, name_b, sample_size): and takes evenly-spaced picks so the sample spans high- and low-impact kernels rather than only the top-N. """ + def _spaced(agg, budget): items = list(agg.values()) if len(items) <= budget: @@ -244,7 +243,11 @@ def cmd_prepare_context(args): ) else: ctx = _build_context( - agg_a, agg_b, args.name_a, args.name_b, "raw_name", + agg_a, + agg_b, + args.name_a, + args.name_b, + "raw_name", extra={"needs_stem_preprocessing": False}, ) @@ -353,7 +356,11 @@ def _stem_key(name): combined_stems = len(set(agg_a) | set(agg_b)) ctx = _build_context( - agg_a, agg_b, args.name_a, args.name_b, "stem", + agg_a, + agg_b, + args.name_a, + args.name_b, + "stem", extra={ "needs_stem_preprocessing": False, "stem_preprocessing_applied": True, @@ -419,8 +426,11 @@ def _apply_side(labels, unified_map, raw_to_stem): if base in unified_map: n_mapped += 1 k["semantic_block"] = unified - return {"kernels": len(labels.get("labeled_kernels", [])), - "mapped": n_mapped, "stemmed": n_stemmed} + return { + "kernels": len(labels.get("labeled_kernels", [])), + "mapped": n_mapped, + "stemmed": n_stemmed, + } def cmd_apply_map(args): @@ -473,18 +483,20 @@ def main(): ) sub = parser.add_subparsers(dest="command", required=True) - p_prep = sub.add_parser( - "prepare-context", help="Build the LLM unification context" - ) + p_prep = sub.add_parser("prepare-context", help="Build the LLM unification context") _add_common(p_prep) p_prep.add_argument("-o", "--output", required=True, help="Output context JSON") p_prep.add_argument( - "--threshold", type=int, default=DEFAULT_THRESHOLD, + "--threshold", + type=int, + default=DEFAULT_THRESHOLD, help=f"Combined-unique count above which stem preprocessing is flagged " f"(default {DEFAULT_THRESHOLD})", ) p_prep.add_argument( - "--sample-size", type=int, default=DEFAULT_SAMPLE_SIZE, + "--sample-size", + type=int, + default=DEFAULT_SAMPLE_SIZE, help=f"Names to sample when over threshold (default {DEFAULT_SAMPLE_SIZE})", ) p_prep.set_defaults(func=cmd_prepare_context) @@ -500,7 +512,9 @@ def main(): ) p_stem.add_argument("-o", "--output", required=True, help="Reduced context JSON") p_stem.add_argument( - "--threshold", type=int, default=DEFAULT_THRESHOLD, + "--threshold", + type=int, + default=DEFAULT_THRESHOLD, help=f"Target combined-stem count (default {DEFAULT_THRESHOLD})", ) p_stem.set_defaults(func=cmd_apply_stem_rules) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py b/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py index f7b51c231..a441ca0a8 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py @@ -38,7 +38,6 @@ from _helpers import load_labels, load_json - def aggregate(labeled_kernels): """Aggregate labeled kernels by semantic_block. diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md index a40ababdd..ce7c6a1c9 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md @@ -626,7 +626,6 @@ The report at `/analysis.md` must use these exact `##` headers — d 5. `## Detailed Analysis` 6. `## Appendix` - ### 11.1 Validate Report Structure (Retry up to 2x) After writing `analysis.md`, validate that the report contains all required `##` section headers. If validation fails, modify the report with the missing sections. diff --git a/TraceLens/Agent/Analysis/utils/classify_kernels.py b/TraceLens/Agent/Analysis/utils/classify_kernels.py index bae3190c7..16c69e396 100644 --- a/TraceLens/Agent/Analysis/utils/classify_kernels.py +++ b/TraceLens/Agent/Analysis/utils/classify_kernels.py @@ -204,13 +204,29 @@ (r"(?i)rocprim|hipcub", "Elementwise", 1), (r"(?i)cub::DeviceScan|DeviceRadixSort|DeviceReduce", "Elementwise", 1), # ---- Triton fused ops near collectives (NOT actual collectives) ---- - (r"(?i)^triton_.*(?:all_to_all|allreduce|all_reduce|allgather|all_gather|reduce_scatter)", "Elementwise", 21), + ( + r"(?i)^triton_.*(?:all_to_all|allreduce|all_reduce|allgather|all_gather|reduce_scatter)", + "Elementwise", + 21, + ), # ---- Communication (priority 20) ---- (r"(?i)nccl|rccl", "Communication", 20), - (r"(?i)allreduce|all_reduce|allgather|all_gather|reduce_scatter|all_to_all|alltoall", "Communication", 20), - (r"(?i)broadcast|bcast|send_recv|sendrecv|isend|irecv|cross_device_reduce", "Communication", 20), + ( + r"(?i)allreduce|all_reduce|allgather|all_gather|reduce_scatter|all_to_all|alltoall", + "Communication", + 20, + ), + ( + r"(?i)broadcast|bcast|send_recv|sendrecv|isend|irecv|cross_device_reduce", + "Communication", + 20, + ), # ---- Layout / data-movement elementwise ---- - (r"(?i)permute|transpose|nchwToNhwc|nhwcToNchw|clone|_unsafe_view|slice|copy|_cat_|clamp|indexSelect", "Elementwise", 10), + ( + r"(?i)permute|transpose|nchwToNhwc|nhwcToNchw|clone|_unsafe_view|slice|copy|_cat_|clamp|indexSelect", + "Elementwise", + 10, + ), # ---- addmm into GEMM catch-all (source had gemm|matmul|bmm|addmm) ---- (r"(?i)addmm", "GEMM", 5), ] diff --git a/TraceLens/Agent/Analysis/utils/comparison_routing.py b/TraceLens/Agent/Analysis/utils/comparison_routing.py index fc7056154..3a3895ecd 100644 --- a/TraceLens/Agent/Analysis/utils/comparison_routing.py +++ b/TraceLens/Agent/Analysis/utils/comparison_routing.py @@ -160,9 +160,7 @@ def classify_comparison_method( reasons = [] if k1["framework"] != k2["framework"]: - reasons.append( - f"frameworks differ ({k1['framework']} vs {k2['framework']})" - ) + reasons.append(f"frameworks differ ({k1['framework']} vs {k2['framework']})") if k1["exec_mode"] == "graph" and not capture1_available: reasons.append("trace1 is graph-mode with no capture trace available") if k2["exec_mode"] == "graph" and not capture2_available: diff --git a/agent_evals/Analysis/eval_utils/compare_lca_partitions.py b/agent_evals/Analysis/eval_utils/compare_lca_partitions.py index 19d9fc024..3c211c8ab 100755 --- a/agent_evals/Analysis/eval_utils/compare_lca_partitions.py +++ b/agent_evals/Analysis/eval_utils/compare_lca_partitions.py @@ -85,7 +85,9 @@ def load(path: Path) -> pd.DataFrame: df["key"] = df["source"].astype(str) + ":" + df["gpu_op_uid"].astype(str) if df["key"].duplicated().any(): n = int(df["key"].duplicated().sum()) - raise ValueError(f"{path}: {n} duplicate (source, gpu_op_uid) keys; not a unique kernel id") + raise ValueError( + f"{path}: {n} duplicate (source, gpu_op_uid) keys; not a unique kernel id" + ) return df @@ -135,7 +137,9 @@ def both_purities(gold: np.ndarray, nc: np.ndarray): return purity_frac(gold, nc), purity_frac(nc, gold) -def strict_consistency_frac(group_labels: np.ndarray, other_labels: np.ndarray) -> float: +def strict_consistency_frac( + group_labels: np.ndarray, other_labels: np.ndarray +) -> float: """Fraction of items whose entire group is homogeneous in ``other_labels``. Group items by ``group_labels``; an item is *consistent* iff every item that @@ -169,13 +173,25 @@ def agreement_report(gold: pd.DataFrame, ncap: pd.DataFrame) -> None: print("=" * 78) print("LCA assignment agreement: with-capture (GOLD) vs no-capture") print("=" * 78) - print(f"with-capture kernels : {len(gold)} | distinct gold LCAs: {gold[LCA_COL].nunique()}") - print(f"no-capture kernels : {len(ncap)} | distinct nc LCAs: {ncap[LCA_COL].nunique()}") + print( + f"with-capture kernels : {len(gold)} | distinct gold LCAs: {gold[LCA_COL].nunique()}" + ) + print( + f"no-capture kernels : {len(ncap)} | distinct nc LCAs: {ncap[LCA_COL].nunique()}" + ) - g = gold[["key", "name", LCA_COL]].rename(columns={LCA_COL: "lca_gold", "name": "name_gold"}) - n = ncap[["key", "name", LCA_COL]].rename(columns={LCA_COL: "lca_nc", "name": "name_nc"}) + g = gold[["key", "name", LCA_COL]].rename( + columns={LCA_COL: "lca_gold", "name": "name_gold"} + ) + n = ncap[["key", "name", LCA_COL]].rename( + columns={LCA_COL: "lca_nc", "name": "name_nc"} + ) merged = g.merge(n, on="key") - name_agree = (merged["name_gold"] == merged["name_nc"]).mean() if len(merged) else float("nan") + name_agree = ( + (merged["name_gold"] == merged["name_nc"]).mean() + if len(merged) + else float("nan") + ) gold_only = len(gold) - len(merged) nc_only = len(ncap) - len(merged) @@ -183,7 +199,9 @@ def agreement_report(gold: pd.DataFrame, ncap: pd.DataFrame) -> None: print(f"matched kernels (in both) : {len(merged)}") print(f"gold-only (unmatched) : {gold_only}") print(f"no-capture-only (unmatched) : {nc_only}") - print(f"kernel-name agreement on matched keys: {name_agree:.4f} (sanity: should be 1.0)") + print( + f"kernel-name agreement on matched keys: {name_agree:.4f} (sanity: should be 1.0)" + ) df = merged[["key", "lca_gold", "lca_nc"]] print("-" * 78) @@ -323,8 +341,12 @@ def baseline_report(merged: pd.DataFrame, title: str, n_trials: int) -> None: def main() -> None: - ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) - ap.add_argument("with_capture", type=Path, help="path to with-capture (GOLD) diff_stats.csv") + ap = argparse.ArgumentParser( + description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter + ) + ap.add_argument( + "with_capture", type=Path, help="path to with-capture (GOLD) diff_stats.csv" + ) ap.add_argument("no_capture", type=Path, help="path to no-capture diff_stats.csv") ap.add_argument( "--trials", @@ -343,11 +365,15 @@ def main() -> None: print() # Matched set for the baselines: identity present in both. Deterministic by key. - merged = gold[["key", LCA_COL]].rename(columns={LCA_COL: "lca_gold"}).merge( - ncap[["key", "source", "gpu_op_uid", LCA_COL, LCA_NAME]].rename( - columns={LCA_COL: "lca_nc", LCA_NAME: "nc_name"} - ), - on="key", + merged = ( + gold[["key", LCA_COL]] + .rename(columns={LCA_COL: "lca_gold"}) + .merge( + ncap[["key", "source", "gpu_op_uid", LCA_COL, LCA_NAME]].rename( + columns={LCA_COL: "lca_nc", LCA_NAME: "nc_name"} + ), + on="key", + ) ) # Guard: the random baseline is O(trials * kernels); cap trials on large sets. diff --git a/agent_evals/Analysis/partial_tests/eval_utils/semantic_partition_scripted_evals.py b/agent_evals/Analysis/partial_tests/eval_utils/semantic_partition_scripted_evals.py index db5d47eb5..50ecdc02d 100644 --- a/agent_evals/Analysis/partial_tests/eval_utils/semantic_partition_scripted_evals.py +++ b/agent_evals/Analysis/partial_tests/eval_utils/semantic_partition_scripted_evals.py @@ -43,7 +43,12 @@ _HERE = os.path.dirname(os.path.abspath(__file__)) _ANALYSIS_EVAL_UTILS = os.path.abspath(os.path.join(_HERE, "..", "..", "eval_utils")) sys.path.insert(0, _ANALYSIS_EVAL_UTILS) -from compare_lca_partitions import LCA_COL, both_purities, both_strict, load # noqa: E402 +from compare_lca_partitions import ( + LCA_COL, + both_purities, + both_strict, + load, +) # noqa: E402 CSV_COLUMNS = [ "index", @@ -92,9 +97,13 @@ def run(output_dir: str, reference_dir: str, results_path: str) -> list[dict]: gold = load(gold_path) cand = load(candidate_path) - merged = gold[["key", LCA_COL]].rename(columns={LCA_COL: "lca_gold"}).merge( - cand[["key", LCA_COL]].rename(columns={LCA_COL: "lca_cand"}), - on="key", + merged = ( + gold[["key", LCA_COL]] + .rename(columns={LCA_COL: "lca_gold"}) + .merge( + cand[["key", LCA_COL]].rename(columns={LCA_COL: "lca_cand"}), + on="key", + ) ) if merged.empty: @@ -140,7 +149,9 @@ def run(output_dir: str, reference_dir: str, results_path: str) -> list[dict]: def main(): - parser = argparse.ArgumentParser(description="LCA-partition purity vs with-capture gold") + parser = argparse.ArgumentParser( + description="LCA-partition purity vs with-capture gold" + ) parser.add_argument("--output-dir", required=True) parser.add_argument("--reference-dir", required=True) parser.add_argument("--results", required=True) diff --git a/agent_evals/Analysis/partial_tests/eval_utils/semantic_purity_aggregate.py b/agent_evals/Analysis/partial_tests/eval_utils/semantic_purity_aggregate.py index 37ec3d1b6..366a9ee26 100644 --- a/agent_evals/Analysis/partial_tests/eval_utils/semantic_purity_aggregate.py +++ b/agent_evals/Analysis/partial_tests/eval_utils/semantic_purity_aggregate.py @@ -76,7 +76,9 @@ def find_run_csvs(results_root: str, test_id: str) -> list[str]: - pattern = os.path.join(results_root, test_id, "run_*", "semantic_purity_results.csv") + pattern = os.path.join( + results_root, test_id, "run_*", "semantic_purity_results.csv" + ) return sorted(glob.glob(pattern)) @@ -128,7 +130,11 @@ def aggregate_one(results_root: str, test_id: str) -> dict: } passed = avg >= floor - n_note = "" if len(parsed) > 1 else " (single run; a multi-run average is a stronger estimate)" + n_note = ( + "" + if len(parsed) > 1 + else " (single run; a multi-run average is a stronger estimate)" + ) details = ( f"n_runs={len(parsed)} strict_forward_values={[round(v, 4) for v in values]} " f"avg_strict_forward={avg:.4f} floor={floor}{n_note}" @@ -140,12 +146,18 @@ def aggregate_one(results_root: str, test_id: str) -> dict: "result": "PASS" if passed else "FAIL", "details": details, "root_cause": "" if passed else "quality", - "recommended_fix": "" if passed else "Semantic-bucketing quality regressed below the observed-performance floor; investigate the clustering change", + "recommended_fix": ( + "" + if passed + else "Semantic-bucketing quality regressed below the observed-performance floor; investigate the clustering change" + ), } def main(): - parser = argparse.ArgumentParser(description="Aggregate semantic-purity gate across repeats") + parser = argparse.ArgumentParser( + description="Aggregate semantic-purity gate across repeats" + ) parser.add_argument("--results-root", required=True) parser.add_argument( "--test-ids", diff --git a/tests/test_compare_lca_partitions.py b/tests/test_compare_lca_partitions.py index 43081e8ed..8d8e920c6 100644 --- a/tests/test_compare_lca_partitions.py +++ b/tests/test_compare_lca_partitions.py @@ -28,7 +28,13 @@ ) from compare_lca_partitions import both_purities, both_strict, load # noqa: E402 -COLUMNS = ["source", "gpu_op_uid", "name", "lowest_common_ancestor_id", "lowest_common_ancestor_name"] +COLUMNS = [ + "source", + "gpu_op_uid", + "name", + "lowest_common_ancestor_id", + "lowest_common_ancestor_name", +] def _write_csv(path, rows): @@ -128,14 +134,18 @@ def test_end_to_end_via_csv_files(tmp_path): ) gold = load(gold_path) cand = load(cand_path) - merged = gold[["key", "lowest_common_ancestor_id"]].rename( - columns={"lowest_common_ancestor_id": "lca_gold"} - ).merge( - cand[["key", "lowest_common_ancestor_id"]].rename( - columns={"lowest_common_ancestor_id": "lca_cand"} - ), - on="key", + merged = ( + gold[["key", "lowest_common_ancestor_id"]] + .rename(columns={"lowest_common_ancestor_id": "lca_gold"}) + .merge( + cand[["key", "lowest_common_ancestor_id"]].rename( + columns={"lowest_common_ancestor_id": "lca_cand"} + ), + on="key", + ) ) assert len(merged) == 4 - fwd, rev = both_purities(merged["lca_gold"].to_numpy(), merged["lca_cand"].to_numpy()) + fwd, rev = both_purities( + merged["lca_gold"].to_numpy(), merged["lca_cand"].to_numpy() + ) assert fwd == 1.0 and rev == 1.0 From 3f745da2abf024ded2aec357f696e7df40e9f640 Mon Sep 17 00:00:00 2001 From: Arseny Date: Tue, 1 Sep 2026 23:02:36 -0700 Subject: [PATCH 39/50] Cosmetic --- TraceLens/Agent/Analysis/utils/comparison_routing.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/TraceLens/Agent/Analysis/utils/comparison_routing.py b/TraceLens/Agent/Analysis/utils/comparison_routing.py index 3a3895ecd..c169097e9 100644 --- a/TraceLens/Agent/Analysis/utils/comparison_routing.py +++ b/TraceLens/Agent/Analysis/utils/comparison_routing.py @@ -43,10 +43,8 @@ import re import sys -# Iteration-annotation markers. Mirrors -# ``TraceLens.TraceUtils.split_inference_trace_annotation.ANNOTATION_PATTERN`` -# so detection stays consistent with the trace splitter. These match the -# per-iteration ``user_annotation`` events emitted by vLLM/SGLang. +# Iteration-annotation markers: per-iteration ``user_annotation`` event +# names emitted by vLLM/SGLang. ANNOTATION_PATTERN = [ re.compile( r"execute_\d+_context_\d+\(sq\d+sk\d+sqsq\d+sqsk\d+\)_generation_\d+\(sq\d+sk\d+sqsq\d+sqsk\d+\)" From 07b6e22d9327acc380adb878e46b283e2cf2c34e Mon Sep 17 00:00:00 2001 From: Arseny Date: Wed, 2 Sep 2026 02:11:10 -0700 Subject: [PATCH 40/50] Substantive changes. Bucket minimal tests, tried to revert non-surgical changes as much as possible. UID multistream fallback. --- .../Analysis/semantic_analyses/_helpers.py | 7 +-- .../semantic_analyses/extract_tree_context.py | 15 ++++- .../semantic_analyses/kernel_unification.py | 17 ++++- .../semantic_analyses/pattern_finder.py | 22 ++++--- .../Agent/Analysis/utils/classify_kernels.py | 27 -------- .../eval_utils/compare_lca_partitions.py | 11 +++- .../semantic_partition_scripted_evals.py | 5 +- .../eval_utils/semantic_purity_aggregate.py | 62 +++++++++++++++++-- 8 files changed, 113 insertions(+), 53 deletions(-) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/_helpers.py b/TraceLens/Agent/Analysis/semantic_analyses/_helpers.py index ec44863bd..8a90b37fd 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/_helpers.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/_helpers.py @@ -4,12 +4,7 @@ # See LICENSE for license information. ############################################################################### -""" -Shared helper functions for the semantic_analyses scripts. - -Merged from the former trace_breakdown/_helpers.py (build_rle, detect_period) -and trace_comparison/_helpers.py (load_labels). -""" +"""Shared helper functions for the semantic_analyses scripts.""" import gzip import json diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py index 81b727400..9e5ef6d3d 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py @@ -83,11 +83,18 @@ def _build_ts_index(tree): return index -def _find_tree_event(ts_index, name, ts, dur): +def _find_tree_event(ts_index, name, ts, dur, uid=None): """Find a tree event matching by name, timestamp, and duration.""" candidates = ts_index.get((name, ts), []) if len(candidates) == 1: return candidates[0] + # On a (name, ts) collision (concurrent same-name kernels in multi-stream / + # graph traces) prefer the exact stable-UID match: the kernel's gpu_op_uid + # equals its tree event UID, so this avoids a silent wrong attach. + if uid is not None: + for c in candidates: + if c.get("UID") == uid: + return c for c in candidates: if c.get("dur") == dur: return c @@ -142,7 +149,11 @@ def extract_tree_context(tree, extracted_data, ts_index=None, capture_augmented= for i, kernel in enumerate(kernels): tree_event = _find_tree_event( - ts_index, kernel["name"], kernel["ts"], kernel["dur"] + ts_index, + kernel["name"], + kernel["ts"], + kernel["dur"], + kernel.get("gpu_op_uid"), ) if tree_event is None: diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py index 984a79665..4f63ef5ff 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py @@ -310,7 +310,22 @@ def stem_for(name, compiled): for r in compiled: if r["regex"].search(name): if r["action"] == "collapse": - return r["regex"].sub(r["replacement"], name), "collapse" + try: + return r["regex"].sub(r["replacement"], name), "collapse" + except re.error as e: + # A malformed replacement template (e.g. a backreference with + # no matching capture group) is only detected by re at + # substitution time. Don't let one bad rule crash the whole + # run: warn once and fall back to preserving the name. + if not r.get("_warned"): + print( + f"[kernel_unification] ignoring stem rule with bad " + f"replacement {r['replacement']!r} for pattern " + f"{r['regex'].pattern!r}: {e}", + file=sys.stderr, + ) + r["_warned"] = True + return name, "preserve" if r["action"] == "preserve": return name, "preserve" return name, "drop" diff --git a/TraceLens/Agent/Analysis/semantic_analyses/pattern_finder.py b/TraceLens/Agent/Analysis/semantic_analyses/pattern_finder.py index 7854242eb..85a259a14 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/pattern_finder.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/pattern_finder.py @@ -34,7 +34,7 @@ # =========================================================================== -# Loop-detection engine (formerly kernel_loop_detection.py) +# Loop-detection engine (data classes + iterative pattern-finding algorithm) # =========================================================================== # --------------------------------------------------------------------------- @@ -833,12 +833,20 @@ def find_repeating_pattern( covered_dense = loop_structures.get_covered_indices() covered_orig = set(idx_map[i] for i in covered_dense) - primary_first = n - primary_last = -1 - if sequences: - for start, end in sequences[0]: - primary_first = min(primary_first, start) - primary_last = max(primary_last, end) + # Primary loop region spans the first to the last covered kernel across ALL + # detected patterns. Patterns are ordered by seed frequency, not position, + # so using sequences[0] alone would miss earlier/later patterns and mislabel + # their gaps. covered_orig already unions every pattern's covered indices. + if covered_orig: + primary_first = min(covered_orig) + primary_last = max(covered_orig) + else: + # No repeating pattern: there is no primary region. Put all uncovered + # kernels in preamble and leave epilogue empty so none are counted twice + # (primary_first=n -> preamble=range(n); primary_last=n-1 -> + # epilogue=range(n, n) is empty). + primary_first = n + primary_last = n - 1 secondary_set = set(secondary_indices) preamble_indices = [ diff --git a/TraceLens/Agent/Analysis/utils/classify_kernels.py b/TraceLens/Agent/Analysis/utils/classify_kernels.py index 16c69e396..39d3d1a40 100644 --- a/TraceLens/Agent/Analysis/utils/classify_kernels.py +++ b/TraceLens/Agent/Analysis/utils/classify_kernels.py @@ -203,32 +203,6 @@ (r"(?i)\bnorm\b", "Normalization", 1), (r"(?i)rocprim|hipcub", "Elementwise", 1), (r"(?i)cub::DeviceScan|DeviceRadixSort|DeviceReduce", "Elementwise", 1), - # ---- Triton fused ops near collectives (NOT actual collectives) ---- - ( - r"(?i)^triton_.*(?:all_to_all|allreduce|all_reduce|allgather|all_gather|reduce_scatter)", - "Elementwise", - 21, - ), - # ---- Communication (priority 20) ---- - (r"(?i)nccl|rccl", "Communication", 20), - ( - r"(?i)allreduce|all_reduce|allgather|all_gather|reduce_scatter|all_to_all|alltoall", - "Communication", - 20, - ), - ( - r"(?i)broadcast|bcast|send_recv|sendrecv|isend|irecv|cross_device_reduce", - "Communication", - 20, - ), - # ---- Layout / data-movement elementwise ---- - ( - r"(?i)permute|transpose|nchwToNhwc|nhwcToNchw|clone|_unsafe_view|slice|copy|_cat_|clamp|indexSelect", - "Elementwise", - 10, - ), - # ---- addmm into GEMM catch-all (source had gemm|matmul|bmm|addmm) ---- - (r"(?i)addmm", "GEMM", 5), ] COMPILED_RULES = [ @@ -258,7 +232,6 @@ "Quantization": "Quantization", "Elementwise": "Elementwise", "MemCpy": "MemCpy", - "Communication": "Communication", "Unknown": "Others", } diff --git a/agent_evals/Analysis/eval_utils/compare_lca_partitions.py b/agent_evals/Analysis/eval_utils/compare_lca_partitions.py index 3c211c8ab..bacf179f1 100755 --- a/agent_evals/Analysis/eval_utils/compare_lca_partitions.py +++ b/agent_evals/Analysis/eval_utils/compare_lca_partitions.py @@ -125,7 +125,7 @@ def purity_frac(labels_a: np.ndarray, labels_b: np.ndarray) -> float: matched = 0 for _, grp in df.groupby("a", sort=False): matched += int(grp["b"].value_counts().iloc[0]) - return matched / len(df) + return matched / len(df) if len(df) else float("nan") def both_purities(gold: np.ndarray, nc: np.ndarray): @@ -360,6 +360,15 @@ def main() -> None: gold = load(args.with_capture) ncap = load(args.no_capture) + # Guard: with no shared identity keys the matched set is empty and every + # downstream report divides by zero / sorts an empty frame. Fail cleanly. + if not (set(gold["key"]) & set(ncap["key"])): + print( + f"No matched keys between the two files ({len(gold)} gold rows, " + f"{len(ncap)} no-capture rows, 0 shared keys). Nothing to compare." + ) + return + # ---- Part 1: LCA-partition agreement ---- agreement_report(gold, ncap) print() diff --git a/agent_evals/Analysis/partial_tests/eval_utils/semantic_partition_scripted_evals.py b/agent_evals/Analysis/partial_tests/eval_utils/semantic_partition_scripted_evals.py index 50ecdc02d..e5c6790c8 100644 --- a/agent_evals/Analysis/partial_tests/eval_utils/semantic_partition_scripted_evals.py +++ b/agent_evals/Analysis/partial_tests/eval_utils/semantic_partition_scripted_evals.py @@ -37,9 +37,7 @@ import os import sys -# compare_lca_partitions.py is the shared metric implementation; it stays in -# agent_evals/Analysis/eval_utils/ (also imported by tests/test_compare_lca_partitions.py). -# This eval now lives in partial_tests/eval_utils/, so reach two levels up. +# compare_lca_partitions lives two dirs up in eval_utils/ (not a package). _HERE = os.path.dirname(os.path.abspath(__file__)) _ANALYSIS_EVAL_UTILS = os.path.abspath(os.path.join(_HERE, "..", "..", "eval_utils")) sys.path.insert(0, _ANALYSIS_EVAL_UTILS) @@ -131,6 +129,7 @@ def run(output_dir: str, reference_dir: str, results_path: str) -> list[dict]: details = ( f"matched={len(merged)} forward_purity={fwd:.4f} reverse_purity={rev:.4f} " f"strict_forward={sfwd:.4f} strict_reverse={srev:.4f} " + f"shared_buckets={merged['lca_cand'].nunique()} " f"(informational only -- see semantic_purity_aggregate.py for the actual gate)" ) rows = [ diff --git a/agent_evals/Analysis/partial_tests/eval_utils/semantic_purity_aggregate.py b/agent_evals/Analysis/partial_tests/eval_utils/semantic_purity_aggregate.py index 366a9ee26..b24084abc 100644 --- a/agent_evals/Analysis/partial_tests/eval_utils/semantic_purity_aggregate.py +++ b/agent_evals/Analysis/partial_tests/eval_utils/semantic_purity_aggregate.py @@ -71,8 +71,21 @@ "semantic_purity_qwen3_30b_a3b": 0.30, } +# Degenerate-collapse guard. strict_forward saturates to ~1.0 when the candidate +# partition collapses toward a single LCA bucket (every gold group is trivially +# homogeneous inside one bucket), so the floor above cannot catch total collapse. +# Distinct candidate LCA buckets on the matched set of observed healthy runs +# ranged 26-32 for both models; total collapse is 1. A floor of 10 sits ~2.6x +# 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, + "semantic_purity_qwen3_30b_a3b": 10, +} + DETAILS_RE = re.compile(r"strict_forward=([0-9.]+)") FORWARD_RE = re.compile(r"forward_purity=([0-9.]+)") +BUCKETS_RE = re.compile(r"shared_buckets=([0-9]+)") def find_run_csvs(results_root: str, test_id: str) -> list[str]: @@ -91,11 +104,13 @@ def parse_run(csv_path: str): details = row.get("details", "") m_sfwd = DETAILS_RE.search(details) m_fwd = FORWARD_RE.search(details) + m_buckets = BUCKETS_RE.search(details) if not m_sfwd: return None # pipeline failure row, no metrics to parse return { "strict_forward": float(m_sfwd.group(1)), "forward_purity": float(m_fwd.group(1)) if m_fwd else None, + "shared_buckets": int(m_buckets.group(1)) if m_buckets else None, "source": csv_path, } @@ -130,15 +145,54 @@ def aggregate_one(results_root: str, test_id: str) -> dict: } passed = avg >= floor + + # Collapse guard: fail hard if the distinct candidate LCA count on the + # matched set drops below the floor, which would saturate strict_forward. + bucket_floor = MIN_SHARED_BUCKETS.get(test_id) + bucket_vals = [ + p["shared_buckets"] for p in parsed if p.get("shared_buckets") is not None + ] + min_buckets = min(bucket_vals) if bucket_vals else None + collapsed = ( + bucket_floor is not None + and min_buckets is not None + and min_buckets < bucket_floor + ) + passed = passed and not collapsed + n_note = ( "" if len(parsed) > 1 else " (single run; a multi-run average is a stronger estimate)" ) + bucket_note = ( + f" min_shared_buckets={min_buckets} bucket_floor={bucket_floor}" + if bucket_floor is not None + else "" + ) details = ( f"n_runs={len(parsed)} strict_forward_values={[round(v, 4) for v in values]} " - f"avg_strict_forward={avg:.4f} floor={floor}{n_note}" + f"avg_strict_forward={avg:.4f} floor={floor}{bucket_note}{n_note}" ) + if collapsed: + details += ( + f" -- FAIL: candidate partition collapsed toward a single LCA bucket " + f"(min {min_buckets} < {bucket_floor}); strict_forward is unreliable" + ) + + if passed: + recommended_fix = "" + elif collapsed: + recommended_fix = ( + "Candidate LCA partition collapsed (near-single-bucket); strict_forward " + "is saturated and meaningless. Investigate the clustering/coherence step." + ) + else: + recommended_fix = ( + "Semantic-bucketing quality regressed below the observed-performance " + "floor; investigate the clustering change" + ) + return { "index": "semantic_purity_aggregate", "category": "Quality", @@ -146,11 +200,7 @@ def aggregate_one(results_root: str, test_id: str) -> dict: "result": "PASS" if passed else "FAIL", "details": details, "root_cause": "" if passed else "quality", - "recommended_fix": ( - "" - if passed - else "Semantic-bucketing quality regressed below the observed-performance floor; investigate the clustering change" - ), + "recommended_fix": recommended_fix, } From 139f5c43067228b639d6adf21315bba6eb880036 Mon Sep 17 00:00:00 2001 From: Arseny Date: Wed, 2 Sep 2026 14:09:50 -0700 Subject: [PATCH 41/50] Current, with re-pointing to the right implementation, dropping outdated copypaste --- .../TraceUtils/split_inference/__init__.py | 37 + .../split_inference/execution_roots.py | 40 + .../split_inference/steady_state_window.py | 364 +++++++ .../split_inference/trace_extraction.py | 486 +++++++++ .../split_inference_trace_annotation.py | 950 +----------------- .../test_split_inference_trace_annotation.py | 80 -- 6 files changed, 951 insertions(+), 1006 deletions(-) create mode 100644 TraceLens/TraceUtils/split_inference/__init__.py create mode 100644 TraceLens/TraceUtils/split_inference/execution_roots.py create mode 100644 TraceLens/TraceUtils/split_inference/steady_state_window.py create mode 100644 TraceLens/TraceUtils/split_inference/trace_extraction.py diff --git a/TraceLens/TraceUtils/split_inference/__init__.py b/TraceLens/TraceUtils/split_inference/__init__.py new file mode 100644 index 000000000..f25444d9d --- /dev/null +++ b/TraceLens/TraceUtils/split_inference/__init__.py @@ -0,0 +1,37 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Inference trace splitting: execution roots, steady-state windows, extraction.""" + +from .execution_roots import find_iteration_roots +from .steady_state_window import ( + compute_reference_pd_ratio, + find_steady_state_window, + identify_steady_state_regions, +) +from .trace_extraction import ( + divide_phases_and_save, + extract_and_save, + extract_iteration, + extract_phases_and_save, + get_filename, + parse_range, + preprocess_trace, +) + +__all__ = [ + "compute_reference_pd_ratio", + "divide_phases_and_save", + "extract_and_save", + "extract_iteration", + "extract_phases_and_save", + "find_iteration_roots", + "find_steady_state_window", + "get_filename", + "identify_steady_state_regions", + "parse_range", + "preprocess_trace", +] diff --git a/TraceLens/TraceUtils/split_inference/execution_roots.py b/TraceLens/TraceUtils/split_inference/execution_roots.py new file mode 100644 index 000000000..568ea7ac0 --- /dev/null +++ b/TraceLens/TraceUtils/split_inference/execution_roots.py @@ -0,0 +1,40 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Stage 1: find iteration execution roots in an inference trace.""" + +from ..annotation_utils import ( + ITERATION_BACKUP_PATTERNS, + ITERATION_PATTERNS, + find_events_by_patterns, +) + + +def find_iteration_roots(events: list[dict]) -> list[dict] | None: + """Return iteration-root events. + + Tries the primary annotation pattern first, then backup patterns, then + falls back to generic call-tree traversal via Trace2Tree. + """ + roots = find_events_by_patterns( + events, ITERATION_PATTERNS, label="execution steps (iteration)", verbose=True + ) + if len(roots) == 0: + print("No primary annotations found; falling back to backup patterns...") + roots = find_events_by_patterns( + events, + ITERATION_BACKUP_PATTERNS, + label="execution steps (iteration, backup)", + verbose=True, + ) + if len(roots) == 0: + print("No annotation patterns found; trying generic call-tree traversal...") + from ...Trace2Tree.inference_iteration_roots import ( + find_iteration_roots_generic, + ) + + roots = find_iteration_roots_generic(events) + return roots diff --git a/TraceLens/TraceUtils/split_inference/steady_state_window.py b/TraceLens/TraceUtils/split_inference/steady_state_window.py new file mode 100644 index 000000000..a792b6915 --- /dev/null +++ b/TraceLens/TraceUtils/split_inference/steady_state_window.py @@ -0,0 +1,364 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Stage 2: steady-state region detection and window selection.""" + +import math +from statistics import mean + +from ..annotation_utils import ( + has_context, + is_decode_only, + is_mixed, + iteration_details, +) + + +def identify_steady_state_regions( + iter_details: list[dict], num_steps: int +) -> tuple[list[tuple[int, int]], int]: + """Detect contiguous steady-state regions based on num_requests proximity to global max. + + Returns ``(regions, global_max)`` where ``regions`` is a list of + ``(start, end)`` index pairs and ``global_max`` is the peak concurrency + observed across all iterations. + """ + n = len(iter_details) + thresh = 0.1 if n >= num_steps else 0.2 + global_max = max(t["num_requests"] for t in iter_details) + + steady_state_started = False + steady_state_ended = False + prev_events_in_steady = 0 + start_index = 0 + regions = [] + + for i, t in enumerate(iter_details): + if abs(t["num_requests"] - global_max) <= max(1, thresh * global_max): + if not steady_state_started: + prev_events_in_steady += 1 + else: + if steady_state_started: + prev_events_in_steady -= 1 + + if prev_events_in_steady > 5 and not steady_state_started: + print(f"Steady state started at index {i - 5}") + steady_state_started = True + start_index = i - prev_events_in_steady + 1 + + if ( + prev_events_in_steady <= 0 + and steady_state_started + and not steady_state_ended + ): + print(f"Steady state ended at index {i}") + steady_state_ended = True + regions.append((start_index, i)) + steady_state_started = False + steady_state_ended = False + prev_events_in_steady = 0 + + if steady_state_started and not steady_state_ended: + regions.append((start_index, i)) + + print(f"Steady state regions: {regions}") + + if len(regions) == 0: + delta = min(n, max(8, num_steps - n)) + start = max(0, delta // 2) + end = max(start + 1, min(n, n - delta // 2)) + regions = [(start, end)] + print( + "Warning: no steady state region found; discarding initial/final iterations " + "and selecting middle region" + ) + + return regions, global_max + + +def compute_reference_pd_ratio( + regions: list[tuple[int, int]], iter_details: list[dict] +) -> tuple[tuple[int, int], float, float]: + """ + Return the largest steady-state region, a reference PD ratio, and the + median PD ratio across all regions. + + The reference ratio starts as the PD/total ratio of the largest region. A + sanity check compares it to the median ratio across ALL regions. If the + largest region deviates by more than 50 % relative from the median, the + median is used instead and a warning is printed. + """ + region_stats = [] + total_steps = 0 + total_pd_steps = 0 + for s, e in regions: + window = iter_details[s:e] + total = len(window) + total_steps += total + pd_count = sum(1 for t in window if has_context(t)) + total_pd_steps += pd_count + ratio = pd_count / total if total > 0 else 0.0 + region_stats.append({"start": s, "end": e, "size": total, "pd_ratio": ratio}) + print( + f" Region [{s}, {e}): size={total}, " + f"prefilldecodemix_steps={pd_count}, prefilldecodemix_to_totalsteps_ratio={ratio:.3f}" + ) + + largest = max(region_stats, key=lambda x: x["size"]) + average_ratio = total_pd_steps / total_steps if total_steps > 0 else 0.0 + largest_window_ratio = largest["pd_ratio"] + print( + f"Reference prefilldecodemix_to_totalsteps_ratio={largest_window_ratio:.3f} (largest region [{largest['start']}, {largest['end']}), Average across all regions={average_ratio:.3f})" + ) + + return (largest["start"], largest["end"]), average_ratio, largest_window_ratio + + +def find_steady_state_window( + iteration_roots: list[dict], + num_steps: int, + steady_state_regions: list[tuple[int, int]], + mode: str = "mixed", + CONC: int | None = None, + OSL: float | None = None, + R: float | None = None, +) -> list[dict]: + """ + Find the best contiguous window of up to ``num_steps`` iterations. + + Parameters + ---------- + iteration_roots : list of iteration-root events + num_steps : requested window size + steady_state_regions : pre-computed steady-state region list as ``(start, end)`` + index pairs. Pass ``[(0, len(iteration_roots))]`` to treat the entire + slice as steady state. + mode : one of ``"mixed"``, ``"decode_only"``, ``"max_prefilldecode"`` + CONC : expected peak concurrency (number of concurrent requests). + If provided, a warning is printed when the observed peak in the trace + differs from this value. + OSL : average output sequence length (decode tokens per request). + Combined with ``R`` to derive the ideal PD ratio. + R : OSL window ratio in [0, 1]. The actual OSL per request is sampled from + ``[R * OSL, OSL]``, giving mean OSL = OSL * (1 + R) / 2. + + When ``CONC``, ``OSL``, and ``R`` are all provided the ideal PD ratio is + + ideal_pd_ratio = (CONC * 2) / (OSL * (1 + R)) + + and ``num_steps`` is automatically raised to ``ceil(1 / ideal_pd_ratio)`` + if it is too small to capture the true DO/PD distribution. + + Modes + ----- + ``"mixed"`` + Pick the sub-window whose pd_ratio is closest to the reference ratio + (ideal when available, otherwise largest-region / median sanity-checked). + Ties broken by highest average num_requests. + ``"decode_only"`` + Fewest-PD window: sub-window with lowest pd_ratio. + ``"max_prefilldecode"`` + Most-PD window: sub-window with highest pd_ratio. + """ + iter_details = iteration_details(iteration_roots) + regions = steady_state_regions + global_max = max(t["num_requests"] for t in iter_details) + + (largest_start, largest_end), reference_ratio, _largest_window_ratio = ( + compute_reference_pd_ratio(regions, iter_details) + ) + + # --- Optional: CONC / OSL / R validation and ideal ratio override ---------- + ideal_pd_ratio: float | None = None + + if CONC is not None and global_max != CONC: + print( + f"Warning: expected peak concurrency CONC={CONC} but the trace peak is " + f"global_max={global_max}. The trace may not contain requests at the " + f"intended concurrency level." + ) + + if CONC is not None and OSL is not None and R is not None: + if not (0.0 <= R <= 1.0): + print(f"Warning: R={R} is outside [0, 1]; clamping to valid range.") + R = max(0.0, min(1.0, R)) + mean_osl = OSL * (1.0 + R) / 2.0 + ideal_pd_ratio = (CONC * 2.0) / (OSL * (1.0 + R)) + print( + f"Ideal prefilldecodemix_to_totalsteps_ratio = (CONC={CONC} * 2) / (OSL={OSL} * (1 + R={R})) " + f"= {ideal_pd_ratio:.4f} [mean OSL = {mean_osl:.1f}]" + ) + + min_steps_for_ratio = math.ceil(1.0 / ideal_pd_ratio) + if num_steps < min_steps_for_ratio: + print( + f"Warning: --num-steps={num_steps} is too small to capture the true " + f"decode_only/prefilldecodemix distribution. At prefilldecodemix_to_totalsteps_ratio={ideal_pd_ratio:.4f} you need at " + f"least {min_steps_for_ratio} steps to see a representative mix. " + f"Raising num_steps to {min_steps_for_ratio}." + ) + num_steps = min_steps_for_ratio + else: + print(f"num_steps={num_steps} >= min required {min_steps_for_ratio} — OK.") + + # Ideal ratio overrides the empirical reference for the mixed mode + reference_ratio = ideal_pd_ratio + print( + f"Using ideal prefilldecodemix_to_totalsteps_ratio={ideal_pd_ratio:.4f} as reference (overrides empirical {reference_ratio:.4f})" + ) + print("\n --------------------------------") + # --------------------------------------------------------------------------- + + divider = max(1, min(int(num_steps / 2), 10)) + step = max(1, num_steps // divider) + + # Build candidate sub-windows from the largest region + candidates = [] + s, e = largest_start, largest_end + + def _count_mixed(window: list[dict]) -> int: + """Count truly-mixed steps (both context and generation requests > 0).""" + return sum(1 for t in window if is_mixed(t)) + + if (e - s) >= num_steps: + for s1 in range(s, e - num_steps + 1, step): + window = iter_details[s1 : s1 + num_steps] + pd_count = sum(1 for t in window if has_context(t)) + candidates.append( + { + "start": s1, + "end": s1 + num_steps, + "pd_count": pd_count, + "pd_ratio": pd_count / num_steps, + "mixed_count": _count_mixed(window), + "avg_requests": mean(t["num_requests"] for t in window), + } + ) + else: + # Region is smaller than num_steps — use the whole region + window = iter_details[s:e] + pd_count = sum(1 for t in window if has_context(t)) + candidates.append( + { + "start": s, + "end": e, + "pd_count": pd_count, + "pd_ratio": pd_count / len(window) if window else 0.0, + "mixed_count": _count_mixed(window), + "avg_requests": ( + mean(t["num_requests"] for t in window) if window else 0 + ), + } + ) + + if mode == "mixed": + # Prefer candidate windows that contain at least one prefill-bearing + # step (pure prefill OR truly mixed, i.e. context_requests > 0). Fall + # back to all candidates only when no window contains any prefill + # activity at all. + pd_candidates = [c for c in candidates if c["pd_count"] > 0] + if pd_candidates: + print( + f"[mixed] Filtering to {len(pd_candidates)}/{len(candidates)} " + f"candidate windows that contain at least one prefill or " + f"prefill-decode step." + ) + selection_pool = pd_candidates + else: + print( + "[mixed] No candidate window contains a prefill or prefill-decode " + "step; falling back to the full candidate set." + ) + selection_pool = candidates + + best = min( + selection_pool, + key=lambda c: (abs(c["pd_ratio"] - reference_ratio), -c["avg_requests"]), + ) + print( + f"[mixed] Selected window [{best['start']}, {best['end']}): " + f"prefilldecodemix_to_totalsteps_ratio={best['pd_ratio']:.3f} (target={reference_ratio:.3f}), " + f"avg_requests={best['avg_requests']:.1f}, " + f"pd_count={best['pd_count']}, mixed_count={best['mixed_count']}" + ) + + elif mode == "decode_only": + # Find the longest contiguous run of pure decode-only steps (active + # generation with no context requests) in the largest steady-state + # region, capped at num_steps. + do_runs: list[tuple[int, int]] = [] # (start, end) in iter_details coords + run_start: int | None = None + for idx in range(largest_start, largest_end): + if is_decode_only(iter_details[idx]): + if run_start is None: + run_start = idx + else: + if run_start is not None: + do_runs.append((run_start, idx)) + run_start = None + if run_start is not None: + do_runs.append((run_start, largest_end)) + + if do_runs: + longest = max(do_runs, key=lambda r: r[1] - r[0]) + run_s, run_e = longest + win_s = run_s + win_e = min(run_e, run_s + num_steps) + print( + f"[decode_only] Longest pure decode-only run: [{run_s}, {run_e}) " + f"({run_e - run_s} steps). " + f"Selected [{win_s}, {win_e}) ({win_e - win_s} steps, " + f"capped at num_steps={num_steps})." + ) + return iteration_roots[win_s:win_e] + else: + print( + "[decode_only] No pure decode-only run found in steady-state region; " + ) + return [] + + elif mode == "max_prefilldecode": + # Find the longest contiguous run of pure PD steps (no decode-only) in + # the largest steady-state region, capped at num_steps. + pd_runs: list[tuple[int, int]] = [] # (start, end) in iter_details coords + run_start: int | None = None + for idx in range(largest_start, largest_end): + if has_context(iter_details[idx]): + if run_start is None: + run_start = idx + else: + if run_start is not None: + pd_runs.append((run_start, idx)) + run_start = None + if run_start is not None: + pd_runs.append((run_start, largest_end)) + + if pd_runs: + # Pick the longest pure-PD run + longest = max(pd_runs, key=lambda r: r[1] - r[0]) + run_s, run_e = longest + # Cap to num_steps from the start of the run + win_s = run_s + win_e = min(run_e, run_s + num_steps) + print( + f"[max_prefilldecode] Longest pure prefilldecodemix run: [{run_s}, {run_e}) " + f"({run_e - run_s} steps). " + f"Selected [{win_s}, {win_e}) ({win_e - win_s} steps, " + f"capped at num_steps={num_steps})." + ) + return iteration_roots[win_s:win_e] + else: + print( + "[max_prefilldecode] No pure prefilldecodemix run found in steady-state " + ) + return [] + + else: + raise ValueError( + f"Unknown mode: {mode!r}. Use 'mixed', 'decode_only', or 'max_prefilldecode'." + ) + + return iteration_roots[best["start"] : best["end"]] diff --git a/TraceLens/TraceUtils/split_inference/trace_extraction.py b/TraceLens/TraceUtils/split_inference/trace_extraction.py new file mode 100644 index 000000000..a035ea7b6 --- /dev/null +++ b/TraceLens/TraceUtils/split_inference/trace_extraction.py @@ -0,0 +1,486 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Stage 3: preprocess traces, extract iteration windows, and write output files.""" + +import gzip +import json +import os +import zipfile + +from tqdm import tqdm + +from ..annotation_utils import ( + ITERATION_BACKUP_PATTERNS, + ITERATION_PATTERNS, + find_phase_from_window, + has_context, + has_generation, + is_decode_only, + iteration_details, +) + +GPU_EVENT_CATEGORIES = ["kernel", "gpu_memcpy", "gpu_memset", "gpu_user_annotation"] + + +def get_filename(filepath: str) -> dict: + """Load trace JSON from file (.json, .json.gz, or .zip).""" + print(f"Loading trace: {filepath}") + if filepath.endswith(".zip"): + with zipfile.ZipFile(filepath, "r") as zf: + # Find the JSON file inside the zip + json_files = [f for f in zf.namelist() if f.endswith(".json")] + if not json_files: + raise ValueError(f"No .json file found in {filepath}") + json_file = json_files[0] + print(f" Reading {json_file} from zip...") + return json_file + return filepath + + +def preprocess_trace(events: list[dict]): + gpu_corr_map = {} + flow_corr_map = {} + meta_events = [] + for e in tqdm(events): + ts = e.get("ts") + ph = e.get("ph") + cat = e.get("cat") + if ts is None: + meta_events.append(e) + continue + if ph in ("s", "f"): + corr = e.get("id") + if corr is not None: + flow_corr_map.setdefault(corr, []).append(e) + continue + if cat in GPU_EVENT_CATEGORIES: + corr = e.get("args", {}).get("correlation") + if corr is not None: + gpu_corr_map.setdefault(corr, []).append(e) + continue + return gpu_corr_map, flow_corr_map, meta_events + + +def extract_iteration( + iteration_roots: list[dict], + events: list[dict], + trace_json: dict, + gpu_corr_map: dict, + flow_corr_map: dict, + meta_events: list[dict], +) -> dict: + """Extract a single iteration trace.""" + + filtered_events = [] + gpu_dur = 0 + gpu_busy = 0 + num_gpu_events = 0 + batch_list = [] + + # Pre-index GPU and flow events by correlation id + + # Compute the global time window for all iteration roots + if not iteration_roots: + return trace_json.copy(), [], 0, 0, 0 + min_iter_ts = min(root.get("ts", 0) for root in iteration_roots) + max_iter_end = max( + root.get("ts", 0) + root.get("dur", 0) for root in iteration_roots + ) + # Collect all relevant tid/pid pairs + tid_pid_set = {(root.get("tid"), root.get("pid")) for root in iteration_roots} + + # Pre-filter all CPU events in the global window and by tid/pid + cpu_events = [] + for e in events: + ts = e.get("ts") + if ts is None: + continue + dur = e.get("dur") + if dur is None: + continue + e_end = ts + dur + e_tid = e.get("tid") + e_pid = e.get("pid") + if (e_tid, e_pid) in tid_pid_set and ( + min_iter_ts <= ts and e_end <= max_iter_end + ): + cpu_events.append(e) + + # For each iteration root, filter CPU events and collect correlation ids + for iteration_root in tqdm(iteration_roots): + start_time = [] + end_time = [] + iter_tid = iteration_root.get("tid") + iter_pid = iteration_root.get("pid") + iter_ts = iteration_root.get("ts", 0) + iter_end = iter_ts + iteration_root.get("dur", 0) + + correlation_ids: set[int] = set() + + # CPU events: filter from pre-filtered list + for e in cpu_events: + ts = e.get("ts") + dur = e.get("dur") + e_end = ts + dur + e_tid = e.get("tid") + e_pid = e.get("pid") + if ( + e_tid == iter_tid + and e_pid == iter_pid + and (iter_ts <= ts and e_end <= iter_end) + ): + filtered_events.append(e) + corr = e.get("args", {}).get("correlation") + if corr is not None: + correlation_ids.add(corr) + + # Add matching flow events + for corr in correlation_ids: + filtered_events.extend(flow_corr_map.get(corr, [])) + # Add matching GPU events + for corr in correlation_ids: + for e in gpu_corr_map.get(corr, []): + filtered_events.append(e) + start_time.append(e.get("ts")) + end_time.append(e.get("ts") + e.get("dur")) + gpu_busy += e.get("dur") + num_gpu_events += 1 + gpu_dur += max(end_time) - min(start_time) if start_time else 0 + + # Add all meta events (no timestamp) + filtered_events.extend(meta_events) + + for e in tqdm(filtered_events): + if "vllm::unified_attention_with_output" in e.get( + "name", "" + ) or "sgl_kernel::sgl_per_token_group_quant_8bit" in e.get("name", ""): + dims = e.get("args", {}).get("Input Dims") + if dims and len(dims) > 0 and len(dims[0]) > 0: + batch_list.append(dims[0][0]) + # Create output trace + output = trace_json.copy() + output["traceEvents"] = filtered_events + return output, list(set(batch_list)), num_gpu_events, gpu_dur, gpu_busy + + +def parse_range(range_str: str, max_len: int) -> tuple[int, int]: + """Parse a range string like '10:20' or 'all'.""" + if range_str == "all": + return 0, max_len + parts = range_str.split(":") + start = int(parts[0]) + end = int(parts[1]) if len(parts) > 1 else start + 1 + return start, min(end, max_len) + + +def extract_and_save( + roots: list[list[dict]], + events: list[dict], + trace_json: dict, + output_dir: str, + base_name: str, + prefix: str, + start: int, + end: int, + gpu_corr_map: dict, + flow_corr_map: dict, + meta_events: list[dict], + output_label: str | None = None, +): + """Extract and save a range of iterations. + + If ``output_label`` is provided the output filename becomes + ``{output_label}_{name_append}_{base_name}.json.gz`` instead of the + default ``{base_name}_{prefix}_{idx}_{name_append}.json.gz``. + """ + extraction_summary = [] + # print(f"roots: {roots}") + if len(roots) == 0 or len(roots[0]) == 0: + print(f"No {prefix} events found in the specified range, skipping extraction") + return extraction_summary + selected = roots[start:end] + indices = range(start, end) + if len(selected) == 0: + print(f"No {prefix} events found in the specified range, skipping extraction") + return extraction_summary + for idx, root in zip(indices, selected): + iter_details = iteration_details(root) + iter_trace, batch_list, num_gpu_events, gpu_dur, gpu_busy = extract_iteration( + root, events, trace_json, gpu_corr_map, flow_corr_map, meta_events + ) + is_annotation = "annotation_iteration" in prefix + # Use the structured phase-aware name for any annotation extraction + # produced by the steady-state code paths (output_label is set), and + # for any multi-step annotation window. Single-step annotations from + # --store-single-iteration keep their literal step name. + is_structured = is_annotation and (output_label is not None or len(root) > 1) + + if (is_structured or not is_annotation) and len(batch_list) == len( + iter_details + ): + for bs, iteration in zip(batch_list, iter_details): + iteration["batch_size"] = bs + + phase_details = find_phase_from_window(iter_details) + + if is_structured: + name_append = ( + f"prefill_{phase_details['num_prefill']}" + f"_prefilldecode_{phase_details['num_prefilldecode']}" + f"_decode_{phase_details['num_decode']}" + f"_bs{phase_details['avg_bs']}_conc{phase_details['avg_conc']}" + ) + elif is_annotation and len(root) == 1: + root_name = root[0]["name"] + is_known_annotation = any( + pat.match(root_name) + for pat in ITERATION_PATTERNS + ITERATION_BACKUP_PATTERNS + ) + if is_known_annotation: + name_append = ( + root_name.replace("/", "_") + .replace("(", "_") + .replace(")", "") + .replace(":", "") + .replace(" ", "_") + ) + else: + name_append = "" + else: + if len(batch_list) == len(iter_details): + name_append = f"batch{int(sum(batch_list)/len(batch_list))}_gpu{prefix}" + else: + name_append = f"batch_NA_gpu{prefix}" + + if output_label is not None: + out_path = os.path.join( + output_dir, f"{output_label}_{name_append}_{base_name}.json.gz" + ) + else: + suffix = f"_{name_append}" if name_append else "" + out_path = os.path.join( + output_dir, f"{base_name}_{prefix}_{idx}{suffix}.json.gz" + ) + with gzip.open(out_path, "wb") as f: + f.write(json.dumps(iter_trace).encode("utf-8")) + + print( + f" {prefix} {idx}: {len(iter_trace['traceEvents'])} events -> {out_path}" + ) + extraction_summary.append( + { + "idx": idx, + "output_path": out_path, + "event_count": len(iter_trace["traceEvents"]), + "num_gpu_events": num_gpu_events, + "gpu_duration": gpu_dur, + "gpu_busy_duration": gpu_busy, + "steps": iter_details, + "phase": phase_details, + } + ) + return extraction_summary + + +def extract_phases_and_save( + roots: list[list[dict]], + events: list[dict], + trace_json: dict, + output_dir: str, + base_name: str, + prefix: str, + start: int, + end: int, + gpu_corr_map: dict, + flow_corr_map: dict, + meta_events: list[dict], +): + """Extract and save a range of iterations.""" + extraction_summary = [] + + if "annotation_iteration" not in prefix: + print("phase extraction only supported for annotation iterations, skipping") + return extraction_summary + for root in roots: + iter_details = iteration_details(root) + prefilldecode_steps = [r for r, i in zip(root, iter_details) if has_context(i)] + decode_steps = [r for r, i in zip(root, iter_details) if is_decode_only(i)] + + if len(prefilldecode_steps) > 0: + iter_details = iteration_details(prefilldecode_steps) + phase_details = find_phase_from_window(iter_details) + + iter_trace, _batch_list, num_gpu_events, gpu_dur, gpu_busy = ( + extract_iteration( + prefilldecode_steps, + events, + trace_json, + gpu_corr_map, + flow_corr_map, + meta_events, + ) + ) + name_append = f"prefilldecode_{phase_details['num_prefilldecode']}_bs{phase_details['avg_bs']}_conc{phase_details['avg_conc']}" + + out_path = os.path.join(output_dir, f"{name_append}_{base_name}.json.gz") + with gzip.open(out_path, "wb") as f: + f.write(json.dumps(iter_trace).encode("utf-8")) + + print(f" {prefix}: {len(iter_trace['traceEvents'])} events -> {out_path}") + extraction_summary.append( + { + "idx": 0, + "output_path": out_path, + "event_count": len(iter_trace["traceEvents"]), + "num_gpu_events": num_gpu_events, + "gpu_duration": gpu_dur, + "gpu_busy_duration": gpu_busy, + "steps": iter_details, + "phase": phase_details, + } + ) + if len(decode_steps) > 0: + iter_details = iteration_details(decode_steps) + phase_details = find_phase_from_window(iter_details) + iter_trace, _batch_list, num_gpu_events, gpu_dur, gpu_busy = ( + extract_iteration( + decode_steps, + events, + trace_json, + gpu_corr_map, + flow_corr_map, + meta_events, + ) + ) + name_append = f"decode_{phase_details['num_decode']}_bs{phase_details['avg_bs']}_conc{phase_details['avg_conc']}" + + out_path = os.path.join(output_dir, f"{name_append}_{base_name}.json.gz") + with gzip.open(out_path, "wb") as f: + f.write(json.dumps(iter_trace).encode("utf-8")) + + print(f" {prefix}: {len(iter_trace['traceEvents'])} events -> {out_path}") + extraction_summary.append( + { + "idx": 0, + "output_path": out_path, + "event_count": len(iter_trace["traceEvents"]), + "num_gpu_events": num_gpu_events, + "gpu_duration": gpu_dur, + "gpu_busy_duration": gpu_busy, + "steps": iter_details, + "phase": phase_details, + } + ) + return extraction_summary + + +def divide_phases_and_save( + iteration_roots: list[dict], + events: list[dict], + trace_json: dict, + output_dir: str, + base_name: str, + gpu_corr_map: dict, + flow_corr_map: dict, + meta_events: list[dict], + steady_state_regions: list[tuple[int, int]], +) -> list[dict]: + """ + Group contiguous steps of the same phase within steady-state regions and + save each contiguous run as a single trace file into one of two sub-folders: + + - ``{output_dir}/prefilldecodemix/`` — runs where every step has ``context_requests > 0`` + - ``{output_dir}/decode_only/`` — runs where every step has ``context_requests == 0`` + and ``generation_requests > 0`` + + A phase transition (PD → DO or DO → PD) always starts a new file. + + Parameters + ---------- + steady_state_regions + Pre-computed steady-state region list as ``(start, end)`` index pairs. + Pass ``[(0, len(iteration_roots))]`` to treat the entire slice as steady state. + """ + iter_details = iteration_details(iteration_roots) + regions = steady_state_regions + print(f"[divide-phases] Steady-state regions: {regions}") + + # Build an ordered list of (phase_label, root) for all steady-state steps + steady_steps: list[tuple[str, dict]] = [] + for s, e in regions: + for idx in range(s, e): + detail = iter_details[idx] + root = iteration_roots[idx] + if has_context(detail): + steady_steps.append(("prefilldecodemix", root)) + elif has_generation(detail): + steady_steps.append(("decode_only", root)) + # steps that are neither (e.g. idle) are skipped + + # Group into contiguous runs of the same phase + runs: list[tuple[str, list[dict]]] = [] # (phase, [roots]) + for phase, root in steady_steps: + if runs and runs[-1][0] == phase: + runs[-1][1].append(root) + else: + runs.append((phase, [root])) + + pd_count = sum(1 for p, _ in runs if p == "prefilldecodemix") + do_count = sum(1 for p, _ in runs if p == "decode_only") + total_pd_steps = sum(len(r) for p, r in runs if p == "prefilldecodemix") + total_do_steps = sum(len(r) for p, r in runs if p == "decode_only") + print( + f"\n[divide-phases] {pd_count} prefilldecodemix runs ({total_pd_steps} steps) and " + f"{do_count} decode_only runs ({total_do_steps} steps) across all steady-state regions." + ) + + pd_dir = os.path.join(output_dir, "prefilldecodemix") + do_dir = os.path.join(output_dir, "decode_only") + if pd_count: + os.makedirs(pd_dir, exist_ok=True) + if do_count: + os.makedirs(do_dir, exist_ok=True) + + extraction_summary = [] + pd_chunk_idx = 0 + do_chunk_idx = 0 + + for phase, chunk_roots in runs: + if phase == "prefilldecodemix": + out_dir = pd_dir + chunk_idx = pd_chunk_idx + pd_chunk_idx += 1 + else: + out_dir = do_dir + chunk_idx = do_chunk_idx + do_chunk_idx += 1 + + phase_details = find_phase_from_window(iteration_details(chunk_roots)) + name_append = ( + f"chunk{chunk_idx}_" + f"steps{len(chunk_roots)}_" + f"bs{phase_details['avg_bs']}_" + f"conc{phase_details['avg_conc']}" + ) + extraction_summary.extend( + extract_and_save( + [chunk_roots], + events, + trace_json, + out_dir, + base_name, + "annotation_iteration", + 0, + 1, + gpu_corr_map, + flow_corr_map, + meta_events, + output_label=f"{phase}_{name_append}", + ) + ) + + return extraction_summary diff --git a/TraceLens/TraceUtils/split_inference_trace_annotation.py b/TraceLens/TraceUtils/split_inference_trace_annotation.py index 6027c3cdf..e483e1768 100644 --- a/TraceLens/TraceUtils/split_inference_trace_annotation.py +++ b/TraceLens/TraceUtils/split_inference_trace_annotation.py @@ -11,7 +11,6 @@ - Individual execution iterations - Steady-state regions (representative execution windows) - Per-phase traces (prefill-decode vs decode-only) -- Dummy run traces (graph capture phases) This enables efficient performance analysis and comparison without processing massive tracefiles. @@ -33,12 +32,7 @@ 'N' - Single iteration N 'START:END' - Iterations START through END-1 - -d, --dummy Dummy run range (default: 'all'): - 'all' - All dummy runs - 'N' - Single dummy run N - 'START:END' - Dummy runs START through END-1 - - --store-single-iteration Store each iteration/dummy run as an individual file + --store-single-iteration Store each iteration as an individual file --find-steady-state Automatically detect steady-state and extract three representative contiguous windows (no idle gaps): @@ -115,15 +109,6 @@ ───────────────────────────────────────────────────────────────────────────── -5. EXTRACT DUMMY RUNS (Graph Capture Phases) - - $ python split_inference_trace_annotation.py trace.json.gz \\ - -o ./dummy_runs --store-single-iteration - - → One trace file per dummy run in ./dummy_runs/ - -───────────────────────────────────────────────────────────────────────────── - Generated outputs: ✓ Individual .json.gz trace files in output directory @@ -167,871 +152,37 @@ """ import argparse -import gzip import json -import math import os -import re -import zipfile -from typing import List, Set, Tuple, Optional -from statistics import mean + +import pandas as pd + from ..util import DataLoader from .annotation_utils import ( - ITERATION_PATTERNS, - ITERATION_BACKUP_PATTERNS, - find_events_by_patterns, - find_phase_from_window, - has_context, - has_generation, - is_decode_only, - is_mixed, + ITERATION_BACKUP_PATTERNS, # noqa: F401 + ITERATION_PATTERNS, # noqa: F401 iteration_details, ) -import pandas as pd - -# Try to use faster JSON parser (orjson is 2-10x faster than json) -from tqdm import tqdm - -GPU_EVENT_CATEGORIES = ["kernel", "gpu_memcpy", "gpu_memset", "gpu_user_annotation"] - - -def get_filename(filepath: str) -> dict: - """Load trace JSON from file (.json, .json.gz, or .zip).""" - print(f"Loading trace: {filepath}") - if filepath.endswith(".zip"): - with zipfile.ZipFile(filepath, "r") as zf: - # Find the JSON file inside the zip - json_files = [f for f in zf.namelist() if f.endswith(".json")] - if not json_files: - raise ValueError(f"No .json file found in {filepath}") - json_file = json_files[0] - print(f" Reading {json_file} from zip...") - return json_file - return filepath - - -def find_iteration_roots(events: List[dict]) -> Optional[List[dict]]: - """Return iteration-root events. - - Tries the primary annotation pattern first, then backup patterns, then - falls back to generic call-tree traversal via Trace2Tree. - """ - roots = find_events_by_patterns( - events, ITERATION_PATTERNS, label="execution steps (iteration)", verbose=True - ) - if len(roots) == 0: - print("No primary annotations found; falling back to backup patterns...") - roots = find_events_by_patterns( - events, - ITERATION_BACKUP_PATTERNS, - label="execution steps (iteration, backup)", - verbose=True, - ) - if len(roots) == 0: - print("No annotation patterns found; trying generic call-tree traversal...") - from ..Trace2Tree.inference_iteration_roots import ( - find_iteration_roots_generic, - ) - - roots = find_iteration_roots_generic(events) - return roots - - -def preprocess_trace(events: List[dict]): - gpu_corr_map = {} - flow_corr_map = {} - meta_events = [] - for e in tqdm(events): - ts = e.get("ts") - ph = e.get("ph") - cat = e.get("cat") - if ts is None: - meta_events.append(e) - continue - if ph in ("s", "f"): - corr = e.get("id") - if corr is not None: - flow_corr_map.setdefault(corr, []).append(e) - continue - if cat in GPU_EVENT_CATEGORIES: - corr = e.get("args", {}).get("correlation") - if corr is not None: - gpu_corr_map.setdefault(corr, []).append(e) - continue - return gpu_corr_map, flow_corr_map, meta_events - - -def extract_iteration( - iteration_roots: List[dict], - events: List[dict], - trace_json: dict, - gpu_corr_map: dict, - flow_corr_map: dict, - meta_events: List[dict], -) -> dict: - """Extract a single iteration trace.""" - - filtered_events = [] - gpu_dur = 0 - gpu_busy = 0 - num_gpu_events = 0 - batch_list = [] - - # Pre-index GPU and flow events by correlation id - - # Compute the global time window for all iteration roots - if not iteration_roots: - return trace_json.copy(), [], 0, 0, 0 - min_iter_ts = min(root.get("ts", 0) for root in iteration_roots) - max_iter_end = max( - root.get("ts", 0) + root.get("dur", 0) for root in iteration_roots - ) - # Collect all relevant tid/pid pairs - tid_pid_set = set((root.get("tid"), root.get("pid")) for root in iteration_roots) - - # Pre-filter all CPU events in the global window and by tid/pid - cpu_events = [] - for e in events: - ts = e.get("ts") - if ts is None: - continue - dur = e.get("dur") - if dur is None: - continue - e_end = ts + dur - e_tid = e.get("tid") - e_pid = e.get("pid") - if (e_tid, e_pid) in tid_pid_set and ( - min_iter_ts <= ts and e_end <= max_iter_end - ): - cpu_events.append(e) - - # For each iteration root, filter CPU events and collect correlation ids - for iteration_root in tqdm(iteration_roots): - start_time = [] - end_time = [] - iter_tid = iteration_root.get("tid") - iter_pid = iteration_root.get("pid") - iter_ts = iteration_root.get("ts", 0) - iter_end = iter_ts + iteration_root.get("dur", 0) - - correlation_ids: Set[int] = set() - - # CPU events: filter from pre-filtered list - for e in cpu_events: - ts = e.get("ts") - dur = e.get("dur") - e_end = ts + dur - e_tid = e.get("tid") - e_pid = e.get("pid") - if ( - e_tid == iter_tid - and e_pid == iter_pid - and (iter_ts <= ts and e_end <= iter_end) - ): - filtered_events.append(e) - corr = e.get("args", {}).get("correlation") - if corr is not None: - correlation_ids.add(corr) - - # Add matching flow events - for corr in correlation_ids: - for e in flow_corr_map.get(corr, []): - filtered_events.append(e) - # Add matching GPU events - for corr in correlation_ids: - for e in gpu_corr_map.get(corr, []): - filtered_events.append(e) - start_time.append(e.get("ts")) - end_time.append(e.get("ts") + e.get("dur")) - gpu_busy += e.get("dur") - num_gpu_events += 1 - gpu_dur += max(end_time) - min(start_time) if start_time else 0 - - # Add all meta events (no timestamp) - filtered_events.extend(meta_events) - - for e in tqdm(filtered_events): - if "vllm::unified_attention_with_output" in e.get( - "name", "" - ) or "sgl_kernel::sgl_per_token_group_quant_8bit" in e.get("name", ""): - dims = e.get("args", {}).get("Input Dims") - if dims and len(dims) > 0 and len(dims[0]) > 0: - batch_list.append(dims[0][0]) - # Create output trace - output = trace_json.copy() - output["traceEvents"] = filtered_events - return output, list(set(batch_list)), num_gpu_events, gpu_dur, gpu_busy - - -def parse_range(range_str: str, max_len: int) -> Tuple[int, int]: - """Parse a range string like '10:20' or 'all'.""" - if range_str == "all": - return 0, max_len - parts = range_str.split(":") - start = int(parts[0]) - end = int(parts[1]) if len(parts) > 1 else start + 1 - return start, min(end, max_len) - - -def extract_and_save( - roots: List[List[dict]], - events: List[dict], - trace_json: dict, - output_dir: str, - base_name: str, - prefix: str, - start: int, - end: int, - gpu_corr_map: dict, - flow_corr_map: dict, - meta_events: List[dict], - output_label: Optional[str] = None, -): - """Extract and save a range of iterations/dummy runs. - - If ``output_label`` is provided the output filename becomes - ``{output_label}_{name_append}_{base_name}.json.gz`` instead of the - default ``{base_name}_{prefix}_{idx}_{name_append}.json.gz``. - """ - extraction_summary = [] - # print(f"roots: {roots}") - if len(roots) == 0 or len(roots[0]) == 0: - print(f"No {prefix} events found in the specified range, skipping extraction") - return extraction_summary - selected = roots[start:end] - indices = range(start, end) - if len(selected) == 0: - print(f"No {prefix} events found in the specified range, skipping extraction") - return extraction_summary - for idx, root in zip(indices, selected): - iter_details = iteration_details(root) - iter_trace, batch_list, num_gpu_events, gpu_dur, gpu_busy = extract_iteration( - root, events, trace_json, gpu_corr_map, flow_corr_map, meta_events - ) - is_annotation = "annotation_iteration" in prefix - # Use the structured phase-aware name for any annotation extraction - # produced by the steady-state code paths (output_label is set), and - # for any multi-step annotation window. Single-step annotations from - # --store-single-iteration keep their literal step name. - is_structured = is_annotation and (output_label is not None or len(root) > 1) - - if is_structured or not is_annotation: - if len(batch_list) == len(iter_details): - for bs, iteration in zip(batch_list, iter_details): - iteration["batch_size"] = bs - - phase_details = find_phase_from_window(iter_details) - - if is_structured: - name_append = ( - f"prefill_{phase_details['num_prefill']}" - f"_prefilldecode_{phase_details['num_prefilldecode']}" - f"_decode_{phase_details['num_decode']}" - f"_bs{phase_details['avg_bs']}_conc{phase_details['avg_conc']}" - ) - elif is_annotation and len(root) == 1: - root_name = root[0]["name"] - is_known_annotation = any( - pat.match(root_name) - for pat in ITERATION_PATTERNS + ITERATION_BACKUP_PATTERNS - ) - if is_known_annotation: - name_append = ( - root_name.replace("/", "_") - .replace("(", "_") - .replace(")", "") - .replace(":", "") - .replace(" ", "_") - ) - else: - name_append = "" - else: - if len(batch_list) == len(iter_details): - name_append = f"batch{int(sum(batch_list)/len(batch_list))}_gpu{prefix}" - else: - name_append = f"batch_NA_gpu{prefix}" - - if output_label is not None: - out_path = os.path.join( - output_dir, f"{output_label}_{name_append}_{base_name}.json.gz" - ) - else: - suffix = f"_{name_append}" if name_append else "" - out_path = os.path.join( - output_dir, f"{base_name}_{prefix}_{idx}{suffix}.json.gz" - ) - with gzip.open(out_path, "wb") as f: - f.write(json.dumps(iter_trace).encode("utf-8")) - - print( - f" {prefix} {idx}: {len(iter_trace['traceEvents'])} events -> {out_path}" - ) - extraction_summary.append( - { - "idx": idx, - "output_path": out_path, - "event_count": len(iter_trace["traceEvents"]), - "num_gpu_events": num_gpu_events, - "gpu_duration": gpu_dur, - "gpu_busy_duration": gpu_busy, - "steps": iter_details, - "phase": phase_details, - } - ) - return extraction_summary - - -def extract_phases_and_save( - roots: List[List[dict]], - events: List[dict], - trace_json: dict, - output_dir: str, - base_name: str, - prefix: str, - start: int, - end: int, - gpu_corr_map: dict, - flow_corr_map: dict, - meta_events: List[dict], -): - """Extract and save a range of iterations/dummy runs.""" - extraction_summary = [] - - if "annotation_iteration" not in prefix: - print("phase extraction only supported for annotation iterations, skipping") - return extraction_summary - for root in roots: - iter_details = iteration_details(root) - prefilldecode_steps = [r for r, i in zip(root, iter_details) if has_context(i)] - decode_steps = [r for r, i in zip(root, iter_details) if is_decode_only(i)] - - if len(prefilldecode_steps) > 0: - iter_details = iteration_details(prefilldecode_steps) - phase_details = find_phase_from_window(iter_details) - - iter_trace, batch_list, num_gpu_events, gpu_dur, gpu_busy = ( - extract_iteration( - prefilldecode_steps, - events, - trace_json, - gpu_corr_map, - flow_corr_map, - meta_events, - ) - ) - name_append = f"prefilldecode_{phase_details['num_prefilldecode']}_bs{phase_details['avg_bs']}_conc{phase_details['avg_conc']}" - - out_path = os.path.join(output_dir, f"{name_append}_{base_name}.json.gz") - with gzip.open(out_path, "wb") as f: - f.write(json.dumps(iter_trace).encode("utf-8")) - - print(f" {prefix}: {len(iter_trace['traceEvents'])} events -> {out_path}") - extraction_summary.append( - { - "idx": 0, - "output_path": out_path, - "event_count": len(iter_trace["traceEvents"]), - "num_gpu_events": num_gpu_events, - "gpu_duration": gpu_dur, - "gpu_busy_duration": gpu_busy, - "steps": iter_details, - "phase": phase_details, - } - ) - if len(decode_steps) > 0: - iter_details = iteration_details(decode_steps) - phase_details = find_phase_from_window(iter_details) - iter_trace, batch_list, num_gpu_events, gpu_dur, gpu_busy = ( - extract_iteration( - decode_steps, - events, - trace_json, - gpu_corr_map, - flow_corr_map, - meta_events, - ) - ) - name_append = f"decode_{phase_details['num_decode']}_bs{phase_details['avg_bs']}_conc{phase_details['avg_conc']}" - - out_path = os.path.join(output_dir, f"{name_append}_{base_name}.json.gz") - with gzip.open(out_path, "wb") as f: - f.write(json.dumps(iter_trace).encode("utf-8")) - - print(f" {prefix}: {len(iter_trace['traceEvents'])} events -> {out_path}") - extraction_summary.append( - { - "idx": 0, - "output_path": out_path, - "event_count": len(iter_trace["traceEvents"]), - "num_gpu_events": num_gpu_events, - "gpu_duration": gpu_dur, - "gpu_busy_duration": gpu_busy, - "steps": iter_details, - "phase": phase_details, - } - ) - return extraction_summary - - -def identify_steady_state_regions( - iter_details: List[dict], num_steps: int -) -> Tuple[List[Tuple[int, int]], int]: - """Detect contiguous steady-state regions based on num_requests proximity to global max. - Returns ``(regions, global_max)`` where ``regions`` is a list of - ``(start, end)`` index pairs and ``global_max`` is the peak concurrency - observed across all iterations. - """ - n = len(iter_details) - thresh = 0.1 if n >= num_steps else 0.2 - global_max = max(t["num_requests"] for t in iter_details) - - steady_state_started = False - steady_state_ended = False - prev_events_in_steady = 0 - start_index = 0 - regions = [] - - for i, t in enumerate(iter_details): - if abs(t["num_requests"] - global_max) <= max(1, thresh * global_max): - if not steady_state_started: - prev_events_in_steady += 1 - else: - if steady_state_started: - prev_events_in_steady -= 1 - - if prev_events_in_steady > 5 and not steady_state_started: - print(f"Steady state started at index {i - 5}") - steady_state_started = True - start_index = i - prev_events_in_steady + 1 - - if ( - prev_events_in_steady <= 0 - and steady_state_started - and not steady_state_ended - ): - print(f"Steady state ended at index {i}") - steady_state_ended = True - regions.append((start_index, i)) - steady_state_started = False - steady_state_ended = False - prev_events_in_steady = 0 - - if steady_state_started and not steady_state_ended: - regions.append((start_index, i)) - - print(f"Steady state regions: {regions}") - - if len(regions) == 0: - delta = min(n, max(8, num_steps - n)) - start = max(0, delta // 2) - end = max(start + 1, min(n, n - delta // 2)) - regions = [(start, end)] - print( - "Warning: no steady state region found; discarding initial/final iterations " - "and selecting middle region" - ) - - return regions, global_max - - -def compute_reference_pd_ratio( - regions: List[Tuple[int, int]], iter_details: List[dict] -) -> Tuple[Tuple[int, int], float, float]: - """ - Return the largest steady-state region, a reference PD ratio, and the - median PD ratio across all regions. - - The reference ratio starts as the PD/total ratio of the largest region. A - sanity check compares it to the median ratio across ALL regions. If the - largest region deviates by more than 50 % relative from the median, the - median is used instead and a warning is printed. - """ - region_stats = [] - total_steps = 0 - total_pd_steps = 0 - for s, e in regions: - window = iter_details[s:e] - total = len(window) - total_steps += total - pd_count = sum(1 for t in window if has_context(t)) - total_pd_steps += pd_count - ratio = pd_count / total if total > 0 else 0.0 - region_stats.append({"start": s, "end": e, "size": total, "pd_ratio": ratio}) - print( - f" Region [{s}, {e}): size={total}, " - f"prefilldecodemix_steps={pd_count}, prefilldecodemix_to_totalsteps_ratio={ratio:.3f}" - ) - - largest = max(region_stats, key=lambda x: x["size"]) - average_ratio = total_pd_steps / total_steps if total_steps > 0 else 0.0 - largest_window_ratio = largest["pd_ratio"] - print( - f"Reference prefilldecodemix_to_totalsteps_ratio={largest_window_ratio:.3f} (largest region [{largest['start']}, {largest['end']}), Average across all regions={average_ratio:.3f})" - ) - - return (largest["start"], largest["end"]), average_ratio, largest_window_ratio - - -def divide_phases_and_save( - iteration_roots: List[dict], - events: List[dict], - trace_json: dict, - output_dir: str, - base_name: str, - gpu_corr_map: dict, - flow_corr_map: dict, - meta_events: List[dict], - steady_state_regions: List[Tuple[int, int]], -) -> List[dict]: - """ - Group contiguous steps of the same phase within steady-state regions and - save each contiguous run as a single trace file into one of two sub-folders: - - - ``{output_dir}/prefilldecodemix/`` — runs where every step has ``context_requests > 0`` - - ``{output_dir}/decode_only/`` — runs where every step has ``context_requests == 0`` - and ``generation_requests > 0`` - - A phase transition (PD → DO or DO → PD) always starts a new file. - - Parameters - ---------- - steady_state_regions - Pre-computed steady-state region list as ``(start, end)`` index pairs. - Pass ``[(0, len(iteration_roots))]`` to treat the entire slice as steady state. - """ - iter_details = iteration_details(iteration_roots) - regions = steady_state_regions - print(f"[divide-phases] Steady-state regions: {regions}") - - # Build an ordered list of (phase_label, root) for all steady-state steps - steady_steps: List[Tuple[str, dict]] = [] - for s, e in regions: - for idx in range(s, e): - detail = iter_details[idx] - root = iteration_roots[idx] - if has_context(detail): - steady_steps.append(("prefilldecodemix", root)) - elif has_generation(detail): - steady_steps.append(("decode_only", root)) - # steps that are neither (e.g. idle) are skipped - - # Group into contiguous runs of the same phase - runs: List[Tuple[str, List[dict]]] = [] # (phase, [roots]) - for phase, root in steady_steps: - if runs and runs[-1][0] == phase: - runs[-1][1].append(root) - else: - runs.append((phase, [root])) - - pd_count = sum(1 for p, _ in runs if p == "prefilldecodemix") - do_count = sum(1 for p, _ in runs if p == "decode_only") - total_pd_steps = sum(len(r) for p, r in runs if p == "prefilldecodemix") - total_do_steps = sum(len(r) for p, r in runs if p == "decode_only") - print( - f"\n[divide-phases] {pd_count} prefilldecodemix runs ({total_pd_steps} steps) and " - f"{do_count} decode_only runs ({total_do_steps} steps) across all steady-state regions." - ) - - pd_dir = os.path.join(output_dir, "prefilldecodemix") - do_dir = os.path.join(output_dir, "decode_only") - if pd_count: - os.makedirs(pd_dir, exist_ok=True) - if do_count: - os.makedirs(do_dir, exist_ok=True) - - extraction_summary = [] - pd_chunk_idx = 0 - do_chunk_idx = 0 - - for phase, chunk_roots in runs: - if phase == "prefilldecodemix": - out_dir = pd_dir - chunk_idx = pd_chunk_idx - pd_chunk_idx += 1 - else: - out_dir = do_dir - chunk_idx = do_chunk_idx - do_chunk_idx += 1 - - phase_details = find_phase_from_window(iteration_details(chunk_roots)) - name_append = ( - f"chunk{chunk_idx}_" - f"steps{len(chunk_roots)}_" - f"bs{phase_details['avg_bs']}_" - f"conc{phase_details['avg_conc']}" - ) - extraction_summary.extend( - extract_and_save( - [chunk_roots], - events, - trace_json, - out_dir, - base_name, - "annotation_iteration", - 0, - 1, - gpu_corr_map, - flow_corr_map, - meta_events, - output_label=f"{phase}_{name_append}", - ) - ) - - return extraction_summary - - -def find_steady_state_window( - iteration_roots: List[dict], - num_steps: int, - steady_state_regions: List[Tuple[int, int]], - mode: str = "mixed", - CONC: Optional[int] = None, - OSL: Optional[float] = None, - R: Optional[float] = None, -) -> List[dict]: - """ - Find the best contiguous window of up to ``num_steps`` iterations. - - Parameters - ---------- - iteration_roots : list of iteration-root events - num_steps : requested window size - steady_state_regions : pre-computed steady-state region list as ``(start, end)`` - index pairs. Pass ``[(0, len(iteration_roots))]`` to treat the entire - slice as steady state. - mode : one of ``"mixed"``, ``"decode_only"``, ``"max_prefilldecode"`` - CONC : expected peak concurrency (number of concurrent requests). - If provided, a warning is printed when the observed peak in the trace - differs from this value. - OSL : average output sequence length (decode tokens per request). - Combined with ``R`` to derive the ideal PD ratio. - R : OSL window ratio in [0, 1]. The actual OSL per request is sampled from - ``[R * OSL, OSL]``, giving mean OSL = OSL * (1 + R) / 2. - - When ``CONC``, ``OSL``, and ``R`` are all provided the ideal PD ratio is - - ideal_pd_ratio = (CONC * 2) / (OSL * (1 + R)) - - and ``num_steps`` is automatically raised to ``ceil(1 / ideal_pd_ratio)`` - if it is too small to capture the true DO/PD distribution. - - Modes - ----- - ``"mixed"`` - Pick the sub-window whose pd_ratio is closest to the reference ratio - (ideal when available, otherwise largest-region / median sanity-checked). - Ties broken by highest average num_requests. - ``"decode_only"`` - Fewest-PD window: sub-window with lowest pd_ratio. - ``"max_prefilldecode"`` - Most-PD window: sub-window with highest pd_ratio. - """ - iter_details = iteration_details(iteration_roots) - regions = steady_state_regions - global_max = max(t["num_requests"] for t in iter_details) - - (largest_start, largest_end), reference_ratio, largest_window_ratio = ( - compute_reference_pd_ratio(regions, iter_details) - ) - - # --- Optional: CONC / OSL / R validation and ideal ratio override ---------- - ideal_pd_ratio: Optional[float] = None - - if CONC is not None and global_max != CONC: - print( - f"Warning: expected peak concurrency CONC={CONC} but the trace peak is " - f"global_max={global_max}. The trace may not contain requests at the " - f"intended concurrency level." - ) - - if CONC is not None and OSL is not None and R is not None: - if not (0.0 <= R <= 1.0): - print(f"Warning: R={R} is outside [0, 1]; clamping to valid range.") - R = max(0.0, min(1.0, R)) - mean_osl = OSL * (1.0 + R) / 2.0 - ideal_pd_ratio = (CONC * 2.0) / (OSL * (1.0 + R)) - print( - f"Ideal prefilldecodemix_to_totalsteps_ratio = (CONC={CONC} * 2) / (OSL={OSL} * (1 + R={R})) " - f"= {ideal_pd_ratio:.4f} [mean OSL = {mean_osl:.1f}]" - ) - - min_steps_for_ratio = math.ceil(1.0 / ideal_pd_ratio) - if num_steps < min_steps_for_ratio: - print( - f"Warning: --num-steps={num_steps} is too small to capture the true " - f"decode_only/prefilldecodemix distribution. At prefilldecodemix_to_totalsteps_ratio={ideal_pd_ratio:.4f} you need at " - f"least {min_steps_for_ratio} steps to see a representative mix. " - f"Raising num_steps to {min_steps_for_ratio}." - ) - num_steps = min_steps_for_ratio - else: - print(f"num_steps={num_steps} >= min required {min_steps_for_ratio} — OK.") - - # Ideal ratio overrides the empirical reference for the mixed mode - reference_ratio = ideal_pd_ratio - print( - f"Using ideal prefilldecodemix_to_totalsteps_ratio={ideal_pd_ratio:.4f} as reference (overrides empirical {reference_ratio:.4f})" - ) - print(f"\n --------------------------------") - # --------------------------------------------------------------------------- - - divider = max(1, min(int(num_steps / 2), 10)) - step = max(1, num_steps // divider) - - # Build candidate sub-windows from the largest region - candidates = [] - s, e = largest_start, largest_end - - def _count_mixed(window: List[dict]) -> int: - """Count truly-mixed steps (both context and generation requests > 0).""" - return sum(1 for t in window if is_mixed(t)) - - if (e - s) >= num_steps: - for s1 in range(s, e - num_steps + 1, step): - window = iter_details[s1 : s1 + num_steps] - pd_count = sum(1 for t in window if has_context(t)) - candidates.append( - { - "start": s1, - "end": s1 + num_steps, - "pd_count": pd_count, - "pd_ratio": pd_count / num_steps, - "mixed_count": _count_mixed(window), - "avg_requests": mean(t["num_requests"] for t in window), - } - ) - else: - # Region is smaller than num_steps — use the whole region - window = iter_details[s:e] - pd_count = sum(1 for t in window if has_context(t)) - candidates.append( - { - "start": s, - "end": e, - "pd_count": pd_count, - "pd_ratio": pd_count / len(window) if window else 0.0, - "mixed_count": _count_mixed(window), - "avg_requests": ( - mean(t["num_requests"] for t in window) if window else 0 - ), - } - ) - - if mode == "mixed": - # Prefer candidate windows that contain at least one prefill-bearing - # step (pure prefill OR truly mixed, i.e. context_requests > 0). Fall - # back to all candidates only when no window contains any prefill - # activity at all. - pd_candidates = [c for c in candidates if c["pd_count"] > 0] - if pd_candidates: - print( - f"[mixed] Filtering to {len(pd_candidates)}/{len(candidates)} " - f"candidate windows that contain at least one prefill or " - f"prefill-decode step." - ) - selection_pool = pd_candidates - else: - print( - "[mixed] No candidate window contains a prefill or prefill-decode " - "step; falling back to the full candidate set." - ) - selection_pool = candidates - - best = min( - selection_pool, - key=lambda c: (abs(c["pd_ratio"] - reference_ratio), -c["avg_requests"]), - ) - print( - f"[mixed] Selected window [{best['start']}, {best['end']}): " - f"prefilldecodemix_to_totalsteps_ratio={best['pd_ratio']:.3f} (target={reference_ratio:.3f}), " - f"avg_requests={best['avg_requests']:.1f}, " - f"pd_count={best['pd_count']}, mixed_count={best['mixed_count']}" - ) - - elif mode == "decode_only": - # Find the longest contiguous run of pure decode-only steps (active - # generation with no context requests) in the largest steady-state - # region, capped at num_steps. - do_runs: List[Tuple[int, int]] = [] # (start, end) in iter_details coords - run_start: Optional[int] = None - for idx in range(largest_start, largest_end): - if is_decode_only(iter_details[idx]): - if run_start is None: - run_start = idx - else: - if run_start is not None: - do_runs.append((run_start, idx)) - run_start = None - if run_start is not None: - do_runs.append((run_start, largest_end)) - - if do_runs: - longest = max(do_runs, key=lambda r: r[1] - r[0]) - run_s, run_e = longest - win_s = run_s - win_e = min(run_e, run_s + num_steps) - print( - f"[decode_only] Longest pure decode-only run: [{run_s}, {run_e}) " - f"({run_e - run_s} steps). " - f"Selected [{win_s}, {win_e}) ({win_e - win_s} steps, " - f"capped at num_steps={num_steps})." - ) - return iteration_roots[win_s:win_e] - else: - print( - "[decode_only] No pure decode-only run found in steady-state region; " - ) - return [] - - elif mode == "max_prefilldecode": - # Find the longest contiguous run of pure PD steps (no decode-only) in - # the largest steady-state region, capped at num_steps. - pd_runs: List[Tuple[int, int]] = [] # (start, end) in iter_details coords - run_start: Optional[int] = None - for idx in range(largest_start, largest_end): - if has_context(iter_details[idx]): - if run_start is None: - run_start = idx - else: - if run_start is not None: - pd_runs.append((run_start, idx)) - run_start = None - if run_start is not None: - pd_runs.append((run_start, largest_end)) - - if pd_runs: - # Pick the longest pure-PD run - longest = max(pd_runs, key=lambda r: r[1] - r[0]) - run_s, run_e = longest - # Cap to num_steps from the start of the run - win_s = run_s - win_e = min(run_e, run_s + num_steps) - print( - f"[max_prefilldecode] Longest pure prefilldecodemix run: [{run_s}, {run_e}) " - f"({run_e - run_s} steps). " - f"Selected [{win_s}, {win_e}) ({win_e - win_s} steps, " - f"capped at num_steps={num_steps})." - ) - return iteration_roots[win_s:win_e] - else: - print( - "[max_prefilldecode] No pure prefilldecodemix run found in steady-state " - ) - return [] - - else: - raise ValueError( - f"Unknown mode: {mode!r}. Use 'mixed', 'decode_only', or 'max_prefilldecode'." - ) - - return iteration_roots[best["start"] : best["end"]] +# Re-exports for tests and downstream callers. +from .split_inference import ( # noqa: F401 + compute_reference_pd_ratio, + divide_phases_and_save, + extract_and_save, + extract_iteration, + extract_phases_and_save, + find_iteration_roots, + find_steady_state_window, + get_filename, + identify_steady_state_regions, + parse_range, + preprocess_trace, +) def main(): parser = argparse.ArgumentParser( - description="Split vLLM trace into per-iteration or per-dummy-run traces" + description="Split vLLM trace into per-iteration traces" ) parser.add_argument("trace_path", help="Path to trace file (.json or .json.gz)") @@ -1042,12 +193,6 @@ def main(): default="all", help="Iteration range: 'all', single index '50', or range '10:20'", ) - parser.add_argument( - "--dummy", - "-d", - default="all", - help="Dummy run range: 'all', single index '0', or range '0:2'", - ) parser.add_argument( "--store-single-iteration", action="store_true", @@ -1119,12 +264,6 @@ def main(): ) args = parser.parse_args() execution_details = [] - RUNTIME_EVENT_PATTERN = [ - re.compile(r"vllm/v1/worker/gpu_model_runner\.py\(\d+\): _dummy_run"), - re.compile( - r"/sgl-workspace/sglang/python/sglang/srt/model_executor/cuda_graph_runner.py\(\d+\): _capture_graph" - ), - ] # Load trace trace_json = DataLoader.load_data(get_filename(args.trace_path)) @@ -1136,11 +275,7 @@ def main(): gpu_corr_map, flow_corr_map, meta_events = preprocess_trace(events) print(f"Loaded {len(events)} events") - # Find iterations and dummy runs iteration_roots = find_iteration_roots(events) - dummy_roots = find_events_by_patterns( - events, RUNTIME_EVENT_PATTERN, cat=None, label="_dummy_run", verbose=True - ) # Create output directory os.makedirs(args.output_dir, exist_ok=True) @@ -1172,10 +307,10 @@ def main(): # Determine the working set and compute steady-state regions once, # shared across all downstream calls. - steady_state_regions: List[Tuple[int, int]] = [] + steady_state_regions: list[tuple[int, int]] = [] if args.iterations != "all": working_roots = iteration_roots[start:end] - steady_state_regions: List[Tuple[int, int]] = [(0, end - start)] + steady_state_regions: list[tuple[int, int]] = [(0, end - start)] print( f"\nUsing explicit iteration range [{start}, {end}) as the working region." ) @@ -1255,43 +390,6 @@ def main(): [pd_roots], *_extract_args, output_label="prefilldecode_steady_state" ) execution_details.extend(temp_execution_details) - # Extract dummy runs - if args.dummy and dummy_roots: - start, end = parse_range(args.dummy, len(dummy_roots)) - if args.store_single_iteration: - print(f"\nExtracting dummy runs {start} to {end-1}...") - temp_execution_details = extract_and_save( - [[root] for root in dummy_roots], - events, - trace_json, - args.output_dir, - base_name, - "run_iteration", - start, - end, - gpu_corr_map, - flow_corr_map, - meta_events, - ) - execution_details.extend(temp_execution_details) - if args.dummy != "all": - print(f"\nExtracting dummy runs {start} to {end-1}...") - temp_execution_details = extract_and_save( - [dummy_roots[start:end]], - events, - trace_json, - args.output_dir, - base_name, - "run_iteration", - 0, - 1, - gpu_corr_map, - flow_corr_map, - meta_events, - ) - execution_details.extend(temp_execution_details) - if args.find_steady_state: - print(f"finding steady state without annotations not supported") print(f"\nDone! Extracted {len(execution_details)} traces to {args.output_dir}") if len(execution_details) > 0: @@ -1303,7 +401,7 @@ def main(): rows = [] for entry in execution_details: row = {k: v for k, v in entry.items() if k not in ("steps", "phase")} - if "phase" in entry and entry["phase"]: + if entry.get("phase"): for pk, pv in entry["phase"].items(): row[f"phase_{pk}"] = pv row["num_steps"] = len(entry.get("steps", [])) diff --git a/tests/test_split_inference_trace_annotation.py b/tests/test_split_inference_trace_annotation.py index a356cfe9e..26a12cd1a 100644 --- a/tests/test_split_inference_trace_annotation.py +++ b/tests/test_split_inference_trace_annotation.py @@ -963,48 +963,6 @@ def test_main_explicit_iteration_range(tmp_path): assert out_dir.exists() -def test_main_dummy_runs_and_steady_state_message(tmp_path, capsys): - dummy_name = "vllm/v1/worker/gpu_model_runner.py(99): _dummy_run" - trace = { - "traceEvents": [ - { - "name": dummy_name, - "cat": "cpu_op", - "ph": "X", - "ts": 0, - "dur": 100, - "tid": 1, - "pid": 1, - "args": {}, - } - ], - "schemaVersion": 1, - } - trace_path = tmp_path / "dummy_trace.json" - trace_path.write_text(json.dumps(trace)) - out_dir = tmp_path / "dummy" - - old_argv = sys.argv - sys.argv = [ - "split_inference_trace_annotation", - str(trace_path), - "-o", - str(out_dir), - "--dummy", - "0:1", - "--find-steady-state", - ] - try: - split.main() - finally: - sys.argv = old_argv - - assert ( - "finding steady state without annotations not supported" - in capsys.readouterr().out - ) - - class TestCaptureMergeAndMoe: def test_align_streams_multistream(self): graph = [ @@ -1040,44 +998,6 @@ def test_moe_sort_scatter_missing_kernel_details(self): assert model.bytes() is None or model.bytes() >= 0 -class TestSplitAnnotationDummyPhase10: - def test_main_dummy_store_single_iteration(self, tmp_path): - - dummy_name = "vllm/v1/worker/gpu_model_runner.py(99): _dummy_run" - trace = {"traceEvents": [], "schemaVersion": 1} - for i in range(5): - trace["traceEvents"].append( - { - "name": dummy_name, - "cat": "user_annotation", - "ph": "X", - "ts": 1000 + i * 1000, - "dur": 100, - "tid": 10, - "pid": 1, - "args": {}, - } - ) - trace_path = tmp_path / "trace.json" - trace_path.write_text(json.dumps(trace)) - out_dir = tmp_path / "out" - old_argv = sys.argv - sys.argv = [ - "split_inference_trace_annotation", - str(trace_path), - "--output-dir", - str(out_dir), - "--dummy", - "1:3", - "--store-single-iteration", - ] - try: - split.main() - finally: - sys.argv = old_argv - assert (out_dir / "execution_details.json").exists() - - class TestCaptureMergeDeep: def test_find_closest_batch_size_and_execution_details(self): assert find_closest_batch_size(128, [64, 256, 512]) == 256 From 8785c10d266287ac2e3977c446888c706f705562 Mon Sep 17 00:00:00 2001 From: Arseny Date: Wed, 2 Sep 2026 15:25:43 -0700 Subject: [PATCH 42/50] Extra vendor anonymization --- .../agents/kernel-coherence-agent.md | 21 +++++++++---------- .../agents/kernel-stem-preprocessing-agent.md | 12 +++++------ .../agents/kernel-unification-agent.md | 8 +++---- .../agents/semantic-comparison-agent.md | 4 +--- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-coherence-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-coherence-agent.md index 0adffbb7b..7ff980c21 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-coherence-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-coherence-agent.md @@ -14,8 +14,8 @@ model: claude-opus-4-8 Second pass over the name-first unification. The first pass leaves **one-sided** buckets: kernels whose unified name appears in only one trace -- most importantly -vendor GEMM families that could not be paired by name (MI300 `Cijk_*` vs B300 -`nvjet_*`). This pass uses the first-pass **shared** buckets as cross-trace +vendor GEMM families that could not be paired by name ((platform 1 name) `(likely gemm name platform 1)_*` vs +(platform 2 name) `(likely gemm name platform 2)_*`). This pass uses the first-pass **shared** buckets as cross-trace positional anchors and re-labels the one-sided buckets by their **neighbor context**. @@ -25,7 +25,7 @@ Two capabilities: one-sided bucket in trace B that sit in the *same* shared-neighbor context are the same operation -- give them the **same new shared name**. (The GEMM between `add_rmsnorm` and `rotary_embedding` is the QKV projection on both - traces, even though the raw kernels are `Cijk_...` vs `nvjet_...`.) + traces, even though the raw kernels are `(likely gemm name platform 1)_...` vs `(likely gemm name platform 2)_...`.) 2. **Context-dependent splitting.** One name that appears in *different* contexts should become *different* buckets (a GEMM between attention and norm vs a GEMM between embedding and MoE). @@ -52,13 +52,12 @@ The full `kernel_coherence_context.json` is provided inline. Key fields: For each one-sided context, work out the operation from: - **`left_window` / `right_window`** -- the primary signal. In a transformer - decoder layer the projections are pinned by their neighbors: + decoder layer the projections are pinned by their neighbors. Possible likely examples (not strict rules): - `(*norm* | rotary_embedding)` -> QKV projection - `(paged_attention | *norm*)` -> output projection - `(*norm* | act_and_mul)` -> gate/up projection - `(act_and_mul | *norm*)` -> down projection -- **kernel name** -- `Cijk_*`, `nvjet_*`, `cublasLt::*`, `_gemm_*` are GEMMs; - `*paged_attention*`, `*fmha*` attention; `*rmsnorm*` norm; `*rope*` rotary. +- **kernel name** -- for example, GEMMs, attention, norms, and rotary embeddings often have characteristic names. - **`sample_input_dims`** and **`kernels_in_run`** -- corroborate a pairing (matching shapes / per-layer counts). @@ -68,7 +67,7 @@ name. Pick a short, vendor-neutral name (`qkv_projection`, `output_projection`, `gate_up_projection`, `down_projection`, ...). **perf_category caveat:** the regex classifier may tag a vendor kernel as -`Others` (e.g. `nvjet_*`). Do **not** require identical `perf_category` to pair +`Others`. Do **not** require identical `perf_category` to pair -- rely on the kernel name and the neighbor context. Still never pair operations that are clearly different types. @@ -77,14 +76,14 @@ that are clearly different types. ```json { "context_renames": { - "MI300:6": "qkv_projection", - "B300:6": "qkv_projection" + "(platform 1 name):6": "qkv_projection", + "(platform 2 name):6": "qkv_projection" }, "fallback_remap_a": { - "Cijk_..._MT64x16x128_...": "qkv_projection" + "(likely gemm name platform 1)_..._(likely gemm signature)_...": "qkv_projection" }, "fallback_remap_b": { - "nvjet_sm103_tst_64x16_64x16_4x1_v_bz_TNT": "qkv_projection" + "(likely gemm name platform 2)_..._(likely gemm signature)_...": "qkv_projection" }, "notes": "optional rationale" } diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md index 636789e22..d5c266234 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md @@ -27,9 +27,9 @@ default 5000). Otherwise skip it entirely. High-cardinality name families blow up the unique count. A single logical GEMM family can appear as thousands of variants that differ only by an autotuner id or embedded shape, e.g. `gemm_013123`, `gemm_013124`, ... or -`Cijk_..._MT32x16x512_...`, `Cijk_..._MT64x16x256_...`. These variants are the +`(vendor gemm name)_..._MT32x16x512_...`, `(vendor gemm name)_..._MT64x16x256_...`. These variants are the same operation for the purpose of establishing cross-trace anchors, so -collapsing them to a **stem** (e.g. `gemm`, `Cijk_..._MT#_...`) drastically +collapsing them to a **stem** (e.g. `gemm`, `(vendor gemm name)_..._MT#_...`) drastically shrinks the set. But **not every varying parameter is noise.** Some distinctions should be kept @@ -73,8 +73,8 @@ setup kernels). Use judgment. - Anchor to the family so a rule cannot over-match a different family. - Collapse the varying token, not the whole name: replace digit runs / shape tokens with a placeholder rather than erasing the identifying prefix. E.g. - `('_MT\d+x\d+x\d+', '_MT#')` keeps `Cijk_..._MT#_...` distinguishable from a - different Cijk variant, while `('_[0-9]+$', '')` strips a trailing id. + `('_MT\d+x\d+x\d+', '_MT#')` keeps `(vendor gemm name)_..._MT#_...` distinguishable from a + different vendor GEMM variant, while `('_[0-9]+$', '')` strips a trailing id. - Keep the stem **stable across both traces** where the operation is the same, but you do not need to make two frameworks' stems identical here -- the `kernel-unification-agent` maps stems across traces afterward. @@ -87,10 +87,10 @@ setup kernels). Use judgment. {"pattern": "^gemm_[0-9]+$", "replacement": "gemm", "action": "collapse", "note": "autotuner-id GEMM family"}, {"pattern": "_MT[0-9]+x[0-9]+x[0-9]+", "replacement": "_MT#", - "action": "collapse", "note": "collapse Cijk tile-size id, keep family"}, + "action": "collapse", "note": "collapse vendor GEMM tile-size id, keep family"}, {"pattern": "(?i)profiler|marker|nvtx", "replacement": "", "action": "drop", "note": "profiler noise"}, - {"pattern": "^(nvjet|cublasLt)", "replacement": "", + {"pattern": "^(vendor gemm prefix)", "replacement": "", "action": "preserve", "note": "keep vendor GEMM dims for later analysis"} ] } diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md index 52c393f04..d3486148c 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md @@ -49,8 +49,8 @@ in `only_in_` when you are **certain** they are the same operation. - **`perf_categories`** -- a GEMM only unifies with a GEMM, SDPA with SDPA, etc. Never unify across different perf categories. -- **Name semantics** -- decode the mangled name. `nvjet_*`, `Cijk_*`, - `cublasLt::*`, `_gemm_a16_w16_*` are vendor GEMM kernels; `*paged_attention*`, +- **Name semantics** -- decode the mangled name. Vendor GEMM kernels often have + characteristic mangled names; `*paged_attention*`, `*fmha*`, `*flash*` are attention; `*rmsnorm*`, `*layer_norm*` are normalization; `*reduce*`, `*all_reduce*`, `*allgather*` are communication. - **`sample_input_dims`** -- matching shapes across traces strengthen a pairing. @@ -82,8 +82,8 @@ Write to the output directory. Exact shape: ```json { - "name_a": "MI300", - "name_b": "B300", + "name_a": "(platform 1 name)", + "name_b": "(platform 2 name)", "map_a": { "moe_attn_vllm": "moe_attn", "(vendor1_gemm_name)_(shape1)": "expert_gemm" diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md index 8d0d94e9f..85c3aa672 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md @@ -234,9 +234,7 @@ shared vocabulary. ### 2.6 Coherence Pass (second pass, LLM) The first pass leaves **one-sided** buckets -- kernels whose unified name -appears in only one trace (most importantly vendor GEMM families: e.g. -`(vendor1_gemm_name)_*` on one platform vs `(vendor2_gemm_name)_*` on the -other, which cannot be paired by name). This pass uses +appears in only one trace. This pass uses the first-pass **shared** buckets as cross-trace positional anchors and re-labels one-sided buckets by their shared-neighbor context, which (a) pairs GEMMs across vendors by position and (b) splits a name that occurs in From 70dcdf22e0342324ae69e0afafbca654ab59ec0c Mon Sep 17 00:00:00 2001 From: Arseny Date: Wed, 2 Sep 2026 18:16:27 -0700 Subject: [PATCH 43/50] Simplification/pruning --- .../semantic_analyses/extract_trace_data.py | 19 -- .../semantic_analyses/extract_tree_context.py | 62 +---- .../agents/semantic-comparison-agent.md | 16 +- .../skills/analysis-orchestrator/reference.md | 21 +- .../Analysis/utils/comparison_routing.py | 222 ------------------ 5 files changed, 18 insertions(+), 322 deletions(-) delete mode 100644 TraceLens/Agent/Analysis/utils/comparison_routing.py diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py index 0659b5cc7..c5e127f5a 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py @@ -10,7 +10,6 @@ Outputs a JSON with: - ordered kernel list (name, duration, timestamp, gpu_op_uid) - - python call stack (nested) - metadata (categories, graph mode detection, total kernel time) vLLM traces with annotation iterations are auto-detected and split into @@ -148,20 +147,6 @@ def detect_graph_mode(by_cat): return len(graph_launches) > 0, graph_launches -def extract_python_callstack(by_cat): - pyfuncs = sorted(by_cat.get("python_function", []), key=lambda e: e["ts"]) - for p in pyfuncs: - p["_end"] = p["ts"] + p["dur"] - stack = [] - result = [] - for p in pyfuncs: - while stack and stack[-1]["_end"] <= p["ts"]: - stack.pop() - result.append({"name": p["name"], "dur": p["dur"], "depth": len(stack)}) - stack.append(p) - return result - - def run_assertions(data, by_cat, kernels, is_graph_mode, strict=True): errors = [] @@ -232,7 +217,6 @@ def extract_and_build_result(data, by_cat, source_file, region_metadata=None): """Build extraction result dict.""" kernels = extract_kernel_sequence(by_cat) is_graph_mode, graph_launches = detect_graph_mode(by_cat) - callstack = extract_python_callstack(by_cat) total_kernel_time = sum(k["dur"] for k in kernels) categories_found = sorted(by_cat.keys()) result = { @@ -243,10 +227,8 @@ def extract_and_build_result(data, by_cat, source_file, region_metadata=None): "is_graph_mode": is_graph_mode, "graph_launch_count": len(graph_launches), "categories": categories_found, - "has_python_stack": len(callstack) > 0, }, "kernels": kernels, - "python_callstack": callstack, } if region_metadata: result["region_metadata"] = region_metadata @@ -325,7 +307,6 @@ def main(): _stamp_raw_uid(data) kernels = extract_kernel_sequence(by_cat) is_graph_mode, graph_launches = detect_graph_mode(by_cat) - callstack = extract_python_callstack(by_cat) errors = run_assertions(data, by_cat, kernels, is_graph_mode) if errors: diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py index 9e5ef6d3d..e5fc25153 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py @@ -21,9 +21,6 @@ Usage (batch -- all regions share one tree build): python extract_tree_context.py --regions-dir / -Capture-trace augmentation (graph-mode traces): - python extract_tree_context.py \ - --capture-trace [-o tree_context.json] """ import argparse @@ -40,27 +37,11 @@ from TraceLens.util import DataLoader from TraceLens.Trace2Tree.trace_to_tree import TraceToTree -from TraceLens.Trace2Tree.trace_capture_merge_experimental import ( - merge_capture_trace_into_graph, -) from _helpers import load_json -def load_and_build_tree(trace_path, capture_trace_path=None): - """Load a trace file and build a TraceToTree. - - When capture_trace_path is provided, merges the capture-phase tree into - the graph-replay tree so that GPU kernels inherit cpu_op ancestors from - the capture recording. This restores near-100% tree coverage for - graph-mode traces. - """ - if capture_trace_path: - print( - f"Merging capture trace {capture_trace_path} into {trace_path}...", - file=sys.stderr, - ) - return merge_capture_trace_into_graph(capture_trace_path, trace_path) - +def load_and_build_tree(trace_path): + """Load a trace file and build a TraceToTree.""" data = DataLoader.load_data(trace_path) events = data.get("traceEvents", []) # Pass the full traceEvents list (do NOT strip metadata first) so that the @@ -125,7 +106,7 @@ def _find_cpu_op_ancestor(tree, event): current = parent -def extract_tree_context(tree, extracted_data, ts_index=None, capture_augmented=False): +def extract_tree_context(tree, extracted_data, ts_index=None): """Match extracted kernels to tree events and extract context. Args: @@ -133,8 +114,6 @@ def extract_tree_context(tree, extracted_data, ts_index=None, capture_augmented= extracted_data: dict from extract_trace_data.py with "kernels" list. ts_index: optional pre-built (name, ts) index from _build_ts_index(). Pass this when processing multiple regions against the same tree. - capture_augmented: if True, the tree was built with capture-trace - augmentation and the flag is propagated into the output JSON. Returns dict with per-kernel tree context, labeled/unlabeled indices, and coverage stats. @@ -199,7 +178,6 @@ def extract_tree_context(tree, extracted_data, ts_index=None, capture_augmented= "coverage": round(coverage, 4), "labeled_count": len(labeled_indices), "unlabeled_count": len(unlabeled_indices), - "capture_augmented": capture_augmented, "labeled_indices": labeled_indices, "unlabeled_indices": unlabeled_indices, "kernels": kernel_contexts, @@ -219,18 +197,14 @@ def _find_region_subdirs(regions_dir): return regions -def _process_single( - tree, ts_index, extracted_path, output_path, capture_augmented=False -): +def _process_single(tree, ts_index, extracted_path, output_path): """Process one extracted.json against a pre-built tree and ts_index.""" with open(extracted_path) as f: extracted = json.load(f) n_kernels = len(extracted["kernels"]) print(f" Matching {n_kernels} kernels...", file=sys.stderr, end=" ") - result = extract_tree_context( - tree, extracted, ts_index=ts_index, capture_augmented=capture_augmented - ) + result = extract_tree_context(tree, extracted, ts_index=ts_index) print(f"{result['coverage']:.1%} coverage", file=sys.stderr) with open(output_path, "w") as f: @@ -258,27 +232,15 @@ def main(): "with extracted.json. Builds tree once, writes " "tree_context.json into each region subdir.", ) - parser.add_argument( - "--capture-trace", - help="Path to a capture-phase trace file. When provided, the " - "capture tree is merged into the graph-replay tree before " - "extracting context, restoring cpu_op ancestry for kernels " - "that would otherwise be hidden under cudaGraphLaunch.", - ) args = parser.parse_args() if not args.extracted_json and not args.regions_dir: parser.error("provide either extracted_json or --regions-dir") - capture_augmented = args.capture_trace is not None - print(f"Building trace tree from {args.trace}...", file=sys.stderr) - tree = load_and_build_tree(args.trace, capture_trace_path=args.capture_trace) + tree = load_and_build_tree(args.trace) ts_index = _build_ts_index(tree) - if capture_augmented: - print("Capture-trace augmentation active", file=sys.stderr) - if args.regions_dir: regions = _find_region_subdirs(args.regions_dir) if not regions: @@ -292,13 +254,7 @@ def main(): print(f"Region '{name}':", file=sys.stderr) extracted_path = os.path.join(subdir, "extracted.json") output_path = os.path.join(subdir, "tree_context.json") - _process_single( - tree, - ts_index, - extracted_path, - output_path, - capture_augmented=capture_augmented, - ) + _process_single(tree, ts_index, extracted_path, output_path) print( f"Wrote tree_context.json to {len(regions)} region subdirs", file=sys.stderr ) @@ -309,9 +265,7 @@ def main(): f"Matching {len(extracted['kernels'])} kernels to tree events...", file=sys.stderr, ) - result = extract_tree_context( - tree, extracted, ts_index=ts_index, capture_augmented=capture_augmented - ) + result = extract_tree_context(tree, extracted, ts_index=ts_index) print( f"Tree context: {result['labeled_count']}/{result['total_kernels']} " diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md index 85c3aa672..d6a7c867e 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md @@ -54,10 +54,6 @@ Ask the user for: **Optional:** - Output directory (default: `comparison_output/`) -- Capture trace A/B paths (for graph-mode traces with companion captures) - -**Auto-detection:** If the user provides a directory, look for paired -`*_graph*` and `*_capture*` files. **vLLM / annotated traces** are auto-detected by `extract_trace_data.py`. No special flag is needed. @@ -89,7 +85,7 @@ run_breakdown() { # Check whether extraction produced region subdirs or a flat file if ls $DIR/*/extracted.json >/dev/null 2>&1; then - # Multi-region. Skip extract_tree_context.py entirely for no-capture + # Multi-region. Skip extract_tree_context.py entirely for # graph-mode traces, same reasoning as the single-trace branch below: # cpu_op/nn_module ancestry is always empty under cudaGraphLaunch, and # gpu_op_uid is already populated per-region by extract_trace_data.py @@ -117,13 +113,12 @@ run_breakdown() { -o $REGION/semantic_labels.json done else - # Single-trace. Skip extract_tree_context.py entirely for no-capture + # Single-trace. Skip extract_tree_context.py entirely for # graph-mode traces: kernels sit directly under cudaGraphLaunch, so # cpu_op/nn_module ancestry is always empty there anyway, and # gpu_op_uid is already populated by extract_trace_data.py itself # (a plain raw-index lookup, no tree build needed). Only build the - # tree when non-graph-mode, or when a companion capture trace is - # available to restore ancestry via --capture-trace. + # tree when non-graph-mode. IS_GRAPH_MODE=$(python -c "import json; print(json.load(open('$DIR/extracted.json'))['metadata']['is_graph_mode'])") python $SCRIPTS/pattern_finder.py $DIR/extracted.json -o $DIR/pattern.json & python $CLASSIFY $DIR/extracted.json -o $DIR/classified.json & @@ -146,11 +141,6 @@ run_breakdown $DIR_B & wait ``` -For multi-region traces, and for single graph-mode traces where a -companion capture trace **is** available, add `--capture-trace -` to the `extract_tree_context.py` call to restore cpu_op -ancestry via the capture/graph-replay merge. - **Output directories:** - Trace A: `/_work//` - Trace B: `/_work//` diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md index 866067c23..e310e64ac 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md @@ -84,7 +84,7 @@ Use vendor-agnostic terminology throughout such as GPU kernels, collective commu - If **Graph replay + capture**, ask for the **Capture Folder Path(s)**: - `standalone`: one folder → ``. Ask: "Please provide the full path to the graph capture traces folder" - `comparative`: one folder per trace → `` (primary/trace1) and `` (comparison/trace2). Ask: "Please provide the graph capture traces folder for the primary trace and for the comparison trace." - - **Comparative + graph replay is routed in Step 0.5** (do not abort): collect capture folders for both traces when available. + - **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). 5. **Environment Setup** - Ask: "Are you running locally or on a cluster?" @@ -162,22 +162,16 @@ Do NOT proceed to Step 1 until validation passes. --- -## Step 0.5: Comparison Method Detection (comparative only) +## Step 0.5: Comparison Method (comparative only) For `standalone`, skip this step. -For `comparative`, auto-detect the comparison path (structural **TraceDiff** vs **semantic**). Pass `--capture{1,2}-available` for any trace that had a capture folder collected: +For `comparative`, set `` directly from what was already collected in Step 0 — no trace inspection or classification: -```bash - python3 TraceLens/Agent/Analysis/utils/comparison_routing.py \ - \ - --platform1 --platform2 \ - [--capture1-available] [--capture2-available] -``` - -Set `` to the printed `method` field and echo `reasons`. +- If a graph-replay trace is involved (`` = `graph_capture`) but capture folders were **not** collected for it in Step 0, set `` = `semantic` (graph traces have no alignable CPU-op tree to diff, so the name-first semantic comparison is used). +- Otherwise set `` = `tracediff`. -If `method` is `semantic` and a graph-mode trace is involved but capture folders were not collected in Step 0, ask for them now: `` (trace1) and `` (trace2). +> v1 scope: semantic is used only for graph+graph comparisons without capture. Cross-framework routing to semantic is deferred to a follow-up. --- @@ -294,7 +288,6 @@ Read and follow the FULL instructions in: - Labels: name-a trace1, name-b trace2 - Output directory: /_semantic/ - Command prefix: read /cache/cmd_prefix.txt — substitute {CMD} -- Capture folders (graph mode only): trace1 , trace2 Run the full semantic comparison through "Generate TraceDiff Output" so that /_semantic/tracediff_output/diff_stats.csv is produced. Return "DONE". @@ -700,6 +693,6 @@ If the plot is skipped, the `{{PERF_PLOT}}` placeholder is removed so the report If Steps 1 or many of Steps 2-5 fail or produce unexpected results, check whether the trace uses the following features before retrying: - **GPU Graph Replay**: raw trace JSON contains `hipGraphLaunch` or `cudaGraphLaunch`. - - **Comparative scope**: graph replay is **supported**; routing (tracediff+capture vs semantic) was already decided in Step 0.5. Ensure capture folders were collected for both traces when available. + - **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. - **Default mode, standalone** (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, standalone**: graph launches are expected and supported; continue whether or not a capture folder was provided (eager mode has none). diff --git a/TraceLens/Agent/Analysis/utils/comparison_routing.py b/TraceLens/Agent/Analysis/utils/comparison_routing.py deleted file mode 100644 index c169097e9..000000000 --- a/TraceLens/Agent/Analysis/utils/comparison_routing.py +++ /dev/null @@ -1,222 +0,0 @@ -#!/usr/bin/env python3 -############################################################################### -# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. -# -# See LICENSE for license information. -############################################################################### - -"""Trace origin/type detection for comparative-analysis routing. - -Decides, from a cheap one-pass scan of a Chrome/PyTorch trace, whether a -comparative run should use the structural TraceDiff path or the semantic -comparison path. - -Two layers: - * ``classify_trace(trace_path)`` -> {framework, exec_mode, annotated} - determines a single trace's origin/type. - * ``classify_comparison_method(trace1, trace2, capture1_available, - capture2_available, platform1, platform2)`` - -> {method, reasons, trace1_kind, trace2_kind} - applies the semantic-vs-tracediff rule across the two traces. - -The routing principle is "semantic only when TraceDiff cannot work": the -structural TraceDiff path needs an alignable CPU-op tree on both sides, so -the semantic path is used only when (a) the two traces come from different -frameworks (their CPU-op trees do not align), or (b) a trace is graph-mode -with no capture trace available (no CPU-op tree to diff against). Everything -else -- including same-framework cross-platform eager traces -- stays on -TraceDiff. - -This intentionally avoids the heavyweight ``split_vllm_trace()`` (which spawns -a subprocess and fully splits the trace); detection only needs a lightweight -scan of ``traceEvents``. - -Usage: - python comparison_routing.py \ - --platform1 MI300X --platform2 MI355X \ - --capture1-available --capture2-available -""" - -import argparse -import gzip -import json -import re -import sys - -# Iteration-annotation markers: per-iteration ``user_annotation`` event -# names emitted by vLLM/SGLang. -ANNOTATION_PATTERN = [ - re.compile( - r"execute_\d+_context_\d+\(sq\d+sk\d+sqsq\d+sqsk\d+\)_generation_\d+\(sq\d+sk\d+sqsq\d+sqsk\d+\)" - ), - re.compile(r"execute_context_\d+\(\d+\)_generation_\d+\(\d+\)"), - re.compile(r"execute_new_\d+_cached_\d+"), - re.compile(r"execute_context_\d+\(\d+_\d+\)_generation_\d+\(\d+\)"), -] - - -def _load_events(trace_path): - """Load ``traceEvents`` from a .json or .json.gz Chrome trace.""" - opener = gzip.open if trace_path.endswith(".gz") else open - with opener(trace_path, "rt") as f: - data = json.load(f) - return data.get("traceEvents", []) - - -def classify_trace(trace_path): - """Determine a single trace's origin/type from a cheap one-pass scan. - - Returns: - dict with - - ``framework``: "vllm" | "sglang" | "plain" - - ``exec_mode``: "graph" | "eager" - - ``annotated``: bool (an inference-framework trace, i.e. carries - vLLM/SGLang annotations / namespaces) - """ - events = _load_events(trace_path) - - has_graph_launch = False - has_vllm = False - has_sglang = False - has_annotation = False - - for e in events: - if not isinstance(e, dict): - continue - name = e.get("name", "") - if not isinstance(name, str): - continue - cat = e.get("cat", "") - - # exec_mode: same substring test as extract_trace_data.detect_graph_mode - # (covers both cudaGraphLaunch and hipGraphLaunch). - if not has_graph_launch and cat == "cuda_runtime" and "GraphLaunch" in name: - has_graph_launch = True - - # Framework markers appear in python_function / user_annotation names - # (module namespaces and file paths). - if not has_sglang and "sglang" in name: - has_sglang = True - if not has_vllm and "vllm" in name: - has_vllm = True - - # Per-iteration annotations indicate an inference workload. - if not has_annotation and cat == "user_annotation": - if any(p.match(name) for p in ANNOTATION_PATTERN): - has_annotation = True - - if has_sglang: - framework = "sglang" - elif has_vllm: - framework = "vllm" - else: - framework = "plain" - - annotated = has_annotation or framework in ("vllm", "sglang") - - return { - "framework": framework, - "exec_mode": "graph" if has_graph_launch else "eager", - "annotated": annotated, - } - - -def classify_comparison_method( - trace1, - trace2, - capture1_available=False, - capture2_available=False, - platform1=None, - platform2=None, -): - """Decide between the structural TraceDiff path and the semantic path. - - Routes to ``semantic`` only when TraceDiff cannot work, i.e. when ANY of: - - the two traces come from different frameworks (their CPU-op trees do - not align, so TraceDiff cannot match them), or - - a trace is graph-mode AND has no capture trace available (no CPU-op - tree to diff against). - - Everything else stays on ``tracediff``. In particular, a platform - difference does NOT force semantic: same-framework cross-platform eager - traces keep an alignable CPU-op tree (only kernel names/durations differ), - which TraceDiff handles. ``platform1``/``platform2`` are accepted only for - human-readable reasons, never for the decision. - - Args: - capture1_available / capture2_available: whether a capture trace was - collected for the corresponding trace (needed to give a graph-mode - trace an alignable CPU-op tree). Capture availability is external - to the trace JSON, so it must be supplied by the caller. - - Returns: - dict with ``method`` ("semantic"|"tracediff"), a human-readable - ``reasons`` list, and the per-trace ``classify_trace`` results. - """ - k1 = classify_trace(trace1) - k2 = classify_trace(trace2) - - reasons = [] - if k1["framework"] != k2["framework"]: - reasons.append(f"frameworks differ ({k1['framework']} vs {k2['framework']})") - if k1["exec_mode"] == "graph" and not capture1_available: - reasons.append("trace1 is graph-mode with no capture trace available") - if k2["exec_mode"] == "graph" and not capture2_available: - reasons.append("trace2 is graph-mode with no capture trace available") - - method = "semantic" if reasons else "tracediff" - - return { - "method": method, - "reasons": reasons, - "trace1_kind": k1, - "trace2_kind": k2, - } - - -def main(): - parser = argparse.ArgumentParser( - description=( - "Classify two traces and decide TraceDiff vs semantic comparison. " - "Prints the decision as JSON." - ) - ) - parser.add_argument("trace1", help="Path to primary trace (.json/.json.gz)") - parser.add_argument("trace2", help="Path to comparison trace (.json/.json.gz)") - parser.add_argument( - "--platform1", - default=None, - help="Platform of trace1 (informational only; not used for the decision)", - ) - parser.add_argument( - "--platform2", - default=None, - help="Platform of trace2 (informational only; not used for the decision)", - ) - parser.add_argument( - "--capture1-available", - action="store_true", - help="A capture trace was collected for trace1 (gives a graph-mode " - "trace an alignable CPU-op tree for TraceDiff)", - ) - parser.add_argument( - "--capture2-available", - action="store_true", - help="A capture trace was collected for trace2", - ) - args = parser.parse_args() - - result = classify_comparison_method( - args.trace1, - args.trace2, - capture1_available=args.capture1_available, - capture2_available=args.capture2_available, - platform1=args.platform1, - platform2=args.platform2, - ) - json.dump(result, sys.stdout, indent=2) - sys.stdout.write("\n") - - -if __name__ == "__main__": - main() From 552a112692adde0016fafafeceb754c5262292b2 Mon Sep 17 00:00:00 2001 From: Arseny Date: Wed, 2 Sep 2026 18:49:24 -0700 Subject: [PATCH 44/50] Simplification and trimming --- .../semantic_analyses/extract_tree_context.py | 3 +- .../semantic_analyses/kernel_coherence.py | 14 ++-- .../semantic_analyses/kernel_runlength.py | 5 +- .../agents/kernel-stem-preprocessing-agent.md | 5 +- .../agents/semantic-comparison-agent.md | 74 +++++-------------- .../skills/analysis-orchestrator/reference.md | 20 ++--- 6 files changed, 43 insertions(+), 78 deletions(-) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py index e5fc25153..19fea0ca6 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py @@ -199,8 +199,7 @@ def _find_region_subdirs(regions_dir): def _process_single(tree, ts_index, extracted_path, output_path): """Process one extracted.json against a pre-built tree and ts_index.""" - with open(extracted_path) as f: - extracted = json.load(f) + extracted = load_json(extracted_path) n_kernels = len(extracted["kernels"]) print(f" Matching {n_kernels} kernels...", file=sys.stderr, end=" ") diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py index 56fda371d..bdbdcc998 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py @@ -10,8 +10,8 @@ After the first-pass name-first unification (``kernel_unification.py``), the comparison still has **one-sided** buckets: kernels whose unified name appears -in only one trace (e.g. vendor GEMM families -- MI300 ``Cijk_*`` vs B300 -``nvjet_*`` -- that could not be paired by name alone). +in only one trace (e.g. vendor GEMM families -- platform-A ``_*`` vs +platform-B ``_*`` -- that could not be paired by name alone). This pass uses the first-pass **shared** buckets as cross-trace-stable positional anchors. For each one-sided bucket it derives the *neighbor context* @@ -42,15 +42,15 @@ python kernel_coherence.py prepare-context \ --labels-a /semantic_labels.json \ --labels-b /semantic_labels.json \ - --name-a MI300 --name-b B300 \ + --name-a platform_a --name-b platform_b \ --neighbor-radius 1 \ -o kernel_coherence_context.json python kernel_coherence.py apply \ --context kernel_coherence_context.json \ --decisions kernel_coherence_decisions.json \ - [--audit-csv-a per_kernel_final_MI300.csv] \ - [--audit-csv-b per_kernel_final_B300.csv] + [--audit-csv-a per_kernel_final_a.csv] \ + [--audit-csv-b per_kernel_final_b.csv] """ import argparse @@ -67,6 +67,7 @@ run_index_per_kernel, shared_neighbor_windows_skip_non_shared, ) +from _helpers import load_json DEFAULT_RADIUS = 1 @@ -74,8 +75,7 @@ def _load(path): - with open(path) as f: - return json.load(f) + return load_json(path) def _dims_repr(dims, limit=160): diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_runlength.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_runlength.py index d6fa690d2..9737ff7b4 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_runlength.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_runlength.py @@ -21,11 +21,12 @@ import json +from _helpers import load_json + def load_sequence(labels_path): """Return the kernel-order list of semantic_block values for a labels file.""" - with open(labels_path) as f: - data = json.load(f) + data = load_json(labels_path) return [k.get("semantic_block", "") for k in data.get("labeled_kernels", [])] diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md index d5c266234..394309144 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md @@ -26,10 +26,9 @@ default 5000). Otherwise skip it entirely. High-cardinality name families blow up the unique count. A single logical GEMM family can appear as thousands of variants that differ only by an autotuner id -or embedded shape, e.g. `gemm_013123`, `gemm_013124`, ... or -`(vendor gemm name)_..._MT32x16x512_...`, `(vendor gemm name)_..._MT64x16x256_...`. These variants are the +or embedded shape/tile suffix. These variants are the same operation for the purpose of establishing cross-trace anchors, so -collapsing them to a **stem** (e.g. `gemm`, `(vendor gemm name)_..._MT#_...`) drastically +collapsing them to a **stem** (dropping the autotuner id and shape/tile suffix) drastically shrinks the set. But **not every varying parameter is noise.** Some distinctions should be kept diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md index d6a7c867e..34b31592e 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md @@ -85,13 +85,7 @@ run_breakdown() { # Check whether extraction produced region subdirs or a flat file if ls $DIR/*/extracted.json >/dev/null 2>&1; then - # Multi-region. Skip extract_tree_context.py entirely for - # graph-mode traces, same reasoning as the single-trace branch below: - # cpu_op/nn_module ancestry is always empty under cudaGraphLaunch, and - # gpu_op_uid is already populated per-region by extract_trace_data.py - # (split_inference_trace_annotation.py persists it onto each event via - # --emit-gpu-op-uid before writing the per-region file, so it survives - # the split subprocess -- no tree build needed to recover it). + # Multi-region graph-mode: skip extract_tree_context.py (gpu_op_uid already populated per-region, no tree build needed). FIRST_REGION=$(ls -d $DIR/*/ | head -1) IS_GRAPH_MODE=$(python -c "import json; print(json.load(open('${FIRST_REGION}extracted.json'))['metadata']['is_graph_mode'])") for REGION in $DIR/*/; do @@ -166,21 +160,16 @@ The LLM unifies raw **kernel names** across the two traces. The unified name is Scripts: `TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py` -### 2.1 Prepare Unification Context [S] +### 2.1 Prepare Unification Context ```bash -KU=TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py -python $KU prepare-context \ +python TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py prepare-context \ --labels-a /_work//semantic_labels.json \ --labels-b /_work//semantic_labels.json \ --name-a --name-b \ -o /_work/kernel_unification_context.json ``` -The context lists each trace's unique kernel names with `perf_categories`, -`kernel_count`, `total_dur_us`, and a `sample_input_dims`, split into -`only_in_` / `only_in_` / `in_both`. - ### 2.2 Stem Preprocessing (conditional, only if flagged) If Step 2.1 prints `STEM PREPROCESSING NEEDED` (combined unique names exceed @@ -188,7 +177,7 @@ the threshold, default 5000), the raw name set is too large for the LLM. Launch the subagent `TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md`, then: ```bash -python $KU apply-stem-rules \ +python TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py apply-stem-rules \ --labels-a /_work//semantic_labels.json \ --labels-b /_work//semantic_labels.json \ --name-a --name-b \ @@ -204,10 +193,10 @@ Re-run until the printed stem count is within budget. Read `TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md` and launch it with `kernel_unification_context.json` inline. For multi-region vLLM: run once per matching region pair. -### 2.4 Apply the Map [S] +### 2.4 Apply the Map ```bash -python $KU apply-map \ +python TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py apply-map \ --labels-a /_work//semantic_labels.json \ --labels-b /_work//semantic_labels.json \ --name-a --name-b \ @@ -231,7 +220,8 @@ pairs GEMMs across vendors by position and (b) splits a name that occurs in different contexts. Skip it only if `apply-map` already reported no meaningful one-sided buckets. -**2.6a Prepare coherence context [S]** +### 2.6a Prepare coherence context + ```bash KC=TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py python $KC prepare-context \ @@ -242,14 +232,17 @@ python $KC prepare-context \ -o /_work/kernel_coherence_context.json ``` -**2.6b Launch coherence agent [LLM]** -- read +### 2.6b Launch coherence agent + +Read `TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-coherence-agent.md` and launch it with `kernel_coherence_context.json` inline. It writes `/_work/kernel_coherence_decisions.json` (`context_renames` + `fallback_remap_a` / `fallback_remap_b`), pairing same-context one-sided buckets across traces into new shared names. -**2.6c Apply [S]** +### 2.6c Apply + ```bash python $KC apply \ --context /_work/kernel_coherence_context.json \ @@ -258,15 +251,12 @@ python $KC apply \ --audit-csv-b /_work/per_kernel_final_.csv ``` -`apply` rewrites `semantic_block` in place and prints any residual one-sided -condensed symbols. If meaningful (non-singleton) symbols remain, revise the -decisions and re-run 2.6b--2.6c; residual pre/post-layer singletons (setup / -copy / prefix-scan kernels with no counterpart) may be accepted. Increase -`--neighbor-radius` in 2.6a if one-sided buckets share an ambiguous context. +`apply` rewrites `semantic_block` in place and prints residual one-sided symbols. +Revise decisions and re-run 2.6b--2.6c if meaningful (non-singleton) symbols remain (singleton setup/copy kernels may be accepted); raise `--neighbor-radius` in 2.6a for ambiguous contexts. --- -## Step 3: Generate TraceDiff Output [S] +## Step 3: Generate TraceDiff Output ```bash python TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py \ @@ -284,17 +274,11 @@ Produces in `/tracediff_output/`: This is a **final deliverable** directory for downstream TraceDiff consumers. -**Perf-report enrichment compatibility:** `diff_stats.csv` carries a -per-kernel `gpu_op_uid` (identical to the perf report's -`kernel_details[].gpu_op_uid`) and a per-LCA `busy_time`, making it -consumable by `enrich_perf_report_dict_inplace` in -`TraceLens/Reporting/tracediff_comparison_extension.py`, which matches -diff rows to `unified_perf_summary` rows via `gpu_op_uid` and adds the -speedup / delta / LCA columns. +**Perf-report enrichment compatibility:** `diff_stats.csv` carries per-kernel `gpu_op_uid` and per-LCA `busy_time`, consumable by `enrich_perf_report_dict_inplace` in `TraceLens/Reporting/tracediff_comparison_extension.py`. --- -## Step 4: Generate Comparison CSV [S] +## Step 4: Generate Comparison CSV **Single-region mode:** ```bash @@ -327,23 +311,5 @@ python TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ ## Final Deliverables -``` -/ - _work/ - /semantic_labels.json - /semantic_labels.json - kernel_unification_context.json - kernel_unification_map.json - raw_to_stem.json - kernel_coherence_context.json - kernel_coherence_decisions.json - per_kernel_final_.csv - comparison.csv - tracediff_output/ - diff_stats.csv - diff_stats_unique_args_summary.csv - cpu_op_map.json - cpu_op_map_trace1.json - cpu_op_map_trace2.json - merged_tree_output.txt -``` +- `/_work/` -- per-trace `semantic_labels.json`, the unification/coherence JSON artifacts, `per_kernel_final_.csv`, and `comparison.csv` +- `/tracediff_output/` -- TraceDiff deliverables (see Step 3) diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md index e310e64ac..f253e8d18 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md @@ -38,7 +38,7 @@ Use vendor-agnostic terminology throughout such as GPU kernels, collective commu optionally invoke agent_extension.py (when present), then embed the PNG into the report. ``` -**Subagent usage:** Only invoke Task subagents in steps that explicitly say "subagent" (Step 1.S semantic diff, Steps 6, 7, 9). All other steps (including Step 7.5) must be performed directly by the orchestrator using the command prefix. +**Subagent usage:** Only invoke Task subagents in steps that explicitly say "subagent" (Step 1.5 semantic diff, Steps 6, 7, 9). All other steps (including Step 7.5) must be performed directly by the orchestrator using the command prefix. --- @@ -82,8 +82,8 @@ Use vendor-agnostic terminology throughout such as GPU kernels, collective commu 2. **Graph replay + capture** (`` = `graph_capture`) — also requires a capture folder path - If **Graph replay + capture**, ask for the **Capture Folder Path(s)**: - - `standalone`: one folder → ``. Ask: "Please provide the full path to the graph capture traces folder" - - `comparative`: one folder per trace → `` (primary/trace1) and `` (comparison/trace2). Ask: "Please provide the graph capture traces folder for the primary trace and for the comparison trace." + - `standalone`: one folder → ``. Ask: "Please provide the full path to the graph capture traces folder" + - `comparative`: one folder per trace → `` (primary/trace1) and `` (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). 5. **Environment Setup** @@ -203,16 +203,16 @@ All commands below append `` and ``, resolved by `` | -| `comparative` trace1 if `` provided | `--comparison_json_path --comparison_capture_folder ` | +| `comparative` trace1 if `` provided | `--comparison_json_path --comparison_capture_folder ` | | `comparative` trace2 | none | **``** — graph capture flags: | scope | value | |-------|-------| -| `standalone` if `` provided | `--capture_folder ` | -| `comparative` trace1 if `` provided | `--capture_folder ` | -| `comparative` trace2 if `` provided | `--capture_folder ` | +| `standalone` if `` provided | `--capture_folder ` | +| `comparative` trace1 if `` provided | `--capture_folder ` | +| `comparative` trace2 if `` provided | `--capture_folder ` | **``** — user extension file: @@ -270,11 +270,11 @@ All commands below append `` and ``, resolved by `` = `semantic` only) +## Step 1.5: Semantic Comparative Ordering (`` = `semantic` only) When `` = `comparative` and `` = `semantic`, run Step 1 in this order: -1. **Trace2 report** — run the analysis-mode CLI above for trace2 using the `comparative` trace2 `` and empty `` (identical to the TraceDiff path). For graph mode add `--capture_folder `. +1. **Trace2 report** — run the analysis-mode CLI above for trace2 using the `comparative` trace2 `` and empty `` (identical to the TraceDiff path). For graph mode add `--capture_folder `. 2. **Semantic diff (subagent)** — launch a Task subagent that reads and follows the FULL instructions in `TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md`. Prompt context: @@ -295,7 +295,7 @@ Run the full semantic comparison through "Generate TraceDiff Output" so that Verify `/_semantic/tracediff_output/diff_stats.csv` exists before continuing. If it is missing, retry the subagent once; if it still fails, stop and report. -3. **Trace1 report** — run the analysis-mode CLI for trace1 with the `comparative` trace1 `` and `` = `--precomputed_diff_stats_csv /_semantic/tracediff_output/diff_stats.csv`. For graph mode also add `--capture_folder `. +3. **Trace1 report** — run the analysis-mode CLI for trace1 with the `comparative` trace1 `` and `` = `--precomputed_diff_stats_csv /_semantic/tracediff_output/diff_stats.csv`. For graph mode also add `--capture_folder `. 4. **Confirm** `/perf_report_trace1_csvs/diff_stats.csv` exists (written by the report script). If absent, copy `/_semantic/tracediff_output/diff_stats.csv` to that path so the comparative fusion step (Steps 2-5) can read it. From a936791056fa61ebcbce803d5a4e2e8b18f4d63f Mon Sep 17 00:00:00 2001 From: Arseny Date: Wed, 2 Sep 2026 20:41:10 -0700 Subject: [PATCH 45/50] Initial test coverage + exclusions --- .coveragerc | 2 + .../build_semantic_labels.py | 4 +- .../semantic_analyses/extract_trace_data.py | 8 +- .../semantic_analyses/extract_tree_context.py | 14 +- .../generate_semantic_diff.py | 6 +- .../semantic_analyses/kernel_coherence.py | 8 +- .../semantic_analyses/kernel_unification.py | 10 +- .../semantic_analyses/match_and_compare.py | 4 +- .../semantic_analyses/trace_split_adapter.py | 2 +- .../skills/analysis-orchestrator/reference.md | 10 +- tests/test_semantic_annotation_metadata.py | 248 +++++++++++++ tests/test_semantic_build_labels.py | 228 ++++++++++++ tests/test_semantic_extract_trace_data.py | 206 +++++++++++ tests/test_semantic_extract_tree_context.py | 173 +++++++++ tests/test_semantic_generate_diff.py | 194 ++++++++++ tests/test_semantic_helpers.py | 99 ++++++ tests/test_semantic_kernel_coherence.py | 220 ++++++++++++ tests/test_semantic_kernel_runlength.py | 112 ++++++ tests/test_semantic_kernel_unification.py | 331 ++++++++++++++++++ tests/test_semantic_match_and_compare.py | 225 ++++++++++++ tests/test_semantic_precomputed_diff_stats.py | 75 ++++ tests/test_semantic_trace_split_adapter.py | 166 +++++++++ 22 files changed, 2311 insertions(+), 34 deletions(-) create mode 100644 tests/test_semantic_annotation_metadata.py create mode 100644 tests/test_semantic_build_labels.py create mode 100644 tests/test_semantic_extract_trace_data.py create mode 100644 tests/test_semantic_extract_tree_context.py create mode 100644 tests/test_semantic_generate_diff.py create mode 100644 tests/test_semantic_helpers.py create mode 100644 tests/test_semantic_kernel_coherence.py create mode 100644 tests/test_semantic_kernel_runlength.py create mode 100644 tests/test_semantic_kernel_unification.py create mode 100644 tests/test_semantic_match_and_compare.py create mode 100644 tests/test_semantic_precomputed_diff_stats.py create mode 100644 tests/test_semantic_trace_split_adapter.py diff --git a/.coveragerc b/.coveragerc index c4bb7d51c..23f815467 100644 --- a/.coveragerc +++ b/.coveragerc @@ -6,6 +6,8 @@ omit = 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 + TraceLens/Agent/Analysis/semantic_analyses/pattern_finder.py [paths] source = diff --git a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py index 3bcbd9b89..e1c4c1703 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py @@ -176,7 +176,7 @@ def build_labels(extracted, classified, pattern, tree_context=None): entry["region"] = "secondary" entry["layer"] = None entry["semantic_block"] = secondary_blocks[i] - else: + else: # pragma: no cover - defensive: every index is body/pre/post/secondary entry["region"] = "body" entry["layer"] = None entry["semantic_block"] = c.get("perf_category", "Others") + "_0" @@ -198,7 +198,7 @@ def build_labels(extracted, classified, pattern, tree_context=None): return result -def main(): +def main(): # pragma: no cover parser = argparse.ArgumentParser( description="Build semantic_labels.json deterministically from breakdown artifacts" ) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py index c5e127f5a..141dcce8a 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py @@ -181,7 +181,7 @@ def run_assertions(data, by_cat, kernels, is_graph_mode, strict=True): return errors -def compute_gpu_timeline_metrics(events): +def compute_gpu_timeline_metrics(events): # pragma: no cover """ Run GPUEventAnalyser on events and return gpu_timeline dict for metadata. Returns None on failure. @@ -235,7 +235,7 @@ def extract_and_build_result(data, by_cat, source_file, region_metadata=None): return result, kernels -def _write_split_regions(split_result, trace_path, output_dir): +def _write_split_regions(split_result, trace_path, output_dir): # pragma: no cover """Write per-region extracted.json + metadata.json files.""" os.makedirs(output_dir, exist_ok=True) for trace_dict, region_meta in split_result: @@ -271,7 +271,7 @@ def _write_split_regions(split_result, trace_path, output_dir): print(f"Wrote {extracted_path} ({len(kernels)} kernels)", file=sys.stderr) -def main(): +def main(): # pragma: no cover parser = argparse.ArgumentParser( description="Extract structured data from a Chrome trace JSON" ) @@ -333,5 +333,5 @@ def main(): print(output) -if __name__ == "__main__": +if __name__ == "__main__": # pragma: no cover main() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py index 19fea0ca6..e184f184f 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py @@ -30,9 +30,9 @@ _this_dir = os.path.dirname(os.path.abspath(__file__)) _repo_root = os.path.abspath(os.path.join(_this_dir, "..", "..", "..", "..")) -if _repo_root not in sys.path: +if _repo_root not in sys.path: # pragma: no cover sys.path.insert(0, _repo_root) -if _this_dir not in sys.path: +if _this_dir not in sys.path: # pragma: no cover sys.path.insert(0, _this_dir) from TraceLens.util import DataLoader @@ -40,7 +40,7 @@ from _helpers import load_json -def load_and_build_tree(trace_path): +def load_and_build_tree(trace_path): # pragma: no cover """Load a trace file and build a TraceToTree.""" data = DataLoader.load_data(trace_path) events = data.get("traceEvents", []) @@ -185,7 +185,7 @@ def extract_tree_context(tree, extracted_data, ts_index=None): return result -def _find_region_subdirs(regions_dir): +def _find_region_subdirs(regions_dir): # pragma: no cover """Find subdirectories containing extracted.json.""" regions = [] for name in sorted(os.listdir(regions_dir)): @@ -197,7 +197,7 @@ def _find_region_subdirs(regions_dir): return regions -def _process_single(tree, ts_index, extracted_path, output_path): +def _process_single(tree, ts_index, extracted_path, output_path): # pragma: no cover """Process one extracted.json against a pre-built tree and ts_index.""" extracted = load_json(extracted_path) @@ -211,7 +211,7 @@ def _process_single(tree, ts_index, extracted_path, output_path): return result -def main(): +def main(): # pragma: no cover parser = argparse.ArgumentParser( description="Extract trace tree context (cpu_op, nn_module) for each kernel" ) @@ -281,5 +281,5 @@ def main(): print(output) -if __name__ == "__main__": +if __name__ == "__main__": # pragma: no cover main() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py b/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py index 5e192467e..420ba478f 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py @@ -324,7 +324,7 @@ def build_merged_tree_text(block_id_map, labeled_a, labeled_b, name_a, name_b): # --------------------------------------------------------------------------- -def write_outputs( +def write_outputs( # pragma: no cover output_dir, diff_stats_df, summary_df, @@ -360,7 +360,7 @@ def write_outputs( # --------------------------------------------------------------------------- -def main(): +def main(): # pragma: no cover parser = argparse.ArgumentParser( description="Generate TraceDiff-compatible output from two semantic breakdowns" ) @@ -442,5 +442,5 @@ def main(): print(f" merged_tree_output.txt", file=sys.stderr) -if __name__ == "__main__": +if __name__ == "__main__": # pragma: no cover main() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py index bdbdcc998..cf94c9337 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py @@ -161,7 +161,7 @@ def _collect_contexts( return out -def cmd_prepare_context(args): +def cmd_prepare_context(args): # pragma: no cover labels_a = _load(args.labels_a) labels_b = _load(args.labels_b) kernels_a = labels_a["labeled_kernels"] @@ -326,7 +326,7 @@ def _final_blocks( return finals, audit -def _write_audit(path, rows): +def _write_audit(path, rows): # pragma: no cover with open(path, "w", newline="") as f: w = csv.DictWriter( f, @@ -357,7 +357,7 @@ def _residual_one_sided(labels_a, labels_b): return sorted(ca - cb), sorted(cb - ca) -def cmd_apply(args): +def cmd_apply(args): # pragma: no cover ctx = _load(args.context) dec = _load(args.decisions) name_a = ctx["name_a"] @@ -442,7 +442,7 @@ def cmd_apply(args): # =========================================================================== -def main(): +def main(): # pragma: no cover parser = argparse.ArgumentParser( description="Second-pass kernel-name coherence (prepare-context / apply)" ) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py index 4f63ef5ff..54b44e65d 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py @@ -210,7 +210,7 @@ def _spaced(agg, budget): return sample -def cmd_prepare_context(args): +def cmd_prepare_context(args): # pragma: no cover labels_a = _load(args.labels_a) labels_b = _load(args.labels_b) agg_a = aggregate_names(labels_a) @@ -332,7 +332,7 @@ def stem_for(name, compiled): return name, "preserve" -def cmd_apply_stem_rules(args): +def cmd_apply_stem_rules(args): # pragma: no cover labels_a = _load(args.labels_a) labels_b = _load(args.labels_b) rules_doc = _load(args.rules) @@ -448,7 +448,7 @@ def _apply_side(labels, unified_map, raw_to_stem): } -def cmd_apply_map(args): +def cmd_apply_map(args): # pragma: no cover labels_a = _load(args.labels_a) labels_b = _load(args.labels_b) map_doc = _load(args.map) @@ -484,14 +484,14 @@ def cmd_apply_map(args): # =========================================================================== -def _add_common(p): +def _add_common(p): # pragma: no cover p.add_argument("--labels-a", required=True, help="Trace A semantic_labels.json") p.add_argument("--labels-b", required=True, help="Trace B semantic_labels.json") p.add_argument("--name-a", default="trace_a", help="Short name for trace A") p.add_argument("--name-b", default="trace_b", help="Short name for trace B") -def main(): +def main(): # pragma: no cover parser = argparse.ArgumentParser( description="Name-first cross-trace kernel-name unification " "(prepare-context / apply-stem-rules / apply-map)" diff --git a/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py b/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py index a441ca0a8..214999bf2 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py @@ -61,7 +61,7 @@ def aggregate(labeled_kernels): return blocks -def load_metadata(path): +def load_metadata(path): # pragma: no cover """Load metadata.json and return gpu_timeline dict if present.""" if not path or not os.path.exists(path): return None @@ -189,7 +189,7 @@ def run_assertions(rows, labeled_a, labeled_b, total_a, total_b, name_a, name_b) return errors -def main(): +def main(): # pragma: no cover parser = argparse.ArgumentParser(description="Compare two semantic breakdowns") parser.add_argument( "trace_a", nargs="?", help="Path to trace A semantic_labels.json" diff --git a/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py b/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py index 58b369561..1ab455d0d 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py @@ -120,7 +120,7 @@ def _iter_type_key(phase: dict) -> str: return f"empty_{bs}" -def split_vllm_trace(trace_path: str) -> Optional[List[Tuple[dict, dict]]]: +def split_vllm_trace(trace_path: str) -> Optional[List[Tuple[dict, dict]]]: # pragma: no cover """ Split a vLLM trace using TraceUtils split_inference_trace_annotation. diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md index f253e8d18..6b9baf7c8 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md @@ -166,13 +166,11 @@ Do NOT proceed to Step 1 until validation passes. For `standalone`, skip this step. -For `comparative`, set `` directly from what was already collected in Step 0 — no trace inspection or classification: +For `comparative`, set `` directly from what was already collected in Step 0: -- If a graph-replay trace is involved (`` = `graph_capture`) but capture folders were **not** collected for it in Step 0, set `` = `semantic` (graph traces have no alignable CPU-op tree to diff, so the name-first semantic comparison is used). +- If a graph-replay trace is involved (`` = `graph_capture`) but capture folders were **not** collected for it in Step 0, set `` = `semantic`. - Otherwise set `` = `tracediff`. -> v1 scope: semantic is used only for graph+graph comparisons without capture. Cross-framework routing to semantic is deferred to a follow-up. - --- ## Step 1: Generate Performance Report @@ -274,7 +272,7 @@ All commands below append `` and ``, resolved by `` = `comparative` and `` = `semantic`, run Step 1 in this order: -1. **Trace2 report** — run the analysis-mode CLI above for trace2 using the `comparative` trace2 `` and empty `` (identical to the TraceDiff path). For graph mode add `--capture_folder `. +1. **Trace2 report** — run the analysis-mode CLI above for trace2 using the `comparative` trace2 `` and empty `` (identical to the TraceDiff path). 2. **Semantic diff (subagent)** — launch a Task subagent that reads and follows the FULL instructions in `TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md`. Prompt context: @@ -295,7 +293,7 @@ Run the full semantic comparison through "Generate TraceDiff Output" so that Verify `/_semantic/tracediff_output/diff_stats.csv` exists before continuing. If it is missing, retry the subagent once; if it still fails, stop and report. -3. **Trace1 report** — run the analysis-mode CLI for trace1 with the `comparative` trace1 `` and `` = `--precomputed_diff_stats_csv /_semantic/tracediff_output/diff_stats.csv`. For graph mode also add `--capture_folder `. +3. **Trace1 report** — run the analysis-mode CLI for trace1 with the `comparative` trace1 `` and `` = `--precomputed_diff_stats_csv /_semantic/tracediff_output/diff_stats.csv`. 4. **Confirm** `/perf_report_trace1_csvs/diff_stats.csv` exists (written by the report script). If absent, copy `/_semantic/tracediff_output/diff_stats.csv` to that path so the comparative fusion step (Steps 2-5) can read it. diff --git a/tests/test_semantic_annotation_metadata.py b/tests/test_semantic_annotation_metadata.py new file mode 100644 index 000000000..4821a9926 --- /dev/null +++ b/tests/test_semantic_annotation_metadata.py @@ -0,0 +1,248 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Unit tests for semantic_analyses/annotation_metadata.py.""" + +import os +import sys + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SEM = os.path.join(REPO_ROOT, "TraceLens", "Agent", "Analysis", "semantic_analyses") +sys.path.insert(0, SEM) + +import annotation_metadata + + +# --------------------------------------------------------------------------- +# parse_filename_metadata +# --------------------------------------------------------------------------- +def test_parse_filename_all_fields_with_path(): + path = "/data/traces/mi355_tp2_isl1024_osl8_conc4_opt.pt.trace.json.gz" + result = annotation_metadata.parse_filename_metadata(path) + assert result["isl"] == 1024 + assert result["osl"] == 8 + assert result["conc"] == 4 + assert result["tp"] == 2 + assert result["num_tokens_prefill"] == 1024 * 4 + assert result["num_tokens_decode"] == 4 + + +def test_parse_filename_all_fields_no_slash(): + result = annotation_metadata.parse_filename_metadata("tp1_isl16_osl2_conc3.json") + assert result["isl"] == 16 + assert result["osl"] == 2 + assert result["conc"] == 3 + assert result["tp"] == 1 + assert result["num_tokens_prefill"] == 48 + assert result["num_tokens_decode"] == 3 + + +def test_parse_filename_no_fields(): + assert annotation_metadata.parse_filename_metadata("randomfile.txt") == {} + + +def test_parse_filename_conc_only_no_isl(): + result = annotation_metadata.parse_filename_metadata("run_conc5.json") + assert result["conc"] == 5 + assert result["num_tokens_decode"] == 5 + assert "num_tokens_prefill" not in result + + +def test_parse_filename_isl_only_no_conc(): + result = annotation_metadata.parse_filename_metadata("run_isl99.json") + assert result["isl"] == 99 + assert "num_tokens_prefill" not in result + assert "num_tokens_decode" not in result + + +# --------------------------------------------------------------------------- +# parse_trace_input_dims +# --------------------------------------------------------------------------- +def test_parse_trace_input_dims_empty(): + assert annotation_metadata.parse_trace_input_dims([]) == {} + + +def test_parse_trace_input_dims_full(): + events = [ + # non-kernel event -> skipped + {"cat": "cpu_op", "name": "unified_attention"}, + # kernel but not attention -> skipped + {"cat": "kernel", "name": "gemm_kernel"}, + # attention kernel, q/k len == 3 + { + "cat": "kernel", + "name": "unified_attention", + "args": {"Input Dims": [[5, 1, 1], [7, 1, 1]]}, + }, + # attention kernel, q/k len > 3 (uses [-3]) + { + "cat": "kernel", + "name": "flash_attention_fwd", + "args": {"Input Dims": [[2, 3, 4, 5], [6, 7, 8, 9]]}, + }, + # attention kernel, dims too short -> skipped + { + "cat": "kernel", + "name": "unified_attention", + "args": {"Input Dims": [[1, 1]]}, + }, + # attention kernel, q/k not list-like -> skips nq/nkv appends + { + "cat": "kernel", + "name": "unified_attention", + "args": {"Input Dims": [5, 6]}, + }, + # attention kernel, q/k list but len < 3 -> skipped + { + "cat": "kernel", + "name": "unified_attention", + "args": {"Input Dims": [[1, 2], [3, 4]]}, + }, + # attention kernel, dims is a non-subscriptable set -> triggers except + { + "cat": "kernel", + "name": "unified_attention", + "args": {"Input Dims": {1, 2, 3}}, + }, + ] + result = annotation_metadata.parse_trace_input_dims(events) + # nq_values = [5, 3] -> avg = 4, count = 2 + assert result["trace_avg_nq"] == 4 + assert result["trace_attention_kernel_count"] == 2 + # nkv_values = [7, 7] -> avg = 7 + assert result["trace_avg_nkv"] == 7 + + +def test_parse_trace_input_dims_no_dims_key(): + events = [{"cat": "kernel", "name": "unified_attention", "args": {}}] + assert annotation_metadata.parse_trace_input_dims(events) == {} + + +# --------------------------------------------------------------------------- +# run_sanity_checks +# --------------------------------------------------------------------------- +def test_run_sanity_checks_all_warnings(): + warnings = annotation_metadata.run_sanity_checks( + annotation_meta={"batch_size": 100, "context_sum": 100}, + filename_meta={"isl": 10, "conc": 100}, + trace_meta={"trace_avg_nq": 200}, + user_meta={"num_tokens": 500}, + ) + assert len(warnings) == 3 + assert any("Batch size mismatch" in w for w in warnings) + assert any("num_tokens mismatch" in w for w in warnings) + assert any("Context sum mismatch" in w for w in warnings) + + +def test_run_sanity_checks_no_warnings_matching(): + warnings = annotation_metadata.run_sanity_checks( + annotation_meta={"batch_size": 1000, "context_sum": 100}, + filename_meta={"isl": 10, "conc": 100}, + trace_meta={"trace_avg_nq": 100}, + user_meta={"num_tokens": 1000}, + ) + assert warnings == [] + + +def test_run_sanity_checks_empty_all(): + assert annotation_metadata.run_sanity_checks({}, {}, {}, {}) == [] + + +def test_run_sanity_checks_filename_missing_conc(): + # isl present but conc missing -> batch_file stays None, no batch warning + warnings = annotation_metadata.run_sanity_checks( + annotation_meta={"batch_size": 100}, + filename_meta={"isl": 10}, + trace_meta={}, + user_meta={}, + ) + assert warnings == [] + + +# --------------------------------------------------------------------------- +# merge_metadata +# --------------------------------------------------------------------------- +def test_merge_metadata_all_none(): + merged = annotation_metadata.merge_metadata() + assert merged["annotation"] == {} + assert merged["filename"] == {} + assert merged["trace"] == {} + assert merged["user"] == {} + assert merged["num_tokens"] is None + assert merged["context_length"] is None + assert merged["batch_size"] is None + assert merged["context_sum"] is None + assert merged["generation_sum"] is None + assert merged["_warnings"] == [] + + +def test_merge_metadata_user_priority(): + merged = annotation_metadata.merge_metadata( + user_meta={"num_tokens": 42, "context_length": 77}, + ) + assert merged["num_tokens"] == 42 + assert merged["context_length"] == 77 + + +def test_merge_metadata_annotation_and_filename_fallbacks(): + merged = annotation_metadata.merge_metadata( + annotation_meta={"context_sum": 256, "generation_sum": 8}, + filename_meta={"num_tokens_prefill": 512, "isl": 128}, + ) + # num_tokens: no user/annotation batch_size -> prefill + assert merged["num_tokens"] == 512 + # context_length: annotation context_sum wins + assert merged["context_length"] == 256 + assert merged["batch_size"] == 512 + assert merged["context_sum"] == 256 + assert merged["generation_sum"] == 8 + + +def test_merge_metadata_context_from_num_tokens_fallback(): + # no context sources except num_tokens (from decode) + merged = annotation_metadata.merge_metadata( + filename_meta={"num_tokens_decode": 4}, + ) + assert merged["num_tokens"] == 4 + assert merged["context_length"] == 4 + + +def test_merge_metadata_emits_warning(): + merged = annotation_metadata.merge_metadata( + annotation_meta={"batch_size": 100}, + user_meta={"num_tokens": 500}, + ) + assert merged["_warnings"] + assert any("num_tokens mismatch" in w for w in merged["_warnings"]) + + +# --------------------------------------------------------------------------- +# gather_metadata +# --------------------------------------------------------------------------- +def test_gather_metadata_with_user_values(): + merged = annotation_metadata.gather_metadata( + trace_path="/x/tp1_isl1024_conc4.json", + events=None, + annotation_meta={"batch_size": 4096}, + num_tokens=4096, + context_length=1024, + ) + assert merged["num_tokens"] == 4096 + assert merged["context_length"] == 1024 + assert merged["filename"]["isl"] == 1024 + assert merged["trace"] == {} + + +def test_gather_metadata_no_user_values(): + merged = annotation_metadata.gather_metadata( + trace_path="plain.json", + events=None, + annotation_meta=None, + num_tokens=None, + context_length=None, + ) + assert merged["user"] == {} + assert merged["num_tokens"] is None diff --git a/tests/test_semantic_build_labels.py b/tests/test_semantic_build_labels.py new file mode 100644 index 000000000..10b48eac1 --- /dev/null +++ b/tests/test_semantic_build_labels.py @@ -0,0 +1,228 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Unit tests for semantic_analyses/build_semantic_labels.py. + +Uses in-memory dict fixtures (no file I/O) to exercise the deterministic +labeling logic: positional block numbering, the layer-cycle detection and +the region (pre / body / post / secondary) helpers. +""" + +import os +import sys + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SEM = os.path.join(REPO_ROOT, "TraceLens", "Agent", "Analysis", "semantic_analyses") +sys.path.insert(0, SEM) + +import build_semantic_labels + + +# --------------------------------------------------------------------------- # +# _deepest_module +# --------------------------------------------------------------------------- # +def test_deepest_module_empty(): + assert build_semantic_labels._deepest_module([]) == "" + + +def test_deepest_module_strips_prefix_and_takes_deepest(): + stack = ["nn.Module: WanTransformer3DModel > nn.Module: WanTransformerBlock"] + assert build_semantic_labels._deepest_module(stack) == "WanTransformerBlock" + + +def test_deepest_module_without_prefix(): + assert build_semantic_labels._deepest_module(["PlainName"]) == "PlainName" + + +# --------------------------------------------------------------------------- # +# _build_cycle_names +# --------------------------------------------------------------------------- # +def test_build_cycle_names_nonpositive_period(): + rle = [("GEMM", 1, [0], ["T"])] + assert build_semantic_labels._build_cycle_names(rle, 0, {}) == [] + + +def test_build_cycle_names_uses_global_counter(): + rle = [ + ("GEMM", 1, [0], ["T"]), + ("Normalization", 1, [1], ["T"]), + ("SDPA", 1, [2], ["T"]), + ] + counter = {"GEMM": 1} # pretend one GEMM was already numbered + names = build_semantic_labels._build_cycle_names(rle, 3, counter) + assert names == ["GEMM_1", "Normalization_0", "SDPA_0"] + assert counter == {"GEMM": 2, "Normalization": 1, "SDPA": 1} + + +# --------------------------------------------------------------------------- # +# _build_region_block_names +# --------------------------------------------------------------------------- # +def test_build_region_block_names_empty(): + assert build_semantic_labels._build_region_block_names(set(), {}, {}) == {} + + +def test_build_region_block_names_groups_consecutive(): + cls_by_idx = { + 0: {"perf_category": "GEMM"}, + 1: {"perf_category": "GEMM"}, + 2: {"perf_category": "Normalization"}, + # index 3 intentionally absent -> defaults to "Others" + } + counter = {} + result = build_semantic_labels._build_region_block_names( + {0, 1, 2, 3}, cls_by_idx, counter + ) + assert result == { + 0: "GEMM_0", + 1: "GEMM_0", + 2: "Normalization_0", + 3: "Others_0", + } + assert counter == {"GEMM": 1, "Normalization": 1, "Others": 1} + + +# --------------------------------------------------------------------------- # +# build_labels (integration over the pure labeling path) +# --------------------------------------------------------------------------- # +def _classified(cats): + return { + "classified_kernels": [ + {"index": i, "perf_category": cat, "kernel_type": "T"} + for i, cat in enumerate(cats) + ] + } + + +def _extracted(n, total_time=123.456, graph_mode=True): + return { + "source_file": "trace.json", + "metadata": { + "total_kernel_time_us": total_time, + "is_graph_mode": graph_mode, + }, + "kernels": [ + {"name": f"k{i}", "dur": float(i + 1), "gpu_op_uid": f"raw{i}"} + for i in range(n) + ], + } + + +def test_build_labels_positional_labels_and_layers(): + # 0,1 = preamble ; 2..13 = body (G,N,S repeated x4) ; 14,15 = epilogue ; 16 = secondary + cats = ( + ["GEMM", "GEMM"] + + ["GEMM", "Normalization", "SDPA"] * 4 + + ["Normalization", "Normalization"] + + ["GEMM"] + ) + extracted = _extracted(len(cats)) + classified = _classified(cats) + pattern = { + "preamble_indices": [0, 1], + "epilogue_indices": [14, 15], + "secondary_stream_indices": [16], + } + tree_context = { + "kernels": [ + { + "index": 2, + "gpu_op_uid": "tree2", + "nn_module_stack": ["nn.Module: Model > nn.Module: Block"], + "cpu_op_name": "aten::mm", + "input_dims": [[1, 2]], + }, + { + # tree entry present but no UID -> falls back to raw uid + "index": 4, + "gpu_op_uid": None, + "nn_module_stack": ["Solo"], + "cpu_op_name": "", + "input_dims": [], + }, + ] + } + + result = build_semantic_labels.build_labels( + extracted, classified, pattern, tree_context + ) + + info = result["model_info"] + assert info["period"] == 3 + assert info["num_layers"] == 4 + assert info["graph_mode"] is True + assert result["total_kernel_time_us"] == 123.46 + assert result["source_file"] == "trace.json" + + kernels = result["labeled_kernels"] + + # Preamble region: GEMM_0 (numbered before the body cycle). + assert kernels[0]["region"] == "pre" + assert kernels[0]["layer"] is None + assert kernels[0]["semantic_block"] == "GEMM_0" + + # Body cycle: GEMM in the body is GEMM_1 (global counter continues). + assert kernels[2]["region"] == "body" + assert kernels[2]["layer"] == 0 + assert kernels[2]["semantic_block"] == "GEMM_1" + assert kernels[3]["semantic_block"] == "Normalization_0" + assert kernels[4]["semantic_block"] == "SDPA_0" + + # Positional labels repeat across layers. + assert kernels[5]["semantic_block"] == "GEMM_1" + assert kernels[5]["layer"] == 1 + assert kernels[13]["semantic_block"] == "SDPA_0" + assert kernels[13]["layer"] == 3 + + # Epilogue + secondary reuse the global counter (unique numbering). + assert kernels[14]["region"] == "post" + assert kernels[14]["semantic_block"] == "Normalization_1" + assert kernels[16]["region"] == "secondary" + assert kernels[16]["semantic_block"] == "GEMM_2" + + # tree_context enrichment + gpu_op_uid preference / fallback. + assert kernels[2]["nn_module"] == "Block" + assert kernels[2]["cpu_op"] == "aten::mm" + assert kernels[2]["gpu_op_uid"] == "tree2" + assert kernels[4]["nn_module"] == "Solo" + assert kernels[4]["gpu_op_uid"] == "raw4" # tree uid was None -> raw fallback + # Kernel with no tree entry -> empty enrichment, raw uid. + assert kernels[3]["nn_module"] == "" + assert kernels[3]["cpu_op"] == "" + assert kernels[3]["gpu_op_uid"] == "raw3" + + +def test_build_labels_no_body_period_zero_and_no_tree_context(): + cats = ["GEMM", "GEMM", "Normalization"] + extracted = {"kernels": [{"name": f"k{i}", "dur": 1.0} for i in range(3)]} + classified = _classified(cats) + pattern = { + "preamble_indices": [0, 1, 2], + "epilogue_indices": [], + "secondary_stream_indices": [], + } + + result = build_semantic_labels.build_labels( + extracted, classified, pattern, tree_context=None + ) + + info = result["model_info"] + assert info["period"] == 0 + assert info["num_layers"] == 0 + assert info["graph_mode"] is False + assert result["total_kernel_time_us"] == 0 + assert result["source_file"] == "" + + kernels = result["labeled_kernels"] + assert [k["semantic_block"] for k in kernels] == [ + "GEMM_0", + "GEMM_0", + "Normalization_0", + ] + assert all(k["region"] == "pre" for k in kernels) + assert all(k["layer"] is None for k in kernels) + # No tree context and no raw uid -> gpu_op_uid is None. + assert kernels[0]["gpu_op_uid"] is None + assert kernels[0]["nn_module"] == "" diff --git a/tests/test_semantic_extract_trace_data.py b/tests/test_semantic_extract_trace_data.py new file mode 100644 index 000000000..5afc94269 --- /dev/null +++ b/tests/test_semantic_extract_trace_data.py @@ -0,0 +1,206 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Unit tests for semantic_analyses/extract_trace_data.py extractors.""" + +import json +import os, sys +import tempfile + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SEM = os.path.join(REPO_ROOT, "TraceLens", "Agent", "Analysis", "semantic_analyses") +sys.path.insert(0, SEM) +import extract_trace_data + + +def _kernel(name, ts, dur, stream=None, cat="kernel", **extra): + ev = {"name": name, "ts": ts, "dur": dur, "cat": cat} + if stream is not None: + ev["args"] = {"stream": stream} + ev.update(extra) + return ev + + +def test_load_trace_from_dict_sorts_and_skips_nondict(): + data_in = { + "traceEvents": [ + {"name": "b", "cat": "kernel", "ts": 5}, + {"name": "a", "cat": "kernel", "ts": 1}, + "not-a-dict", + {"name": "c", "cat": "cpu_op", "ts": 3}, + ] + } + data, by_cat = extract_trace_data.load_trace(data_in) + assert data is data_in + # Non-dict element skipped; kernels sorted by ts. + assert [e["name"] for e in by_cat["kernel"]] == ["a", "b"] + assert [e["name"] for e in by_cat["cpu_op"]] == ["c"] + + +def test_load_trace_from_path(): + payload = {"traceEvents": [{"name": "k", "cat": "kernel", "ts": 1}]} + with tempfile.NamedTemporaryFile("w", suffix=".json", delete=False) as tmp: + json.dump(payload, tmp) + path = tmp.name + try: + data, by_cat = extract_trace_data.load_trace(path) + assert data["traceEvents"][0]["name"] == "k" + assert [e["name"] for e in by_cat["kernel"]] == ["k"] + finally: + os.unlink(path) + + +def test_stamp_raw_uid(): + data = {"traceEvents": [{"name": "a"}, "skip", {"name": "b"}]} + extract_trace_data._stamp_raw_uid(data) + assert data["traceEvents"][0]["_gpu_op_uid"] == 0 + assert data["traceEvents"][2]["_gpu_op_uid"] == 2 + + +def test_get_stream_id_variants(): + # Valid string stream -> int. + assert extract_trace_data.get_stream_id({"args": {"stream": "3"}}) == 3 + # Unhashable stream value raises TypeError -> falls back to tid. + assert extract_trace_data.get_stream_id({"args": {"stream": [1]}, "tid": 7}) == 7 + # Non-numeric stream string raises ValueError -> falls back to tid. + assert extract_trace_data.get_stream_id({"args": {"stream": "x"}, "tid": 4}) == 4 + # No stream, tid present. + assert extract_trace_data.get_stream_id({"tid": 5}) == 5 + # Invalid tid -> None. + assert extract_trace_data.get_stream_id({"tid": "nope"}) is None + # Nothing usable -> None. + assert extract_trace_data.get_stream_id({}) is None + + +def test_filter_to_primary_stream_empty(): + by_cat = {} + extract_trace_data.filter_to_primary_stream(by_cat) + assert by_cat == {} + + +def test_filter_to_primary_stream_single_stream_noop(): + kernels = [_kernel("k", 1, 10, stream=0), _kernel("k", 2, 10, stream=0)] + by_cat = {"kernel": kernels} + extract_trace_data.filter_to_primary_stream(by_cat) + assert len(by_cat["kernel"]) == 2 + + +def test_filter_to_primary_stream_filters_minor_secondary(): + kernels = [_kernel("k", i, 10, stream=0) for i in range(9)] + kernels.append(_kernel("k", 100, 1, stream=1)) + by_cat = {"kernel": kernels} + extract_trace_data.filter_to_primary_stream(by_cat) + # Secondary stream is <5% of time -> dropped, keeping primary only. + assert all(k["args"]["stream"] == 0 for k in by_cat["kernel"]) + assert len(by_cat["kernel"]) == 9 + + +def test_filter_to_primary_stream_keeps_significant_secondary(): + kernels = [_kernel("k", i, 10, stream=0) for i in range(5)] + kernels.append(_kernel("k", 100, 10, stream=1)) + by_cat = {"kernel": kernels} + extract_trace_data.filter_to_primary_stream(by_cat) + # Secondary stream >5% of time -> keep all streams. + assert len(by_cat["kernel"]) == 6 + + +def test_extract_kernel_sequence(): + by_cat = { + "kernel": [ + _kernel("gemm", 5, 3, stream=0, _gpu_op_uid=11), + _kernel("relu", 1, 2, stream=0, gpu_op_uid=22), + ], + "gpu_memcpy": [_kernel("memcpy", 3, 1, cat="gpu_memcpy")], + } + seq = extract_trace_data.extract_kernel_sequence(by_cat) + # Sorted by ts across kernels + memcpy. + assert [k["name"] for k in seq] == ["relu", "memcpy", "gemm"] + # _gpu_op_uid preferred, else gpu_op_uid. + assert seq[2]["gpu_op_uid"] == 11 + assert seq[0]["gpu_op_uid"] == 22 + # memcpy has neither -> None. + assert seq[1]["gpu_op_uid"] is None + assert seq[1]["cat"] == "gpu_memcpy" + + +def test_detect_graph_mode(): + by_cat = {"cuda_runtime": [{"name": "hipGraphLaunch"}, {"name": "other"}]} + is_graph, launches = extract_trace_data.detect_graph_mode(by_cat) + assert is_graph is True + assert len(launches) == 1 + + is_graph2, launches2 = extract_trace_data.detect_graph_mode({}) + assert is_graph2 is False + assert launches2 == [] + + +def test_run_assertions_happy_path(): + data = {"traceEvents": [1]} + by_cat = {"kernel": [], "cpu_op": []} + kernels = [ + {"name": "a", "ts": 1, "dur": 2.0}, + {"name": "b", "ts": 3, "dur": 4.0}, + ] + errors = extract_trace_data.run_assertions(data, by_cat, kernels, False) + assert errors == [] + + +def test_run_assertions_missing_trace_events_and_categories(): + data = {} + by_cat = {"kernel": []} # cpu_op missing under strict. + kernels = [{"name": "a", "ts": 1, "dur": 2.0}] + errors = extract_trace_data.run_assertions(data, by_cat, kernels, False) + joined = " ".join(errors) + assert "A1.1 FAIL" in joined + assert "A1.2 FAIL" in joined + + +def test_run_assertions_no_kernels_and_zero_time(): + data = {"traceEvents": []} + by_cat = {"kernel": [], "cpu_op": []} + errors = extract_trace_data.run_assertions(data, by_cat, [], False) + joined = " ".join(errors) + assert "A1.3 FAIL" in joined + assert "A1.5 FAIL" in joined + + +def test_run_assertions_nonpositive_duration(): + data = {"traceEvents": [1]} + by_cat = {"kernel": [], "cpu_op": []} + kernels = [{"name": "bad", "ts": 1, "dur": 0}] + errors = extract_trace_data.run_assertions(data, by_cat, kernels, False) + assert any("A3.2 FAIL" in e for e in errors) + + +def test_run_assertions_nonmonotonic_timestamps(): + data = {"traceEvents": [1]} + by_cat = {"kernel": [], "cpu_op": []} + kernels = [ + {"name": "a", "ts": 5, "dur": 1.0}, + {"name": "b", "ts": 1, "dur": 1.0}, + ] + errors = extract_trace_data.run_assertions(data, by_cat, kernels, False) + assert any("A3.1 FAIL" in e for e in errors) + + +def test_extract_and_build_result_with_and_without_region_meta(): + by_cat = { + "kernel": [_kernel("gemm", 1, 3, stream=0, _gpu_op_uid=0)], + "cpu_op": [], + } + result, kernels = extract_trace_data.extract_and_build_result( + {"traceEvents": []}, by_cat, "trace.json" + ) + assert result["source_file"] == "trace.json" + assert result["metadata"]["total_kernels"] == 1 + assert result["metadata"]["total_kernel_time_us"] == 3.0 + assert "region_metadata" not in result + assert len(kernels) == 1 + + result2, _ = extract_trace_data.extract_and_build_result( + {"traceEvents": []}, by_cat, "trace.json", region_metadata={"region": "steady"} + ) + assert result2["region_metadata"] == {"region": "steady"} diff --git a/tests/test_semantic_extract_tree_context.py b/tests/test_semantic_extract_tree_context.py new file mode 100644 index 000000000..337589eb1 --- /dev/null +++ b/tests/test_semantic_extract_tree_context.py @@ -0,0 +1,173 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Unit tests for semantic_analyses/extract_tree_context.py matching logic.""" + +import os, sys + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SEM = os.path.join(REPO_ROOT, "TraceLens", "Agent", "Analysis", "semantic_analyses") +sys.path.insert(0, SEM) +import extract_tree_context + + +class FakeTree: + """Minimal tree stub exposing only what the matching functions read.""" + + def __init__(self, events): + self.events = events + + def get_parent_event(self, event): + return event.get("_parent") + + def event_to_category(self, event): + return event.get("_cat") + + def traverse_parents_and_get_callstack(self, event): + return "callstack:" + event.get("name", "") + + +def test_build_ts_index(): + events = [ + {"name": "a", "ts": 1}, + {"name": "a", "ts": 1}, + {"name": "b", "ts": 2}, + ] + index = extract_tree_context._build_ts_index(FakeTree(events)) + assert len(index[("a", 1)]) == 2 + assert len(index[("b", 2)]) == 1 + + +def test_find_tree_event_single_candidate(): + e = {"name": "a", "ts": 1, "dur": 3, "UID": 1} + index = {("a", 1): [e]} + assert extract_tree_context._find_tree_event(index, "a", 1, 3) is e + + +def test_find_tree_event_uid_disambiguates_collision(): + e1 = {"name": "a", "ts": 1, "dur": 3, "UID": 10} + e2 = {"name": "a", "ts": 1, "dur": 3, "UID": 20} + index = {("a", 1): [e1, e2]} + got = extract_tree_context._find_tree_event(index, "a", 1, 3, uid=20) + assert got is e2 + + +def test_find_tree_event_dur_fallback_on_collision(): + e1 = {"name": "a", "ts": 1, "dur": 3, "UID": 10} + e2 = {"name": "a", "ts": 1, "dur": 9, "UID": 20} + index = {("a", 1): [e1, e2]} + # No uid given -> disambiguate by dur. + got = extract_tree_context._find_tree_event(index, "a", 1, 9) + assert got is e2 + + +def test_find_tree_event_first_when_no_match(): + e1 = {"name": "a", "ts": 1, "dur": 3, "UID": 10} + e2 = {"name": "a", "ts": 1, "dur": 4, "UID": 20} + index = {("a", 1): [e1, e2]} + # uid + dur both fail to match -> first candidate. + got = extract_tree_context._find_tree_event(index, "a", 1, 99, uid=999) + assert got is e1 + + +def test_find_tree_event_none_when_missing(): + assert extract_tree_context._find_tree_event({}, "a", 1, 3) is None + + +def test_find_cpu_op_ancestor_walks_to_cpu_op(): + cpu_op = { + "name": "aten::mm", + "_cat": "cpu_op", + "args": {"Input Dims": [[2, 2]]}, + "nn_module_stack": ["mod"], + } + mid = {"name": "py_fn", "_cat": "python_function", "_parent": cpu_op} + gpu = {"name": "gemm", "_cat": "kernel", "_parent": mid} + tree = FakeTree([cpu_op, mid, gpu]) + + name, callstack, nn_module, input_dims = extract_tree_context._find_cpu_op_ancestor( + tree, gpu + ) + assert name == "aten::mm" + assert callstack == "callstack:aten::mm" + assert nn_module == ["mod"] + assert input_dims == [[2, 2]] + + +def test_find_cpu_op_ancestor_no_parent(): + gpu = {"name": "gemm", "_cat": "kernel"} + tree = FakeTree([gpu]) + name, callstack, nn_module, input_dims = extract_tree_context._find_cpu_op_ancestor( + tree, gpu + ) + assert name == "" + assert callstack == "" + assert nn_module == [] + assert input_dims == [] + + +def test_extract_tree_context_mixed(): + cpu_op = { + "name": "aten::mm", + "ts": 1, + "UID": 10, + "_cat": "cpu_op", + "args": {"Input Dims": [[2, 2]]}, + "nn_module_stack": ["m"], + } + gpu = { + "name": "gemm", + "ts": 5, + "dur": 3, + "UID": 11, + "_cat": "kernel", + "_parent": cpu_op, + } + solo = {"name": "solo", "ts": 9, "dur": 2, "UID": 12, "_cat": "kernel"} + tree = FakeTree([cpu_op, gpu, solo]) + + extracted = { + "source_file": "f.json", + "kernels": [ + {"name": "gemm", "ts": 5, "dur": 3, "gpu_op_uid": 11}, + {"name": "solo", "ts": 9, "dur": 2, "gpu_op_uid": 12}, + {"name": "missing", "ts": 99, "dur": 1, "gpu_op_uid": 99}, + ], + } + + result = extract_tree_context.extract_tree_context(tree, extracted) + + assert result["total_kernels"] == 3 + assert result["labeled_count"] == 1 + assert result["unlabeled_count"] == 2 + assert result["labeled_indices"] == [0] + assert result["unlabeled_indices"] == [1, 2] + assert result["coverage"] == round(1 / 3, 4) + + # Matched kernel with cpu_op ancestor. + ctx0 = result["kernels"][0] + assert ctx0["gpu_op_uid"] == 11 + assert ctx0["cpu_op_name"] == "aten::mm" + assert ctx0["input_dims"] == [[2, 2]] + + # Matched kernel with no cpu_op ancestor. + assert result["kernels"][1]["cpu_op_name"] == "" + assert result["kernels"][1]["gpu_op_uid"] == 12 + + # Unmatched kernel. + assert result["kernels"][2]["gpu_op_uid"] is None + assert result["kernels"][2]["cpu_op_name"] == "" + + +def test_extract_tree_context_empty_uses_prebuilt_index(): + tree = FakeTree([]) + ts_index = extract_tree_context._build_ts_index(tree) + result = extract_tree_context.extract_tree_context( + tree, {"kernels": []}, ts_index=ts_index + ) + assert result["total_kernels"] == 0 + assert result["coverage"] == 0.0 + assert result["source_file"] == "" diff --git a/tests/test_semantic_generate_diff.py b/tests/test_semantic_generate_diff.py new file mode 100644 index 000000000..8b69fec95 --- /dev/null +++ b/tests/test_semantic_generate_diff.py @@ -0,0 +1,194 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Unit tests for semantic_analyses/generate_semantic_diff.py builders.""" + +import os, sys + +import pandas as pd + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SEM = os.path.join(REPO_ROOT, "TraceLens", "Agent", "Analysis", "semantic_analyses") +sys.path.insert(0, SEM) +import generate_semantic_diff + + +def _labeled(): + labeled_a = [ + { + "name": "kA1", + "semantic_block": "QKV", + "nn_module": "attn", + "cpu_op": "aten::mm", + "dur": 10.0, + "input_dims": [[1, 2], (3, 4), 5], + "gpu_op_uid": 100, + }, + { + "name": "kA2", + "semantic_block": "MLP", + "perf_category": "Compute", + "dur": 5.0, + "input_dims": [], + "gpu_op_uid": 101, + }, + { + "name": "kA3", + "semantic_block": "OnlyA", + "dur": 2.0, + "gpu_op_uid": 102, + }, + ] + labeled_b = [ + { + "name": "kB1", + "semantic_block": "QKV", + "nn_module": "attn", + "cpu_op": "aten::mm", + "dur": 12.0, + "input_dims": [[1, 2]], + "gpu_op_uid": 200, + }, + { + "name": "kB2", + "semantic_block": "MLP", + "perf_category": "Compute", + "dur": 6.0, + "gpu_op_uid": 201, + }, + { + "name": "kB3", + "semantic_block": "OnlyB", + "dur": 3.0, + "gpu_op_uid": 202, + }, + ] + return labeled_a, labeled_b + + +def _diff_df(): + labeled_a, labeled_b = _labeled() + rows, _ = generate_semantic_diff.build_diff_stats(labeled_a, labeled_b) + df = pd.DataFrame(rows) + df["busy_time"] = ( + df.groupby(["source", "lowest_common_ancestor_id"])["kernel_time"] + .transform("sum") + .round(3) + ) + return df + + +def test_build_diff_stats(): + labeled_a, labeled_b = _labeled() + rows, block_id_map = generate_semantic_diff.build_diff_stats(labeled_a, labeled_b) + + assert len(rows) == 6 + assert block_id_map == {"QKV": 0, "MLP": 1, "OnlyA": 2, "OnlyB": 3} + + by_name = {r["name"]: r for r in rows} + # nn_module present. + assert by_name["kA1"]["nn_module_stack"] == "attn" + # falls back to perf_category. + assert by_name["kA2"]["nn_module_stack"] == "Compute" + # falls back to "Others". + assert by_name["kA3"]["nn_module_stack"] == "Others" + + # cpu_op present vs. falling back to the block name. + assert by_name["kA1"]["cpu_op_name"] == "aten::mm" + assert by_name["kA3"]["cpu_op_name"] == "OnlyA" + + # _format_dims: list, tuple, and scalar entries. + assert by_name["kA1"]["Input Dims"] == "(1, 2), (3, 4), 5" + # empty dims -> empty string. + assert by_name["kA2"]["Input Dims"] == "" + + assert by_name["kA1"]["source"] == "trace1" + assert by_name["kB1"]["source"] == "trace2" + assert by_name["kA1"]["kernel_time"] == 10.0 + + +def test_build_unique_args_summary(): + df = _diff_df() + summary = generate_semantic_diff.build_unique_args_summary(df) + + assert "kernel_time_sum" in summary.columns + assert "operation_count" in summary.columns + # 6 unique kernels -> 6 aggregated rows. + assert len(summary) == 6 + # sorted descending by kernel_time_sum. + vals = list(summary["kernel_time_sum"]) + assert vals == sorted(vals, reverse=True) + + +def test_build_unique_args_summary_unhashable_fallback(): + # A list-valued grouping column forces the TypeError -> str-repr branch. + df = pd.DataFrame( + [ + { + "name": "x", + "cpu_op_name": [1, 2], + "source": "trace1", + "kernel_time": 1.0, + }, + { + "name": "y", + "cpu_op_name": [3, 4], + "source": "trace1", + "kernel_time": 2.0, + }, + { + "name": "x", + "cpu_op_name": [1, 2], + "source": "trace1", + "kernel_time": 4.0, + }, + ] + ) + summary = generate_semantic_diff.build_unique_args_summary(df) + assert isinstance(summary, pd.DataFrame) + assert "kernel_time_sum" in summary.columns + assert "operation_count" in summary.columns + + +def test_build_cpu_op_maps(): + df = _diff_df() + cpu_op_map, t1, t2 = generate_semantic_diff.build_cpu_op_maps(df) + + assert "aten::mm" in cpu_op_map + assert set(cpu_op_map["aten::mm"].keys()) == {"trace1", "trace2"} + assert cpu_op_map["aten::mm"]["trace1"]["kernels"] == ["kA1"] + assert cpu_op_map["aten::mm"]["trace2"]["kernels"] == ["kB1"] + + # Per-source grouped frames. + t1_map = t1.to_dict()["name"] + t2_map = t2.to_dict()["name"] + assert t1_map["aten::mm"] == ["kA1"] + assert t2_map["OnlyB"] == ["kB3"] + assert "OnlyA" not in t2_map + + +def test_build_merged_tree_text(): + labeled_a, labeled_b = _labeled() + _, block_id_map = generate_semantic_diff.build_diff_stats(labeled_a, labeled_b) + text = generate_semantic_diff.build_merged_tree_text( + block_id_map, labeled_a, labeled_b, "MI355", "B200" + ) + + assert text.startswith("└── Root (MI355 vs B200)") + # Combined block (present in both) shows the plain label. + assert "QKV" in text + # trace1-only and trace2-only markers. + assert ">> trace1: OnlyA" in text + assert "<< trace2: OnlyB" in text + # Kernel of a combined block rendered plainly. + assert "kA1" in text + # Kernel of a trace1-only block carries the >> marker. + assert ">> trace1: kA3" in text + assert "<< trace2: kB3" in text + # Grouping by nn_module / perf_category. + assert "attn" in text + assert "Compute" in text + assert "Others" in text diff --git a/tests/test_semantic_helpers.py b/tests/test_semantic_helpers.py new file mode 100644 index 000000000..20312028c --- /dev/null +++ b/tests/test_semantic_helpers.py @@ -0,0 +1,99 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Unit tests for semantic_analyses/_helpers.py.""" + +import gzip +import json +import os +import sys + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SEM = os.path.join(REPO_ROOT, "TraceLens", "Agent", "Analysis", "semantic_analyses") +sys.path.insert(0, SEM) + +from _helpers import build_rle, detect_period, load_json, load_labels + + +# --------------------------------------------------------------------------- +# build_rle +# --------------------------------------------------------------------------- +def test_build_rle_empty(): + assert build_rle([], {}) == [] + + +def test_build_rle_single_group(): + cls = { + 0: {"perf_category": "Compute", "kernel_type": "gemm"}, + 1: {"perf_category": "Compute", "kernel_type": "gemm"}, + } + groups = build_rle([0, 1], cls) + assert groups == [("Compute", 2, [0, 1], ["gemm", "gemm"])] + + +def test_build_rle_multiple_groups_with_defaults(): + cls = { + 0: {"perf_category": "Compute", "kernel_type": "gemm"}, + 1: {"perf_category": "Compute", "kernel_type": "gemm"}, + 2: {"perf_category": "Memory", "kernel_type": "copy"}, + # idx 3 missing -> defaults ("Others", "Unknown") + } + groups = build_rle([0, 1, 2, 3], cls) + assert groups == [ + ("Compute", 2, [0, 1], ["gemm", "gemm"]), + ("Memory", 1, [2], ["copy"]), + ("Others", 1, [3], ["Unknown"]), + ] + + +# --------------------------------------------------------------------------- +# detect_period +# --------------------------------------------------------------------------- +def test_detect_period_short_returns_length(): + groups = [("A",), ("B",), ("C",), ("D",), ("E",)] # n = 5 < 6 + assert detect_period(groups) == 5 + + +def test_detect_period_repeating(): + # ABC repeated 4 times -> n = 12, period = 3 + cats = ["A", "B", "C"] * 4 + groups = [(c,) for c in cats] + assert detect_period(groups) == 3 + + +def test_detect_period_no_period(): + cats = ["A", "B", "C", "D", "E", "F"] # n = 6, no repetition + groups = [(c,) for c in cats] + assert detect_period(groups) == 6 + + +def test_detect_period_empty(): + assert detect_period([]) == 0 + + +# --------------------------------------------------------------------------- +# load_json / load_labels +# --------------------------------------------------------------------------- +def test_load_json_plain(tmp_path): + p = tmp_path / "data.json" + payload = {"a": 1, "b": [2, 3]} + p.write_text(json.dumps(payload)) + assert load_json(str(p)) == payload + + +def test_load_json_gzip(tmp_path): + p = tmp_path / "data.json.gz" + payload = {"x": "y"} + with gzip.open(str(p), "wt") as f: + json.dump(payload, f) + assert load_json(str(p)) == payload + + +def test_load_labels(tmp_path): + p = tmp_path / "semantic_labels.json" + payload = {"labeled_kernels": [{"semantic_block": "attn"}]} + p.write_text(json.dumps(payload)) + assert load_labels(str(p)) == payload diff --git a/tests/test_semantic_kernel_coherence.py b/tests/test_semantic_kernel_coherence.py new file mode 100644 index 000000000..7c47ec880 --- /dev/null +++ b/tests/test_semantic_kernel_coherence.py @@ -0,0 +1,220 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Unit tests for semantic_analyses/kernel_coherence.py deterministic core.""" + +import json +import os +import sys + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SEM = os.path.join(REPO_ROOT, "TraceLens", "Agent", "Analysis", "semantic_analyses") +sys.path.insert(0, SEM) + +import kernel_coherence # noqa: E402 +import kernel_runlength # noqa: E402 + + +# --------------------------------------------------------------------------- +# _load / _dims_repr +# --------------------------------------------------------------------------- + + +def test_load_reads_json(tmp_path): + p = tmp_path / "doc.json" + p.write_text(json.dumps({"labeled_kernels": []})) + assert kernel_coherence._load(str(p)) == {"labeled_kernels": []} + + +def test_dims_repr_empty_and_compact_and_truncate(): + assert kernel_coherence._dims_repr(None) == "" + assert kernel_coherence._dims_repr([[1, 2]]) == "[[1,2]]" + long = kernel_coherence._dims_repr([[i] for i in range(200)], limit=10) + assert long.endswith("...") + assert len(long) == 13 + + +# --------------------------------------------------------------------------- +# _run_to_kernel_indices +# --------------------------------------------------------------------------- + + +def test_run_to_kernel_indices(): + mapping = kernel_coherence._run_to_kernel_indices([0, 0, 1, 2, 2]) + assert dict(mapping) == {0: [0, 1], 1: [2], 2: [3, 4]} + + +# --------------------------------------------------------------------------- +# _symbol_evidence +# --------------------------------------------------------------------------- + + +def _kernels_for_evidence(): + return [ + {"name": "gemm", "dur": 10.0, "perf_category": "GEMM", "input_dims": [[1, 2]]}, + {"name": "gemm", "dur": 5.0, "perf_category": "GEMM"}, + { + "name": "elem", + "dur": 3.0, + "perf_category": "Elementwise", + "input_dims": [[9]], + }, + ] + + +def test_symbol_evidence_ranks_and_aggregates(): + kernels = _kernels_for_evidence() + cats, dims, top = kernel_coherence._symbol_evidence(kernels, [0, 1, 2], 5) + assert cats == ["Elementwise", "GEMM"] + assert dims == "[[1,2]]" # first non-empty input_dims + assert top[0] == {"kernel_name": "gemm", "total_us": 15.0, "kernel_count": 2} + assert top[1] == {"kernel_name": "elem", "total_us": 3.0, "kernel_count": 1} + + +def test_symbol_evidence_top_kernels_limit(): + kernels = _kernels_for_evidence() + _, _, top = kernel_coherence._symbol_evidence(kernels, [0, 1, 2], 1) + assert [t["kernel_name"] for t in top] == ["gemm"] + + +# --------------------------------------------------------------------------- +# _collect_contexts +# --------------------------------------------------------------------------- + + +def test_collect_contexts_unique_neighbor_contexts(): + seq = ["A", "X", "B", "A", "X", "B", "A", "X", "C"] + kernels = [ + {"name": f"k{i}", "semantic_block": s, "dur": float(i + 1)} + for i, s in enumerate(seq) + ] + condensed = kernel_runlength.collapse_consecutive(seq) + run_per_kernel = kernel_runlength.run_index_per_kernel(seq) + shared = {"A", "B", "C"} + problematic = {"X"} + + detail = kernel_coherence._collect_contexts( + "A", kernels, condensed, run_per_kernel, shared, problematic, 1, 5 + ) + assert list(detail) == ["X"] + contexts = detail["X"]["contexts"] + # (A,B) appears twice but is deduped; (A,C) is distinct -> 2 contexts + assert detail["X"]["context_count"] == 2 + assert contexts[0]["id"] == "A:0" + assert contexts[0]["left_window"] == ["A"] + assert contexts[0]["right_window"] == ["B"] + assert contexts[1]["id"] == "A:1" + assert contexts[1]["right_window"] == ["C"] + assert contexts[0]["first_pass_block"] == "X" + + +# --------------------------------------------------------------------------- +# _context_lookup +# --------------------------------------------------------------------------- + + +def test_context_lookup_builds_key_map(): + catalog = [ + { + "id": "A:0", + "workload": "A", + "first_pass_block": "X", + "left_window": ["A"], + "right_window": ["B"], + }, + { + "id": "A:1", + "workload": "A", + "first_pass_block": "X", + "left_window": None, + "right_window": ["C"], + }, + ] + lookup = kernel_coherence._context_lookup(catalog) + assert lookup[("A", "X", ("A",), ("B",))] == "A:0" + # left_window None coerced to empty tuple + assert lookup[("A", "X", (), ("C",))] == "A:1" + + +# --------------------------------------------------------------------------- +# _final_blocks +# --------------------------------------------------------------------------- + + +def _final_kernels(): + return [ + {"name": "a", "semantic_block": "S1", "dur": 1.0, "index": 100}, + {"name": "b", "semantic_block": "P", "dur": 5.0, "index": 101}, + {"name": "c", "semantic_block": "S2", "dur": 2.0}, # no index -> uses i + ] + + +def test_final_blocks_context_rename(): + kernels = _final_kernels() + lookup = {("A", "P", ("S1",), ("S2",)): "A:0"} + finals, audit = kernel_coherence._final_blocks( + "A", kernels, {"S1", "S2"}, {"P"}, 1, lookup, {"A:0": "QKV"}, {} + ) + assert finals == ["S1", "QKV", "S2"] + assert audit[1]["context_id"] == "A:0" + assert audit[1]["first_pass_block"] == "P" + assert audit[1]["final_block"] == "QKV" + assert audit[1]["kernel_index"] == 101 + # kernel without "index" falls back to positional index + assert audit[2]["kernel_index"] == 2 + + +def test_final_blocks_fallback_remap(): + kernels = _final_kernels() + lookup = {("A", "P", ("S1",), ("S2",)): "A:0"} + finals, _ = kernel_coherence._final_blocks( + "A", kernels, {"S1", "S2"}, {"P"}, 1, lookup, {}, {"P": "FB"} + ) + # cid found but not in renames -> fallback used + assert finals == ["S1", "FB", "S2"] + + +def test_final_blocks_no_decision_keeps_first_pass(): + kernels = _final_kernels() + finals, audit = kernel_coherence._final_blocks( + "A", kernels, {"S1", "S2"}, {"P"}, 1, {}, {}, {} + ) + assert finals == ["S1", "P", "S2"] + assert audit[1]["context_id"] == "" + + +def test_final_blocks_missing_context_uses_fallback(): + kernels = _final_kernels() + # empty lookup -> cid "" -> falls through to fallback + finals, audit = kernel_coherence._final_blocks( + "A", kernels, {"S1", "S2"}, {"P"}, 1, {}, {}, {"P": "FB"} + ) + assert finals == ["S1", "FB", "S2"] + assert audit[1]["context_id"] == "" + + +# --------------------------------------------------------------------------- +# _residual_one_sided +# --------------------------------------------------------------------------- + + +def test_residual_one_sided(): + labels_a = { + "labeled_kernels": [ + {"semantic_block": "A"}, + {"semantic_block": "A"}, + {"semantic_block": "X"}, + ] + } + labels_b = { + "labeled_kernels": [ + {"semantic_block": "A"}, + {"semantic_block": "Y"}, + ] + } + res_a, res_b = kernel_coherence._residual_one_sided(labels_a, labels_b) + assert res_a == ["X"] + assert res_b == ["Y"] diff --git a/tests/test_semantic_kernel_runlength.py b/tests/test_semantic_kernel_runlength.py new file mode 100644 index 000000000..ee5629a21 --- /dev/null +++ b/tests/test_semantic_kernel_runlength.py @@ -0,0 +1,112 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Unit tests for semantic_analyses/kernel_runlength.py.""" + +import json +import os +import sys + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SEM = os.path.join(REPO_ROOT, "TraceLens", "Agent", "Analysis", "semantic_analyses") +sys.path.insert(0, SEM) + +import kernel_runlength + + +# --------------------------------------------------------------------------- +# load_sequence +# --------------------------------------------------------------------------- +def test_load_sequence(tmp_path): + p = tmp_path / "semantic_labels.json" + payload = { + "labeled_kernels": [ + {"semantic_block": "A"}, + {"semantic_block": "B"}, + {}, # missing key -> "" + ] + } + p.write_text(json.dumps(payload)) + assert kernel_runlength.load_sequence(str(p)) == ["A", "B", ""] + + +def test_load_sequence_no_kernels(tmp_path): + p = tmp_path / "empty_labels.json" + p.write_text(json.dumps({})) + assert kernel_runlength.load_sequence(str(p)) == [] + + +# --------------------------------------------------------------------------- +# collapse_consecutive +# --------------------------------------------------------------------------- +def test_collapse_consecutive_empty(): + assert kernel_runlength.collapse_consecutive([]) == [] + + +def test_collapse_consecutive_basic(): + assert kernel_runlength.collapse_consecutive(["A", "A", "B", "D", "D"]) == [ + "A", + "B", + "D", + ] + + +def test_collapse_consecutive_no_dups(): + assert kernel_runlength.collapse_consecutive(["A", "B", "C"]) == ["A", "B", "C"] + + +# --------------------------------------------------------------------------- +# run_index_per_kernel +# --------------------------------------------------------------------------- +def test_run_index_per_kernel_empty(): + assert kernel_runlength.run_index_per_kernel([]) == [] + + +def test_run_index_per_kernel_basic(): + # A A B D D -> runs: A(0) A(0) B(1) D(2) D(2) + assert kernel_runlength.run_index_per_kernel(["A", "A", "B", "D", "D"]) == [ + 0, + 0, + 1, + 2, + 2, + ] + + +# --------------------------------------------------------------------------- +# shared_neighbor_windows_skip_non_shared +# --------------------------------------------------------------------------- +def test_shared_neighbor_windows_basic(): + # 0 1 2 3 4 5 6 + condensed = ["S1", "x", "S2", "C", "S3", "y", "S4"] + shared = {"S1", "S2", "S3", "S4"} + left, right = kernel_runlength.shared_neighbor_windows_skip_non_shared( + condensed, center_j=3, shared=shared, radius=2 + ) + # left: walk from idx 2 -> S2 (shared), idx 1 x (skip), idx 0 S1 (shared) + assert left == ["S2", "S1"] + # right: idx 4 S3 (shared), idx 5 y (skip), idx 6 S4 (shared) + assert right == ["S3", "S4"] + + +def test_shared_neighbor_windows_radius_limit(): + condensed = ["S1", "S2", "C", "S3", "S4"] + shared = {"S1", "S2", "S3", "S4"} + left, right = kernel_runlength.shared_neighbor_windows_skip_non_shared( + condensed, center_j=2, shared=shared, radius=1 + ) + assert left == ["S2"] + assert right == ["S3"] + + +def test_shared_neighbor_windows_boundaries(): + condensed = ["C", "S1"] + shared = {"S1"} + left, right = kernel_runlength.shared_neighbor_windows_skip_non_shared( + condensed, center_j=0, shared=shared, radius=3 + ) + assert left == [] + assert right == ["S1"] diff --git a/tests/test_semantic_kernel_unification.py b/tests/test_semantic_kernel_unification.py new file mode 100644 index 000000000..772a89858 --- /dev/null +++ b/tests/test_semantic_kernel_unification.py @@ -0,0 +1,331 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Unit tests for semantic_analyses/kernel_unification.py pure transforms.""" + +import json +import os +import sys + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SEM = os.path.join(REPO_ROOT, "TraceLens", "Agent", "Analysis", "semantic_analyses") +sys.path.insert(0, SEM) + +import kernel_unification # noqa: E402 + + +# --------------------------------------------------------------------------- +# _load / _dims_repr +# --------------------------------------------------------------------------- + + +def test_load_reads_json(tmp_path): + p = tmp_path / "doc.json" + p.write_text(json.dumps({"a": 1, "b": [2, 3]})) + assert kernel_unification._load(str(p)) == {"a": 1, "b": [2, 3]} + + +def test_dims_repr_empty(): + assert kernel_unification._dims_repr(None) == "" + assert kernel_unification._dims_repr([]) == "" + + +def test_dims_repr_compact(): + assert kernel_unification._dims_repr([[1, 2], [3, 4]]) == "[[1,2],[3,4]]" + + +def test_dims_repr_truncates(): + dims = [[i, i + 1] for i in range(200)] + out = kernel_unification._dims_repr(dims, limit=20) + assert out.endswith("...") + assert len(out) == 23 # 20 + "..." + + +# --------------------------------------------------------------------------- +# aggregate_names +# --------------------------------------------------------------------------- + + +def _labels(kernels): + return {"labeled_kernels": kernels} + + +def test_aggregate_names_duplicates_and_ordering(): + labels = _labels( + [ + {"name": "small", "dur": 1.0, "perf_category": "Elementwise"}, + { + "name": "big", + "dur": 10.0, + "perf_category": "GEMM", + "input_dims": [[1, 2]], + }, + {"name": "big", "dur": 5.0, "perf_category": "GEMM"}, + {"name": "big", "dur": 2.0, "perf_category": "Attention"}, + ] + ) + agg = kernel_unification.aggregate_names(labels) + # ordered by descending total duration -> big (17) before small (1) + assert list(agg) == ["big", "small"] + big = agg["big"] + assert big["kernel_count"] == 3 + assert big["total_dur_us"] == 17.0 + # perf_categories deduped + sorted + assert big["perf_categories"] == ["Attention", "GEMM"] + # first non-empty input_dims sampled + assert big["sample_input_dims"] == "[[1,2]]" + # without key_fn there are no raw-name samples + assert "sample_raw_names" not in big + + +def test_aggregate_names_missing_and_none_dur(): + labels = _labels( + [ + {"dur": None}, # missing name -> "", None dur -> 0 + {"name": "", "dur": 4.0}, + ] + ) + agg = kernel_unification.aggregate_names(labels) + assert list(agg) == [""] + assert agg[""]["kernel_count"] == 2 + assert agg[""]["total_dur_us"] == 4.0 + assert agg[""]["sample_input_dims"] == "" + + +def test_aggregate_names_key_fn_collects_raw_names(): + labels = _labels( + [ + {"name": "moe_attn_vllm", "dur": 3.0}, + {"name": "sglang_moe_attention", "dur": 2.0}, + {"name": "moe_attn", "dur": 1.0}, # equals key -> not sampled + ] + ) + agg = kernel_unification.aggregate_names(labels, key_fn=lambda n: "moe_attn") + assert list(agg) == ["moe_attn"] + entry = agg["moe_attn"] + assert entry["kernel_count"] == 3 + # raw names differing from the key are recorded and sorted + assert entry["sample_raw_names"] == ["moe_attn_vllm", "sglang_moe_attention"] + + +def test_aggregate_names_key_fn_none_drops_kernel(): + labels = _labels( + [ + {"name": "keep", "dur": 1.0}, + {"name": "drop", "dur": 9.0}, + ] + ) + agg = kernel_unification.aggregate_names( + labels, key_fn=lambda n: None if n == "drop" else n + ) + assert list(agg) == ["keep"] + + +# --------------------------------------------------------------------------- +# _entry_list / _build_context +# --------------------------------------------------------------------------- + + +def test_entry_list_preserves_agg_order(): + labels = _labels( + [ + {"name": "b", "dur": 5.0}, + {"name": "a", "dur": 9.0}, + ] + ) + agg = kernel_unification.aggregate_names(labels) # order: a, b + picked = kernel_unification._entry_list(agg, {"a", "b"}) + assert [e["name"] for e in picked] == ["a", "b"] + + +def test_build_context_shape_and_extra(): + agg_a = kernel_unification.aggregate_names( + _labels([{"name": "shared", "dur": 2.0}, {"name": "onlyA", "dur": 1.0}]) + ) + agg_b = kernel_unification.aggregate_names( + _labels([{"name": "shared", "dur": 2.0}, {"name": "onlyB", "dur": 1.0}]) + ) + ctx = kernel_unification._build_context( + agg_a, agg_b, "MI300", "B300", "raw_name", extra={"flag": True} + ) + assert ctx["name_a"] == "MI300" + assert ctx["key_level"] == "raw_name" + assert ctx["summary"]["combined_unique"] == 3 + assert ctx["summary"]["in_both"] == 1 + assert ctx["in_both"] == ["shared"] + assert [e["name"] for e in ctx["only_in_MI300"]] == ["onlyA"] + assert [e["name"] for e in ctx["only_in_B300"]] == ["onlyB"] + assert ctx["flag"] is True + + +def test_build_context_no_extra(): + agg = kernel_unification.aggregate_names(_labels([{"name": "x", "dur": 1.0}])) + ctx = kernel_unification._build_context(agg, agg, "a", "b", "stem") + assert ctx["summary"]["combined_unique"] == 1 + assert "flag" not in ctx + + +# --------------------------------------------------------------------------- +# _sample_names +# --------------------------------------------------------------------------- + + +def test_sample_names_small_returns_all_tagged(): + agg_a = kernel_unification.aggregate_names(_labels([{"name": "a", "dur": 1.0}])) + agg_b = kernel_unification.aggregate_names(_labels([{"name": "b", "dur": 1.0}])) + sample = kernel_unification._sample_names(agg_a, agg_b, "A", "B", 10) + traces = {row["trace"] for row in sample} + assert traces == {"A", "B"} + assert len(sample) == 2 + + +def test_sample_names_spaced_subset(): + agg_a = kernel_unification.aggregate_names( + _labels([{"name": n, "dur": float(i)} for i, n in enumerate("abcd")]) + ) + agg_b = kernel_unification.aggregate_names( + _labels([{"name": n, "dur": float(i)} for i, n in enumerate("wxyz")]) + ) + sample = kernel_unification._sample_names(agg_a, agg_b, "A", "B", 2) + # sample_size 2 -> half=1 from A, 1 from B + assert len(sample) == 2 + assert [r["trace"] for r in sample] == ["A", "B"] + + +# --------------------------------------------------------------------------- +# _compile_rules +# --------------------------------------------------------------------------- + + +def test_compile_rules_valid(): + compiled = kernel_unification._compile_rules( + [ + {"pattern": r"foo_\d+", "action": "collapse", "replacement": "foo"}, + {"pattern": "bar", "action": "preserve"}, + {"pattern": "baz"}, # default action collapse + ] + ) + assert [c["action"] for c in compiled] == ["collapse", "preserve", "collapse"] + assert compiled[0]["regex"].search("foo_123") + + +def test_compile_rules_bad_action(): + try: + kernel_unification._compile_rules([{"pattern": "x", "action": "nope"}]) + assert False, "expected SystemExit" + except SystemExit as e: + assert "invalid action" in str(e) + + +def test_compile_rules_bad_regex(): + try: + kernel_unification._compile_rules([{"pattern": "(", "action": "preserve"}]) + assert False, "expected SystemExit" + except SystemExit as e: + assert "bad regex" in str(e) + + +# --------------------------------------------------------------------------- +# stem_for +# --------------------------------------------------------------------------- + + +def test_stem_for_collapse(): + compiled = kernel_unification._compile_rules( + [{"pattern": r"gemm_[a-z0-9]+", "action": "collapse", "replacement": "gemm"}] + ) + assert kernel_unification.stem_for("gemm_fp16x8", compiled) == ("gemm", "collapse") + + +def test_stem_for_preserve_and_drop(): + compiled = kernel_unification._compile_rules( + [ + {"pattern": "keep", "action": "preserve"}, + {"pattern": "trash", "action": "drop"}, + ] + ) + assert kernel_unification.stem_for("keep_me", compiled) == ("keep_me", "preserve") + assert kernel_unification.stem_for("trash_me", compiled) == ("trash_me", "drop") + + +def test_stem_for_no_match_defaults_preserve(): + compiled = kernel_unification._compile_rules( + [{"pattern": "zzz", "action": "collapse", "replacement": "z"}] + ) + assert kernel_unification.stem_for("other", compiled) == ("other", "preserve") + + +def test_stem_for_bad_replacement_falls_back(capsys): + # replacement references a non-existent capture group -> re.error at sub time + compiled = kernel_unification._compile_rules( + [{"pattern": r"(a)b", "action": "collapse", "replacement": r"\2"}] + ) + # first call warns and preserves + assert kernel_unification.stem_for("ab", compiled) == ("ab", "preserve") + err = capsys.readouterr().err + assert "ignoring stem rule" in err + assert compiled[0]["_warned"] is True + # second call is already warned -> no new warning, still preserves + assert kernel_unification.stem_for("ab", compiled) == ("ab", "preserve") + assert capsys.readouterr().err == "" + + +# --------------------------------------------------------------------------- +# _load_map_side +# --------------------------------------------------------------------------- + + +def test_load_map_side_by_side_key(): + doc = {"map_a": {"foo": "bar"}} + assert kernel_unification._load_map_side(doc, "a", "MI300") == {"foo": "bar"} + + +def test_load_map_side_by_name_key(): + doc = {"map_MI300": {"foo": "bar"}} + assert kernel_unification._load_map_side(doc, "a", "MI300") == {"foo": "bar"} + + +def test_load_map_side_nested_map(): + doc = {"a": {"map": {"foo": "bar"}, "notes": "x"}} + assert kernel_unification._load_map_side(doc, "a", "MI300") == {"foo": "bar"} + + +def test_load_map_side_missing_returns_empty(): + assert kernel_unification._load_map_side({}, "a", "MI300") == {} + + +# --------------------------------------------------------------------------- +# _apply_side +# --------------------------------------------------------------------------- + + +def test_apply_side_no_stem_map(): + labels = _labels( + [ + {"name": "foo", "dur": 1.0}, + {"name": "baz", "dur": 1.0}, + ] + ) + stats = kernel_unification._apply_side(labels, {"foo": "FOO"}, None) + blocks = [k["semantic_block"] for k in labels["labeled_kernels"]] + assert blocks == ["FOO", "baz"] # unmapped falls back to raw + assert stats == {"kernels": 2, "mapped": 1, "stemmed": 0} + + +def test_apply_side_with_stem_map(): + labels = _labels( + [ + {"name": "gemm_v1", "dur": 1.0}, + {"name": "plain", "dur": 1.0}, + ] + ) + raw_to_stem = {"gemm_v1": "gemm", "plain": "plain"} + unified = {"gemm": "GEMM_UNIFIED"} + stats = kernel_unification._apply_side(labels, unified, raw_to_stem) + blocks = [k["semantic_block"] for k in labels["labeled_kernels"]] + assert blocks == ["GEMM_UNIFIED", "plain"] + # gemm_v1 was stemmed (base != raw); plain was not + assert stats == {"kernels": 2, "mapped": 1, "stemmed": 1} diff --git a/tests/test_semantic_match_and_compare.py b/tests/test_semantic_match_and_compare.py new file mode 100644 index 000000000..44696d586 --- /dev/null +++ b/tests/test_semantic_match_and_compare.py @@ -0,0 +1,225 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Unit tests for semantic_analyses/match_and_compare.py. + +Uses in-memory dict fixtures (no file I/O) to exercise the pure +aggregation / comparison / assertion helpers. +""" + +import os +import sys + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SEM = os.path.join(REPO_ROOT, "TraceLens", "Agent", "Analysis", "semantic_analyses") +sys.path.insert(0, SEM) + +from match_and_compare import aggregate, build_comparison, run_assertions + + +def _labeled(spec): + """Build a list of labeled-kernel dicts from compact tuples. + + Each tuple is (semantic_block, name, dur, perf_category, nn_module). + """ + return [ + { + "name": name, + "dur": dur, + "semantic_block": block, + "perf_category": pc, + "nn_module": nm, + } + for (block, name, dur, pc, nm) in spec + ] + + +# Standard, self-consistent A/B fixture used by several tests. +LABELED_A = _labeled( + [ + ("GEMM_0", "aa", 10.0, "GEMM", "Blk"), + ("GEMM_0", "bb", 30.0, "GEMM", "Blk"), + ("GEMM_0", "aa", 10.0, "GEMM", "Blk"), # duplicate name -> deduped in set + ("Norm_0", "cc", 20.0, "Normalization", "Blk"), + ("Extra_0", "dd", 10.0, "Others", ""), # block only present in A + ] +) +TOTAL_A = 80.0 + +LABELED_B = _labeled( + [ + ("GEMM_0", "dd", 20.0, "GEMM", "Blk"), + ("Norm_0", "ee", 10.0, "Normalization", "Blk"), + ("Norm_0", "ff", 10.0, "Normalization", "Blk"), + ("SDPA_0", "gg", 5.0, "SDPA", "Blk"), # block only present in B + ] +) +TOTAL_B = 45.0 + + +def _agg_pair(): + return aggregate(LABELED_A), aggregate(LABELED_B) + + +def _rows(**kwargs): + agg_a, agg_b = _agg_pair() + return build_comparison(agg_a, agg_b, TOTAL_A, TOTAL_B, "MI355", "B200", **kwargs) + + +# --------------------------------------------------------------------------- # +# aggregate +# --------------------------------------------------------------------------- # +def test_aggregate_groups_dedups_names_and_counts(): + agg = aggregate(LABELED_A) + assert list(agg.keys()) == ["GEMM_0", "Norm_0", "Extra_0"] + gemm = agg["GEMM_0"] + assert gemm["count"] == 3 + assert gemm["durs"] == [10.0, 30.0, 10.0] + assert gemm["names"] == {"aa", "bb"} # duplicate "aa" collapsed + + +def test_aggregate_carries_perf_category_and_nn_module(): + agg = aggregate(LABELED_A) + assert agg["GEMM_0"]["perf_category"] == "GEMM" + assert agg["GEMM_0"]["nn_module"] == "Blk" + + +def test_aggregate_empty_input(): + assert aggregate([]) == {} + + +# --------------------------------------------------------------------------- # +# build_comparison +# --------------------------------------------------------------------------- # +def test_build_comparison_rows_ratios_and_order(): + rows = _rows() + blocks = [r["semantic_block"] for r in rows] + assert blocks == ["GEMM_0", "Norm_0", "Extra_0", "SDPA_0"] + + by_block = {r["semantic_block"]: r for r in rows} + + gemm = by_block["GEMM_0"] + assert gemm["MI355_kernel_count"] == 3 + assert gemm["MI355_total_us"] == 50.0 + assert gemm["MI355_avg_us"] == round(50.0 / 3, 2) + assert gemm["B200_total_us"] == 20.0 + assert gemm["MI355_vs_B200_ratio"] == 2.5 + assert gemm["MI355_kernel_names"] == "aa | bb" + assert gemm["algorithm_order"] == 1 + + # Block only in A -> B side empty, ratio "inf", zero avg on B. + extra = by_block["Extra_0"] + assert extra["B200_kernel_count"] == 0 + assert extra["B200_avg_us"] == 0 + assert extra["MI355_vs_B200_ratio"] == "inf" + + # Block only in B -> A side empty. + sdpa = by_block["SDPA_0"] + assert sdpa["MI355_kernel_count"] == 0 + assert sdpa["MI355_avg_us"] == 0 + assert sdpa["MI355_vs_B200_ratio"] == 0.0 + + +def test_build_comparison_region_field_present(): + rows = _rows(region="prefill_only_3072") + assert rows[0]["region"] == "prefill_only_3072" + assert list(rows[0].keys())[0] == "region" + + +def test_build_comparison_gpu_timeline_fields(): + rows = _rows( + gpu_timeline_a={"busy_time_us": 2000.0, "idle_pct": 10.0}, + gpu_timeline_b={"busy_time_us": 4000.0, "idle_pct": 25.0}, + ) + r = rows[0] + assert r["MI355_busy_ms"] == 2.0 + assert r["MI355_idle_pct"] == 10.0 + assert r["B200_busy_ms"] == 4.0 + assert r["B200_idle_pct"] == 25.0 + + +def test_build_comparison_no_gpu_timeline_when_one_missing(): + rows = _rows(gpu_timeline_a={"busy_time_us": 2000.0, "idle_pct": 10.0}) + assert "MI355_busy_ms" not in rows[0] + + +def test_build_comparison_empty_inputs(): + assert build_comparison({}, {}, 0, 0, "MI355", "B200") == [] + + +def test_build_comparison_perf_category_and_module_fallback(): + labeled = _labeled([("X_0", "x", 5.0, None, None)]) + agg = aggregate(labeled) + rows = build_comparison(agg, agg, 5.0, 5.0, "A", "B") + assert rows[0]["perf_category"] == "Others" + assert rows[0]["nn_module"] == "" + + +def test_build_comparison_zero_totals_give_zero_pct(): + agg_a, agg_b = _agg_pair() + rows = build_comparison(agg_a, agg_b, 0, 0, "MI355", "B200") + assert all(r["MI355_pct"] == 0 for r in rows) + assert all(r["B200_pct"] == 0 for r in rows) + + +# --------------------------------------------------------------------------- # +# run_assertions +# --------------------------------------------------------------------------- # +def test_run_assertions_pass_on_consistent_data(): + rows = _rows() + errors = run_assertions( + rows, LABELED_A, LABELED_B, TOTAL_A, TOTAL_B, "MI355", "B200" + ) + assert errors == [] + + +def test_run_assertions_count_mismatch_a(): + rows = _rows() + padded_a = LABELED_A + [{"name": "z", "dur": 0.0, "semantic_block": "GEMM_0"}] + errors = run_assertions( + rows, padded_a, LABELED_B, TOTAL_A, TOTAL_B, "MI355", "B200" + ) + assert any("A6.1" in e and "MI355" in e for e in errors) + assert not any("A6.2" in e for e in errors) + + +def test_run_assertions_count_mismatch_b(): + rows = _rows() + padded_b = LABELED_B + [{"name": "z", "dur": 0.0, "semantic_block": "SDPA_0"}] + errors = run_assertions( + rows, LABELED_A, padded_b, TOTAL_A, TOTAL_B, "MI355", "B200" + ) + assert any("A6.2" in e and "B200" in e for e in errors) + + +def test_run_assertions_time_mismatch_both_sides(): + rows = _rows() + errors = run_assertions( + rows, LABELED_A, LABELED_B, TOTAL_A + 5.0, TOTAL_B + 5.0, "MI355", "B200" + ) + assert any("A6.3" in e and "MI355" in e for e in errors) + assert any("A6.3" in e and "B200" in e for e in errors) + + +def test_run_assertions_pct_mismatch_both_sides(): + # Feed doubled totals into build_comparison so percentages sum to ~50%. + agg_a, agg_b = _agg_pair() + rows = build_comparison(agg_a, agg_b, TOTAL_A * 2, TOTAL_B * 2, "MI355", "B200") + errors = run_assertions( + rows, LABELED_A, LABELED_B, TOTAL_A * 2, TOTAL_B * 2, "MI355", "B200" + ) + assert any("A7.2" in e and "MI355" in e for e in errors) + assert any("A7.2" in e and "B200" in e for e in errors) + + +def test_run_assertions_ratio_mismatch(): + rows = _rows() + # Corrupt the stored ratio of the GEMM_0 row (expected 2.5). + rows[0]["MI355_vs_B200_ratio"] = 9.999 + errors = run_assertions( + rows, LABELED_A, LABELED_B, TOTAL_A, TOTAL_B, "MI355", "B200" + ) + assert any("A7.5" in e for e in errors) diff --git a/tests/test_semantic_precomputed_diff_stats.py b/tests/test_semantic_precomputed_diff_stats.py new file mode 100644 index 000000000..bfaa959fe --- /dev/null +++ b/tests/test_semantic_precomputed_diff_stats.py @@ -0,0 +1,75 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Integration test for the semantic->report handoff via precomputed diff_stats. + +The semantic comparison path emits a TraceDiff-schema ``diff_stats.csv`` and +feeds it to the perf-report generators through ``precomputed_diff_stats_csv``. +When set (and no ``comparison_json_path``), the generator skips the internal +TraceDiff and loads the CSV as-is, then enriches the report and emits a +``diff_stats`` sheet. These tests exercise that branch for both the training +and inference report variants. +""" + +import json +import os + +import pytest + +from tests.fixtures.reporting import _build_synthetic_trace +from TraceLens.Reporting.generate_perf_report_pytorch import ( + generate_perf_report_pytorch, +) +from TraceLens.Reporting.generate_perf_report_pytorch_inference import ( + generate_perf_report_pytorch as generate_inference_report, +) + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +_DIFF_STATS_CSV = os.path.join( + REPO_ROOT, "tests", "traces", "tracediff_test", "diff_stats.csv" +) + +pytestmark = pytest.mark.filterwarnings( + "ignore:Source column .* not found.*:UserWarning", + "ignore:There are hipgraph launches.*:UserWarning", + "ignore:Found .* events with failed performance metric.*:UserWarning", + "ignore:Input list of events is empty.*:UserWarning", +) + + +def _write_trace(tmp_path, specs): + path = tmp_path / "trace.json" + path.write_text(json.dumps(_build_synthetic_trace(specs))) + return str(path) + + +def test_precomputed_diff_stats_csv_is_used_pytorch(tmp_path): + trace = _write_trace( + tmp_path, + [("aten::mm", "gemm_kernel", 100), ("aten::relu", "relu_kernel", 20)], + ) + result = generate_perf_report_pytorch( + profile_json_path=trace, + output_csvs_dir=str(tmp_path / "csvs"), + collective_analysis=False, + precomputed_diff_stats_csv=_DIFF_STATS_CSV, + ) + # The elif branch loaded the CSV and emitted the diff_stats sheet without + # running the internal TraceDiff (no comparison_json_path was supplied). + assert "diff_stats" in result + assert not result["diff_stats"].empty + + +def test_precomputed_diff_stats_csv_is_used_inference(tmp_path): + trace = _write_trace(tmp_path, [("aten::mm", "gemm_kernel", 100)]) + result = generate_inference_report( + profile_json_path=trace, + output_csvs_dir=str(tmp_path / "csvs"), + collective_analysis=False, + precomputed_diff_stats_csv=_DIFF_STATS_CSV, + ) + assert "diff_stats" in result + assert not result["diff_stats"].empty diff --git a/tests/test_semantic_trace_split_adapter.py b/tests/test_semantic_trace_split_adapter.py new file mode 100644 index 000000000..59313859e --- /dev/null +++ b/tests/test_semantic_trace_split_adapter.py @@ -0,0 +1,166 @@ +############################################################################### +# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. +# +# See LICENSE for license information. +############################################################################### + +"""Unit tests for semantic_analyses/trace_split_adapter pure helpers. + +Covers the deterministic phase/metadata mapping used to convert TraceUtils +annotation-split output into the region_metadata shape expected by +extract_trace_data. The subprocess driver ``split_vllm_trace`` is excluded +from coverage (it shells out to TraceLens.TraceUtils.split_inference_trace_ +annotation and is exercised only in the end-to-end path). +""" + +import json +import os +import sys + +REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +SEM = os.path.join(REPO_ROOT, "TraceLens", "Agent", "Analysis", "semantic_analyses") +sys.path.insert(0, SEM) + +import trace_split_adapter as tsa # noqa: E402 + + +# --------------------------------------------------------------------------- # +# get_steady_state_key +# --------------------------------------------------------------------------- # +def test_steady_state_key_prefill_only(): + meta = {"context_requests": 4, "generation_requests": 0, "context_sum": 128} + assert tsa.get_steady_state_key(meta) == "prefill_only_128" + + +def test_steady_state_key_decode_only(): + meta = {"context_requests": 0, "generation_requests": 8, "generation_sum": 64} + assert tsa.get_steady_state_key(meta) == "decode_only_64" + + +def test_steady_state_key_prefill_decode(): + meta = { + "context_requests": 2, + "generation_requests": 3, + "context_sum": 100, + "generation_sum": 50, + } + assert tsa.get_steady_state_key(meta) == "prefill_decode_100_50" + + +def test_steady_state_key_fallback_uses_batch(): + # ctx == 0 and gen == 0 -> batch/batch fallback branch + meta = {"context_requests": 0, "generation_requests": 0, "batch_size": 16} + assert tsa.get_steady_state_key(meta) == "prefill_decode_16_16" + + +def test_steady_state_key_defaults_when_empty(): + assert tsa.get_steady_state_key({}) == "prefill_decode_0_0" + + +# --------------------------------------------------------------------------- # +# _phase_to_region_meta +# --------------------------------------------------------------------------- # +def test_phase_to_region_meta_prefill_only(): + phase = { + "num_prefill": 5, + "num_prefilldecode": 0, + "num_decode": 0, + "avg_bs": 32, + "avg_conc": 5, + } + out = tsa._phase_to_region_meta(phase) + assert out == { + "context_requests": 5, + "generation_requests": 0, + "context_sum": 32, + "generation_sum": 0, + "batch_size": 32, + "num_requests": 5, + } + + +def test_phase_to_region_meta_decode_only(): + phase = { + "num_prefill": 0, + "num_prefilldecode": 0, + "num_decode": 7, + "avg_bs": 8, + "avg_conc": 7, + } + out = tsa._phase_to_region_meta(phase) + assert out == { + "context_requests": 0, + "generation_requests": 7, + "context_sum": 0, + "generation_sum": 8, + "batch_size": 8, + "num_requests": 7, + } + + +def test_phase_to_region_meta_combined(): + phase = { + "num_prefill": 2, + "num_prefilldecode": 3, + "num_decode": 4, + "avg_bs": 10, + "avg_conc": 9, + } + out = tsa._phase_to_region_meta(phase) + assert out["context_requests"] == 5 # num_prefill + num_prefilldecode + assert out["generation_requests"] == 7 # num_decode + num_prefilldecode + assert out["context_sum"] == 10 + assert out["generation_sum"] == 10 + assert out["batch_size"] == 10 + assert out["num_requests"] == 9 + + +def test_phase_to_region_meta_defaults_empty(): + # empty phase -> falls through to combined branch with all zeros + out = tsa._phase_to_region_meta({}) + assert out["context_requests"] == 0 + assert out["generation_requests"] == 0 + assert out["batch_size"] == 0 + + +# --------------------------------------------------------------------------- # +# _is_single_iteration +# --------------------------------------------------------------------------- # +def test_is_single_iteration_true(): + assert tsa._is_single_iteration({"num_prefill": 1}) is True + assert tsa._is_single_iteration({}) is True # total 0 + + +def test_is_single_iteration_false(): + assert tsa._is_single_iteration({"num_prefill": 1, "num_decode": 2}) is False + + +# --------------------------------------------------------------------------- # +# _iter_type_key +# --------------------------------------------------------------------------- # +def test_iter_type_key_prefill(): + assert tsa._iter_type_key({"num_prefill": 1, "avg_bs": 4}) == "prefill_4" + + +def test_iter_type_key_prefilldecode(): + assert ( + tsa._iter_type_key({"num_prefilldecode": 1, "avg_bs": 2}) == "prefilldecode_2" + ) + + +def test_iter_type_key_decode(): + assert tsa._iter_type_key({"num_decode": 1, "avg_bs": 8}) == "decode_8" + + +def test_iter_type_key_empty(): + assert tsa._iter_type_key({"avg_bs": 3}) == "empty_3" + + +# --------------------------------------------------------------------------- # +# _load_trace (thin wrapper over _helpers.load_json) +# --------------------------------------------------------------------------- # +def test_load_trace_reads_plain_json(tmp_path): + p = tmp_path / "trace.json" + p.write_text(json.dumps({"traceEvents": [{"name": "a"}]})) + out = tsa._load_trace(str(p)) + assert out == {"traceEvents": [{"name": "a"}]} From 83dcf9de1c24b8fced0b9c00e17421c202bdde49 Mon Sep 17 00:00:00 2001 From: Arseny Date: Wed, 2 Sep 2026 21:14:32 -0700 Subject: [PATCH 46/50] Tests, cosmetic changes with the proper lint version. --- .../semantic_analyses/generate_semantic_diff.py | 1 - .../Analysis/semantic_analyses/kernel_coherence.py | 1 - .../Analysis/semantic_analyses/kernel_unification.py | 1 - .../Analysis/semantic_analyses/trace_split_adapter.py | 4 +++- tests/test_semantic_extract_tree_context.py | 11 +++++++++++ tests/test_semantic_helpers.py | 9 +++++++++ tests/test_semantic_kernel_coherence.py | 1 - tests/test_semantic_kernel_unification.py | 1 - 8 files changed, 23 insertions(+), 6 deletions(-) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py b/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py index 420ba478f..3863afcab 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py @@ -47,7 +47,6 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from _helpers import load_labels - # --------------------------------------------------------------------------- # diff_stats.csv generation # --------------------------------------------------------------------------- diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py index cf94c9337..2d227c631 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py @@ -69,7 +69,6 @@ ) from _helpers import load_json - DEFAULT_RADIUS = 1 DEFAULT_TOP_KERNELS = 5 diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py index 54b44e65d..1f50c019c 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py @@ -73,7 +73,6 @@ sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from _helpers import load_json - DEFAULT_THRESHOLD = 5000 DEFAULT_SAMPLE_SIZE = 300 diff --git a/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py b/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py index 1ab455d0d..5333b6ee3 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py @@ -120,7 +120,9 @@ def _iter_type_key(phase: dict) -> str: return f"empty_{bs}" -def split_vllm_trace(trace_path: str) -> Optional[List[Tuple[dict, dict]]]: # pragma: no cover +def split_vllm_trace( + trace_path: str, +) -> Optional[List[Tuple[dict, dict]]]: # pragma: no cover """ Split a vLLM trace using TraceUtils split_inference_trace_annotation. diff --git a/tests/test_semantic_extract_tree_context.py b/tests/test_semantic_extract_tree_context.py index 337589eb1..2f23b7560 100644 --- a/tests/test_semantic_extract_tree_context.py +++ b/tests/test_semantic_extract_tree_context.py @@ -171,3 +171,14 @@ def test_extract_tree_context_empty_uses_prebuilt_index(): assert result["total_kernels"] == 0 assert result["coverage"] == 0.0 assert result["source_file"] == "" + + +def test_extract_tree_context_gpu_op_uid_comes_from_tree_event(): + # The output gpu_op_uid must be the matched TREE EVENT UID, not the kernel own + # gpu_op_uid; give them distinct values to pin down where the value is sourced. + gpu = {"name": "gemm", "ts": 5, "dur": 3, "UID": 777, "_cat": "kernel"} + tree = FakeTree([gpu]) + extracted = {"kernels": [{"name": "gemm", "ts": 5, "dur": 3, "gpu_op_uid": 11}]} + result = extract_tree_context.extract_tree_context(tree, extracted) + ctx = result["kernels"][0] + assert ctx["gpu_op_uid"] == 777 diff --git a/tests/test_semantic_helpers.py b/tests/test_semantic_helpers.py index 20312028c..020412845 100644 --- a/tests/test_semantic_helpers.py +++ b/tests/test_semantic_helpers.py @@ -97,3 +97,12 @@ def test_load_labels(tmp_path): payload = {"labeled_kernels": [{"semantic_block": "attn"}]} p.write_text(json.dumps(payload)) assert load_labels(str(p)) == payload + + +def test_detect_period_fuzzy_one_defect(): + # ABC repeated 4x with a single defect in the last group -> matches 8/9 > 0.85, + # exercising the non-exact fuzzy-match branch (still returns period 3). + cats = ["A", "B", "C"] * 4 + cats[-1] = "X" + groups = [(c,) for c in cats] + assert detect_period(groups) == 3 diff --git a/tests/test_semantic_kernel_coherence.py b/tests/test_semantic_kernel_coherence.py index 7c47ec880..5c6c33060 100644 --- a/tests/test_semantic_kernel_coherence.py +++ b/tests/test_semantic_kernel_coherence.py @@ -17,7 +17,6 @@ import kernel_coherence # noqa: E402 import kernel_runlength # noqa: E402 - # --------------------------------------------------------------------------- # _load / _dims_repr # --------------------------------------------------------------------------- diff --git a/tests/test_semantic_kernel_unification.py b/tests/test_semantic_kernel_unification.py index 772a89858..83de7a2a2 100644 --- a/tests/test_semantic_kernel_unification.py +++ b/tests/test_semantic_kernel_unification.py @@ -16,7 +16,6 @@ import kernel_unification # noqa: E402 - # --------------------------------------------------------------------------- # _load / _dims_repr # --------------------------------------------------------------------------- From e73ac94101e5803dd9315aed5d24fba2c46d09d8 Mon Sep 17 00:00:00 2001 From: Arseny Date: Thu, 3 Sep 2026 00:14:22 -0700 Subject: [PATCH 47/50] Further refinements/simplification --- .../semantic_analyses/extract_trace_data.py | 10 +++++++++- .../semantic_analyses/kernel_unification.py | 6 +++--- .../semantic_analyses/match_and_compare.py | 20 +++++++++---------- .../skills/analysis-orchestrator/reference.md | 10 +++++----- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py index 141dcce8a..ef9b5d632 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_trace_data.py @@ -187,10 +187,18 @@ def compute_gpu_timeline_metrics(events): # pragma: no cover Returns None on failure. """ try: - # Ensure events have UID (required by GPUEventAnalyser for overlap computation) + # GPUEventAnalyser needs a unique UID per event for overlap + # computation. Raw trace events don't carry one, so assign a contiguous + # 0..N-1. If an event already has a "UID", our assumption is broken and + # uniqueness is no longer guaranteed -- fail loudly rather than proceed. for i, e in enumerate(events): if "UID" not in e: e["UID"] = i + else: + raise ValueError( + "Event unexpectedly already carries a 'UID'; " + "cannot guarantee unique ids for GPUEventAnalyser" + ) analyzer = GPUEventAnalyser(events) metrics = analyzer.compute_metrics() total = metrics.get("total_time", 0) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py index 1f50c019c..14316fb83 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py @@ -44,13 +44,13 @@ python kernel_unification.py prepare-context \ --labels-a /semantic_labels.json \ --labels-b /semantic_labels.json \ - --name-a MI300 --name-b B300 \ + --name-a --name-b \ -o kernel_unification_context.json python kernel_unification.py apply-stem-rules \ --labels-a /semantic_labels.json \ --labels-b /semantic_labels.json \ - --name-a MI300 --name-b B300 \ + --name-a --name-b \ --rules stem_rules.json \ --raw-to-stem raw_to_stem.json \ -o kernel_unification_context.json @@ -58,7 +58,7 @@ python kernel_unification.py apply-map \ --labels-a /semantic_labels.json \ --labels-b /semantic_labels.json \ - --name-a MI300 --name-b B300 \ + --name-a --name-b \ --map kernel_unification_map.json \ [--raw-to-stem raw_to_stem.json] """ diff --git a/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py b/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py index 214999bf2..5954119ab 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py @@ -15,13 +15,13 @@ Output: comparison.csv Usage: - python match_and_compare.py \ - --name-a MI355 --name-b B200 \ + python match_and_compare.py \ + --name-a --name-b \ [-o comparison.csv] For multi-region (per steady-state), use --regions-dir-a and --regions-dir-b: - python match_and_compare.py --regions-dir-a output/MI355 --regions-dir-b output/B200 \ - --name-a MI355 --name-b B200 -o comparison.csv + python match_and_compare.py --regions-dir-a output/ --regions-dir-b output/ \ + --name-a --name-b -o comparison.csv This matches regions by subdir name (e.g. prefill_only_3072) and compares only corresponding regions (apples-to-apples). @@ -192,10 +192,10 @@ def run_assertions(rows, labeled_a, labeled_b, total_a, total_b, name_a, name_b) def main(): # pragma: no cover parser = argparse.ArgumentParser(description="Compare two semantic breakdowns") parser.add_argument( - "trace_a", nargs="?", help="Path to trace A semantic_labels.json" + "labels_a", nargs="?", help="Path to trace A semantic_labels.json" ) parser.add_argument( - "trace_b", nargs="?", help="Path to trace B semantic_labels.json" + "labels_b", nargs="?", help="Path to trace B semantic_labels.json" ) parser.add_argument( "--regions-dir-a", @@ -269,12 +269,12 @@ def main(): # pragma: no cover print("No matching regions found", file=sys.stderr) sys.exit(1) else: - if not args.trace_a or not args.trace_b: + if not args.labels_a or not args.labels_b: parser.error( - "Provide trace_a and trace_b, or --regions-dir-a and --regions-dir-b" + "Provide labels_a and labels_b, or --regions-dir-a and --regions-dir-b" ) - data_a = load_labels(args.trace_a) - data_b = load_labels(args.trace_b) + data_a = load_labels(args.labels_a) + data_b = load_labels(args.labels_b) labeled_a = data_a["labeled_kernels"] labeled_b = data_b["labeled_kernels"] total_a = data_a.get("total_kernel_time_us", sum(k["dur"] for k in labeled_a)) diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md index 6b9baf7c8..a9cf8d1e1 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/reference.md @@ -284,18 +284,18 @@ Read and follow the FULL instructions in: - Trace A (primary/trace1): (platform ) - Trace B (comparison/trace2): (platform ) - Labels: name-a trace1, name-b trace2 -- Output directory: /_semantic/ +- Output directory: /semantic/ - Command prefix: read /cache/cmd_prefix.txt — substitute {CMD} Run the full semantic comparison through "Generate TraceDiff Output" so that -/_semantic/tracediff_output/diff_stats.csv is produced. Return "DONE". +/semantic/tracediff_output/diff_stats.csv is produced. Return "DONE". ``` - Verify `/_semantic/tracediff_output/diff_stats.csv` exists before continuing. If it is missing, retry the subagent once; if it still fails, stop and report. + Verify `/semantic/tracediff_output/diff_stats.csv` exists before continuing. If it is missing, retry the subagent once; if it still fails, stop and report. -3. **Trace1 report** — run the analysis-mode CLI for trace1 with the `comparative` trace1 `` and `` = `--precomputed_diff_stats_csv /_semantic/tracediff_output/diff_stats.csv`. +3. **Trace1 report** — run the analysis-mode CLI for trace1 with the `comparative` trace1 `` and `` = `--precomputed_diff_stats_csv /semantic/tracediff_output/diff_stats.csv`. -4. **Confirm** `/perf_report_trace1_csvs/diff_stats.csv` exists (written by the report script). If absent, copy `/_semantic/tracediff_output/diff_stats.csv` to that path so the comparative fusion step (Steps 2-5) can read it. +4. **Confirm** `/perf_report_trace1_csvs/diff_stats.csv` exists (written by the report script). If absent, copy `/semantic/tracediff_output/diff_stats.csv` to that path so the comparative fusion step (Steps 2-5) can read it. --- From d8a378083288b8df5a8503ed357c21b95d33e4f8 Mon Sep 17 00:00:00 2001 From: Arseny Date: Thu, 3 Sep 2026 00:31:34 -0700 Subject: [PATCH 48/50] Further refinements, mostly stylistic/minor --- .../Analysis/semantic_analyses/build_semantic_labels.py | 2 -- .../Analysis/semantic_analyses/extract_tree_context.py | 6 ------ .../Analysis/semantic_analyses/generate_semantic_diff.py | 1 - .../Agent/Analysis/semantic_analyses/kernel_coherence.py | 3 --- .../Agent/Analysis/semantic_analyses/kernel_unification.py | 2 -- .../Agent/Analysis/semantic_analyses/match_and_compare.py | 1 - .../Agent/Analysis/semantic_analyses/trace_split_adapter.py | 1 - 7 files changed, 16 deletions(-) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py index e1c4c1703..0c01e14d9 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py @@ -29,10 +29,8 @@ import argparse import json -import os import sys -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from _helpers import build_rle, detect_period diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py index e184f184f..ad2a9c4c5 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py @@ -28,12 +28,6 @@ import os import sys -_this_dir = os.path.dirname(os.path.abspath(__file__)) -_repo_root = os.path.abspath(os.path.join(_this_dir, "..", "..", "..", "..")) -if _repo_root not in sys.path: # pragma: no cover - sys.path.insert(0, _repo_root) -if _this_dir not in sys.path: # pragma: no cover - sys.path.insert(0, _this_dir) from TraceLens.util import DataLoader from TraceLens.Trace2Tree.trace_to_tree import TraceToTree diff --git a/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py b/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py index 3863afcab..a28baf86a 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py @@ -44,7 +44,6 @@ import pandas as pd -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from _helpers import load_labels # --------------------------------------------------------------------------- diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py index 2d227c631..a717ad28d 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py @@ -56,14 +56,11 @@ import argparse import csv import json -import os import sys from collections import OrderedDict, defaultdict -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from kernel_runlength import ( collapse_consecutive, - load_sequence, run_index_per_kernel, shared_neighbor_windows_skip_non_shared, ) diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py index 14316fb83..c3111b3dc 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py @@ -65,12 +65,10 @@ import argparse import json -import os import re import sys from collections import OrderedDict -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from _helpers import load_json DEFAULT_THRESHOLD = 5000 diff --git a/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py b/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py index 5954119ab..956c3eae3 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py @@ -34,7 +34,6 @@ import sys from collections import OrderedDict -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from _helpers import load_labels, load_json diff --git a/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py b/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py index 5333b6ee3..d7d918114 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/trace_split_adapter.py @@ -26,7 +26,6 @@ import tempfile from typing import List, Optional, Tuple -sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from _helpers import load_json From 2af607478653eed8227cbcc41afd0cb0bdd683a7 Mon Sep 17 00:00:00 2001 From: Arseny Date: Thu, 3 Sep 2026 01:24:00 -0700 Subject: [PATCH 49/50] Further pruning --- .../build_semantic_labels.py | 55 +--- .../semantic_analyses/extract_tree_context.py | 279 ------------------ .../semantic_analyses/kernel_runlength.py | 2 - .../agents/semantic-comparison-agent.md | 29 +- tests/test_semantic_build_labels.py | 61 +--- tests/test_semantic_extract_tree_context.py | 184 ------------ 6 files changed, 27 insertions(+), 583 deletions(-) delete mode 100644 TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py delete mode 100644 tests/test_semantic_extract_tree_context.py diff --git a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py index 0c01e14d9..02320726c 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/build_semantic_labels.py @@ -8,7 +8,7 @@ """ Build semantic_labels.json deterministically from breakdown artifacts. -Combines extracted.json + classified.json + pattern.json + tree_context.json +Combines extracted.json + classified.json + pattern.json into the labeled kernel format consumed by the comparison pipeline. Each kernel gets a positionally-indexed ``semantic_block`` name (e.g. @@ -24,7 +24,7 @@ Usage: python build_semantic_labels.py extracted.json classified.json pattern.json \ - --tree-context tree_context.json [-o semantic_labels.json] + [-o semantic_labels.json] """ import argparse @@ -34,22 +34,6 @@ from _helpers import build_rle, detect_period -def _deepest_module(nn_module_stack): - """Extract the deepest nn.Module name from the stack list. - - Input like: ["nn.Module: WanTransformer3DModel > nn.Module: WanTransformerBlock"] - Returns: "WanTransformerBlock" - """ - if not nn_module_stack: - return "" - last_entry = nn_module_stack[-1] - parts = last_entry.split(" > ") - deepest = parts[-1] - if deepest.startswith("nn.Module: "): - deepest = deepest[len("nn.Module: ") :] - return deepest - - def _build_cycle_names(body_rle, period, cat_counter): """Build positionally-indexed block names for one layer cycle. @@ -100,15 +84,12 @@ def _build_region_block_names(index_set, cls_by_idx, cat_counter): return result -def build_labels(extracted, classified, pattern, tree_context=None): +def build_labels(extracted, classified, pattern): """Build semantic_labels.json from breakdown artifacts.""" kernels = extracted["kernels"] total_kernels = len(kernels) cls_by_idx = {c["index"]: c for c in classified["classified_kernels"]} - tree_by_idx = {} - if tree_context: - tree_by_idx = {k["index"]: k for k in tree_context["kernels"]} preamble_set = set(pattern.get("preamble_indices", [])) epilogue_set = set(pattern.get("epilogue_indices", [])) @@ -139,22 +120,21 @@ def build_labels(extracted, classified, pattern, tree_context=None): for i in range(total_kernels): k = kernels[i] c = cls_by_idx.get(i, {}) - tc = tree_by_idx.get(i, {}) - tree_uid = tc.get("gpu_op_uid") entry = { "index": i, "name": k["name"], "dur": k["dur"], - # Prefer the tree-built UID when tree-context ran (e.g. - # capture-augmented); fall back to the raw-index UID - # extract_trace_data.py already stamps on single-trace kernels - # when tree-context was skipped entirely (no-capture graph mode). - "gpu_op_uid": tree_uid if tree_uid is not None else k.get("gpu_op_uid"), + # Raw-index UID stamped by extract_trace_data.py; aligns with + # the perf report's kernel_details gpu_op_uid. + "gpu_op_uid": k.get("gpu_op_uid"), "perf_category": c.get("perf_category", "Others"), - "nn_module": _deepest_module(tc.get("nn_module_stack", [])), - "cpu_op": tc.get("cpu_op_name", ""), - "input_dims": tc.get("input_dims", []), + # nn_module / cpu_op / input_dims need cpu_op ancestry from a + # trace tree, unavailable for graph-mode / no-capture traces. + # Left empty; downstream falls back to semantic_block. + "nn_module": "", + "cpu_op": "", + "input_dims": [], } if i in body_index_to_rle_group: @@ -203,10 +183,6 @@ def main(): # pragma: no cover parser.add_argument("extracted_json", help="Path to extracted.json") parser.add_argument("classified_json", help="Path to classified.json") parser.add_argument("pattern_json", help="Path to pattern.json") - parser.add_argument( - "--tree-context", - help="Path to tree_context.json (optional, enriches nn_module and cpu_op)", - ) parser.add_argument("-o", "--output", help="Output JSON path (default: stdout)") args = parser.parse_args() @@ -217,12 +193,7 @@ def main(): # pragma: no cover with open(args.pattern_json) as f: pattern = json.load(f) - tree_context = None - if args.tree_context: - with open(args.tree_context) as f: - tree_context = json.load(f) - - result = build_labels(extracted, classified, pattern, tree_context) + result = build_labels(extracted, classified, pattern) output = json.dumps(result, indent=2) if args.output: diff --git a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py b/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py deleted file mode 100644 index ad2a9c4c5..000000000 --- a/TraceLens/Agent/Analysis/semantic_analyses/extract_tree_context.py +++ /dev/null @@ -1,279 +0,0 @@ -#!/usr/bin/env python3 -############################################################################### -# Copyright (c) 2024 - 2025 Advanced Micro Devices, Inc. All rights reserved. -# -# See LICENSE for license information. -############################################################################### - -""" -Extract trace tree context (cpu_op ancestors, nn_module_stack) for each kernel. - -Builds a TraceToTree from the raw trace and matches each kernel from -extracted.json to its tree event, walking the parent chain to find -cpu_op ancestors and nn_module_stack information. - -The output is raw data with no semantic interpretation -- downstream -LLM steps decide how to use cpu_op names and nn_module_stack for labeling. - -Usage (single region): - python extract_tree_context.py [-o tree_context.json] - -Usage (batch -- all regions share one tree build): - python extract_tree_context.py --regions-dir / - -""" - -import argparse -import json -import os -import sys - - -from TraceLens.util import DataLoader -from TraceLens.Trace2Tree.trace_to_tree import TraceToTree -from _helpers import load_json - - -def load_and_build_tree(trace_path): # pragma: no cover - """Load a trace file and build a TraceToTree.""" - data = DataLoader.load_data(trace_path) - events = data.get("traceEvents", []) - # Pass the full traceEvents list (do NOT strip metadata first) so that the - # per-event UID -- assigned as the enumerate() index in TraceToTree -- is - # identical to the one produced by TreePerfAnalyzer.from_file (which also - # builds from data["traceEvents"] as-is). This keeps the diff_stats - # gpu_op_uid aligned with the perf report's kernel_details gpu_op_uid so - # the comparison enrichment can map semantic rows onto perf-summary rows. - tree = TraceToTree(events, prune_nongpu_paths=True) - tree.build_tree(add_python_func=True, link_fwd_bwd=False) - return tree - - -def _build_ts_index(tree): - """Build (name, ts) -> [event] index for fast matching.""" - index = {} - for event in tree.events: - key = (event.get("name"), event.get("ts")) - index.setdefault(key, []).append(event) - return index - - -def _find_tree_event(ts_index, name, ts, dur, uid=None): - """Find a tree event matching by name, timestamp, and duration.""" - candidates = ts_index.get((name, ts), []) - if len(candidates) == 1: - return candidates[0] - # On a (name, ts) collision (concurrent same-name kernels in multi-stream / - # graph traces) prefer the exact stable-UID match: the kernel's gpu_op_uid - # equals its tree event UID, so this avoids a silent wrong attach. - if uid is not None: - for c in candidates: - if c.get("UID") == uid: - return c - for c in candidates: - if c.get("dur") == dur: - return c - return candidates[0] if candidates else None - - -def _find_cpu_op_ancestor(tree, event): - """Walk up parent chain to find nearest cpu_op ancestor. - - Returns (cpu_op_name, callstack_str, nn_module_stack_list, input_dims). - """ - current = event - nn_module = event.get("nn_module_stack", []) - - while True: - parent = tree.get_parent_event(current) - if parent is None: - return "", "", nn_module or [], [] - if tree.event_to_category(parent) == "cpu_op": - callstack = tree.traverse_parents_and_get_callstack(parent) - if not nn_module: - nn_module = parent.get("nn_module_stack", []) - args = parent.get("args", {}) - input_dims = args.get("Input Dims", []) or [] - return parent.get("name", ""), callstack, nn_module or [], input_dims - if not nn_module: - nn_module = parent.get("nn_module_stack", []) - current = parent - - -def extract_tree_context(tree, extracted_data, ts_index=None): - """Match extracted kernels to tree events and extract context. - - Args: - tree: TraceToTree instance. - extracted_data: dict from extract_trace_data.py with "kernels" list. - ts_index: optional pre-built (name, ts) index from _build_ts_index(). - Pass this when processing multiple regions against the same tree. - - Returns dict with per-kernel tree context, labeled/unlabeled indices, - and coverage stats. - """ - kernels = extracted_data["kernels"] - if ts_index is None: - ts_index = _build_ts_index(tree) - - labeled_indices = [] - unlabeled_indices = [] - kernel_contexts = [] - - for i, kernel in enumerate(kernels): - tree_event = _find_tree_event( - ts_index, - kernel["name"], - kernel["ts"], - kernel["dur"], - kernel.get("gpu_op_uid"), - ) - - if tree_event is None: - kernel_contexts.append( - { - "index": i, - "gpu_op_uid": None, - "cpu_op_name": "", - "cpu_op_callstack": "", - "nn_module_stack": [], - "input_dims": [], - } - ) - unlabeled_indices.append(i) - continue - - cpu_op_name, callstack, nn_module, input_dims = _find_cpu_op_ancestor( - tree, tree_event - ) - - kernel_contexts.append( - { - "index": i, - "gpu_op_uid": tree_event.get("UID"), - "cpu_op_name": cpu_op_name, - "cpu_op_callstack": callstack, - "nn_module_stack": nn_module, - "input_dims": input_dims, - } - ) - - if cpu_op_name: - labeled_indices.append(i) - else: - unlabeled_indices.append(i) - - total = len(kernels) - coverage = len(labeled_indices) / total if total > 0 else 0.0 - - result = { - "source_file": extracted_data.get("source_file", ""), - "total_kernels": total, - "coverage": round(coverage, 4), - "labeled_count": len(labeled_indices), - "unlabeled_count": len(unlabeled_indices), - "labeled_indices": labeled_indices, - "unlabeled_indices": unlabeled_indices, - "kernels": kernel_contexts, - } - return result - - -def _find_region_subdirs(regions_dir): # pragma: no cover - """Find subdirectories containing extracted.json.""" - regions = [] - for name in sorted(os.listdir(regions_dir)): - subdir = os.path.join(regions_dir, name) - if os.path.isdir(subdir) and os.path.isfile( - os.path.join(subdir, "extracted.json") - ): - regions.append((name, subdir)) - return regions - - -def _process_single(tree, ts_index, extracted_path, output_path): # pragma: no cover - """Process one extracted.json against a pre-built tree and ts_index.""" - extracted = load_json(extracted_path) - - n_kernels = len(extracted["kernels"]) - print(f" Matching {n_kernels} kernels...", file=sys.stderr, end=" ") - result = extract_tree_context(tree, extracted, ts_index=ts_index) - print(f"{result['coverage']:.1%} coverage", file=sys.stderr) - - with open(output_path, "w") as f: - json.dump(result, f, indent=2) - return result - - -def main(): # pragma: no cover - parser = argparse.ArgumentParser( - description="Extract trace tree context (cpu_op, nn_module) for each kernel" - ) - parser.add_argument("trace", help="Path to raw trace file (.json or .json.gz)") - parser.add_argument( - "extracted_json", - nargs="?", - default=None, - help="Path to extracted.json (single-region mode)", - ) - parser.add_argument( - "-o", "--output", help="Output JSON path (single-region: default stdout)" - ) - parser.add_argument( - "--regions-dir", - help="Batch mode: directory containing region subdirs " - "with extracted.json. Builds tree once, writes " - "tree_context.json into each region subdir.", - ) - args = parser.parse_args() - - if not args.extracted_json and not args.regions_dir: - parser.error("provide either extracted_json or --regions-dir") - - print(f"Building trace tree from {args.trace}...", file=sys.stderr) - tree = load_and_build_tree(args.trace) - ts_index = _build_ts_index(tree) - - if args.regions_dir: - regions = _find_region_subdirs(args.regions_dir) - if not regions: - print( - f"No region subdirs with extracted.json in {args.regions_dir}", - file=sys.stderr, - ) - sys.exit(1) - print(f"Batch mode: {len(regions)} regions found", file=sys.stderr) - for name, subdir in regions: - print(f"Region '{name}':", file=sys.stderr) - extracted_path = os.path.join(subdir, "extracted.json") - output_path = os.path.join(subdir, "tree_context.json") - _process_single(tree, ts_index, extracted_path, output_path) - print( - f"Wrote tree_context.json to {len(regions)} region subdirs", file=sys.stderr - ) - else: - extracted = load_json(args.extracted_json) - - print( - f"Matching {len(extracted['kernels'])} kernels to tree events...", - file=sys.stderr, - ) - result = extract_tree_context(tree, extracted, ts_index=ts_index) - - print( - f"Tree context: {result['labeled_count']}/{result['total_kernels']} " - f"kernels have cpu_op ancestors ({result['coverage']:.1%})", - file=sys.stderr, - ) - - output = json.dumps(result, indent=2) - if args.output: - with open(args.output, "w") as f: - f.write(output) - print(f"Wrote {args.output}", file=sys.stderr) - else: - print(output) - - -if __name__ == "__main__": # pragma: no cover - main() diff --git a/TraceLens/Agent/Analysis/semantic_analyses/kernel_runlength.py b/TraceLens/Agent/Analysis/semantic_analyses/kernel_runlength.py index 9737ff7b4..250541f49 100644 --- a/TraceLens/Agent/Analysis/semantic_analyses/kernel_runlength.py +++ b/TraceLens/Agent/Analysis/semantic_analyses/kernel_runlength.py @@ -19,8 +19,6 @@ one-sided -- a symbol present in only one trace's condensed set. """ -import json - from _helpers import load_json diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md index 34b31592e..f32024edd 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md @@ -83,49 +83,26 @@ run_breakdown() { # Extract (auto-splits vLLM traces into region subdirs) python $SCRIPTS/extract_trace_data.py $TRACE -o $DIR/ - # Check whether extraction produced region subdirs or a flat file + # Check whether extraction produced region subdirs or a flat file. + # gpu_op_uid is stamped by extract_trace_data.py (raw-index UID aligned + # with the perf report); no trace-tree build is needed. if ls $DIR/*/extracted.json >/dev/null 2>&1; then - # Multi-region graph-mode: skip extract_tree_context.py (gpu_op_uid already populated per-region, no tree build needed). - FIRST_REGION=$(ls -d $DIR/*/ | head -1) - IS_GRAPH_MODE=$(python -c "import json; print(json.load(open('${FIRST_REGION}extracted.json'))['metadata']['is_graph_mode'])") for REGION in $DIR/*/; do python $SCRIPTS/pattern_finder.py $REGION/extracted.json -o $REGION/pattern.json & python $CLASSIFY $REGION/extracted.json -o $REGION/classified.json & done - if [ "$IS_GRAPH_MODE" != "True" ]; then - python $SCRIPTS/extract_tree_context.py $TRACE --regions-dir $DIR/ - fi wait for REGION in $DIR/*/; do - TREE_ARGS="" - if [ -f "$REGION/tree_context.json" ]; then - TREE_ARGS="--tree-context $REGION/tree_context.json" - fi python $SCRIPTS/build_semantic_labels.py \ $REGION/extracted.json $REGION/classified.json $REGION/pattern.json \ - $TREE_ARGS \ -o $REGION/semantic_labels.json done else - # Single-trace. Skip extract_tree_context.py entirely for - # graph-mode traces: kernels sit directly under cudaGraphLaunch, so - # cpu_op/nn_module ancestry is always empty there anyway, and - # gpu_op_uid is already populated by extract_trace_data.py itself - # (a plain raw-index lookup, no tree build needed). Only build the - # tree when non-graph-mode. - IS_GRAPH_MODE=$(python -c "import json; print(json.load(open('$DIR/extracted.json'))['metadata']['is_graph_mode'])") python $SCRIPTS/pattern_finder.py $DIR/extracted.json -o $DIR/pattern.json & python $CLASSIFY $DIR/extracted.json -o $DIR/classified.json & - - TREE_ARGS="" - if [ "$IS_GRAPH_MODE" != "True" ]; then - python $SCRIPTS/extract_tree_context.py $TRACE $DIR/extracted.json -o $DIR/tree_context.json - TREE_ARGS="--tree-context $DIR/tree_context.json" - fi wait python $SCRIPTS/build_semantic_labels.py \ $DIR/extracted.json $DIR/classified.json $DIR/pattern.json \ - $TREE_ARGS \ -o $DIR/semantic_labels.json fi } diff --git a/tests/test_semantic_build_labels.py b/tests/test_semantic_build_labels.py index 10b48eac1..0ef492a73 100644 --- a/tests/test_semantic_build_labels.py +++ b/tests/test_semantic_build_labels.py @@ -21,22 +21,6 @@ import build_semantic_labels -# --------------------------------------------------------------------------- # -# _deepest_module -# --------------------------------------------------------------------------- # -def test_deepest_module_empty(): - assert build_semantic_labels._deepest_module([]) == "" - - -def test_deepest_module_strips_prefix_and_takes_deepest(): - stack = ["nn.Module: WanTransformer3DModel > nn.Module: WanTransformerBlock"] - assert build_semantic_labels._deepest_module(stack) == "WanTransformerBlock" - - -def test_deepest_module_without_prefix(): - assert build_semantic_labels._deepest_module(["PlainName"]) == "PlainName" - - # --------------------------------------------------------------------------- # # _build_cycle_names # --------------------------------------------------------------------------- # @@ -125,29 +109,7 @@ def test_build_labels_positional_labels_and_layers(): "epilogue_indices": [14, 15], "secondary_stream_indices": [16], } - tree_context = { - "kernels": [ - { - "index": 2, - "gpu_op_uid": "tree2", - "nn_module_stack": ["nn.Module: Model > nn.Module: Block"], - "cpu_op_name": "aten::mm", - "input_dims": [[1, 2]], - }, - { - # tree entry present but no UID -> falls back to raw uid - "index": 4, - "gpu_op_uid": None, - "nn_module_stack": ["Solo"], - "cpu_op_name": "", - "input_dims": [], - }, - ] - } - - result = build_semantic_labels.build_labels( - extracted, classified, pattern, tree_context - ) + result = build_semantic_labels.build_labels(extracted, classified, pattern) info = result["model_info"] assert info["period"] == 3 @@ -182,19 +144,20 @@ def test_build_labels_positional_labels_and_layers(): assert kernels[16]["region"] == "secondary" assert kernels[16]["semantic_block"] == "GEMM_2" - # tree_context enrichment + gpu_op_uid preference / fallback. - assert kernels[2]["nn_module"] == "Block" - assert kernels[2]["cpu_op"] == "aten::mm" - assert kernels[2]["gpu_op_uid"] == "tree2" - assert kernels[4]["nn_module"] == "Solo" - assert kernels[4]["gpu_op_uid"] == "raw4" # tree uid was None -> raw fallback - # Kernel with no tree entry -> empty enrichment, raw uid. + # Enrichment fields are always empty (no trace-tree build); gpu_op_uid + # comes straight from the raw-index UID stamped by extract_trace_data. + assert kernels[2]["nn_module"] == "" + assert kernels[2]["cpu_op"] == "" + assert kernels[2]["input_dims"] == [] + assert kernels[2]["gpu_op_uid"] == "raw2" + assert kernels[4]["nn_module"] == "" + assert kernels[4]["gpu_op_uid"] == "raw4" assert kernels[3]["nn_module"] == "" assert kernels[3]["cpu_op"] == "" assert kernels[3]["gpu_op_uid"] == "raw3" -def test_build_labels_no_body_period_zero_and_no_tree_context(): +def test_build_labels_no_body_period_zero(): cats = ["GEMM", "GEMM", "Normalization"] extracted = {"kernels": [{"name": f"k{i}", "dur": 1.0} for i in range(3)]} classified = _classified(cats) @@ -204,9 +167,7 @@ def test_build_labels_no_body_period_zero_and_no_tree_context(): "secondary_stream_indices": [], } - result = build_semantic_labels.build_labels( - extracted, classified, pattern, tree_context=None - ) + result = build_semantic_labels.build_labels(extracted, classified, pattern) info = result["model_info"] assert info["period"] == 0 diff --git a/tests/test_semantic_extract_tree_context.py b/tests/test_semantic_extract_tree_context.py deleted file mode 100644 index 2f23b7560..000000000 --- a/tests/test_semantic_extract_tree_context.py +++ /dev/null @@ -1,184 +0,0 @@ -############################################################################### -# Copyright (c) 2026 Advanced Micro Devices, Inc. All rights reserved. -# -# See LICENSE for license information. -############################################################################### - -"""Unit tests for semantic_analyses/extract_tree_context.py matching logic.""" - -import os, sys - -REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) -SEM = os.path.join(REPO_ROOT, "TraceLens", "Agent", "Analysis", "semantic_analyses") -sys.path.insert(0, SEM) -import extract_tree_context - - -class FakeTree: - """Minimal tree stub exposing only what the matching functions read.""" - - def __init__(self, events): - self.events = events - - def get_parent_event(self, event): - return event.get("_parent") - - def event_to_category(self, event): - return event.get("_cat") - - def traverse_parents_and_get_callstack(self, event): - return "callstack:" + event.get("name", "") - - -def test_build_ts_index(): - events = [ - {"name": "a", "ts": 1}, - {"name": "a", "ts": 1}, - {"name": "b", "ts": 2}, - ] - index = extract_tree_context._build_ts_index(FakeTree(events)) - assert len(index[("a", 1)]) == 2 - assert len(index[("b", 2)]) == 1 - - -def test_find_tree_event_single_candidate(): - e = {"name": "a", "ts": 1, "dur": 3, "UID": 1} - index = {("a", 1): [e]} - assert extract_tree_context._find_tree_event(index, "a", 1, 3) is e - - -def test_find_tree_event_uid_disambiguates_collision(): - e1 = {"name": "a", "ts": 1, "dur": 3, "UID": 10} - e2 = {"name": "a", "ts": 1, "dur": 3, "UID": 20} - index = {("a", 1): [e1, e2]} - got = extract_tree_context._find_tree_event(index, "a", 1, 3, uid=20) - assert got is e2 - - -def test_find_tree_event_dur_fallback_on_collision(): - e1 = {"name": "a", "ts": 1, "dur": 3, "UID": 10} - e2 = {"name": "a", "ts": 1, "dur": 9, "UID": 20} - index = {("a", 1): [e1, e2]} - # No uid given -> disambiguate by dur. - got = extract_tree_context._find_tree_event(index, "a", 1, 9) - assert got is e2 - - -def test_find_tree_event_first_when_no_match(): - e1 = {"name": "a", "ts": 1, "dur": 3, "UID": 10} - e2 = {"name": "a", "ts": 1, "dur": 4, "UID": 20} - index = {("a", 1): [e1, e2]} - # uid + dur both fail to match -> first candidate. - got = extract_tree_context._find_tree_event(index, "a", 1, 99, uid=999) - assert got is e1 - - -def test_find_tree_event_none_when_missing(): - assert extract_tree_context._find_tree_event({}, "a", 1, 3) is None - - -def test_find_cpu_op_ancestor_walks_to_cpu_op(): - cpu_op = { - "name": "aten::mm", - "_cat": "cpu_op", - "args": {"Input Dims": [[2, 2]]}, - "nn_module_stack": ["mod"], - } - mid = {"name": "py_fn", "_cat": "python_function", "_parent": cpu_op} - gpu = {"name": "gemm", "_cat": "kernel", "_parent": mid} - tree = FakeTree([cpu_op, mid, gpu]) - - name, callstack, nn_module, input_dims = extract_tree_context._find_cpu_op_ancestor( - tree, gpu - ) - assert name == "aten::mm" - assert callstack == "callstack:aten::mm" - assert nn_module == ["mod"] - assert input_dims == [[2, 2]] - - -def test_find_cpu_op_ancestor_no_parent(): - gpu = {"name": "gemm", "_cat": "kernel"} - tree = FakeTree([gpu]) - name, callstack, nn_module, input_dims = extract_tree_context._find_cpu_op_ancestor( - tree, gpu - ) - assert name == "" - assert callstack == "" - assert nn_module == [] - assert input_dims == [] - - -def test_extract_tree_context_mixed(): - cpu_op = { - "name": "aten::mm", - "ts": 1, - "UID": 10, - "_cat": "cpu_op", - "args": {"Input Dims": [[2, 2]]}, - "nn_module_stack": ["m"], - } - gpu = { - "name": "gemm", - "ts": 5, - "dur": 3, - "UID": 11, - "_cat": "kernel", - "_parent": cpu_op, - } - solo = {"name": "solo", "ts": 9, "dur": 2, "UID": 12, "_cat": "kernel"} - tree = FakeTree([cpu_op, gpu, solo]) - - extracted = { - "source_file": "f.json", - "kernels": [ - {"name": "gemm", "ts": 5, "dur": 3, "gpu_op_uid": 11}, - {"name": "solo", "ts": 9, "dur": 2, "gpu_op_uid": 12}, - {"name": "missing", "ts": 99, "dur": 1, "gpu_op_uid": 99}, - ], - } - - result = extract_tree_context.extract_tree_context(tree, extracted) - - assert result["total_kernels"] == 3 - assert result["labeled_count"] == 1 - assert result["unlabeled_count"] == 2 - assert result["labeled_indices"] == [0] - assert result["unlabeled_indices"] == [1, 2] - assert result["coverage"] == round(1 / 3, 4) - - # Matched kernel with cpu_op ancestor. - ctx0 = result["kernels"][0] - assert ctx0["gpu_op_uid"] == 11 - assert ctx0["cpu_op_name"] == "aten::mm" - assert ctx0["input_dims"] == [[2, 2]] - - # Matched kernel with no cpu_op ancestor. - assert result["kernels"][1]["cpu_op_name"] == "" - assert result["kernels"][1]["gpu_op_uid"] == 12 - - # Unmatched kernel. - assert result["kernels"][2]["gpu_op_uid"] is None - assert result["kernels"][2]["cpu_op_name"] == "" - - -def test_extract_tree_context_empty_uses_prebuilt_index(): - tree = FakeTree([]) - ts_index = extract_tree_context._build_ts_index(tree) - result = extract_tree_context.extract_tree_context( - tree, {"kernels": []}, ts_index=ts_index - ) - assert result["total_kernels"] == 0 - assert result["coverage"] == 0.0 - assert result["source_file"] == "" - - -def test_extract_tree_context_gpu_op_uid_comes_from_tree_event(): - # The output gpu_op_uid must be the matched TREE EVENT UID, not the kernel own - # gpu_op_uid; give them distinct values to pin down where the value is sourced. - gpu = {"name": "gemm", "ts": 5, "dur": 3, "UID": 777, "_cat": "kernel"} - tree = FakeTree([gpu]) - extracted = {"kernels": [{"name": "gemm", "ts": 5, "dur": 3, "gpu_op_uid": 11}]} - result = extract_tree_context.extract_tree_context(tree, extracted) - ctx = result["kernels"][0] - assert ctx["gpu_op_uid"] == 777 From 6e2a83da3b66eccd169525e1f4a78f152b2b40dc Mon Sep 17 00:00:00 2001 From: Arseny Date: Thu, 3 Sep 2026 04:03:26 -0700 Subject: [PATCH 50/50] Further stylistic improvements --- .../agents/kernel-coherence-agent.md | 4 +- .../agents/kernel-stem-preprocessing-agent.md | 4 +- .../agents/kernel-unification-agent.md | 2 +- .../agents/semantic-comparison-agent.md | 110 +++++++++--------- 4 files changed, 65 insertions(+), 55 deletions(-) diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-coherence-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-coherence-agent.md index 7ff980c21..e1e75e97f 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-coherence-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-coherence-agent.md @@ -115,8 +115,10 @@ Resolution order applied per kernel (see `apply`): ## Apply + verify +The orchestrator runs: + ```bash -python TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py apply \ + python3 TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py apply \ --context /kernel_coherence_context.json \ --decisions /kernel_coherence_decisions.json \ --audit-csv-a /per_kernel_final_.csv \ diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md index 394309144..fdf3ec8c9 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md @@ -104,8 +104,10 @@ Fields per rule: ## Apply loop +The orchestrator runs: + ```bash -python TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py apply-stem-rules \ + python3 TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py apply-stem-rules \ --labels-a /semantic_labels.json \ --labels-b /semantic_labels.json \ --name-a --name-b \ diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md index d3486148c..6764f0750 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-unification-agent.md @@ -112,7 +112,7 @@ keys. The orchestrator runs: ```bash -python TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py apply-map \ + python3 TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py apply-map \ --labels-a /semantic_labels.json \ --labels-b /semantic_labels.json \ --name-a --name-b \ diff --git a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md index f32024edd..8fe3e7c8b 100644 --- a/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md +++ b/TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/semantic-comparison-agent.md @@ -6,7 +6,7 @@ See LICENSE for license information. --- name: semantic-comparison-agent -description: End-to-end semantic comparison of two graph-mode GPU traces. Runs deterministic breakdown per trace (extraction + tree context + classification + pattern finding + label assembly), then a name-first LLM kernel-name unification pass that establishes cross-trace matching anchors in the semantic_block field, followed by a comparison pipeline. +description: End-to-end semantic comparison of two graph-mode GPU traces. Runs deterministic breakdown per trace (extraction + classification + pattern finding + label assembly), then a name-first LLM kernel-name unification pass that establishes cross-trace matching anchors in the semantic_block field, followed by a comparison pipeline. model: claude-opus-4-8 --- @@ -29,6 +29,12 @@ field, which the downstream comparison uses as its matching key. Use vendor-agnostic terminology (GPU kernels, vendor GEMM library, etc.) except when quoting actual kernel names from traces. +**Command prefix.** All commands below run through ``: read the command +prefix path from your execution context (`/cache/cmd_prefix.txt`) and +substitute the command for `{CMD}`. `` is blank for local runs and wraps +commands into the target environment otherwise. Shell control flow (`for`, `if`, +`wait`) and variable assignments run in the driving shell and are not prefixed. + --- ## Workflow Steps @@ -73,35 +79,35 @@ background jobs + `wait`. ```bash SCRIPTS=TraceLens/Agent/Analysis/semantic_analyses CLASSIFY=TraceLens/Agent/Analysis/utils/classify_kernels.py -DIR_A=/_work/ -DIR_B=/_work/ -mkdir -p $DIR_A $DIR_B +DIR_A=/work/ +DIR_B=/work/ + mkdir -p $DIR_A $DIR_B run_breakdown() { local TRACE=$1 DIR=$2 # Extract (auto-splits vLLM traces into region subdirs) - python $SCRIPTS/extract_trace_data.py $TRACE -o $DIR/ + python3 $SCRIPTS/extract_trace_data.py $TRACE -o $DIR/ # Check whether extraction produced region subdirs or a flat file. # gpu_op_uid is stamped by extract_trace_data.py (raw-index UID aligned # with the perf report); no trace-tree build is needed. - if ls $DIR/*/extracted.json >/dev/null 2>&1; then + if ls $DIR/*/extracted.json >/dev/null 2>&1; then for REGION in $DIR/*/; do - python $SCRIPTS/pattern_finder.py $REGION/extracted.json -o $REGION/pattern.json & - python $CLASSIFY $REGION/extracted.json -o $REGION/classified.json & + python3 $SCRIPTS/pattern_finder.py $REGION/extracted.json -o $REGION/pattern.json & + python3 $CLASSIFY $REGION/extracted.json -o $REGION/classified.json & done wait for REGION in $DIR/*/; do - python $SCRIPTS/build_semantic_labels.py \ + python3 $SCRIPTS/build_semantic_labels.py \ $REGION/extracted.json $REGION/classified.json $REGION/pattern.json \ -o $REGION/semantic_labels.json done else - python $SCRIPTS/pattern_finder.py $DIR/extracted.json -o $DIR/pattern.json & - python $CLASSIFY $DIR/extracted.json -o $DIR/classified.json & + python3 $SCRIPTS/pattern_finder.py $DIR/extracted.json -o $DIR/pattern.json & + python3 $CLASSIFY $DIR/extracted.json -o $DIR/classified.json & wait - python $SCRIPTS/build_semantic_labels.py \ + python3 $SCRIPTS/build_semantic_labels.py \ $DIR/extracted.json $DIR/classified.json $DIR/pattern.json \ -o $DIR/semantic_labels.json fi @@ -113,8 +119,8 @@ wait ``` **Output directories:** -- Trace A: `/_work//` -- Trace B: `/_work//` +- Trace A: `/work//` +- Trace B: `/work//` For multi-region traces, each directory contains per-region subdirs (e.g., `decode_only_3/`, `prefill_only_1024/`). @@ -140,11 +146,11 @@ Scripts: `TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py` ### 2.1 Prepare Unification Context ```bash -python TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py prepare-context \ - --labels-a /_work//semantic_labels.json \ - --labels-b /_work//semantic_labels.json \ + python3 TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py prepare-context \ + --labels-a /work//semantic_labels.json \ + --labels-b /work//semantic_labels.json \ --name-a --name-b \ - -o /_work/kernel_unification_context.json + -o /work/kernel_unification_context.json ``` ### 2.2 Stem Preprocessing (conditional, only if flagged) @@ -154,13 +160,13 @@ the threshold, default 5000), the raw name set is too large for the LLM. Launch the subagent `TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-stem-preprocessing-agent.md`, then: ```bash -python TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py apply-stem-rules \ - --labels-a /_work//semantic_labels.json \ - --labels-b /_work//semantic_labels.json \ + python3 TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py apply-stem-rules \ + --labels-a /work//semantic_labels.json \ + --labels-b /work//semantic_labels.json \ --name-a --name-b \ - --rules /_work/stem_rules.json \ - --raw-to-stem /_work/raw_to_stem.json \ - -o /_work/kernel_unification_context.json + --rules /work/stem_rules.json \ + --raw-to-stem /work/raw_to_stem.json \ + -o /work/kernel_unification_context.json ``` Re-run until the printed stem count is within budget. @@ -173,18 +179,18 @@ launch it with `kernel_unification_context.json` inline. For multi-region vLLM: ### 2.4 Apply the Map ```bash -python TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py apply-map \ - --labels-a /_work//semantic_labels.json \ - --labels-b /_work//semantic_labels.json \ + python3 TraceLens/Agent/Analysis/semantic_analyses/kernel_unification.py apply-map \ + --labels-a /work//semantic_labels.json \ + --labels-b /work//semantic_labels.json \ --name-a --name-b \ - --map /_work/kernel_unification_map.json \ - --raw-to-stem /_work/raw_to_stem.json # only if 2.2 ran + --map /work/kernel_unification_map.json \ + --raw-to-stem /work/raw_to_stem.json # only if 2.2 ran ``` ### 2.5 Verify Unification Check that `kernel_unification_context.json` and `kernel_unification_map.json` -exist in `/_work/`, and that `apply-map` reported a non-empty +exist in `/work/`, and that `apply-map` reported a non-empty shared vocabulary. ### 2.6 Coherence Pass (second pass, LLM) @@ -201,12 +207,12 @@ meaningful one-sided buckets. ```bash KC=TraceLens/Agent/Analysis/semantic_analyses/kernel_coherence.py -python $KC prepare-context \ - --labels-a /_work//semantic_labels.json \ - --labels-b /_work//semantic_labels.json \ + python3 $KC prepare-context \ + --labels-a /work//semantic_labels.json \ + --labels-b /work//semantic_labels.json \ --name-a --name-b \ --neighbor-radius 1 \ - -o /_work/kernel_coherence_context.json + -o /work/kernel_coherence_context.json ``` ### 2.6b Launch coherence agent @@ -214,18 +220,18 @@ python $KC prepare-context \ Read `TraceLens/Agent/Analysis/skills/analysis-orchestrator/agents/kernel-coherence-agent.md` and launch it with `kernel_coherence_context.json` inline. It writes -`/_work/kernel_coherence_decisions.json` (`context_renames` + +`/work/kernel_coherence_decisions.json` (`context_renames` + `fallback_remap_a` / `fallback_remap_b`), pairing same-context one-sided buckets across traces into new shared names. ### 2.6c Apply ```bash -python $KC apply \ - --context /_work/kernel_coherence_context.json \ - --decisions /_work/kernel_coherence_decisions.json \ - --audit-csv-a /_work/per_kernel_final_.csv \ - --audit-csv-b /_work/per_kernel_final_.csv + python3 $KC apply \ + --context /work/kernel_coherence_context.json \ + --decisions /work/kernel_coherence_decisions.json \ + --audit-csv-a /work/per_kernel_final_.csv \ + --audit-csv-b /work/per_kernel_final_.csv ``` `apply` rewrites `semantic_block` in place and prints residual one-sided symbols. @@ -236,9 +242,9 @@ Revise decisions and re-run 2.6b--2.6c if meaningful (non-singleton) symbols rem ## Step 3: Generate TraceDiff Output ```bash -python TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py \ - /_work//semantic_labels.json \ - /_work//semantic_labels.json \ + python3 TraceLens/Agent/Analysis/semantic_analyses/generate_semantic_diff.py \ + /work//semantic_labels.json \ + /work//semantic_labels.json \ --name-a --name-b \ -o /tracediff_output/ ``` @@ -259,20 +265,20 @@ This is a **final deliverable** directory for downstream TraceDiff consumers. **Single-region mode:** ```bash -python TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ - /_work//semantic_labels.json \ - /_work//semantic_labels.json \ + python3 TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ + /work//semantic_labels.json \ + /work//semantic_labels.json \ --name-a --name-b \ - -o /_work/comparison.csv + -o /work/comparison.csv ``` **Multi-region mode (vLLM):** ```bash -python TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ - --regions-dir-a /_work/ \ - --regions-dir-b /_work/ \ + python3 TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ + --regions-dir-a /work/ \ + --regions-dir-b /work/ \ --name-a --name-b \ - -o /_work/comparison.csv + -o /work/comparison.csv ``` --- @@ -288,5 +294,5 @@ python TraceLens/Agent/Analysis/semantic_analyses/match_and_compare.py \ ## Final Deliverables -- `/_work/` -- per-trace `semantic_labels.json`, the unification/coherence JSON artifacts, `per_kernel_final_.csv`, and `comparison.csv` +- `/work/` -- per-trace `semantic_labels.json`, the unification/coherence JSON artifacts, `per_kernel_final_.csv`, and `comparison.csv` - `/tracediff_output/` -- TraceDiff deliverables (see Step 3)

  2. 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 z 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 z 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%0Dfh-c#xfgFwIU5<^PYf6>F>Pe-P!|>h z*(;POk6xWG`nzhJf~Z$F3m1I|)WVB5Bd}XauFK?QnRup|R;l3oELDxY@AY8(ovu;5 z=Yg!Gufd+ieGm>TLUPfbj?fx-iEeVxGk(tM#5CPUHuUxjl8iRJmw+VAM+Q z8iH`~a&n2q;bNkOZFe+JDIIF7cRY=>frl^spdQ!2bvr1n?_+pZ26F|<{R_io?Km4b)IvvZSZ(v7k7M76btLz{vnk4nx@33D)GD^H8a^ph%uo?Wt> zwiRz!h@f5E2VWlLWAnsRj4ZQBmOk+Y4}-qL$7KHndQTM?)1`8<-;HR^q*UCAqkMhql=Sq^`>l995#HJFXvIT&1bodPFCoJlqed&O9LsVRtQad} ziH})W{~>qH>lb6#uXtI_Vuo{B*a7QT7q3dS)y5OgdX?RvIJa(@(hH*3u`0bZE;!edm~XuYeOMkK9&Pjpz>I;5#Tw~Pxuc4)L$ z1TX)4eE+3&bLbjibu^0Z;E_$;W$S40pdZFfVpCg4dsxaMC+?}ICPte)OaGSJY8xGW zp@2KiVnjp($C@|Mb@9RybIz2)a6WMHJ@1}SUVuegwUM7-wJk=G+6KN52$kDwyO;Zv z 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