tritonparse 0.3.1.dev20251019071438__tar.gz → 0.3.1.dev20251021071528__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tritonparse might be problematic. Click here for more details.
- {tritonparse-0.3.1.dev20251019071438/tritonparse.egg-info → tritonparse-0.3.1.dev20251021071528}/PKG-INFO +1 -1
- tritonparse-0.3.1.dev20251021071528/tritonparse/reproducer/function_extractor.py +220 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/placeholder_replacer.py +11 -0
- tritonparse-0.3.1.dev20251021071528/tritonparse/reproducer/templates/example.py +30 -0
- tritonparse-0.3.1.dev20251019071438/tritonparse/reproducer/templates/example.py → tritonparse-0.3.1.dev20251021071528/tritonparse/reproducer/utils.py +158 -89
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528/tritonparse.egg-info}/PKG-INFO +1 -1
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse.egg-info/SOURCES.txt +1 -0
- tritonparse-0.3.1.dev20251019071438/tritonparse/reproducer/utils.py +0 -365
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.ci/README.md +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.ci/install-project.sh +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.ci/install-triton.sh +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.ci/run-tests.sh +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.ci/setup.sh +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.github/PAGES_SETUP.md +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.github/workflows/deploy-pages-standalone.yml +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.github/workflows/deploy-pages.yml +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.github/workflows/nightly-pypi.yml +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.github/workflows/test.yml +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.gitignore +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/CHANGELOG.md +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/CODE_OF_CONDUCT.md +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/CONTRIBUTING.md +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/LICENSE +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/Makefile +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/README.md +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/__init__.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/pyproject.toml +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/run.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/setup.cfg +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/README.md +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/__init__.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/example_output/logs/dedicated_log_triton_trace_findhao_.ndjson +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/example_output/parsed_output/dedicated_log_triton_trace_findhao__mapped.ndjson.gz +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/example_output/parsed_output/f0_fc0_a0_cai-.ndjson.gz +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/example_output/parsed_output/log_file_list.json +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/example_output/parsed_output_complex/dedicated_log_triton_trace_findhao__mapped.ndjson.gz +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/example_output/parsed_output_complex/log_file_list.json +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/test_add.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/test_tritonparse.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/__init__.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/__main__.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/cli.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/common.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/context_manager.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/event_diff.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/extract_source_mappings.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/ir_parser.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/mapper.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/__init__.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/cli.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/ingestion/ndjson.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/orchestrator.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/templates/__init__.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/templates/loader.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/types.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/shared_vars.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/source_type.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/sourcemap_utils.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/structured_logging.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/__init__.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/decompress_bin_ndjson.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/disasm.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/format_fix.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/load_tensor.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/prettify_ndjson.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/readme.md +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tp_logger.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/trace_processor.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/utils.py +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse.egg-info/dependency_links.txt +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse.egg-info/entry_points.txt +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse.egg-info/requires.txt +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse.egg-info/top_level.txt +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/eslint.config.js +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/index.html +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/package-lock.json +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/package.json +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/public/dedicated_log_triton_trace_findhao__mapped.ndjson.gz +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/public/f0_fc0_a0_cai-.ndjson +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/public/favicon.ico +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/public/logo.svg +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/scripts/inline-html.js +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/App.css +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/App.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/assets/react.svg +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/ArgumentViewer.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/Callstack.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/CodeComparisonView.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/CodeViewer.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/CompilationInfo.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/CopyCodeButton.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/DataSourceSelector.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/DiffComparisonView.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/DiffViewer.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/ExternalLink.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/SingleCodeViewer.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/StackDiffViewer.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/ToggleSwitch.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/TritonIRs.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/WelcomeScreen.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/context/FileDiffSession.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/index.css +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/main.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/pages/CodeView.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/pages/FileDiffView.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/pages/KernelOverview.tsx +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/utils/dataLoader.ts +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/utils/fbDetection.ts +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/utils/safeImport.ts +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/utils/tensor.ts +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/vite-env.d.ts +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/tsconfig.app.json +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/tsconfig.json +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/tsconfig.node.json +0 -0
- {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/vite.config.ts +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tritonparse
|
|
3
|
-
Version: 0.3.1.
|
|
3
|
+
Version: 0.3.1.dev20251021071528
|
|
4
4
|
Summary: TritonParse: A Compiler Tracer, Visualizer, and mini-Reproducer Generator for Triton Kernels
|
|
5
5
|
Author-email: Yueming Hao <yhao@meta.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Function extractor for reproducer utility functions.
|
|
3
|
+
|
|
4
|
+
This module extracts utility functions from utils.py and load_tensor.py
|
|
5
|
+
using AST parsing, and generates standalone code for reproducers.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import ast
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def extract_utility_functions() -> str:
|
|
13
|
+
"""
|
|
14
|
+
Extract all utility functions needed for the reproducer template.
|
|
15
|
+
|
|
16
|
+
Uses AST parsing to extract functions and constants from source files
|
|
17
|
+
without importing them (avoiding potential side effects).
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
str: Complete Python code including imports and all utility functions.
|
|
21
|
+
"""
|
|
22
|
+
# Prepare file paths
|
|
23
|
+
base_dir = Path(__file__).parent
|
|
24
|
+
utils_path = base_dir / "utils.py"
|
|
25
|
+
load_tensor_path = base_dir.parent / "tools" / "load_tensor.py"
|
|
26
|
+
|
|
27
|
+
# Parse source files
|
|
28
|
+
utils_tree, utils_lines = _parse_source_file(utils_path)
|
|
29
|
+
load_tensor_tree, load_tensor_lines = _parse_source_file(load_tensor_path)
|
|
30
|
+
|
|
31
|
+
# Define what to extract (in dependency order)
|
|
32
|
+
utils_function_names = [
|
|
33
|
+
"_get_triton_tensor_types",
|
|
34
|
+
"create_args_from_json_file",
|
|
35
|
+
"create_args_from_json",
|
|
36
|
+
"_apply_stride_and_offset",
|
|
37
|
+
"_create_base_tensor",
|
|
38
|
+
"_create_tensor",
|
|
39
|
+
"_create_arg_from_info",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
load_tensor_function_names = [
|
|
43
|
+
"load_tensor",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
# Extract content
|
|
47
|
+
extracted_parts = []
|
|
48
|
+
|
|
49
|
+
# Add required imports
|
|
50
|
+
extracted_parts.append(_generate_imports())
|
|
51
|
+
|
|
52
|
+
# Extract constant
|
|
53
|
+
constant = _extract_assignment(
|
|
54
|
+
utils_tree, utils_lines, "TRITON_KERNELS_CUSTOM_TYPES"
|
|
55
|
+
)
|
|
56
|
+
if constant:
|
|
57
|
+
extracted_parts.append(constant)
|
|
58
|
+
|
|
59
|
+
# Extract load_tensor functions
|
|
60
|
+
extracted_parts.extend(
|
|
61
|
+
_extract_functions(
|
|
62
|
+
load_tensor_tree, load_tensor_lines, load_tensor_function_names
|
|
63
|
+
)
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Extract utils functions
|
|
67
|
+
extracted_parts.extend(
|
|
68
|
+
_extract_functions(utils_tree, utils_lines, utils_function_names)
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
# Combine all parts
|
|
72
|
+
return "\n\n".join(extracted_parts)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _parse_source_file(file_path: Path) -> tuple[ast.Module, list[str]]:
|
|
76
|
+
"""
|
|
77
|
+
Parse a Python source file and return its AST and source lines.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
file_path: Path to the Python source file
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
tuple: (AST tree, list of source code lines)
|
|
84
|
+
|
|
85
|
+
Raises:
|
|
86
|
+
FileNotFoundError: If the source file doesn't exist
|
|
87
|
+
SyntaxError: If the source file has syntax errors
|
|
88
|
+
"""
|
|
89
|
+
try:
|
|
90
|
+
source_code = file_path.read_text(encoding="utf-8")
|
|
91
|
+
tree = ast.parse(source_code, filename=str(file_path))
|
|
92
|
+
except FileNotFoundError as e:
|
|
93
|
+
raise FileNotFoundError(f"Source file not found: {file_path}") from e
|
|
94
|
+
except SyntaxError as e:
|
|
95
|
+
raise SyntaxError(f"Failed to parse {file_path}: {e}") from e
|
|
96
|
+
|
|
97
|
+
lines = source_code.splitlines()
|
|
98
|
+
return tree, lines
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _extract_assignment(
|
|
102
|
+
tree: ast.Module, lines: list[str], var_name: str
|
|
103
|
+
) -> str | None:
|
|
104
|
+
"""
|
|
105
|
+
Extract a module-level assignment statement by variable name.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
tree: AST tree of the source file
|
|
109
|
+
lines: Source code lines
|
|
110
|
+
var_name: Name of the variable to extract
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
Complete assignment statement source code, or None if not found
|
|
114
|
+
|
|
115
|
+
Example:
|
|
116
|
+
Extracts:
|
|
117
|
+
TRITON_KERNELS_CUSTOM_TYPES = (
|
|
118
|
+
importlib.util.find_spec("triton_kernels") is not None
|
|
119
|
+
and importlib.util.find_spec("triton_kernels.tensor") is not None
|
|
120
|
+
)
|
|
121
|
+
"""
|
|
122
|
+
# Search only at module level
|
|
123
|
+
for node in tree.body:
|
|
124
|
+
if isinstance(node, ast.Assign):
|
|
125
|
+
for target in node.targets:
|
|
126
|
+
if isinstance(target, ast.Name) and target.id == var_name:
|
|
127
|
+
# Found it! Extract source code using line numbers
|
|
128
|
+
start_line = node.lineno - 1 # Convert to 0-based index
|
|
129
|
+
end_line = node.end_lineno # Already suitable for slicing
|
|
130
|
+
assignment_lines = lines[start_line:end_line]
|
|
131
|
+
return "\n".join(assignment_lines)
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def _extract_function(tree: ast.Module, lines: list[str], func_name: str) -> str | None:
|
|
136
|
+
"""
|
|
137
|
+
Extract a function definition by name, including decorators.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
tree: AST tree of the source file
|
|
141
|
+
lines: Source code lines
|
|
142
|
+
func_name: Name of the function to extract
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
Complete function source code including decorators, or None if not found
|
|
146
|
+
|
|
147
|
+
Example:
|
|
148
|
+
Extracts:
|
|
149
|
+
@lru_cache(maxsize=1)
|
|
150
|
+
def _get_triton_tensor_types():
|
|
151
|
+
'''Docstring'''
|
|
152
|
+
...
|
|
153
|
+
"""
|
|
154
|
+
# Walk the entire tree (handles nested functions if needed)
|
|
155
|
+
for node in ast.walk(tree):
|
|
156
|
+
if isinstance(node, ast.FunctionDef) and node.name == func_name:
|
|
157
|
+
# If function has decorators, start from the first decorator
|
|
158
|
+
if node.decorator_list:
|
|
159
|
+
start_line = node.decorator_list[0].lineno - 1
|
|
160
|
+
else:
|
|
161
|
+
start_line = node.lineno - 1
|
|
162
|
+
|
|
163
|
+
end_line = node.end_lineno
|
|
164
|
+
func_lines = lines[start_line:end_line]
|
|
165
|
+
return "\n".join(func_lines)
|
|
166
|
+
return None
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _extract_functions(
|
|
170
|
+
tree: ast.Module, lines: list[str], func_names: list[str]
|
|
171
|
+
) -> list[str]:
|
|
172
|
+
"""
|
|
173
|
+
Extract multiple functions from a source file.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
tree: AST tree of the source file
|
|
177
|
+
lines: Source code lines
|
|
178
|
+
func_names: List of function names to extract
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
List of function source codes in the same order as func_names
|
|
182
|
+
|
|
183
|
+
Raises:
|
|
184
|
+
ValueError: If any function is not found
|
|
185
|
+
"""
|
|
186
|
+
extracted = []
|
|
187
|
+
for func_name in func_names:
|
|
188
|
+
func_source = _extract_function(tree, lines, func_name)
|
|
189
|
+
if func_source is None:
|
|
190
|
+
raise ValueError(
|
|
191
|
+
f"Function '{func_name}' not found in source. "
|
|
192
|
+
f"Available functions might have been renamed or removed."
|
|
193
|
+
)
|
|
194
|
+
extracted.append(func_source)
|
|
195
|
+
return extracted
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def _generate_imports() -> str:
|
|
199
|
+
"""
|
|
200
|
+
Generate the import statements needed for the extracted functions.
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
str: Import statements as a single string
|
|
204
|
+
"""
|
|
205
|
+
imports = [
|
|
206
|
+
"import gzip",
|
|
207
|
+
"import hashlib",
|
|
208
|
+
"import importlib",
|
|
209
|
+
"import importlib.util",
|
|
210
|
+
"import io",
|
|
211
|
+
"import json",
|
|
212
|
+
"import logging",
|
|
213
|
+
"import sys",
|
|
214
|
+
"from functools import lru_cache",
|
|
215
|
+
"from pathlib import Path",
|
|
216
|
+
"from typing import Union",
|
|
217
|
+
"",
|
|
218
|
+
"import torch",
|
|
219
|
+
]
|
|
220
|
+
return "\n".join(imports)
|
|
@@ -2,6 +2,7 @@ from abc import ABC
|
|
|
2
2
|
|
|
3
3
|
from typing import Any, Dict, Protocol
|
|
4
4
|
|
|
5
|
+
from tritonparse.reproducer.function_extractor import extract_utility_functions
|
|
5
6
|
from tritonparse.reproducer.ingestion.ndjson import ContextBundle
|
|
6
7
|
from tritonparse.reproducer.types import KernelImportMode
|
|
7
8
|
from tritonparse.reproducer.utils import (
|
|
@@ -82,6 +83,9 @@ class DefaultPlaceholderReplacer(PlaceholderReplacer):
|
|
|
82
83
|
)
|
|
83
84
|
self.register("# {{KERNEL_SYSPATH_PLACEHOLDER}}", self._replace_kernel_syspath)
|
|
84
85
|
self.register("# {{KERNEL_IMPORT_PLACEHOLDER}}", self._replace_kernel_import)
|
|
86
|
+
self.register(
|
|
87
|
+
"# {{UTILITY_FUNCTIONS_PLACEHOLDER}}", self._replace_utility_functions
|
|
88
|
+
)
|
|
85
89
|
self.register(
|
|
86
90
|
"# {{KERNEL_INVOCATION_PLACEHOLDER}}", self._replace_kernel_invocation
|
|
87
91
|
)
|
|
@@ -217,6 +221,13 @@ triton.autotune = _patched_autotune
|
|
|
217
221
|
else:
|
|
218
222
|
raise ValueError(f"Unknown kernel_import mode: {kernel_import}")
|
|
219
223
|
|
|
224
|
+
def _replace_utility_functions(
|
|
225
|
+
self, code: str, context_bundle: ContextBundle, **kwargs
|
|
226
|
+
) -> str:
|
|
227
|
+
"""Replace the utility functions placeholder with extracted functions."""
|
|
228
|
+
utility_code = extract_utility_functions()
|
|
229
|
+
return code.replace("# {{UTILITY_FUNCTIONS_PLACEHOLDER}}", utility_code)
|
|
230
|
+
|
|
220
231
|
def _replace_kernel_invocation(
|
|
221
232
|
self, code: str, context_bundle: ContextBundle, **kwargs
|
|
222
233
|
) -> str:
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This file is automatically generated by TritonParse reproducer.
|
|
3
|
+
It contains a smallest testing example for a Triton kernel.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import torch
|
|
7
|
+
|
|
8
|
+
# {{IR_OVERRIDE_SETUP_PLACEHOLDER}}
|
|
9
|
+
|
|
10
|
+
# {{KERNEL_SYSPATH_PLACEHOLDER}}
|
|
11
|
+
|
|
12
|
+
# {{KERNEL_IMPORT_PLACEHOLDER}}
|
|
13
|
+
|
|
14
|
+
# {{UTILITY_FUNCTIONS_PLACEHOLDER}}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
if __name__ == "__main__":
|
|
18
|
+
script_dir = Path(__file__).resolve().parent # noqa: F821
|
|
19
|
+
json_file = script_dir / "{{JSON_FILE_NAME_PLACEHOLDER}}"
|
|
20
|
+
grid, args_dict = create_args_from_json_file(str(json_file)) # noqa: F821
|
|
21
|
+
|
|
22
|
+
print("Generated kernel arguments dictionary:")
|
|
23
|
+
for name, arg in args_dict.items():
|
|
24
|
+
print(f" {name}: {arg}")
|
|
25
|
+
print(f"Grid: {grid}")
|
|
26
|
+
|
|
27
|
+
# {{KERNEL_INVOCATION_PLACEHOLDER}}
|
|
28
|
+
|
|
29
|
+
torch.cuda.synchronize()
|
|
30
|
+
print("Kernel execution finished.")
|
|
@@ -1,27 +1,16 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This file is automatically generated by TritonParse reproducer.
|
|
3
|
-
It contains a smallest testing example for a Triton kernel.
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
import gzip
|
|
7
|
-
import hashlib
|
|
8
1
|
import importlib
|
|
9
2
|
import importlib.util
|
|
10
|
-
import io
|
|
11
3
|
import json
|
|
12
4
|
import logging
|
|
13
5
|
import sys
|
|
6
|
+
from datetime import datetime
|
|
14
7
|
from functools import lru_cache
|
|
15
8
|
from pathlib import Path
|
|
16
|
-
from typing import Union
|
|
17
9
|
|
|
18
10
|
import torch
|
|
19
11
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
# {{KERNEL_SYSPATH_PLACEHOLDER}}
|
|
23
|
-
|
|
24
|
-
# {{KERNEL_IMPORT_PLACEHOLDER}}
|
|
12
|
+
from tritonparse.tools.load_tensor import load_tensor
|
|
13
|
+
from tritonparse.tp_logger import logger
|
|
25
14
|
|
|
26
15
|
TRITON_KERNELS_CUSTOM_TYPES = (
|
|
27
16
|
importlib.util.find_spec("triton_kernels") is not None
|
|
@@ -31,15 +20,6 @@ TRITON_KERNELS_CUSTOM_TYPES = (
|
|
|
31
20
|
|
|
32
21
|
@lru_cache(maxsize=1)
|
|
33
22
|
def _get_triton_tensor_types():
|
|
34
|
-
"""
|
|
35
|
-
Import and cache Triton custom tensor types.
|
|
36
|
-
|
|
37
|
-
Returns:
|
|
38
|
-
tuple: (Tensor, Storage, StridedLayout) classes from triton_kernels.tensor.
|
|
39
|
-
|
|
40
|
-
Raises:
|
|
41
|
-
ImportError: If the optional module 'triton_kernels.tensor' is not available.
|
|
42
|
-
"""
|
|
43
23
|
mod = importlib.import_module("triton_kernels.tensor")
|
|
44
24
|
return (
|
|
45
25
|
mod.Tensor,
|
|
@@ -48,66 +28,16 @@ def _get_triton_tensor_types():
|
|
|
48
28
|
)
|
|
49
29
|
|
|
50
30
|
|
|
51
|
-
def
|
|
31
|
+
def create_args_from_json_file(json_path):
|
|
52
32
|
"""
|
|
53
|
-
Load
|
|
33
|
+
Load and parse a reproducer JSON file.
|
|
54
34
|
|
|
55
35
|
Args:
|
|
56
|
-
|
|
57
|
-
- .bin.gz: gzip-compressed tensor (hash is of uncompressed data)
|
|
58
|
-
- .bin: uncompressed tensor (for backward compatibility)
|
|
59
|
-
device (str, optional): Device to load the tensor to (e.g., 'cuda:0', 'cpu').
|
|
60
|
-
If None, keeps the tensor on its original device.
|
|
36
|
+
json_path (str): Path to the JSON file describing the kernel launch.
|
|
61
37
|
|
|
62
38
|
Returns:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
Raises:
|
|
66
|
-
FileNotFoundError: If the tensor file doesn't exist
|
|
67
|
-
RuntimeError: If the tensor cannot be loaded
|
|
68
|
-
ValueError: If the computed hash doesn't match the filename hash
|
|
39
|
+
tuple[list, dict]: Grid specification list and map of argument name to value.
|
|
69
40
|
"""
|
|
70
|
-
blob_path = Path(tensor_file_path)
|
|
71
|
-
|
|
72
|
-
if not blob_path.exists():
|
|
73
|
-
raise FileNotFoundError(f"Tensor blob not found: {blob_path}")
|
|
74
|
-
|
|
75
|
-
# Detect compression by file extension
|
|
76
|
-
is_compressed = blob_path.name.endswith(".bin.gz")
|
|
77
|
-
|
|
78
|
-
# Read file contents (decompress if needed)
|
|
79
|
-
try:
|
|
80
|
-
with open(blob_path, "rb") as f:
|
|
81
|
-
file_obj = gzip.GzipFile(fileobj=f, mode="rb") if is_compressed else f
|
|
82
|
-
file_contents = file_obj.read()
|
|
83
|
-
except (OSError, gzip.BadGzipFile) as e:
|
|
84
|
-
if is_compressed:
|
|
85
|
-
raise RuntimeError(f"Failed to decompress gzip file {blob_path}: {str(e)}")
|
|
86
|
-
else:
|
|
87
|
-
raise RuntimeError(f"Failed to read file {blob_path}: {str(e)}")
|
|
88
|
-
|
|
89
|
-
# Extract expected hash from filename
|
|
90
|
-
# abc123.bin.gz -> abc123 or abc123.bin -> abc123
|
|
91
|
-
expected_hash = blob_path.name.removesuffix(".bin.gz" if is_compressed else ".bin")
|
|
92
|
-
|
|
93
|
-
# Compute hash of uncompressed data
|
|
94
|
-
computed_hash = hashlib.blake2b(file_contents).hexdigest()
|
|
95
|
-
|
|
96
|
-
# Verify hash matches filename
|
|
97
|
-
if computed_hash != expected_hash:
|
|
98
|
-
raise ValueError(
|
|
99
|
-
f"Hash verification failed: expected '{expected_hash}' but computed '{computed_hash}'"
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
try:
|
|
103
|
-
# Load the tensor from memory buffer
|
|
104
|
-
tensor = torch.load(io.BytesIO(file_contents), map_location=device)
|
|
105
|
-
return tensor
|
|
106
|
-
except Exception as e:
|
|
107
|
-
raise RuntimeError(f"Failed to load tensor from {blob_path}: {str(e)}")
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def create_args_from_json_file(json_path):
|
|
111
41
|
with open(json_path, "r") as f:
|
|
112
42
|
data = json.load(f)
|
|
113
43
|
return create_args_from_json(data)
|
|
@@ -118,7 +48,7 @@ def create_args_from_json(data):
|
|
|
118
48
|
Parse a reproducer JSON and build kernel grid and argument dictionary.
|
|
119
49
|
|
|
120
50
|
Args:
|
|
121
|
-
|
|
51
|
+
data (dict | list): JSON data describing the kernel launch.
|
|
122
52
|
|
|
123
53
|
Returns:
|
|
124
54
|
tuple[list, dict]: Grid specification list and map of argument name to value.
|
|
@@ -197,6 +127,15 @@ def _apply_stride_and_offset(tensor, shape, stride, storage_offset):
|
|
|
197
127
|
|
|
198
128
|
|
|
199
129
|
def _create_base_tensor(arg_info) -> torch.Tensor:
|
|
130
|
+
"""
|
|
131
|
+
Create a base tensor without stride/offset modifications.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
arg_info (dict): Argument information including dtype, shape, device, etc.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
torch.Tensor: The created base tensor
|
|
138
|
+
"""
|
|
200
139
|
if arg_info.get("blob_path"):
|
|
201
140
|
return load_tensor(arg_info.get("blob_path"), arg_info.get("device"))
|
|
202
141
|
|
|
@@ -210,6 +149,9 @@ def _create_base_tensor(arg_info) -> torch.Tensor:
|
|
|
210
149
|
|
|
211
150
|
shape = arg_info.get("shape", [])
|
|
212
151
|
device = arg_info.get("device", "cpu")
|
|
152
|
+
# Normalize cuda device to cuda:0
|
|
153
|
+
if isinstance(device, str) and device.startswith("cuda"):
|
|
154
|
+
device = "cuda:0"
|
|
213
155
|
|
|
214
156
|
# Extract statistical information if available
|
|
215
157
|
mean = arg_info.get("mean")
|
|
@@ -301,6 +243,15 @@ def _create_base_tensor(arg_info) -> torch.Tensor:
|
|
|
301
243
|
|
|
302
244
|
|
|
303
245
|
def _create_tensor(arg_info) -> torch.Tensor:
|
|
246
|
+
"""
|
|
247
|
+
Create a tensor with stride and storage offset if needed.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
arg_info (dict): Argument information including dtype, shape, stride, etc.
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
torch.Tensor: The created tensor with applied stride/offset
|
|
254
|
+
"""
|
|
304
255
|
tensor = _create_base_tensor(arg_info)
|
|
305
256
|
|
|
306
257
|
# Apply stride and storage offset if needed
|
|
@@ -374,17 +325,135 @@ def _create_arg_from_info(arg_info):
|
|
|
374
325
|
return None
|
|
375
326
|
|
|
376
327
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
328
|
+
def determine_output_paths(out_dir: str, kernel_name: str):
|
|
329
|
+
"""
|
|
330
|
+
Determine output file paths for reproducer script and context data.
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
out_dir: Output directory path. If empty, uses default location.
|
|
334
|
+
kernel_name: Name of the kernel for default directory naming.
|
|
335
|
+
|
|
336
|
+
Returns:
|
|
337
|
+
Tuple of (python_script_path, json_context_path) as Path objects.
|
|
338
|
+
"""
|
|
339
|
+
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
|
|
340
|
+
output_directory = Path(out_dir) / kernel_name
|
|
341
|
+
output_directory.mkdir(parents=True, exist_ok=True)
|
|
381
342
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
print(f" {name}: {arg}")
|
|
385
|
-
print(f"Grid: {grid}")
|
|
343
|
+
out_py_path = output_directory / f"repro_{timestamp}.py"
|
|
344
|
+
temp_json_path = output_directory / f"repro_context_{timestamp}.json"
|
|
386
345
|
|
|
387
|
-
|
|
346
|
+
return out_py_path, temp_json_path
|
|
388
347
|
|
|
389
|
-
|
|
390
|
-
|
|
348
|
+
|
|
349
|
+
def _generate_import_statements(kernel_info) -> tuple[str, str]:
|
|
350
|
+
"""
|
|
351
|
+
Generate (sys.path insertion statement, import statement) for the kernel.
|
|
352
|
+
|
|
353
|
+
Strategy:
|
|
354
|
+
- Always add the kernel file's parent directory to sys.path.
|
|
355
|
+
- If the filename (without .py) is a valid identifier, import using that
|
|
356
|
+
module name: `from <stem> import <func> as imported_kernel_function`.
|
|
357
|
+
- Otherwise, fall back to dynamic import via importlib.util and bind
|
|
358
|
+
`imported_kernel_function` from the loaded module.
|
|
359
|
+
"""
|
|
360
|
+
file_path = Path(kernel_info.file_path)
|
|
361
|
+
function_name = kernel_info.function_name
|
|
362
|
+
|
|
363
|
+
if not file_path or not function_name:
|
|
364
|
+
raise ValueError("Kernel file path or function name missing from context.")
|
|
365
|
+
|
|
366
|
+
# Always add the file's parent directory to sys.path
|
|
367
|
+
sys_stmt = (
|
|
368
|
+
"import sys; p = r'" + str(file_path.parent) + "';\n"
|
|
369
|
+
"if p not in sys.path: sys.path.insert(0, p)"
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
module_name = file_path.with_suffix("").name
|
|
373
|
+
if module_name.isidentifier():
|
|
374
|
+
import_stmt = (
|
|
375
|
+
f"from {module_name} import {function_name} as imported_kernel_function"
|
|
376
|
+
)
|
|
377
|
+
logger.debug("Generated direct import statement: %s", import_stmt)
|
|
378
|
+
return sys_stmt, import_stmt
|
|
379
|
+
|
|
380
|
+
# Fallback: dynamic import when filename is not a valid identifier
|
|
381
|
+
import_stmt = (
|
|
382
|
+
"import importlib.util\n"
|
|
383
|
+
f"_spec = importlib.util.spec_from_file_location('kernel_mod', r'{str(file_path)}')\n"
|
|
384
|
+
"_mod = importlib.util.module_from_spec(_spec)\n"
|
|
385
|
+
"_spec.loader.exec_module(_mod)\n"
|
|
386
|
+
f"imported_kernel_function = getattr(_mod, '{function_name}')"
|
|
387
|
+
)
|
|
388
|
+
logger.debug("Generated dynamic import for file: %s", file_path)
|
|
389
|
+
return sys_stmt, import_stmt
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def _parse_kernel_signature(kernel_source_code: str) -> tuple[list[str], list[str]]:
|
|
393
|
+
"""
|
|
394
|
+
Parses a Triton kernel's source code to distinguish positional args
|
|
395
|
+
from keyword args (those with default values).
|
|
396
|
+
"""
|
|
397
|
+
signature_lines = []
|
|
398
|
+
in_signature = False
|
|
399
|
+
for line in kernel_source_code.splitlines():
|
|
400
|
+
# Mark beginning of signature when function definition is found
|
|
401
|
+
if line.strip().startswith("def "):
|
|
402
|
+
in_signature = True
|
|
403
|
+
if in_signature:
|
|
404
|
+
# Strip comments and leading/trailing whitespace
|
|
405
|
+
clean_line = line.split("#")[0].strip()
|
|
406
|
+
signature_lines.append(clean_line)
|
|
407
|
+
# Stop capturing after the signature ends
|
|
408
|
+
if "):" in line:
|
|
409
|
+
break
|
|
410
|
+
|
|
411
|
+
full_signature = "".join(signature_lines)
|
|
412
|
+
# Extract content between the first '(' and the last '):'
|
|
413
|
+
try:
|
|
414
|
+
params_str = full_signature[
|
|
415
|
+
full_signature.find("(") + 1 : full_signature.rfind("):")
|
|
416
|
+
]
|
|
417
|
+
except IndexError as exc:
|
|
418
|
+
raise ValueError("Could not parse kernel signature.") from exc
|
|
419
|
+
|
|
420
|
+
# Clean up and split the parameters string
|
|
421
|
+
params = [p.strip() for p in params_str.replace("\n", "").split(",") if p.strip()]
|
|
422
|
+
|
|
423
|
+
positional_args = []
|
|
424
|
+
keyword_args = []
|
|
425
|
+
|
|
426
|
+
for param in params:
|
|
427
|
+
if "=" in param:
|
|
428
|
+
# Keyword arguments have a default value
|
|
429
|
+
arg_name = param.split("=")[0].strip()
|
|
430
|
+
keyword_args.append(arg_name)
|
|
431
|
+
else:
|
|
432
|
+
# Positional arguments do not have a default value
|
|
433
|
+
arg_name = param.split(":")[0].strip()
|
|
434
|
+
positional_args.append(arg_name)
|
|
435
|
+
|
|
436
|
+
logger.debug("Parsed positional args: %s", positional_args)
|
|
437
|
+
logger.debug("Parsed keyword args: %s", keyword_args)
|
|
438
|
+
return positional_args, keyword_args
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def _generate_invocation_snippet(
|
|
442
|
+
positional_args: list[str], keyword_args: list[str]
|
|
443
|
+
) -> str:
|
|
444
|
+
"""Generates a single-line Python code snippet for kernel invocation."""
|
|
445
|
+
# Prepare positional args for direct injection into the call
|
|
446
|
+
pos_args_str = ", ".join([f'args_dict["{arg}"]' for arg in positional_args])
|
|
447
|
+
|
|
448
|
+
# Prepare keyword args for direct injection
|
|
449
|
+
kw_args_str = ", ".join([f'{arg}=args_dict["{arg}"]' for arg in keyword_args])
|
|
450
|
+
|
|
451
|
+
# Combine them, ensuring proper comma separation
|
|
452
|
+
all_args = []
|
|
453
|
+
if pos_args_str:
|
|
454
|
+
all_args.append(pos_args_str)
|
|
455
|
+
if kw_args_str:
|
|
456
|
+
all_args.append(kw_args_str)
|
|
457
|
+
|
|
458
|
+
# Create the single-line call
|
|
459
|
+
return f"imported_kernel_function[tuple(grid)]({', '.join(all_args)})"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tritonparse
|
|
3
|
-
Version: 0.3.1.
|
|
3
|
+
Version: 0.3.1.dev20251021071528
|
|
4
4
|
Summary: TritonParse: A Compiler Tracer, Visualizer, and mini-Reproducer Generator for Triton Kernels
|
|
5
5
|
Author-email: Yueming Hao <yhao@meta.com>
|
|
6
6
|
License-Expression: BSD-3-Clause
|
|
@@ -52,6 +52,7 @@ tritonparse.egg-info/requires.txt
|
|
|
52
52
|
tritonparse.egg-info/top_level.txt
|
|
53
53
|
tritonparse/reproducer/__init__.py
|
|
54
54
|
tritonparse/reproducer/cli.py
|
|
55
|
+
tritonparse/reproducer/function_extractor.py
|
|
55
56
|
tritonparse/reproducer/orchestrator.py
|
|
56
57
|
tritonparse/reproducer/placeholder_replacer.py
|
|
57
58
|
tritonparse/reproducer/types.py
|