Repository navigation
Conversation
Adds the `rewrite` op. A rewrite deletes whole lines, and splits identifiers before matching literal text, so a replacement cannot match inside a longer identifier.
…hain imports - Adds the `extension` op, deriving native extension conversions from a declaration. A declared module that upstream builds at import time with `var = torch.utils.cpp_extension.load(name="<module>", ...)` becomes `from ._ops import ops as var`, and the module-level statements that only fed the build (source paths, flags, the load import) are removed. Removing a trailing PYBIND11_MODULE no longer leaves blank lines at the end of the file. - remap_module also remaps `import a.b as x`. An unaliased `import a.b` binds `a`, so remapping it is an error rather than silently skipped. - convert_import converts an unaliased `import a.b.c` used as `a.b.c.attr` into `from a.b import c` with `c.attr` uses, refusing when `a` is used any other way or `c` is already a name in the module. - mark_tests only="<test>,..." marks just the named tests.
`kernel ... follow_includes=#true` (and `manifest ... torch_follow_includes=#true`) add every file the selected sources reach through #include, searched the way the compiler does: quoted includes next to the includer and then in the include directories, angle-bracket includes only in the include directories. A recipe then names compilation units instead of maintaining header lists that drift from what upstream actually includes.
- Relative imports must resolve: after the last op, every relative `from` import in the tree must name a module or package that is in the port (`torch-ext/<pkg>/_ops` is generated by the build). An upstream file that starts importing a module the recipe prunes now fails the port instead of failing at import time. - Every torch-ext declaration must match its definition: each function declared in a C-family file under torch-ext must have a definition in the output with the same parameter types (names and default arguments may differ). The error shows both lists and the first parameter that differs. - `expect blob=` pins the upstream file an overlay copy was made from. A find= guard only notices upstream changes to the lines it names, so an overlay copy of an upstream file could silently go stale. blob= pins the whole file by its git blob id; on a mismatch the error prints the git diff between the old and new blob, which is what to carry into the overlay copy. - Python import edits are spliced into the text so untouched code keeps its layout. Occurrences were found by text search alone, so an import that also appeared in a string literal or comment made the op refuse, and `import b` could match inside `from a import b`. Only occurrences that begin a statement, per libcst's tokenizer, now count, and every rewrite is located in the original text before any is applied.
Coverage report —
|
| Name | Stmts | Miss | Cover | Missing |
|---|---|---|---|---|
| src/kernels/__init__.py | 14 | 0 | 100% | |
| src/kernels/_system.py | 6 | 1 | 83% | 10 |
| src/kernels/_versions.py | 130 | 14 | 89% | 53, 59-60, 63-64, 102, 165-170, 199, 219 |
| src/kernels/archs.py | 56 | 1 | 98% | 94 |
| src/kernels/backends.py | 215 | 63 | 71% | 42, 46, 50-53, 70, 92, 110, 119, 123, 127-129, 150, 159, 163, 167-169, 190, 201, 203, 210-213, 222, 226, 230-255, 263, 286-306 |
| src/kernels/compat.py | 9 | 1 | 89% | 5 |
| src/kernels/deps.py | 70 | 1 | 99% | 56 |
| src/kernels/digest.py | 58 | 5 | 91% | 71-73, 136-137 |
| src/kernels/hf_hub.py | 62 | 2 | 97% | 21, 23 |
| src/kernels/importer.py | 74 | 5 | 93% | 158, 162, 165, 179-180 |
| src/kernels/install.py | 21 | 7 | 67% | 76-100 |
| src/kernels/layer/__init__.py | 7 | 0 | 100% | |
| src/kernels/layer/_interval_tree.py | 103 | 4 | 96% | 23, 52, 147, 150 |
| src/kernels/layer/device.py | 48 | 12 | 75% | 42, 47-49, 91, 96-98, 101, 149, 152, 156 |
| src/kernels/layer/func.py | 93 | 5 | 95% | 94, 119, 195, 315, 390 |
| src/kernels/layer/globals.py | 5 | 0 | 100% | |
| src/kernels/layer/inspect.py | 27 | 0 | 100% | |
| src/kernels/layer/kernelize.py | 83 | 7 | 92% | 306, 314-315, 321, 325, 341-343 |
| src/kernels/layer/layer.py | 320 | 14 | 96% | 212, 259, 447, 606-607, 628, 636, 647, 688, 692, 705, 760, 801, 876 |
| src/kernels/layer/mode.py | 14 | 0 | 100% | |
| src/kernels/layer/repos.py | 136 | 36 | 74% | 32, 35-42, 73, 86, 90, 99-100, 103, 106-109, 116-117, 120, 123-126, 133-134, 137, 140-143, 150-151, 154, 157-160, 235 |
| src/kernels/load.py | 71 | 2 | 97% | 338, 378 |
| src/kernels/locking.py | 89 | 64 | 28% | 35-83, 91-98, 102-125, 137, 152-159, 165-175, 179-186 |
| src/kernels/python_deps.py | 58 | 6 | 90% | 59-60, 64-65, 101, 104 |
| src/kernels/resolver.py | 162 | 1 | 99% | 248 |
| src/kernels/status.py | 50 | 2 | 96% | 25, 79 |
| src/kernels/validate.py | 104 | 7 | 93% | 9, 101, 172, 195-196, 232-233 |
| src/kernels/variants.py | 278 | 17 | 94% | 65, 96, 117, 147, 256-257, 299-302, 304, 388-394, 400-406, 455-461 |
| src/kernels/verify.py | 102 | 6 | 94% | 44, 176-178, 266-267 |
| TOTAL | 2465 | 283 | 89% |
Updated by the Test kernels workflow on commit b3c667eac2e1b49da7ced52b4f2514f40fc99849.
Member
|
I know this is still draft but would be nice to substantiate this with a real example. |
drbh
added a commit
to huggingface/kernels-community
that referenced
this pull request
Oct 28, 2026
this generates `flash-attn3/src` from `flash-attn3/port/port.kdl` and `flash-attn3/port/overlay`, pinned to the same upstream commit as the hand port (`0816ef12`) - the fixed `flash_attn_3` op namespace in `flash_api_stable.cpp` is rewritten by `extension` and the module entry point now lives in `torch-ext/torch_binding.cpp` (upstream's unused `PyInit__C` is kept) - `flash_api.cpp` is no longer vendored since it was never compiled - `flash_attn_interface.py` and the tests keep upstream's formatting and dispatch through `flash_attn_3_gpu = ops` - `build.toml` header lists come from `follow_includes` note: check ports runs kernel-port from the `kernel-port-declarative` branch until huggingface/kernels#946 is merged
Collaborator
Author
|
just added an example that ports flash-attn3 huggingface/kernels-community#1283 it makes use of |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
this pr adds a few kernel-port ops and post-port checks so recipes can handle native extensions and catch upstream drift at port time instead of at build or import time
#includes when a globmoverenames filesrewrite, a structural find/replaceextensionto convert native extensions to._opsmark_tests only=follow_includes=#trueforkernelandmanifestexpect blob=to pin overlay copies