feat: experimental kernel porting tool - #776
Conversation
Coverage report —
|
| Name | Stmts | Miss | Cover | Missing |
|---|---|---|---|---|
| src/kernels/__init__.py | 13 | 0 | 100% | |
| src/kernels/_system.py | 6 | 1 | 83% | 10 |
| src/kernels/_versions.py | 63 | 7 | 89% | 46, 49, 52-53, 56-57, 100 |
| src/kernels/backends.py | 212 | 62 | 71% | 40, 44, 48-51, 68, 90, 108, 117, 121, 125-127, 148, 157, 161, 165-167, 188, 199, 201, 208-211, 224, 228, 232-252, 260, 283-303 |
| src/kernels/compat.py | 8 | 1 | 88% | 5 |
| src/kernels/deps.py | 58 | 4 | 93% | 59-60, 101, 104 |
| src/kernels/hf_hub.py | 62 | 5 | 92% | 18, 20, 114, 136-137 |
| src/kernels/importer.py | 48 | 3 | 94% | 106, 110, 113 |
| src/kernels/install.py | 50 | 5 | 90% | 78, 116-117, 155, 173 |
| src/kernels/layer/__init__.py | 6 | 0 | 100% | |
| src/kernels/layer/_interval_tree.py | 103 | 4 | 96% | 23, 52, 147, 150 |
| src/kernels/layer/device.py | 48 | 14 | 71% | 42, 47-49, 91, 96-98, 101, 149, 152, 155-157 |
| src/kernels/layer/func.py | 82 | 7 | 91% | 83, 113, 185, 303, 309, 322, 340 |
| src/kernels/layer/globals.py | 5 | 0 | 100% | |
| src/kernels/layer/kernelize.py | 74 | 8 | 89% | 255, 281, 289-290, 296, 300, 316-318 |
| src/kernels/layer/layer.py | 211 | 16 | 92% | 169, 212, 218, 231, 339, 419-420, 432, 441, 449, 460, 489, 493, 506, 559, 589 |
| src/kernels/layer/mode.py | 14 | 0 | 100% | |
| src/kernels/layer/repos.py | 144 | 42 | 71% | 27, 33, 36-43, 63-64, 70, 73-76, 90, 94, 103-104, 110, 113-116, 123-124, 130, 133-136, 143-144, 150, 153-156, 163-164, 170, 173-176, 257 |
| src/kernels/load.py | 74 | 9 | 88% | 218, 224, 230-231, 252-264 |
| src/kernels/locking.py | 108 | 70 | 35% | 42-109, 113-136, 144, 148-155, 159-169, 173-180 |
| src/kernels/status.py | 49 | 2 | 96% | 23, 81 |
| src/kernels/variants.py | 278 | 22 | 92% | 64, 95, 116, 146, 255-256, 298-301, 303, 387-394, 400-406, 437-443, 455-461, 611-613 |
| src/kernels/verify.py | 88 | 1 | 99% | 32 |
| TOTAL | 1804 | 283 | 84% |
Updated by the Test kernels workflow on commit f2c269d417a645b10e1f394ce98e7f74dcb8f7d8.
We might want to elaborate on what overlay means in this context.
Is the manual specification for
How are those pins derived?
Do the users have to specify More comments
|
the docs on the readme may already fill this need https://github.com/huggingface/kernels/blob/b7062eed8821f6a1235680844ad4bbc4711d7a7c/kernel-port/README.md#overlay copied for reference Note
|
Very good idea, IMO. But would we have a simple way to quickly test the correctness of its implementation? Not a blocker but I think we should strive for simplicity here.
Maybe we need to distinguish between required pins and optional pins?
Cool, that works for me!
Not sure if I fully understood it. Why would it differ for an external repo from
Oh okay. I was under the impression that without the |
| # Local packages/hooks. | ||
| kernel-builder = final.callPackage ./pkgs/kernel-builder { inherit builderProvenance; }; | ||
|
|
||
| kernel-port = final.callPackage ./pkgs/kernel-port { }; |
There was a problem hiding this comment.
Any reasoning behind making it a part of our nix-builder? For future CI?
sayakpaul
left a comment
There was a problem hiding this comment.
Thanks just left a bunch of comments. I think we are headed in a good direction. Once this takes a bit more shape, we could think about how we wire this in the CI, etc.
Warning
This is an experiment/draft. The recipe language, the op set, and the CLI are all subject to change without notice.
this pr adds
kernel-port, an experimental tool for porting kernel repos into the kernel-builder layout by running a recipe instead of doing it by hand.the idea is that porting an existing kernel to the kernel-builder is a set of deterministic rewrites/restructuring. a recipe is a list of those operations, which has the benefit of being able to be checked into the repo and provide a way to deterministically reproduce given a specific upstream commit.
one of the difficulties of maintaining a port is that the upstream repo can drift and currently keeping the port in sync is a manual process.
recipes are a way to codify the porting process, so that if the upstream repo drifts we can simply bump the commit in the recipe and re-run the porting process. if the upstream repo has changed in a way that breaks the porting process, the recipe will fail to apply and we can fix it before continuing.
a port is a
port.kdlrecipe plus an overlay dir of checked in files. same pins + same recipe gives a byte identical tree every time, and every op hard fails on drift rather than silently porting the wrong thing.recipes are kdl 2.0 documents, one node per op:
there are 15 ops (
source,vendor,prune,delete,move,overlay,replace,strip_suffix,expect,convert_import,remap_module,relativize_imports,ensure_init,kernel,manifest). python rewrites go through libcst so comments and formatting are preserved byte for byte.build.tomlis always generated by themanifestop, never overlaid.the pins are the whole point.
count=,files=andchanges=are literals that have to match exactly, so a new file upstream cannot be rewritten without someone looking at it:you can try an op without a checkout at all,
-etakes the recipe inline and--file path=contentbuilds the input tree in memorythe readme has a cookbook with one runnable command per op, plus the full arg list and failure modes for each. every example in it was run and pasted, not written by hand.
***NEXT STEPS are to target a JIT and AOT kernel in the kernels-community and experiment using this tool