Skip to content

[ExecuTorch][WebGPU] Add linear_qcs4w op (et_vk.linear_qcs4w)#21211

Open
JCNTH wants to merge 1 commit into
gh/JCNTH/171/basefrom
gh/JCNTH/171/head
Open

[ExecuTorch][WebGPU] Add linear_qcs4w op (et_vk.linear_qcs4w)#21211
JCNTH wants to merge 1 commit into
gh/JCNTH/171/basefrom
gh/JCNTH/171/head

Conversation

@JCNTH

@JCNTH JCNTH commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Stack from ghstack (oldest at bottom):

Problem: The WebGPU delegate has no et_vk.linear_qcs4w — a 4-bit channels-symmetric-weight linear (per-output-channel symmetric weight, no zero-point). It is reachable via the VulkanQuantizer weight-only 4-bit path (distinct from the XNNPACK static-PT2E path that produces the q8ta ops), but had no WebGPU handler.

Solution: Port et_vk.linear_qcs4w (fp32 activation, int4 weight), mirroring the landed linear_q4gsw register-tiled buffer GEMM (quantized_linear/QuantizedLinear.cpp + q4gsw_linear.wgsl) simplified to per-channel scale. Vulkan ref: impl/QuantizedLinearQCSNW.cpp linear_qcs4w (check_linear_qcsnw_args: args [mat1, qmat2=[N,K/2] 4-bit, scales=[N], out], symmetric per-output-channel, no group, no zero-point, no bias) + glsl/linear_qcsnw_coop.glsl. Before/After vs q4gsw: q4gsw scale is grouped scales[(k/group_size)*padded_N + n]; qcs4w scale is per-channel scales[n] (1D [N]) — no group_size, no padded_N, no bias.

Implementation: linear_qcs4w/QuantizedLinearQcs4w.cpp registers et_vk.linear_qcs4w -> qcs4w_linear_impl, args [in, weight, scales, out] (out=args.back()). qcs4w_linear.wgsl: register-tiled (TM=TN=4) GEMM, acc += in[m,k] * (unpack_int4(w) - 8) * scales[n], 2D-folded dispatch (lifts the 65535 cap). Qcs4wParams (16 bytes: M/N/K/K_packed) matches the WGSL Params. Guards fp32 in/out, K_packed==ceil(K/2), N*K_packed%4==0 (u32-packed), scales>=N, all fail-loud. Resize hook recomputes live M + dispatch.

Constraints / divergences from the Vulkan reference: (1) buffer re-derivation of Vulkan's texture-based qcs4w GEMM (WebGPU always buffers). (2) CRITICAL — nibble order: the qcs4w AOT packer (_passes/fuse_quantized_ops.py) stores (even_col<<4)|odd_col, the SWAP of q4gsw's pack_4bit_weight_tensor (odd<<4)|even — so this kernel reads even-k from the HIGH nibble and odd-k from the LOW nibble, the reverse of q4gsw_linear.wgsl (verified against the packer, the Vulkan linear_qcsnw_coop.glsl unpack, and a byte-search of the served .pte). (3) +8-shifted int4 recovered as signed [-8,7] (same as q4gsw). (4) one tiled kernel only (q4gsw's GEMV/shmem perf variants are separate, Canary-gated follow-ups). Bias is out of the op (a Linear bias lowers to a separate aten.add).

Differential Revision: D112257623

[ghstack-poisoned]
@pytorch-bot

pytorch-bot Bot commented Jul 22, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/21211

Note: Links to docs will display an error until the docs builds have been completed.

❗ 1 Active SEVs

There are 1 currently active SEVs. If your PR is affected, please view them below:

❌ 46 New Failures, 3 Unrelated Failures

As of commit cc9e073 with merge base 266e0dc (image):

NEW FAILURES - The following jobs have failed:

FLAKY - The following jobs failed but were likely due to flakiness present on trunk:

  • pull / unittest / windows / windows-job (gh) (matched win rule in flaky-rules.json)
    Can't find 'action.yml', 'action.yaml' or 'Dockerfile' under 'C:\actions-runner\_work\executorch\executorch\test-infra\.github\actions\teardown-windows'. Did you forget to run actions/checkout before running your local action?
  • pull / unittest-editable / windows / windows-job (gh) (matched win rule in flaky-rules.json)
    Can't find 'action.yml', 'action.yaml' or 'Dockerfile' under 'C:\actions-runner\_work\executorch\executorch\test-infra\.github\actions\teardown-windows'. Did you forget to run actions/checkout before running your local action?

BROKEN TRUNK - The following job failed but were present on the merge base:

👉 Rebase onto the `viable/strict` branch to avoid these failures

This comment was automatically generated by Dr. CI and updates every 15 minutes.

This was referenced Jul 22, 2026
This was referenced Jul 22, 2026
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jul 22, 2026
@JCNTH
JCNTH requested a review from psiddh July 23, 2026 02:01

@psiddh psiddh left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving full WebGPU stack

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants