benchmark
c960e717 - Add a user-kernel HOP registry and register Triton with it

Commit
5 days ago
Add a user-kernel HOP registry and register Triton with it Summary: X-link: https://github.com/pytorch/pytorch/pull/203473 Seventeen places outside triton_kernel_wrap.py recognize a user kernel by comparing a node's target with Triton's HOPs, so a second kernel DSL's HOPs would be skipped, or would crash, at each of them. This PR adds a registry of user-kernel HOP pairs and registers Triton with its current behavior; the next PR, #202442, routes those sites through the registry. Only this PR's tests read the registry, and reinplacing, the one pass it touches, calls Triton's kernel-name function instead of the same code inline, so no pass behaves differently. - `torch/_higher_order_ops/user_kernel_hop.py`: each DSL registers a `UserKernelHOPInfo` with its mutation/functional HOP pair, a getter for the kernel's write set, a kernel name for logs, a getter for the layout constraint Inductor gives the mutation HOP's tensor arguments, the `ReInplaceTrigger` member that keys its reinplacing counters, and `serializable` (whether torch.export can write its nodes). The class docstring states the HOP kwargs layout the passes rely on. `register_user_kernel_hop` checks everything before writing anything (HOP types, the functional HOP's CompositeExplicitAutograd py_impl, two distinct HOPs that no other info registered, and a trigger that is `USER_KERNEL_OPS` or one `TRIGGER_DSLS` gives to this DSL, never `AUTO_FUNC_V1` or `AUTO_FUNC_V2`), so a refused registration leaves the registry unchanged. A lock is held across the ownership checks and both writes, and every lookup takes it, so DSLs registering from different threads cannot both claim a HOP and no reader sees half of a pair. Infos compare by identity (`eq=False`), so a DSL's callables need not be hashable. The sites will ask `get_user_kernel_hop_info` (optionally for one role), `is_user_kernel_mutation_hop`, `is_user_kernel_functional_hop` or `user_kernel_hop_infos`. - `torch/_higher_order_ops/triton_kernel_wrap.py`: Triton's registration (`TRITON_OPS`, `serializable=True`) and `get_triton_layout_constraint`, which checks `triton_kernel_default_layout_constraint` and, for an unknown value, raises the error graph.py raises today. The reinplacing pass's kernel-name code moves here as `get_triton_kernel_name`. - `ReInplaceTrigger` moves from `torch._dynamo.utils`, which re-exports it, to the new `torch/_higher_order_ops/reinplace_trigger.py`, which adds `USER_KERNEL_OPS` (for DSLs without a member of their own) and `TRIGGER_DSLS`. Importing triton_kernel_wrap still imports neither `torch._dynamo` nor `torch._inductor`. `triton_kernel_default_layout_constraint` stays Triton's: every other DSL returns its own constraint from its getter (the CuTeDSL registration in #203538 asks for `needs_fixed_stride_order`). The FX graph cache still keys only Triton kernels by source, so a DSL with cacheable HOPs must extend the cache key first; the CuTeDSL HOPs (#203538) are not cacheable. This PR was split out of #202442 to keep each PR under the 1500-line limit. ### Test plan New CPU tests in test/inductor/test_triton_kernels.py cover the lookups, each refused registration (which must leave the registry unchanged), the registry lock and Triton's layout-constraint getter, with a second HOP pair defined in the test file; test_not_import_dynamo_from_user_kernel_hops in test/test_testing.py checks the import claim above. ``` python test/inductor/test_triton_kernels.py -k user_kernel_hop \ -k layout_constraint_config python test/test_testing.py -k test_not_import_dynamo_from_user_kernel_hops ``` The split, the review fixes and this description were drafted with an AI assistant. ghstack-source-id: 466260746 exported-using-ghexport Reviewed By: desertfire Differential Revision: D129753992 fbshipit-source-id: f0522dc1f3c886560dc4a88245e08209dccdbdcd
Author
Committer
Parents
Loading