From eb1ee330f0b480d52873f23da7683a5124c3b523 Mon Sep 17 00:00:00 2001 From: Nick Riasanovsky Date: Thu, 23 Oct 2025 14:44:22 -0700 Subject: [PATCH 1/5] Add the web frontend (#182) Summary: Pull Request resolved: https://github.com/meta-pytorch/tritonparse/pull/182 Differential Revision: D85376311 --- website/src/App.tsx | 27 +++++++++++- website/src/pages/IRAnalysis.tsx | 75 ++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 website/src/pages/IRAnalysis.tsx diff --git a/website/src/App.tsx b/website/src/App.tsx index c6d8d2c..75530ba 100644 --- a/website/src/App.tsx +++ b/website/src/App.tsx @@ -12,6 +12,7 @@ import CodeView from "./pages/CodeView"; import FileDiffView from "./pages/FileDiffView"; import SingleCodeViewer from "./components/SingleCodeViewer"; import KernelOverview from "./pages/KernelOverview"; +import IRAnalysis from "./pages/IRAnalysis"; import DataSourceSelector from "./components/DataSourceSelector"; import WelcomeScreen from "./components/WelcomeScreen"; import ExternalLink from "./components/ExternalLink"; @@ -409,7 +410,7 @@ function App() { ); } else { - // Show either overview, IR code, or file diff based on active tab + // Show either overview, IR code, IR analysis, or file diff based on active tab if (activeTab === "overview") { return ( ); } + if (activeTab === "ir_analysis") { + return ( + + ); + } if (activeTab === "comparison") { return ( File Diff + diff --git a/website/src/pages/IRAnalysis.tsx b/website/src/pages/IRAnalysis.tsx new file mode 100644 index 0000000..386bc38 --- /dev/null +++ b/website/src/pages/IRAnalysis.tsx @@ -0,0 +1,75 @@ +import React from "react"; +import { ProcessedKernel } from "../utils/dataLoader"; + +interface IRAnalysisProps { + kernels: ProcessedKernel[]; + selectedKernel: number; +} + +const formatMetadataValue = (value: any): string => { + if (value === null) { + return "null"; + } + if (typeof value === "boolean") { + return value ? "true" : "false"; + } + if (Array.isArray(value)) { + return JSON.stringify(value); + } + if (typeof value === "object") { + return JSON.stringify(value); + } + return String(value); +}; + +interface MetadataItemProps { + label: string; + value: React.ReactNode; +} + +const MetadataItem: React.FC = ({ label, value }) => ( +
+ {label} + {value} +
+); + +const IRAnalysis: React.FC = ({ kernels, selectedKernel }) => { + if (kernels.length === 0) { + return ( +
+
No kernel data available
+
+ ); + } + + const kernel = kernels[selectedKernel]; + + return ( +
+

Triton Kernel IR Analysis

+ +
+

+ Kernel: {kernel.name} +

+ +
+

+ The IR analysis provides helpful insights into important kernel properties + that were derived from the IR. +

+
+ +
+

+ IR analysis data will be displayed here when available in the + kernel data structure. +

+
+
+
+ ); +}; + +export default IRAnalysis; From 17fb4009dce52799ac68ff9af2fb45c2101650d3 Mon Sep 17 00:00:00 2001 From: Nick Riasanovsky Date: Fri, 24 Oct 2025 17:11:23 -0700 Subject: [PATCH 2/5] Updated website, need devmate to improve code --- tritonparse/ir_analysis.py | 11 +++-- tritonparse/trace_processor.py | 11 +++-- website/src/App.tsx | 3 +- website/src/pages/IRAnalysis.tsx | 71 ++++++++++++++++---------------- website/src/utils/dataLoader.ts | 16 +++++++ 5 files changed, 68 insertions(+), 44 deletions(-) diff --git a/tritonparse/ir_analysis.py b/tritonparse/ir_analysis.py index 20addd3..3f5a183 100644 --- a/tritonparse/ir_analysis.py +++ b/tritonparse/ir_analysis.py @@ -40,7 +40,7 @@ def process_amd_gcn_bufferops( ) -> dict[str, int]: ir_content = load_ir_contents(key, file_content, file_path) # TODO: Add atomics - io_keys = ["global_load_", "global_store_", "buffer_load_", "buffer_store_"] + io_keys = ["global_load", "global_store", "buffer_load", "buffer_store"] return process_amd_bufferop(ir_content, io_keys) @@ -64,9 +64,12 @@ def _generate_ir_analysis(entry: str): gcn_bufferops_info = process_amd_gcn_bufferops( amdgcn_key, file_content, file_path ) + io_counts = {} # NDJSON format requires a newline at the end of each line if ttgir_bufferops_info: - ir_analysis["amd_ttgir_bufferops_count"] = ttgir_bufferops_info + io_counts["amd_ttgir_bufferops_count"] = ttgir_bufferops_info if gcn_bufferops_info: - ir_analysis["amd_gcn_bufferops_count"] = gcn_bufferops_info - return {"ir_analysis": ir_analysis} + io_counts["amd_gcn_bufferops_count"] = gcn_bufferops_info + if io_counts: + ir_analysis["io_counts"] = io_counts + return ir_analysis diff --git a/tritonparse/trace_processor.py b/tritonparse/trace_processor.py index b321e6b..e797dae 100644 --- a/tritonparse/trace_processor.py +++ b/tritonparse/trace_processor.py @@ -299,10 +299,15 @@ def parse_single_file( ) if compilation_event: - ir_analysis_event = _generate_ir_analysis(compilation_event) + ir_analysis = _generate_ir_analysis(compilation_event) if ir_analysis_event: - all_output_lines[output_file].append( - json.dumps(ir_analysis_event, separators=(",", ":")) + "\n" + ir_analysis_event = { + "event_type": "ir_analysis", + "hash": _kernel_hash, + "ir_analysis": ir_analysis, + } + all_output_lines[output_file].append( + json.dumps(ir_analysis_event, separators=(",", ":")) + "\n" ) if compilation_event and launches_with_indices: diff --git a/website/src/App.tsx b/website/src/App.tsx index 75530ba..142812f 100644 --- a/website/src/App.tsx +++ b/website/src/App.tsx @@ -559,7 +559,6 @@ function App() { )} - + {dataLoaded && kernels.length > 0 && ( + )} diff --git a/website/src/pages/IRAnalysis.tsx b/website/src/pages/IRAnalysis.tsx index 386bc38..2412b52 100644 --- a/website/src/pages/IRAnalysis.tsx +++ b/website/src/pages/IRAnalysis.tsx @@ -6,34 +6,6 @@ interface IRAnalysisProps { selectedKernel: number; } -const formatMetadataValue = (value: any): string => { - if (value === null) { - return "null"; - } - if (typeof value === "boolean") { - return value ? "true" : "false"; - } - if (Array.isArray(value)) { - return JSON.stringify(value); - } - if (typeof value === "object") { - return JSON.stringify(value); - } - return String(value); -}; - -interface MetadataItemProps { - label: string; - value: React.ReactNode; -} - -const MetadataItem: React.FC = ({ label, value }) => ( -
- {label} - {value} -
-); - const IRAnalysis: React.FC = ({ kernels, selectedKernel }) => { if (kernels.length === 0) { return ( @@ -44,6 +16,16 @@ const IRAnalysis: React.FC = ({ kernels, selectedKernel }) => { } const kernel = kernels[selectedKernel]; + if (kernel.ir_analysis === null) { + return ( +
+
No IR Analysis available
+
+ ); + } + const io_counts = kernel.ir_analysis!.io_counts + const ttgir_info = kernel.ir_analysis!.io_counts!["amd_ttgir_bufferops_count"]; + const amdgcn_info = kernel.ir_analysis!.io_counts!["amd_gcn_bufferops_count"]; return (
@@ -54,17 +36,34 @@ const IRAnalysis: React.FC = ({ kernels, selectedKernel }) => { Kernel: {kernel.name} -
-

- The IR analysis provides helpful insights into important kernel properties - that were derived from the IR. -

-
+

+ AMD BufferOps Information: +

- IR analysis data will be displayed here when available in the - kernel data structure. + Tiled Buffer Load Count: {ttgir_info["tt.load_count"]} +

+

+ Tiled Buffer Store Count: {ttgir_info["tt.store_count"]} +

+

+ Tiled Global Load Count: {ttgir_info["amdgpu.buffer_load_count"]} +

+

+ Tiled Global Store Count:{ttgir_info["amdgpu.buffer_store_count"]} +

+

+ AMDGCN Buffer Load Instruction Count: {amdgcn_info["global_load_count"]} +

+

+ AMDGCN Buffer Store Instruction Count: {amdgcn_info["global_store_count"]} +

+

+ AMDGCN Global Load Instruction Count: {amdgcn_info["buffer_load_count"]} +

+

+ AMDGCN Global Store Instruction Count: {amdgcn_info["buffer_store_count"]}

diff --git a/website/src/utils/dataLoader.ts b/website/src/utils/dataLoader.ts index 924f990..c064e49 100644 --- a/website/src/utils/dataLoader.ts +++ b/website/src/utils/dataLoader.ts @@ -167,6 +167,11 @@ export interface CompilationMetadata { [key: string]: any; // Allow additional unknown fields } +export interface IRAnalysisData { + // Mapping from IR stage -> count> + io_counts?: Record>; +} + /** * Extracted argument information */ @@ -224,6 +229,7 @@ export interface LogEntry { launch_index_map?: LaunchRange[]; diffs?: LaunchDiffData; sames?: LaunchSamesData; + ir_analysis?: IRAnalysisData; // Stored IR Analysis information. } /** @@ -239,6 +245,7 @@ export interface ProcessedKernel { pythonSourceInfo?: PythonSourceCodeInfo; // Python source code information metadata?: KernelMetadata; // Compilation metadata launchDiff?: LogEntry; // Aggregated launch event differences + ir_analysis?: IRAnalysisData; // Stored IR Analysis information. } /** @@ -503,6 +510,15 @@ export function processKernelData(logEntries: LogEntry[]): ProcessedKernel[] { console.warn(`Could not find matching kernel for launch_diff hash: ${hash}`); } } + if (entry.event_type === "ir_analysis") { + const hash = entry.hash; + if (hash && kernelsByHash.has(hash)) { + const kernel = kernelsByHash.get(hash)!; + kernel.ir_analysis = entry.ir_analysis!; // Attach the ir_analysis + } else { + console.warn(`Could not find matching kernel for ir_analysis hash: ${hash}`); + } + } } const finalKernels = Array.from(kernelsByHash.values()); From 800d176aeabf322ad53929ef989d344808fd4dc2 Mon Sep 17 00:00:00 2001 From: Nick Riasanovsky Date: Sat, 25 Oct 2025 18:19:40 -0400 Subject: [PATCH 3/5] Cleaned up the code --- website/src/pages/IRAnalysis.tsx | 87 ++++++++++++++++++++------------ 1 file changed, 55 insertions(+), 32 deletions(-) diff --git a/website/src/pages/IRAnalysis.tsx b/website/src/pages/IRAnalysis.tsx index 2412b52..9bac4f4 100644 --- a/website/src/pages/IRAnalysis.tsx +++ b/website/src/pages/IRAnalysis.tsx @@ -23,9 +23,10 @@ const IRAnalysis: React.FC = ({ kernels, selectedKernel }) => { ); } - const io_counts = kernel.ir_analysis!.io_counts - const ttgir_info = kernel.ir_analysis!.io_counts!["amd_ttgir_bufferops_count"]; - const amdgcn_info = kernel.ir_analysis!.io_counts!["amd_gcn_bufferops_count"]; + + const io_counts = kernel.ir_analysis?.io_counts; + const ttgir_info = io_counts?.["amd_ttgir_bufferops_count"]; + const amdgcn_info = io_counts?.["amd_gcn_bufferops_count"]; return (
@@ -36,36 +37,58 @@ const IRAnalysis: React.FC = ({ kernels, selectedKernel }) => { Kernel: {kernel.name} -

- AMD BufferOps Information: -

+ {io_counts && (ttgir_info || amdgcn_info) && ( + <> +

+ AMD BufferOps Information +

-
-

- Tiled Buffer Load Count: {ttgir_info["tt.load_count"]} -

-

- Tiled Buffer Store Count: {ttgir_info["tt.store_count"]} -

-

- Tiled Global Load Count: {ttgir_info["amdgpu.buffer_load_count"]} -

-

- Tiled Global Store Count:{ttgir_info["amdgpu.buffer_store_count"]} -

-

- AMDGCN Buffer Load Instruction Count: {amdgcn_info["global_load_count"]} -

-

- AMDGCN Buffer Store Instruction Count: {amdgcn_info["global_store_count"]} -

-

- AMDGCN Global Load Instruction Count: {amdgcn_info["buffer_load_count"]} -

-

- AMDGCN Global Store Instruction Count: {amdgcn_info["buffer_store_count"]} -

-
+
+
+ {ttgir_info && ( + <> +
+ Tiled Buffer Load Count + {ttgir_info["tt.load_count"] ?? "NaN"} +
+
+ Tiled Buffer Store Count + {ttgir_info["tt.store_count"] ?? "NaN"} +
+
+ Tiled Global Load Count + {ttgir_info["amdgpu.buffer_load_count"] ?? "NaN"} +
+
+ Tiled Global Store Count + {ttgir_info["amdgpu.buffer_store_count"] ?? "NaN"} +
+ + )} + {amdgcn_info && ( + <> +
+ AMDGCN Buffer Load Instruction Count + {amdgcn_info["global_load_count"] ?? "NaN"} +
+
+ AMDGCN Buffer Store Instruction Count + {amdgcn_info["global_store_count"] ?? "NaN"} +
+
+ AMDGCN Global Load Instruction Count + {amdgcn_info["buffer_load_count"] ?? "NaN"} +
+
+ AMDGCN Global Store Instruction Count + {amdgcn_info["buffer_store_count"] ?? "NaN"} +
+ + )} +
+
+ + )}
); From 6f5043da4b44e96f493b5118d9a5c69e8fbe9411 Mon Sep 17 00:00:00 2001 From: Nick Riasanovsky Date: Sat, 25 Oct 2025 18:34:29 -0400 Subject: [PATCH 4/5] Fixed the formatting issues --- tritonparse/trace_processor.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tritonparse/trace_processor.py b/tritonparse/trace_processor.py index e797dae..904e052 100644 --- a/tritonparse/trace_processor.py +++ b/tritonparse/trace_processor.py @@ -300,14 +300,14 @@ def parse_single_file( if compilation_event: ir_analysis = _generate_ir_analysis(compilation_event) - if ir_analysis_event: + if ir_analysis: ir_analysis_event = { "event_type": "ir_analysis", "hash": _kernel_hash, "ir_analysis": ir_analysis, } - all_output_lines[output_file].append( - json.dumps(ir_analysis_event, separators=(",", ":")) + "\n" + all_output_lines[output_file].append( + json.dumps(ir_analysis_event, separators=(",", ":")) + "\n" ) if compilation_event and launches_with_indices: From 9074bcfdab16aa88ea8c682c24e82f2ea728f78f Mon Sep 17 00:00:00 2001 From: Nick Riasanovsky Date: Mon, 27 Oct 2025 11:39:40 -0400 Subject: [PATCH 5/5] Applied feedback --- website/src/pages/IRAnalysis.tsx | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/website/src/pages/IRAnalysis.tsx b/website/src/pages/IRAnalysis.tsx index 9bac4f4..39d97e5 100644 --- a/website/src/pages/IRAnalysis.tsx +++ b/website/src/pages/IRAnalysis.tsx @@ -27,6 +27,7 @@ const IRAnalysis: React.FC = ({ kernels, selectedKernel }) => { const io_counts = kernel.ir_analysis?.io_counts; const ttgir_info = io_counts?.["amd_ttgir_bufferops_count"]; const amdgcn_info = io_counts?.["amd_gcn_bufferops_count"]; + const getCount = (info: Record | undefined, key: string): string => { return info?.[key]?.toString() ?? "N/A"; }; return (
@@ -49,39 +50,39 @@ const IRAnalysis: React.FC = ({ kernels, selectedKernel }) => { <>
Tiled Buffer Load Count - {ttgir_info["tt.load_count"] ?? "NaN"} + {getCount(ttgir_info, "tt.load_count")}
Tiled Buffer Store Count - {ttgir_info["tt.store_count"] ?? "NaN"} + {getCount(ttgir_info, "tt.store_count")}
Tiled Global Load Count - {ttgir_info["amdgpu.buffer_load_count"] ?? "NaN"} + {getCount(ttgir_info, "amdgpu.buffer_load_count")}
Tiled Global Store Count - {ttgir_info["amdgpu.buffer_store_count"] ?? "NaN"} + {getCount(ttgir_info, "amdgpu.buffer_store_count")}
)} {amdgcn_info && ( <>
- AMDGCN Buffer Load Instruction Count - {amdgcn_info["global_load_count"] ?? "NaN"} + AMDGCN Global Load Instruction Count + {getCount(amdgcn_info, "global_load_count")}
- AMDGCN Buffer Store Instruction Count - {amdgcn_info["global_store_count"] ?? "NaN"} + AMDGCN Global Store Instruction Count + {getCount(amdgcn_info, "global_store_count")}
- AMDGCN Global Load Instruction Count - {amdgcn_info["buffer_load_count"] ?? "NaN"} + AMDGCN Buffer Load Instruction Count + {getCount(amdgcn_info, "buffer_load_count")}
- AMDGCN Global Store Instruction Count - {amdgcn_info["buffer_store_count"] ?? "NaN"} + AMDGCN Buffer Store Instruction Count + {getCount(amdgcn_info, "buffer_store_count")}
)}