[ExecuTorch][WebGPU] Add f16-multiply variant of the steel q4gsw prefill GEMM#20752
Conversation
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/20752
Note: Links to docs will display an error until the docs builds have been completed. ❌ 4 New Failures, 1 Cancelled Job, 2 PendingAs of commit 061b444 with merge base f4b01a8 ( NEW FAILURES - The following jobs have failed:
CANCELLED JOB - The following job was cancelled. Please retry:
This comment was automatically generated by Dr. CI and updates every 15 minutes. |
This PR needs a
|
|
@claude throoughly review, check for overengineering, correctness, and areaas for modularization |
|
Claude finished @JCNTH's task in 4m 27s —— View job Review: f16-multiply steel q4gsw prefill GEMM
Overall this is a clean, well-scoped change. The template splits are minimal and the f32 variant provably regenerates byte-identical (the committed Correctness — looks right
Things worth flagging (not blockers)
Note on verificationI could not run |
SS-JIA
left a comment
There was a problem hiding this comment.
Review automatically exported from Phabricator review in Meta.
SS-JIA
left a comment
There was a problem hiding this comment.
Review automatically exported from Phabricator review in Meta.
…ill GEMM Pull Request resolved: #20752 **Enables an f16-multiply path for the 256-thread steel q4gsw prefill GEMM** on devices that negotiated WebGPU shader-f16 — f16 shared memory + f16 multiply with an f32 accumulator (storage stays f32). It is opt-in and default-off, so no ExecuTorch consumer's numerics change; the default build keeps the f32 kernel and the strict f32 golden. f16 multiply / f32 accumulate (never f16-accumulate, which is numerically unstable on the target GPUs) is a measured prefill win the f32-only kernel could not express. **Key changes:** - `q4gsw_linear_gemm_steel.yaml` — add a `half` variant (`SUFFIX: half`) beside the `float` variant. - `q4gsw_linear_gemm_steel.wgsl` — three `$if DTYPE == "half"` splits (`enable f16;`, an f16 dequant multiply, an `f32(a * b)` cast on the MAC so the accumulator stays f32); each `$else` is the verbatim f32 line, so the float variant regenerates byte-identical. - `q4gsw_linear_gemm_steel_half_wgsl.h` — generated `kQ4gswLinearGemmSteelHalfWGSL` (f16 shared memory + multiply, f32 accumulate, f32 storage). - `QuantizedLinear.cpp` — under `WGPU_BACKEND_STEEL_F16`, select the half shader only when `use_steel` and `ctx->shader_f16_supported`; else fall back to the f32 steel kernel (fail-closed). Bindings, tile, and workgroup count are identical — only `shader_src` differs. The device-negotiation gate has no Vulkan analogue: WebGPU shader-f16 is an optional WGSL feature requested at device creation, unlike Vulkan's host-side dtype pick (`add_dtype_suffix`). Co-authored-with: Claude Code. ghstack-source-id: 401515172 @exported-using-ghexport Differential Revision: [D110802531](https://our.internmc.facebook.com/intern/diff/D110802531/)
…ill GEMM Pull Request resolved: #20752 **Enables an f16-multiply path for the 256-thread steel q4gsw prefill GEMM** on devices that negotiated WebGPU shader-f16 — f16 shared memory + f16 multiply with an f32 accumulator (storage stays f32). It is opt-in and default-off, so no ExecuTorch consumer's numerics change; the default build keeps the f32 kernel and the strict f32 golden. f16 multiply / f32 accumulate (never f16-accumulate, which is numerically unstable on the target GPUs) is a measured prefill win the f32-only kernel could not express. **Key changes:** - `q4gsw_linear_gemm_steel.yaml` — add a `half` variant (`SUFFIX: half`) beside the `float` variant. - `q4gsw_linear_gemm_steel.wgsl` — three `$if DTYPE == "half"` splits (`enable f16;`, an f16 dequant multiply, an `f32(a * b)` cast on the MAC so the accumulator stays f32); each `$else` is the verbatim f32 line, so the float variant regenerates byte-identical. - `q4gsw_linear_gemm_steel_half_wgsl.h` — generated `kQ4gswLinearGemmSteelHalfWGSL` (f16 shared memory + multiply, f32 accumulate, f32 storage). - `QuantizedLinear.cpp` — under `WGPU_BACKEND_STEEL_F16`, select the half shader only when `use_steel` and `ctx->shader_f16_supported`; else fall back to the f32 steel kernel (fail-closed). Bindings, tile, and workgroup count are identical — only `shader_src` differs. The device-negotiation gate has no Vulkan analogue: WebGPU shader-f16 is an optional WGSL feature requested at device creation, unlike Vulkan's host-side dtype pick (`add_dtype_suffix`). Co-authored-with: Claude Code. ghstack-source-id: 401515172 @exported-using-ghexport Differential Revision: [D110802531](https://our.internmc.facebook.com/intern/diff/D110802531/)
…ill GEMM Pull Request resolved: #20752 **Enables an f16-multiply path for the 256-thread steel q4gsw prefill GEMM** on devices that negotiated WebGPU shader-f16 — f16 shared memory + f16 multiply with an f32 accumulator (storage stays f32). It is opt-in and default-off, so no ExecuTorch consumer's numerics change; the default build keeps the f32 kernel and the strict f32 golden. f16 multiply / f32 accumulate (never f16-accumulate, which is numerically unstable on the target GPUs) is a measured prefill win the f32-only kernel could not express. **Key changes:** - `q4gsw_linear_gemm_steel.yaml` — add a `half` variant (`SUFFIX: half`) beside the `float` variant. - `q4gsw_linear_gemm_steel.wgsl` — three `$if DTYPE == "half"` splits (`enable f16;`, an f16 dequant multiply, an `f32(a * b)` cast on the MAC so the accumulator stays f32); each `$else` is the verbatim f32 line, so the float variant regenerates byte-identical. - `q4gsw_linear_gemm_steel_half_wgsl.h` — generated `kQ4gswLinearGemmSteelHalfWGSL` (f16 shared memory + multiply, f32 accumulate, f32 storage). - `QuantizedLinear.cpp` — under `WGPU_BACKEND_STEEL_F16`, select the half shader only when `use_steel` and `ctx->shader_f16_supported`; else fall back to the f32 steel kernel (fail-closed). Bindings, tile, and workgroup count are identical — only `shader_src` differs. The device-negotiation gate has no Vulkan analogue: WebGPU shader-f16 is an optional WGSL feature requested at device creation, unlike Vulkan's host-side dtype pick (`add_dtype_suffix`). Co-authored-with: Claude Code. ghstack-source-id: 401515172 @exported-using-ghexport Differential Revision: [D110802531](https://our.internmc.facebook.com/intern/diff/D110802531/)
…ill GEMM Pull Request resolved: #20752 **Enables an f16-multiply path for the 256-thread steel q4gsw prefill GEMM** on devices that negotiated WebGPU shader-f16 — f16 shared memory + f16 multiply with an f32 accumulator (storage stays f32). It is opt-in and default-off, so no ExecuTorch consumer's numerics change; the default build keeps the f32 kernel and the strict f32 golden. f16 multiply / f32 accumulate (never f16-accumulate, which is numerically unstable on the target GPUs) is a measured prefill win the f32-only kernel could not express. **Key changes:** - `q4gsw_linear_gemm_steel.yaml` — add a `half` variant (`SUFFIX: half`) beside the `float` variant. - `q4gsw_linear_gemm_steel.wgsl` — three `$if DTYPE == "half"` splits (`enable f16;`, an f16 dequant multiply, an `f32(a * b)` cast on the MAC so the accumulator stays f32); each `$else` is the verbatim f32 line, so the float variant regenerates byte-identical. - `q4gsw_linear_gemm_steel_half_wgsl.h` — generated `kQ4gswLinearGemmSteelHalfWGSL` (f16 shared memory + multiply, f32 accumulate, f32 storage). - `QuantizedLinear.cpp` — under `WGPU_BACKEND_STEEL_F16`, select the half shader only when `use_steel` and `ctx->shader_f16_supported`; else fall back to the f32 steel kernel (fail-closed). Bindings, tile, and workgroup count are identical — only `shader_src` differs. The device-negotiation gate has no Vulkan analogue: WebGPU shader-f16 is an optional WGSL feature requested at device creation, unlike Vulkan's host-side dtype pick (`add_dtype_suffix`). Co-authored-with: Claude Code. ghstack-source-id: 401515172 @exported-using-ghexport Differential Revision: [D110802531](https://our.internmc.facebook.com/intern/diff/D110802531/)
…ill GEMM Pull Request resolved: #20752 **Enables an f16-multiply path for the 256-thread steel q4gsw prefill GEMM** on devices that negotiated WebGPU shader-f16 — f16 shared memory + f16 multiply with an f32 accumulator (storage stays f32). It is opt-in and default-off, so no ExecuTorch consumer's numerics change; the default build keeps the f32 kernel and the strict f32 golden. f16 multiply / f32 accumulate (never f16-accumulate, which is numerically unstable on the target GPUs) is a measured prefill win the f32-only kernel could not express. **Key changes:** - `q4gsw_linear_gemm_steel.yaml` — add a `half` variant (`SUFFIX: half`) beside the `float` variant. - `q4gsw_linear_gemm_steel.wgsl` — three `$if DTYPE == "half"` splits (`enable f16;`, an f16 dequant multiply, an `f32(a * b)` cast on the MAC so the accumulator stays f32); each `$else` is the verbatim f32 line, so the float variant regenerates byte-identical. - `q4gsw_linear_gemm_steel_half_wgsl.h` — generated `kQ4gswLinearGemmSteelHalfWGSL` (f16 shared memory + multiply, f32 accumulate, f32 storage). - `QuantizedLinear.cpp` — under `WGPU_BACKEND_STEEL_F16`, select the half shader only when `use_steel` and `ctx->shader_f16_supported`; else fall back to the f32 steel kernel (fail-closed). Bindings, tile, and workgroup count are identical — only `shader_src` differs. The device-negotiation gate has no Vulkan analogue: WebGPU shader-f16 is an optional WGSL feature requested at device creation, unlike Vulkan's host-side dtype pick (`add_dtype_suffix`). Co-authored-with: Claude Code. ghstack-source-id: 401515172 @exported-using-ghexport Differential Revision: [D110802531](https://our.internmc.facebook.com/intern/diff/D110802531/)
Stack from ghstack (oldest at bottom):
Enables an f16-multiply path for the 256-thread steel q4gsw prefill GEMM on devices that negotiated WebGPU shader-f16 — f16 shared memory + f16 multiply with an f32 accumulator (storage stays f32). It is opt-in and default-off, so no ExecuTorch consumer's numerics change; the default build keeps the f32 kernel and the strict f32 golden. f16 multiply / f32 accumulate (never f16-accumulate, which is numerically unstable on the target GPUs) is a measured prefill win the f32-only kernel could not express.
Key changes:
q4gsw_linear_gemm_steel.yaml— add ahalfvariant (SUFFIX: half) beside thefloatvariant.q4gsw_linear_gemm_steel.wgsl— three$if DTYPE == "half"splits (enable f16;, an f16 dequant multiply, anf32(a * b)cast on the MAC so the accumulator stays f32); each$elseis the verbatim f32 line, so the float variant regenerates byte-identical.q4gsw_linear_gemm_steel_half_wgsl.h— generatedkQ4gswLinearGemmSteelHalfWGSL(f16 shared memory + multiply, f32 accumulate, f32 storage).QuantizedLinear.cpp— underWGPU_BACKEND_STEEL_F16, select the half shader only whenuse_steelandctx->shader_f16_supported; else fall back to the f32 steel kernel (fail-closed). Bindings, tile, and workgroup count are identical — onlyshader_srcdiffers.The device-negotiation gate has no Vulkan analogue: WebGPU shader-f16 is an optional WGSL feature requested at device creation, unlike Vulkan's host-side dtype pick (
add_dtype_suffix).Co-authored-with: Claude Code.
@exported-using-ghexport
Differential Revision: D110802531
Differential Revision: D110802531