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.

Files changed (115) hide show
  1. {tritonparse-0.3.1.dev20251019071438/tritonparse.egg-info → tritonparse-0.3.1.dev20251021071528}/PKG-INFO +1 -1
  2. tritonparse-0.3.1.dev20251021071528/tritonparse/reproducer/function_extractor.py +220 -0
  3. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/placeholder_replacer.py +11 -0
  4. tritonparse-0.3.1.dev20251021071528/tritonparse/reproducer/templates/example.py +30 -0
  5. tritonparse-0.3.1.dev20251019071438/tritonparse/reproducer/templates/example.py → tritonparse-0.3.1.dev20251021071528/tritonparse/reproducer/utils.py +158 -89
  6. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528/tritonparse.egg-info}/PKG-INFO +1 -1
  7. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse.egg-info/SOURCES.txt +1 -0
  8. tritonparse-0.3.1.dev20251019071438/tritonparse/reproducer/utils.py +0 -365
  9. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.ci/README.md +0 -0
  10. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.ci/install-project.sh +0 -0
  11. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.ci/install-triton.sh +0 -0
  12. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.ci/run-tests.sh +0 -0
  13. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.ci/setup.sh +0 -0
  14. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.github/PAGES_SETUP.md +0 -0
  15. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.github/workflows/deploy-pages-standalone.yml +0 -0
  16. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.github/workflows/deploy-pages.yml +0 -0
  17. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.github/workflows/nightly-pypi.yml +0 -0
  18. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.github/workflows/test.yml +0 -0
  19. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/.gitignore +0 -0
  20. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/CHANGELOG.md +0 -0
  21. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/CODE_OF_CONDUCT.md +0 -0
  22. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/CONTRIBUTING.md +0 -0
  23. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/LICENSE +0 -0
  24. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/Makefile +0 -0
  25. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/README.md +0 -0
  26. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/__init__.py +0 -0
  27. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/pyproject.toml +0 -0
  28. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/run.py +0 -0
  29. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/setup.cfg +0 -0
  30. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/README.md +0 -0
  31. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/__init__.py +0 -0
  32. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/example_output/logs/dedicated_log_triton_trace_findhao_.ndjson +0 -0
  33. {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
  34. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/example_output/parsed_output/f0_fc0_a0_cai-.ndjson.gz +0 -0
  35. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/example_output/parsed_output/log_file_list.json +0 -0
  36. {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
  37. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/example_output/parsed_output_complex/log_file_list.json +0 -0
  38. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/test_add.py +0 -0
  39. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tests/test_tritonparse.py +0 -0
  40. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/__init__.py +0 -0
  41. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/__main__.py +0 -0
  42. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/cli.py +0 -0
  43. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/common.py +0 -0
  44. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/context_manager.py +0 -0
  45. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/event_diff.py +0 -0
  46. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/extract_source_mappings.py +0 -0
  47. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/ir_parser.py +0 -0
  48. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/mapper.py +0 -0
  49. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/__init__.py +0 -0
  50. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/cli.py +0 -0
  51. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/ingestion/ndjson.py +0 -0
  52. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/orchestrator.py +0 -0
  53. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/templates/__init__.py +0 -0
  54. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/templates/loader.py +0 -0
  55. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/reproducer/types.py +0 -0
  56. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/shared_vars.py +0 -0
  57. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/source_type.py +0 -0
  58. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/sourcemap_utils.py +0 -0
  59. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/structured_logging.py +0 -0
  60. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/__init__.py +0 -0
  61. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/decompress_bin_ndjson.py +0 -0
  62. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/disasm.py +0 -0
  63. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/format_fix.py +0 -0
  64. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/load_tensor.py +0 -0
  65. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/prettify_ndjson.py +0 -0
  66. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tools/readme.md +0 -0
  67. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/tp_logger.py +0 -0
  68. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/trace_processor.py +0 -0
  69. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse/utils.py +0 -0
  70. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse.egg-info/dependency_links.txt +0 -0
  71. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse.egg-info/entry_points.txt +0 -0
  72. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse.egg-info/requires.txt +0 -0
  73. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/tritonparse.egg-info/top_level.txt +0 -0
  74. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/eslint.config.js +0 -0
  75. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/index.html +0 -0
  76. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/package-lock.json +0 -0
  77. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/package.json +0 -0
  78. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/public/dedicated_log_triton_trace_findhao__mapped.ndjson.gz +0 -0
  79. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/public/f0_fc0_a0_cai-.ndjson +0 -0
  80. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/public/favicon.ico +0 -0
  81. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/public/logo.svg +0 -0
  82. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/scripts/inline-html.js +0 -0
  83. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/App.css +0 -0
  84. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/App.tsx +0 -0
  85. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/assets/react.svg +0 -0
  86. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/ArgumentViewer.tsx +0 -0
  87. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/Callstack.tsx +0 -0
  88. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/CodeComparisonView.tsx +0 -0
  89. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/CodeViewer.tsx +0 -0
  90. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/CompilationInfo.tsx +0 -0
  91. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/CopyCodeButton.tsx +0 -0
  92. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/DataSourceSelector.tsx +0 -0
  93. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/DiffComparisonView.tsx +0 -0
  94. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/DiffViewer.tsx +0 -0
  95. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/ExternalLink.tsx +0 -0
  96. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/SingleCodeViewer.tsx +0 -0
  97. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/StackDiffViewer.tsx +0 -0
  98. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/ToggleSwitch.tsx +0 -0
  99. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/TritonIRs.tsx +0 -0
  100. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/components/WelcomeScreen.tsx +0 -0
  101. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/context/FileDiffSession.tsx +0 -0
  102. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/index.css +0 -0
  103. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/main.tsx +0 -0
  104. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/pages/CodeView.tsx +0 -0
  105. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/pages/FileDiffView.tsx +0 -0
  106. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/pages/KernelOverview.tsx +0 -0
  107. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/utils/dataLoader.ts +0 -0
  108. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/utils/fbDetection.ts +0 -0
  109. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/utils/safeImport.ts +0 -0
  110. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/utils/tensor.ts +0 -0
  111. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/src/vite-env.d.ts +0 -0
  112. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/tsconfig.app.json +0 -0
  113. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/tsconfig.json +0 -0
  114. {tritonparse-0.3.1.dev20251019071438 → tritonparse-0.3.1.dev20251021071528}/website/tsconfig.node.json +0 -0
  115. {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.dev20251019071438
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
- # {{IR_OVERRIDE_SETUP_PLACEHOLDER}}
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 load_tensor(tensor_file_path: Union[str, Path], device: str = None) -> torch.Tensor:
31
+ def create_args_from_json_file(json_path):
52
32
  """
53
- Load a tensor from its file path and verify its integrity using the hash in the filename.
33
+ Load and parse a reproducer JSON file.
54
34
 
55
35
  Args:
56
- tensor_file_path (str | Path): Direct path to the tensor file. Supports both:
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
- torch.Tensor: The loaded tensor (moved to the specified device if provided)
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
- json_path (str): Path to the JSON file describing the kernel launch.
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
- if __name__ == "__main__":
378
- script_dir = Path(__file__).resolve().parent
379
- json_file = script_dir / "{{JSON_FILE_NAME_PLACEHOLDER}}"
380
- grid, args_dict = create_args_from_json_file(str(json_file))
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
- print("Generated kernel arguments dictionary:")
383
- for name, arg in args_dict.items():
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
- # {{KERNEL_INVOCATION_PLACEHOLDER}}
346
+ return out_py_path, temp_json_path
388
347
 
389
- torch.cuda.synchronize()
390
- print("Kernel execution finished.")
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.dev20251019071438
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