helion 0.0.1__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.
Files changed (72) hide show
  1. helion-0.0.1/PKG-INFO +234 -0
  2. helion-0.0.1/README.md +214 -0
  3. helion-0.0.1/helion/__init__.py +23 -0
  4. helion-0.0.1/helion/_compat.py +81 -0
  5. helion-0.0.1/helion/_compiler/__init__.py +1 -0
  6. helion-0.0.1/helion/_compiler/ast_extension.py +253 -0
  7. helion-0.0.1/helion/_compiler/ast_read_writes.py +109 -0
  8. helion-0.0.1/helion/_compiler/compile_environment.py +276 -0
  9. helion-0.0.1/helion/_compiler/device_function.py +396 -0
  10. helion-0.0.1/helion/_compiler/device_ir.py +711 -0
  11. helion-0.0.1/helion/_compiler/error_reporting.py +116 -0
  12. helion-0.0.1/helion/_compiler/generate_ast.py +272 -0
  13. helion-0.0.1/helion/_compiler/host_function.py +226 -0
  14. helion-0.0.1/helion/_compiler/indexing_strategy.py +423 -0
  15. helion-0.0.1/helion/_compiler/inductor_lowering.py +722 -0
  16. helion-0.0.1/helion/_compiler/lift_closures.py +68 -0
  17. helion-0.0.1/helion/_compiler/output_header.py +86 -0
  18. helion-0.0.1/helion/_compiler/program_id.py +126 -0
  19. helion-0.0.1/helion/_compiler/reduction_strategy.py +327 -0
  20. helion-0.0.1/helion/_compiler/roll_reduction.py +246 -0
  21. helion-0.0.1/helion/_compiler/source_location.py +179 -0
  22. helion-0.0.1/helion/_compiler/tile_dispatch.py +148 -0
  23. helion-0.0.1/helion/_compiler/tile_index_proxy.py +122 -0
  24. helion-0.0.1/helion/_compiler/tile_strategy.py +492 -0
  25. helion-0.0.1/helion/_compiler/traceback_compat.py +215 -0
  26. helion-0.0.1/helion/_compiler/type_printer.py +76 -0
  27. helion-0.0.1/helion/_compiler/type_propagation.py +1956 -0
  28. helion-0.0.1/helion/_compiler/variable_origin.py +241 -0
  29. helion-0.0.1/helion/_testing.py +52 -0
  30. helion-0.0.1/helion/autotuner/__init__.py +8 -0
  31. helion-0.0.1/helion/autotuner/base_search.py +484 -0
  32. helion-0.0.1/helion/autotuner/config_fragment.py +162 -0
  33. helion-0.0.1/helion/autotuner/config_generation.py +155 -0
  34. helion-0.0.1/helion/autotuner/config_spec.py +349 -0
  35. helion-0.0.1/helion/autotuner/differential_evolution.py +102 -0
  36. helion-0.0.1/helion/autotuner/finite_search.py +44 -0
  37. helion-0.0.1/helion/autotuner/logger.py +83 -0
  38. helion-0.0.1/helion/autotuner/random_search.py +41 -0
  39. helion-0.0.1/helion/exc.py +253 -0
  40. helion-0.0.1/helion/language/__init__.py +9 -0
  41. helion-0.0.1/helion/language/_decorators.py +243 -0
  42. helion-0.0.1/helion/language/_tracing_ops.py +204 -0
  43. helion-0.0.1/helion/language/constexpr.py +26 -0
  44. helion-0.0.1/helion/language/creation_ops.py +71 -0
  45. helion-0.0.1/helion/language/loops.py +124 -0
  46. helion-0.0.1/helion/language/memory_ops.py +72 -0
  47. helion-0.0.1/helion/language/view_ops.py +58 -0
  48. helion-0.0.1/helion/runtime/__init__.py +5 -0
  49. helion-0.0.1/helion/runtime/config.py +106 -0
  50. helion-0.0.1/helion/runtime/kernel.py +511 -0
  51. helion-0.0.1/helion/runtime/precompile_shim.py +62 -0
  52. helion-0.0.1/helion/runtime/settings.py +116 -0
  53. helion-0.0.1/helion.egg-info/PKG-INFO +234 -0
  54. helion-0.0.1/helion.egg-info/SOURCES.txt +70 -0
  55. helion-0.0.1/helion.egg-info/dependency_links.txt +1 -0
  56. helion-0.0.1/helion.egg-info/requires.txt +2 -0
  57. helion-0.0.1/helion.egg-info/top_level.txt +1 -0
  58. helion-0.0.1/pyproject.toml +66 -0
  59. helion-0.0.1/setup.cfg +4 -0
  60. helion-0.0.1/setup.py +22 -0
  61. helion-0.0.1/test/test_autotuner.py +194 -0
  62. helion-0.0.1/test/test_broadcasting.py +362 -0
  63. helion-0.0.1/test/test_closures.py +305 -0
  64. helion-0.0.1/test/test_constexpr.py +181 -0
  65. helion-0.0.1/test/test_control_flow.py +193 -0
  66. helion-0.0.1/test/test_examples.py +652 -0
  67. helion-0.0.1/test/test_generate_ast.py +705 -0
  68. helion-0.0.1/test/test_loops.py +293 -0
  69. helion-0.0.1/test/test_matmul.py +633 -0
  70. helion-0.0.1/test/test_reductions.py +421 -0
  71. helion-0.0.1/test/test_type_propagation.py +948 -0
  72. helion-0.0.1/test/test_views.py +274 -0
helion-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,234 @@
1
+ Metadata-Version: 2.4
2
+ Name: helion
3
+ Version: 0.0.1
4
+ Summary: A Python-embedded DSL that makes it easy to write ML kernels
5
+ Home-page: https://github.com/pytorch-labs/helion
6
+ Author: Jason Ansel
7
+ Author-email: Jason Ansel <jansel@meta.com>
8
+ License-Expression: BSD-3-Clause
9
+ Project-URL: Homepage, https://github.com/pytorch-labs/helion
10
+ Project-URL: Issues, https://github.com/pytorch-labs/helion/issues
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ Requires-Dist: torch>=2.7.0
16
+ Requires-Dist: typing_extensions>=4.0.0
17
+ Dynamic: author
18
+ Dynamic: home-page
19
+ Dynamic: requires-python
20
+
21
+ # Helion
22
+
23
+ **Helion** is a Python-embedded domain-specific language (DSL) for
24
+ authoring machine learning kernels, designed to compile down to [Triton],
25
+ a performant backend for programming GPUs and other devices. Helion aims
26
+ to raise the level of abstraction compared to Triton, making it easier
27
+ to write correct and efficient kernels while enabling more automation
28
+ in the autotuning process.
29
+
30
+ The name *Helion* refers to the nucleus of a helium-3 atom, while *Triton*
31
+ refers to hydrogen-3.
32
+
33
+ [Triton]: https://github.com/triton-lang/triton
34
+
35
+ > ⚠️ **Early Development Warning**
36
+ > Helion is currently in an experimental stage. You should expect bugs, incomplete features, and APIs that may change in future versions. Feedback and bug reports are welcome and appreciated!
37
+
38
+ ## Example
39
+
40
+ A minimal matrix multiplication kernel in Helion looks like this:
41
+
42
+ ```python
43
+ import torch, helion, helion.language as hl
44
+
45
+ @helion.kernel()
46
+ def matmul(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
47
+ m, k = x.size()
48
+ k, n = y.size()
49
+ out = torch.empty([m, n], dtype=x.dtype, device=x.device)
50
+
51
+ for tile_m, tile_n in hl.tile([m, n]):
52
+ acc = hl.zeros([tile_m, tile_n], dtype=torch.float32)
53
+ for tile_k in hl.tile(k):
54
+ acc = torch.addmm(acc, x[tile_m, tile_k], y[tile_k, tile_n])
55
+ out[tile_m, tile_n] = acc
56
+
57
+ return out
58
+ ```
59
+
60
+ The code outside the `for` loops is standard PyTorch code executed on
61
+ the CPU. It is typically used for tasks like allocating output tensors
62
+ and performing shape computations.
63
+
64
+ The code inside the `for` loops is compiled into a Triton kernel,
65
+ resulting in a single GPU kernel. A single Helion kernel is always
66
+ compiled to exactly one GPU kernel.
67
+
68
+ The `hl.tile` function subdivides the iteration space (in this case `m` by
69
+ `n`) into tiles. These tiles are executed in parallel on the GPU. Tiling
70
+ details, such as dimensionality (1D vs 2D), tile sizes, and loop ordering,
71
+ are automatically determined by Helion's autotuner. Alternatively, these
72
+ details can be explicitly specified using the `config=` argument in
73
+ `helion.kernel`.
74
+
75
+ * The outer `for` loop is mapped onto the grid of the generated
76
+ kernel. The grid size is determined automatically based on the chosen
77
+ tile size.
78
+
79
+ * The inner `for` loop translates into a loop within the generated kernel,
80
+ and its tile size is also determined automatically.
81
+
82
+ Within a Helion kernel, standard PyTorch operators (like
83
+ `torch.addmm`) are automatically mapped to Triton operations using
84
+ [TorchInductor](https://github.com/pytorch/pytorch/tree/main/torch/_inductor).
85
+ Thus, familiarity with PyTorch means you already know most of
86
+ Helion. Helion supports a wide range of operations including pointwise
87
+ (`add`, `sigmoid`, etc.), reductions (`sum`, `softmax`, etc.), views,
88
+ and matrix multiplication operations. Arbitrary function calls
89
+ within a Helion kernel are supported, but must be traceable with
90
+ [make_fx](https://pytorch.org/docs/stable/generated/torch.fx.experimental.proxy_tensor.make_fx.html).
91
+
92
+ ## Autotuning
93
+
94
+ The above example can be executed with:
95
+
96
+ ```python
97
+ out = matmul(torch.randn([2048, 2028], device="cuda"),
98
+ torch.randn([2048, 2028], device="cuda"))
99
+ ```
100
+
101
+ When a kernel runs for the first time, Helion initiates autotuning. A
102
+ typical autotuning session produces output similar to:
103
+
104
+ ```
105
+ [0s] Starting DifferentialEvolutionSearch with population=40, generations=20, crossover_rate=0.8
106
+ [20s] Initial population: failed=10 min=0.9677s mid=3.0013s max=22.1430s best=Config(block_sizes=[[64, 32], [32]], loop_orders=[[1, 0]], num_warps=2, num_stages=2, indexing='pointer', l2_grouping=1, use_yz_grid=False)
107
+ [52s] Generation 2: replaced=16 min=0.7731s mid=1.7203s max=3.1227s best=Config(block_sizes=[[32, 128], [16]], loop_orders=[[0, 1]], num_warps=4, num_stages=4, indexing='block_ptr', l2_grouping=16)
108
+ [85s] Generation 3: replaced=19 min=0.6256s mid=1.3916s max=2.7868s best=Config(block_sizes=[[64, 128], [16]], loop_orders=[[0, 1]], num_warps=4, num_stages=4, indexing='block_ptr', l2_grouping=16)
109
+ ...
110
+ [593s] Generation 19: replaced=7 min=0.6072s mid=0.6626s max=0.7496s best=Config(block_sizes=[[64, 128], [16]], loop_orders=[[1, 0]], num_warps=4, num_stages=3, indexing='block_ptr', l2_grouping=32)
111
+ [593s] Autotuning complete in 593.1s after searching 1520 configs.
112
+ One can hardcode the best config and skip autotuning with:
113
+ @helion.kernel(config=helion.Config(block_sizes=[[64, 128], [16]], loop_orders=[[1, 0]], num_warps=4, num_stages=3, indexing='block_ptr', l2_grouping=32))
114
+ ```
115
+
116
+ Because autotuning can be time-consuming (around 10 minutes in the above
117
+ example), you may want to manually specify the best configuration found from
118
+ autotuning to avoid repeated tuning:
119
+
120
+ ```python
121
+ @helion.kernel(config=helion.Config(
122
+ block_sizes=[[64, 128], [16]],
123
+ loop_orders=[[1, 0]],
124
+ num_warps=4,
125
+ num_stages=3,
126
+ indexing='block_ptr',
127
+ l2_grouping=32
128
+ ))
129
+ def matmul(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
130
+ ...
131
+ ```
132
+
133
+ This explicit configuration skips autotuning on subsequent runs.
134
+
135
+ You can also specify multiple configurations, prompting Helion to perform
136
+ a more lightweight autotuning process:
137
+
138
+ ```python
139
+ @helion.kernel(configs=[
140
+ helion.Config(...),
141
+ helion.Config(...),
142
+ ])
143
+ def matmul(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
144
+ ...
145
+ ```
146
+
147
+ In this case, Helion evaluates the provided configurations and selects the fastest one.
148
+
149
+ Additionally, Helion provides programmatic APIs to manage autotuning
150
+ and configurations directly from your code.
151
+
152
+ ## Configurations
153
+
154
+ Helion configurations include the following options:
155
+
156
+ * **block\_sizes** (`list[int | list[int]]`):
157
+ Controls tile sizes corresponding to each `hl.tile` invocation in the
158
+ kernel. For tiles with two or more dimensions, you can use either an
159
+ integer to flatten the iteration space into a single dimension or a list
160
+ of integers for multi-dimensional tiling.
161
+
162
+ * **loop\_orders** (`list[list[int]]`):
163
+ Contains one entry per `hl.tile` call with two or more dimensions,
164
+ allowing you to permute the iteration order of the tiles.
165
+
166
+ * **reduction\_loops** (`list[int | None]`):
167
+ Contains one entry per reduction dimension (see
168
+ `examples/softmax.py`). Using `None` triggers a persistent reduction,
169
+ where the entire reduction is processed in a single tile. Specifying an
170
+ integer block size converts the reduction into a loop, beneficial for
171
+ larger reductions that exceed the registers available.
172
+
173
+ * **l2\_grouping** (`int`):
174
+ Reorders the program IDs (PIDs) of the generated kernel for improved L2
175
+ cache behavior. A value of `1` disables this optimization, while higher
176
+ values specify the grouping size.
177
+
178
+ * **indexing** (`"pointer"`, `"tensor_descriptor"` or `"block_ptr"`):
179
+ Specifies the type of indexing code to generate. The `"tensor_descriptor"`
180
+ option uses Tensor Memory Accelerators (TMAs) but requires a Hopper or
181
+ newer GPU and the latest development version of Triton.
182
+
183
+ * **use\_yz\_grid** (`bool`):
184
+ Determines if the `y` and `z` dimensions of the launch grid are utilized,
185
+ or if only the `x` dimension is used. This option is ignored if `l2_grouping>1`.
186
+
187
+ * **num\_warps** (`int`):
188
+ Sets the number of warps the kernel will use.
189
+
190
+ * **num\_stages** (`int`):
191
+ Defines the number of pipeline stages to be passed to Triton.
192
+
193
+ Changing these options results in often significantly different
194
+ output Triton code, allowing the autotuner to explore a wide range of
195
+ implementations from a single Helion kernel.
196
+
197
+ ## Requirements
198
+
199
+ Helion currently targets Linux systems and requires a recent Python and PyTorch environment:
200
+
201
+ - Linux-based OS
202
+ - Python 3.10, 3.11, or 3.12
203
+ - [PyTorch] 2.7 or newer
204
+ - A development version of [Triton], installed from source
205
+ *(Older versions may work, but will lack support for features like
206
+ TMA on Hopper/Blackwell GPUs and may exhibit lower performance.)*
207
+
208
+ [PyTorch]: https://github.com/pytorch/pytorch
209
+
210
+ ## Installation
211
+
212
+ We recommend using a [conda] environment to manage dependencies. First,
213
+ install compatible versions of [PyTorch] and [Triton].
214
+
215
+ [conda]: https://www.anaconda.com/docs/getting-started/miniconda/install#linux
216
+
217
+ Once your environment is set up, you can install Helion directly from GitHub:
218
+
219
+ ```bash
220
+ pip install git+https://github.com/pytorch-labs/helion.git
221
+ ```
222
+
223
+ Alternatively, you may install from source for development purposes:
224
+ ```bash
225
+ git clone https://github.com/pytorch-labs/helion.git
226
+ cd helion
227
+ python setup.py develop
228
+ ````
229
+ This installs Helion in "editable" mode so that changes to the source
230
+ code take effect without needing to reinstall.
231
+
232
+ ## License
233
+
234
+ Helion is BSD-style licensed, as found in the LICENSE file.
helion-0.0.1/README.md ADDED
@@ -0,0 +1,214 @@
1
+ # Helion
2
+
3
+ **Helion** is a Python-embedded domain-specific language (DSL) for
4
+ authoring machine learning kernels, designed to compile down to [Triton],
5
+ a performant backend for programming GPUs and other devices. Helion aims
6
+ to raise the level of abstraction compared to Triton, making it easier
7
+ to write correct and efficient kernels while enabling more automation
8
+ in the autotuning process.
9
+
10
+ The name *Helion* refers to the nucleus of a helium-3 atom, while *Triton*
11
+ refers to hydrogen-3.
12
+
13
+ [Triton]: https://github.com/triton-lang/triton
14
+
15
+ > ⚠️ **Early Development Warning**
16
+ > Helion is currently in an experimental stage. You should expect bugs, incomplete features, and APIs that may change in future versions. Feedback and bug reports are welcome and appreciated!
17
+
18
+ ## Example
19
+
20
+ A minimal matrix multiplication kernel in Helion looks like this:
21
+
22
+ ```python
23
+ import torch, helion, helion.language as hl
24
+
25
+ @helion.kernel()
26
+ def matmul(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
27
+ m, k = x.size()
28
+ k, n = y.size()
29
+ out = torch.empty([m, n], dtype=x.dtype, device=x.device)
30
+
31
+ for tile_m, tile_n in hl.tile([m, n]):
32
+ acc = hl.zeros([tile_m, tile_n], dtype=torch.float32)
33
+ for tile_k in hl.tile(k):
34
+ acc = torch.addmm(acc, x[tile_m, tile_k], y[tile_k, tile_n])
35
+ out[tile_m, tile_n] = acc
36
+
37
+ return out
38
+ ```
39
+
40
+ The code outside the `for` loops is standard PyTorch code executed on
41
+ the CPU. It is typically used for tasks like allocating output tensors
42
+ and performing shape computations.
43
+
44
+ The code inside the `for` loops is compiled into a Triton kernel,
45
+ resulting in a single GPU kernel. A single Helion kernel is always
46
+ compiled to exactly one GPU kernel.
47
+
48
+ The `hl.tile` function subdivides the iteration space (in this case `m` by
49
+ `n`) into tiles. These tiles are executed in parallel on the GPU. Tiling
50
+ details, such as dimensionality (1D vs 2D), tile sizes, and loop ordering,
51
+ are automatically determined by Helion's autotuner. Alternatively, these
52
+ details can be explicitly specified using the `config=` argument in
53
+ `helion.kernel`.
54
+
55
+ * The outer `for` loop is mapped onto the grid of the generated
56
+ kernel. The grid size is determined automatically based on the chosen
57
+ tile size.
58
+
59
+ * The inner `for` loop translates into a loop within the generated kernel,
60
+ and its tile size is also determined automatically.
61
+
62
+ Within a Helion kernel, standard PyTorch operators (like
63
+ `torch.addmm`) are automatically mapped to Triton operations using
64
+ [TorchInductor](https://github.com/pytorch/pytorch/tree/main/torch/_inductor).
65
+ Thus, familiarity with PyTorch means you already know most of
66
+ Helion. Helion supports a wide range of operations including pointwise
67
+ (`add`, `sigmoid`, etc.), reductions (`sum`, `softmax`, etc.), views,
68
+ and matrix multiplication operations. Arbitrary function calls
69
+ within a Helion kernel are supported, but must be traceable with
70
+ [make_fx](https://pytorch.org/docs/stable/generated/torch.fx.experimental.proxy_tensor.make_fx.html).
71
+
72
+ ## Autotuning
73
+
74
+ The above example can be executed with:
75
+
76
+ ```python
77
+ out = matmul(torch.randn([2048, 2028], device="cuda"),
78
+ torch.randn([2048, 2028], device="cuda"))
79
+ ```
80
+
81
+ When a kernel runs for the first time, Helion initiates autotuning. A
82
+ typical autotuning session produces output similar to:
83
+
84
+ ```
85
+ [0s] Starting DifferentialEvolutionSearch with population=40, generations=20, crossover_rate=0.8
86
+ [20s] Initial population: failed=10 min=0.9677s mid=3.0013s max=22.1430s best=Config(block_sizes=[[64, 32], [32]], loop_orders=[[1, 0]], num_warps=2, num_stages=2, indexing='pointer', l2_grouping=1, use_yz_grid=False)
87
+ [52s] Generation 2: replaced=16 min=0.7731s mid=1.7203s max=3.1227s best=Config(block_sizes=[[32, 128], [16]], loop_orders=[[0, 1]], num_warps=4, num_stages=4, indexing='block_ptr', l2_grouping=16)
88
+ [85s] Generation 3: replaced=19 min=0.6256s mid=1.3916s max=2.7868s best=Config(block_sizes=[[64, 128], [16]], loop_orders=[[0, 1]], num_warps=4, num_stages=4, indexing='block_ptr', l2_grouping=16)
89
+ ...
90
+ [593s] Generation 19: replaced=7 min=0.6072s mid=0.6626s max=0.7496s best=Config(block_sizes=[[64, 128], [16]], loop_orders=[[1, 0]], num_warps=4, num_stages=3, indexing='block_ptr', l2_grouping=32)
91
+ [593s] Autotuning complete in 593.1s after searching 1520 configs.
92
+ One can hardcode the best config and skip autotuning with:
93
+ @helion.kernel(config=helion.Config(block_sizes=[[64, 128], [16]], loop_orders=[[1, 0]], num_warps=4, num_stages=3, indexing='block_ptr', l2_grouping=32))
94
+ ```
95
+
96
+ Because autotuning can be time-consuming (around 10 minutes in the above
97
+ example), you may want to manually specify the best configuration found from
98
+ autotuning to avoid repeated tuning:
99
+
100
+ ```python
101
+ @helion.kernel(config=helion.Config(
102
+ block_sizes=[[64, 128], [16]],
103
+ loop_orders=[[1, 0]],
104
+ num_warps=4,
105
+ num_stages=3,
106
+ indexing='block_ptr',
107
+ l2_grouping=32
108
+ ))
109
+ def matmul(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
110
+ ...
111
+ ```
112
+
113
+ This explicit configuration skips autotuning on subsequent runs.
114
+
115
+ You can also specify multiple configurations, prompting Helion to perform
116
+ a more lightweight autotuning process:
117
+
118
+ ```python
119
+ @helion.kernel(configs=[
120
+ helion.Config(...),
121
+ helion.Config(...),
122
+ ])
123
+ def matmul(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
124
+ ...
125
+ ```
126
+
127
+ In this case, Helion evaluates the provided configurations and selects the fastest one.
128
+
129
+ Additionally, Helion provides programmatic APIs to manage autotuning
130
+ and configurations directly from your code.
131
+
132
+ ## Configurations
133
+
134
+ Helion configurations include the following options:
135
+
136
+ * **block\_sizes** (`list[int | list[int]]`):
137
+ Controls tile sizes corresponding to each `hl.tile` invocation in the
138
+ kernel. For tiles with two or more dimensions, you can use either an
139
+ integer to flatten the iteration space into a single dimension or a list
140
+ of integers for multi-dimensional tiling.
141
+
142
+ * **loop\_orders** (`list[list[int]]`):
143
+ Contains one entry per `hl.tile` call with two or more dimensions,
144
+ allowing you to permute the iteration order of the tiles.
145
+
146
+ * **reduction\_loops** (`list[int | None]`):
147
+ Contains one entry per reduction dimension (see
148
+ `examples/softmax.py`). Using `None` triggers a persistent reduction,
149
+ where the entire reduction is processed in a single tile. Specifying an
150
+ integer block size converts the reduction into a loop, beneficial for
151
+ larger reductions that exceed the registers available.
152
+
153
+ * **l2\_grouping** (`int`):
154
+ Reorders the program IDs (PIDs) of the generated kernel for improved L2
155
+ cache behavior. A value of `1` disables this optimization, while higher
156
+ values specify the grouping size.
157
+
158
+ * **indexing** (`"pointer"`, `"tensor_descriptor"` or `"block_ptr"`):
159
+ Specifies the type of indexing code to generate. The `"tensor_descriptor"`
160
+ option uses Tensor Memory Accelerators (TMAs) but requires a Hopper or
161
+ newer GPU and the latest development version of Triton.
162
+
163
+ * **use\_yz\_grid** (`bool`):
164
+ Determines if the `y` and `z` dimensions of the launch grid are utilized,
165
+ or if only the `x` dimension is used. This option is ignored if `l2_grouping>1`.
166
+
167
+ * **num\_warps** (`int`):
168
+ Sets the number of warps the kernel will use.
169
+
170
+ * **num\_stages** (`int`):
171
+ Defines the number of pipeline stages to be passed to Triton.
172
+
173
+ Changing these options results in often significantly different
174
+ output Triton code, allowing the autotuner to explore a wide range of
175
+ implementations from a single Helion kernel.
176
+
177
+ ## Requirements
178
+
179
+ Helion currently targets Linux systems and requires a recent Python and PyTorch environment:
180
+
181
+ - Linux-based OS
182
+ - Python 3.10, 3.11, or 3.12
183
+ - [PyTorch] 2.7 or newer
184
+ - A development version of [Triton], installed from source
185
+ *(Older versions may work, but will lack support for features like
186
+ TMA on Hopper/Blackwell GPUs and may exhibit lower performance.)*
187
+
188
+ [PyTorch]: https://github.com/pytorch/pytorch
189
+
190
+ ## Installation
191
+
192
+ We recommend using a [conda] environment to manage dependencies. First,
193
+ install compatible versions of [PyTorch] and [Triton].
194
+
195
+ [conda]: https://www.anaconda.com/docs/getting-started/miniconda/install#linux
196
+
197
+ Once your environment is set up, you can install Helion directly from GitHub:
198
+
199
+ ```bash
200
+ pip install git+https://github.com/pytorch-labs/helion.git
201
+ ```
202
+
203
+ Alternatively, you may install from source for development purposes:
204
+ ```bash
205
+ git clone https://github.com/pytorch-labs/helion.git
206
+ cd helion
207
+ python setup.py develop
208
+ ````
209
+ This installs Helion in "editable" mode so that changes to the source
210
+ code take effect without needing to reinstall.
211
+
212
+ ## License
213
+
214
+ Helion is BSD-style licensed, as found in the LICENSE file.
@@ -0,0 +1,23 @@
1
+ from __future__ import annotations
2
+
3
+ from . import exc
4
+ from . import language
5
+ from . import runtime
6
+ from .runtime import Config
7
+ from .runtime import Kernel
8
+ from .runtime import kernel
9
+ from .runtime import kernel as jit # alias
10
+ from helion.runtime.settings import Settings
11
+ from helion.runtime.settings import set_default_settings
12
+
13
+ __all__ = [
14
+ "Config",
15
+ "Kernel",
16
+ "Settings",
17
+ "exc",
18
+ "jit",
19
+ "kernel",
20
+ "language",
21
+ "runtime",
22
+ "set_default_settings",
23
+ ]
@@ -0,0 +1,81 @@
1
+ from __future__ import annotations
2
+
3
+ import functools
4
+ import importlib
5
+
6
+ import torch
7
+ from torch._inductor.runtime.hints import DeviceProperties
8
+ from torch._inductor.utils import triton_type
9
+ from triton.backends.compiler import GPUTarget
10
+ import triton.language as tl
11
+
12
+
13
+ def supports_tensor_descriptor() -> bool:
14
+ # call private func we can patch in testing
15
+ return _supports_tensor_descriptor()
16
+
17
+
18
+ @functools.cache
19
+ def _supports_tensor_descriptor() -> bool:
20
+ if not torch.cuda.is_available():
21
+ return False
22
+ major, _ = torch.cuda.get_device_capability(torch.cuda.current_device())
23
+ if major < 9:
24
+ return False
25
+ try:
26
+ return get_triton_tensor_descriptor_import_path() is not None
27
+ except ImportError:
28
+ return False
29
+
30
+
31
+ @functools.cache
32
+ def get_triton_tensor_descriptor_import_path() -> str:
33
+ """Attempt to import TensorDescriptor object from known Triton modules."""
34
+ possible_modules = [
35
+ "triton.tools.experimental_descriptor",
36
+ "triton.tools.tensor_descriptor",
37
+ ]
38
+ for module_name in possible_modules:
39
+ try:
40
+ module = importlib.import_module(module_name)
41
+ if hasattr(module, "TensorDescriptor"):
42
+ return f"from {module_name} import TensorDescriptor"
43
+ except ImportError:
44
+ continue
45
+ raise ImportError("TensorDescriptor not found in any of the known Triton modules.")
46
+
47
+
48
+ @functools.cache
49
+ def torch_dtype_to_tl(torch_dtype: torch.dtype) -> object:
50
+ """Return the `triton.language` dtype that matches a `torch.dtype`."""
51
+ name_str = triton_type(torch_dtype).replace("tl.", "")
52
+ return getattr(tl, name_str)
53
+
54
+
55
+ @functools.cache
56
+ def min_dot_size(
57
+ device: torch.device, lhs: torch.dtype, rhs: torch.torch.dtype
58
+ ) -> tuple[int, int, int]:
59
+ if device.type != "cuda":
60
+ # TODO(jansel): support non-cuda properly
61
+ return (16, 16, 16)
62
+
63
+ from triton.backends.nvidia.compiler import min_dot_size as min_dot_size_cuda
64
+
65
+ props = DeviceProperties.create(device)
66
+ return min_dot_size_cuda(
67
+ GPUTarget(
68
+ backend=props.type,
69
+ arch=props.cc,
70
+ warp_size=props.warp_size or 32,
71
+ )
72
+ )(torch_dtype_to_tl(lhs), torch_dtype_to_tl(rhs))
73
+
74
+
75
+ def warps_to_threads(num_warps: int) -> int:
76
+ if torch.cuda.is_available():
77
+ props = DeviceProperties.create(
78
+ torch.device("cuda", torch.cuda.current_device())
79
+ )
80
+ return num_warps * (props.warp_size or 32)
81
+ return num_warps * 32
@@ -0,0 +1 @@
1
+ from __future__ import annotations