Repository navigation
contract: an XPU device runner (gates 1 to 4 on a B70, gate 5 live, planted controls) - #2269
Conversation
|
Thanks @tolewis. The runner does what #2080 agreed: the glue through gates 1 to 4 on the card, five planted controls each red at its own gate, and gate 5 checked live against the card and each loaded image. |
c503217 to
a358383
Compare
|
@tolewis, #2269 came up in our landing queue but stopped on its own CI. Now that your #2155 is on main, two things:
With both fixed and CI green on the new head, it goes straight back in the queue. |
a358383 to
b79eb6b
Compare
|
Thanks @ashhart. Both are fixed on
On this head: The B70 run in the description is of |
b79eb6b to
f454898
Compare
|
/atc exchange 88927731373e58d9619d034e78818cab5f5c591dcb4302eb1d8faca8457817d3 |
… and kernel checks
…without a work-group size
…ate controls on a card
… from the card's own activation bytes
…d's one fp16 rounding covers a tie
f454898 to
465ab61
Compare
|
Thank you @tolewis. This is merged into main with your commits under your own name, so you're listed as a TensorFold contributor. It ships in the next release, credited to you in the changelog and the release notes. |
What this changes
XPU kernels now run gates 1 to 4 of the kernel contract on the card.
tf-xpu-contract-runopens an Arc Pro B70 through Level Zero. It runs nine registrations of the Qwen3.8-27B glue and five planted gate controls, then runs gate 5 live against the card's own properties. This follows the HIP runner's shape.53311e7e), now that contract: an XPU limits backend (gate 5, the .ze_info reader, planted controls) #2155 is merged. Ten commits: the eight of the runner, your changelog commit, andf454898b, which declares-Dxpu-imageson every target.atc overlap --json: not run, because the CLI needsghauth that I do not use here. By hand: 43 open pull requests change a file this head changes. I rangit merge-treeof each one against main and against this head. This head adds no conflict that the pull request does not already have with main. This head merges into current main (53311e7e) cleanly.The B70 run, exit 0:
Each planted control going red, from the same run:
fmax, which drops a NaN that float64 keepsatomic_add)Gate 5 also runs live. The card's PCI id, EUs a Xe-core, threads an EU, SIMD width and Xe-core count are checked against the BMG-G31 row from #2155. Each loaded kernel's required work-group, sub-group, SLM bytes, spill bytes and argument count are checked against its record, and its work-group against what a Xe-core holds at its GRF mode. The runner loads the same native zebins that the #2155 audit reads, so the GRF mode the record states is the loaded image's mode.
zig/tests/xpu/contract_run.zigtf-xpu-contract-run [--device N]: the device, the runner list and theSUMMARYlinezig/tests/xpu/contract_rig.zigzig/tests/xpu/contract_kit.zigzig/tests/xpu/contract_norm.zigadd_rmsnorm,add_rmsnorm_decandgated_norm: the normed row and the residual in placezig/tests/xpu/contract_swiglu.zigswiglu: the activation and the row sums it writes beside itzig/tests/xpu/contract_argmax.zigargmax, with its stated NaN and tie rulezig/tests/xpu/contract_embed.zigembed, with its stated rounding rulezig/tests/xpu/contract_controls.zigzig/tests/xpu/contract_live.zigzig/kernels/xpu/contract_gate_controls.clzig/src/core/contract/xpu_ref.zigzig/src/core/contract/xpu_limits.zigzig/src/core/contract/contract.zigstorespec termzig/src/xpu/module.zigloadNativefor a zebin, andkernelAt, which sets no work-group sizezig/build/xpu_contract.zigtf-xpu-contract-run,xpu-contract-runand-Dxpu-images=DIRzig/src/core/contract.zigdocs/kernel-contract.mdstore, and where an XPU test type goesTwo changes reach code outside the XPU contract:
Spec.storeis a new optional field,nullby default. The residual thatadd_rmsnormwrites in place holds bf16 values in fp32 words, asglue.cl'srbfstores them. Withstore = .bf16, the bound allows one bf16 rounding there, not one fp32 rounding, which is the same allowance HIP gives a bf16 residual. Withnull,boundandboundExactgive the same values as before, so every other registration is unchanged.Module.loadNativeloads a zebin withZE_MODULE_FORMAT_NATIVEthrough the same path asload, which still builds SPIR-V.kernelnow callskernelAtand then sets the work-group size, so its callers see no change. Gate 5 live useskernelAtso that a size the device refuses cannot hide the kernel's properties.The SwiGLU row sums' reference is the unrounded float64 mean, computed from the activation bytes that the card wrote. The bound already allows one fp16 rounding at the store. A reference that is already rounded leaves no room at an fp16 tie. A B70 run before
c5032171failed at -19.28125 where the rounded reference gave -19.296875, with the exact value near the tie between them. The host testa SwiGLU row sum at an fp16 tie is not rounded in the reference, so either neighbour is within the boundholds that case. In the run above, the row sums' worst shape is 0.996 of the bound.Checks on this head
f454898b. It isb79eb6bdrebased onto main53311e7efor aCHANGELOG.mdconflict. OutsideCHANGELOG.mdthe change is byte-identical, and CI was green onb79eb6bd. The checks below ran onb79eb6bd.python3 tools/zig/lean_check.py, on the base (6433d511) and on this head: 252 and 252, the same lines; 0 new findings.zig build test-kernel-contract: 210 passed, 0 failed, 0 skipped.zig build test: 7414 tests, 7352 passed, 1 failed, 61 skipped. The failure is the listener test that binds the IPv6 loopback, which this machine does not have. It also fails on main on the same machine.zig fmt --check zig/: clean.python3 -m unittest tools/zig/build_options_test.py: 5 passed. It failed on CI before the-Dxpu-imagesfix, because-Dxpu-imageswas declared only with-Dxpu-contract=true.Receipt
c5032171, this branch before the rebase, on contract: an XPU limits backend (gate 5, the .ze_info reader, planted controls) #2155 (3cbd915d). The rebase onto6433d511changes no kernel. Main changed three files the runner compiles:rows.ziggainslayer_normandgelu,xpu/kernels.ziggains the LFM3 images (the runner links none), andcore/contract.zigexports one more module. None changes a path the runner takes, and the zebins are the same three, with the same hashes. Linux, Zig 0.17.0, ocloc 26.35.39758.10, one Intel Arc Pro B70 (PCI id 0xe223). No checkpoint is needed.xpu/module.zigonly. No inference path changes, so no model ran. The Zig host has no ocloc, so I made the zebins on the B70 host with the commands below. I linked them with-Dxpu-images=DIR, then ran the binary once on one B70.tools/bench_concurrent.py --alone --serialortoken_shaagainst"draft": false: n/a. No kernel, weight or inference path changes.tools/bench_openai.py: n/a, for the same reason.The zebins, from the repository root of this head (ocloc 26.35.39758.10):
glue.bin678dc97fc959d8e196b21cf59750acc054961e97e22c6389dce63248def51725contract_controls.binad38214f86268ec752608207e32b9dfbed3720bc07a5b3ea413a8131077e7024contract_gate_controls.bin506e9fbd5792fd5932fe76a5744de0c6996dbeb26edc28fedb79a41515b517a6On a B70 host with both tools,
zig build -Dxpu-contract=true xpu-contract-run -Docloc=ocloc -Dxpu-device=bmgmakes the zebins and runs the binary in one step.The full run, 65 lines, exit 0. The first two lines are from the driver (the second is a NUL byte, left out here). It refuses the 160 KiB SLM control image of #2155, which is planted. Gate 5 then reports that image as
N/Aand checks its limits from the table.tf-xpu-contract-run, full output
Kernel contract, only when a GPU kernel is new or changed
add_rmsnormandadd_rmsnorm_dec(the normed row, and the residual in place),gated_norm,swiglu(the activation, and the row sums),argmaxandembed. None replaces a kernel. These kernels do not change.SUMMARYline and exit status:SUMMARY bmg-g31 0xe223 9 kernels: 9 pass gates 1-4, 0 fail, 0 known findings; 5 controls: 5 red as planted, 0 missed; 0 limit problems; gates 7955 ms, limits 0 ms, exit 0.Checklist