sync 2e7068faf55e
Browse files- README.md +90 -0
- build/webgpu/bench.json +823 -0
- build/webgpu/manifest.json +1480 -0
- build/webgpu/matmul-nbits-dp4a-quantize.wgsl.jinja +46 -0
- build/webgpu/matmul-nbits-gemv-q4.wgsl.jinja +144 -0
- build/webgpu/matmul-nbits-q4-dp4a-prefill.wgsl.jinja +104 -0
- build/webgpu/matmul-nbits-q4-prefill-tile4x4.wgsl.jinja +171 -0
- build/webgpu/matmul-nbits-q4-prefill-tiled-reg.wgsl.jinja +200 -0
- build/webgpu/matmul-nbits-q4-prefill-tiled.wgsl.jinja +130 -0
- build/webgpu/matmul-nbits-q4-sgmat.wgsl.jinja +193 -0
- build/webgpu/matmul-nbits.wgsl.jinja +69 -0
- build/webgpu/metadata.json +25 -0
- build/webgpu/test.json +1967 -0
README.md
CHANGED
|
@@ -1,3 +1,93 @@
|
|
| 1 |
---
|
|
|
|
| 2 |
license: apache-2.0
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
library_name: kernels
|
| 3 |
license: apache-2.0
|
| 4 |
+
tags:
|
| 5 |
+
- kernel
|
| 6 |
+
- webgpu
|
| 7 |
+
- wgsl
|
| 8 |
---
|
| 9 |
+
# com.microsoft.MatMulNBits
|
| 10 |
+
|
| 11 |
+
`com.microsoft` · ONNX Runtime contrib operator · contrib since_version 1
|
| 12 |
+
|
| 13 |
+
## Description
|
| 14 |
+
|
| 15 |
+
Matrix multiplication with `B` block-quantized along K and dequantized as `(code - zero_point) * scale`. Each power-of-two `block_size` group has a scale and optional zero point; optional bias is added afterward. Two-, four-, and eight-bit codes are packed low-first, and `A` may have rank 2 or 3. This package supports standard unpacked zero points with the same dtype as `A`. Deprecated `g_idx`, prepacked weights, and bfloat16 tensors are not implemented.
|
| 16 |
+
|
| 17 |
+
See the [ONNX Runtime `MatMulNBits` contrib-operator spec](https://github.com/microsoft/onnxruntime/blob/main/docs/ContribOperators.md#com.microsoft.MatMulNBits) for the reference semantics.
|
| 18 |
+
|
| 19 |
+
## Inputs
|
| 20 |
+
|
| 21 |
+
| Name | Bind key | Logical dtype | Rank | Shape | Description | Presence |
|
| 22 |
+
| --- | --- | --- | --- | --- | --- | --- |
|
| 23 |
+
| `A` | `aT` | `T1` | — | — | Float input matrix, not quantized. Rank 2 has shape `(M, K)` and rank 3 has shape `(batch, sequence, K)`; only the last axis is the reduction axis and the leading axes fold into the row count, so the ordinary activation needs no surrounding Reshape. | required |
|
| 24 |
+
| `B` | `bT` | `uint8` | `3` | — | Bit-packed uint8 weight matrix of shape `(N, k_blocks, blob_size)`, where `k_blocks = ceil(K / block_size)` and `blob_size = block_size * bits / 8`. Codes are packed low-first along K. | required |
|
| 25 |
+
| `scales` | `scalesT` | `T1` | `2` | — | Per-block dequantization scale factors of shape `(N, k_blocks)`, with the same dtype as `A`. | required |
|
| 26 |
+
| `zero_points` | `zeroPointsT` | `T3` | `2` | — | Standard unpacked per-block zero points with shape `(N, k_blocks)` and the same dtype as `A`. Omission uses `2^(bits - 1)`. | optional |
|
| 27 |
+
| `bias` | `biasT` | `T1` | `1` | — | Optional bias vector of shape `[N]` added to the output. | optional |
|
| 28 |
+
|
| 29 |
+
## Outputs
|
| 30 |
+
|
| 31 |
+
| Name | Bind key | Logical dtype | Rank | Shape | Description | Presence |
|
| 32 |
+
| --- | --- | --- | --- | --- | --- | --- |
|
| 33 |
+
| `Y` | `yT` | `T1` | same as `A` | derived; see description | Result of A multiplied by the dequantized weight matrix, with optional bias, same dtype and rank as A: the leading axes of A with a trailing N. | required |
|
| 34 |
+
|
| 35 |
+
## Attributes
|
| 36 |
+
|
| 37 |
+
Attributes and default values (overridable per request):
|
| 38 |
+
|
| 39 |
+
| Attribute | Default | Description |
|
| 40 |
+
| --- | --- | --- |
|
| 41 |
+
| `accuracy_level` | `0` | Minimum internal accuracy level: 0 (unset), 1 (float32), 2 (float16), 3 (bfloat16), or 4 (int8). |
|
| 42 |
+
| `bits` | `4` | Bit width used to quantize B; this package supports 2, 4, and 8. |
|
| 43 |
+
| `K` | — | Input feature dimension of the weight matrix. |
|
| 44 |
+
| `N` | — | Output feature dimension of the weight matrix. |
|
| 45 |
+
| `block_size` | — | Power-of-two quantization block size along K; it must be at least 16. |
|
| 46 |
+
|
| 47 |
+
## Type constraints
|
| 48 |
+
|
| 49 |
+
| Variable | Allowed dtypes |
|
| 50 |
+
| --- | --- |
|
| 51 |
+
| `T1` | `float32`, `float16` |
|
| 52 |
+
| `T3` | `float32`, `float16` |
|
| 53 |
+
|
| 54 |
+
## Device requirements
|
| 55 |
+
|
| 56 |
+
Some implementation variants require `subgroup-matrix` and `subgroups`. These are route-specific capabilities, not package-wide requirements; availability also depends on the request shape and dtype.
|
| 57 |
+
|
| 58 |
+
## Files
|
| 59 |
+
|
| 60 |
+
- [`metadata.json`](build/webgpu/metadata.json) — kernel metadata (id, digests, provenance)
|
| 61 |
+
- [`manifest.json`](build/webgpu/manifest.json) — the op contract (source of truth)
|
| 62 |
+
- [`test.json`](build/webgpu/test.json) — correctness cases
|
| 63 |
+
- [`bench.json`](build/webgpu/bench.json) — benchmark + tuning cases
|
| 64 |
+
- [`matmul-nbits-dp4a-quantize.wgsl.jinja`](build/webgpu/matmul-nbits-dp4a-quantize.wgsl.jinja)
|
| 65 |
+
- [`matmul-nbits-gemv-q4.wgsl.jinja`](build/webgpu/matmul-nbits-gemv-q4.wgsl.jinja)
|
| 66 |
+
- [`matmul-nbits-q4-dp4a-prefill.wgsl.jinja`](build/webgpu/matmul-nbits-q4-dp4a-prefill.wgsl.jinja)
|
| 67 |
+
- [`matmul-nbits-q4-prefill-tile4x4.wgsl.jinja`](build/webgpu/matmul-nbits-q4-prefill-tile4x4.wgsl.jinja)
|
| 68 |
+
- [`matmul-nbits-q4-prefill-tiled-reg.wgsl.jinja`](build/webgpu/matmul-nbits-q4-prefill-tiled-reg.wgsl.jinja)
|
| 69 |
+
- [`matmul-nbits-q4-prefill-tiled.wgsl.jinja`](build/webgpu/matmul-nbits-q4-prefill-tiled.wgsl.jinja)
|
| 70 |
+
- [`matmul-nbits-q4-sgmat.wgsl.jinja`](build/webgpu/matmul-nbits-q4-sgmat.wgsl.jinja)
|
| 71 |
+
- [`matmul-nbits.wgsl.jinja`](build/webgpu/matmul-nbits.wgsl.jinja)
|
| 72 |
+
|
| 73 |
+
## Use with `@huggingface/kernels`
|
| 74 |
+
|
| 75 |
+
The loader derives every required output's shape and logical dtype from the manifest contract and this call.
|
| 76 |
+
It then allocates the result tensors automatically.
|
| 77 |
+
|
| 78 |
+
The `version: 1` option selects the published kernel contract; it is independent of any operator opset, contrib `since_version`, or model version.
|
| 79 |
+
|
| 80 |
+
Replace each `*Data` placeholder with a typed array containing the corresponding input data.
|
| 81 |
+
|
| 82 |
+
```js
|
| 83 |
+
import { getKernel } from "@huggingface/kernels";
|
| 84 |
+
|
| 85 |
+
const kernel = await getKernel("webgpu-kernels/com.microsoft.MatMulNBits", { version: 1 });
|
| 86 |
+
const { yT } = await kernel({
|
| 87 |
+
aT: { data: aTData, shape: [2, 17] },
|
| 88 |
+
bT: { data: bTData, shape: [2, 2, 8] },
|
| 89 |
+
scalesT: { data: scalesTData, shape: [2, 2] },
|
| 90 |
+
}, {
|
| 91 |
+
attrs: { K: 17, N: 2, block_size: 16 },
|
| 92 |
+
});
|
| 93 |
+
```
|
build/webgpu/bench.json
ADDED
|
@@ -0,0 +1,823 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"op": "com.microsoft.MatMulNBits",
|
| 3 |
+
"tunableSpace": { "workgroupSize": [64, 128, 256] },
|
| 4 |
+
"cases": [
|
| 5 |
+
{
|
| 6 |
+
"name": "qwen3-qproj-decode-m1-q8g32-zero-bias-gemv",
|
| 7 |
+
"preset": "smoke",
|
| 8 |
+
"vars": { "M": 1, "K": 2560, "N": 4096, "bits": 8, "blockSize": 32 },
|
| 9 |
+
"inputs": {
|
| 10 |
+
"aT": { "shape": [1, 2560], "dtype": "float32", "dist": "normal", "seed": 360, "scale": 0.2 },
|
| 11 |
+
"bT": { "shape": [4096, 80, 32], "dtype": "uint8", "dist": "linearMod", "mod": 256, "step": 7 },
|
| 12 |
+
"scalesT": {
|
| 13 |
+
"shape": [4096, 80],
|
| 14 |
+
"dtype": "float32",
|
| 15 |
+
"dist": "uniform",
|
| 16 |
+
"seed": 362,
|
| 17 |
+
"offset": 0.04,
|
| 18 |
+
"scale": 0.01,
|
| 19 |
+
"signed": false
|
| 20 |
+
},
|
| 21 |
+
"zeroPointsT": {
|
| 22 |
+
"shape": [4096, 80],
|
| 23 |
+
"dtype": "float32",
|
| 24 |
+
"dist": "randint",
|
| 25 |
+
"seed": 363,
|
| 26 |
+
"min": 120,
|
| 27 |
+
"max": 140
|
| 28 |
+
},
|
| 29 |
+
"biasT": { "shape": [4096], "dtype": "float32", "dist": "normal", "seed": 364, "scale": 0.05 }
|
| 30 |
+
},
|
| 31 |
+
"outputs": { "yT": { "shape": [1, 4096], "dtype": "float32" } },
|
| 32 |
+
"bench": {
|
| 33 |
+
"metrics": [
|
| 34 |
+
{
|
| 35 |
+
"type": "bandwidth",
|
| 36 |
+
"value": "numel(shapes.bT) * 4 + numel(shapes.zeroPointsT) * 4 + (numel(shapes.aT) + numel(shapes.scalesT) + numel(shapes.biasT) + numel(shapes.yT)) * 4"
|
| 37 |
+
}
|
| 38 |
+
]
|
| 39 |
+
},
|
| 40 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 8, "block_size": 32 }
|
| 41 |
+
},
|
| 42 |
+
{
|
| 43 |
+
"name": "qwen3-qproj-decode-m1-q8g32-zero-bias-gemv-ncols8",
|
| 44 |
+
"tunables": { "GEMV_N_COLS": 8 },
|
| 45 |
+
"preset": "smoke",
|
| 46 |
+
"vars": { "M": 1, "K": 2560, "N": 4096, "bits": 8, "blockSize": 32 },
|
| 47 |
+
"inputs": {
|
| 48 |
+
"aT": { "shape": [1, 2560], "dtype": "float32", "dist": "normal", "seed": 360, "scale": 0.2 },
|
| 49 |
+
"bT": { "shape": [4096, 80, 32], "dtype": "uint8", "dist": "linearMod", "mod": 256, "step": 7 },
|
| 50 |
+
"scalesT": {
|
| 51 |
+
"shape": [4096, 80],
|
| 52 |
+
"dtype": "float32",
|
| 53 |
+
"dist": "uniform",
|
| 54 |
+
"seed": 362,
|
| 55 |
+
"offset": 0.04,
|
| 56 |
+
"scale": 0.01,
|
| 57 |
+
"signed": false
|
| 58 |
+
},
|
| 59 |
+
"zeroPointsT": {
|
| 60 |
+
"shape": [4096, 80],
|
| 61 |
+
"dtype": "float32",
|
| 62 |
+
"dist": "randint",
|
| 63 |
+
"seed": 363,
|
| 64 |
+
"min": 120,
|
| 65 |
+
"max": 140
|
| 66 |
+
},
|
| 67 |
+
"biasT": { "shape": [4096], "dtype": "float32", "dist": "normal", "seed": 364, "scale": 0.05 }
|
| 68 |
+
},
|
| 69 |
+
"outputs": { "yT": { "shape": [1, 4096], "dtype": "float32" } },
|
| 70 |
+
"bench": {
|
| 71 |
+
"metrics": [
|
| 72 |
+
{
|
| 73 |
+
"type": "bandwidth",
|
| 74 |
+
"value": "numel(shapes.bT) * 4 + numel(shapes.zeroPointsT) * 4 + (numel(shapes.aT) + numel(shapes.scalesT) + numel(shapes.biasT) + numel(shapes.yT)) * 4"
|
| 75 |
+
}
|
| 76 |
+
]
|
| 77 |
+
},
|
| 78 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 8, "block_size": 32 }
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"name": "matmul-nbits-q4-64x128x128",
|
| 82 |
+
"preset": "smoke",
|
| 83 |
+
"vars": { "M": 64, "K": 128, "N": 128, "bits": 4, "blockSize": 32 },
|
| 84 |
+
"inputs": {
|
| 85 |
+
"aT": { "shape": [64, 128], "dtype": "float32", "dist": "normal", "seed": 210, "scale": 0.2 },
|
| 86 |
+
"bT": { "shape": [128, 4, 16], "dtype": "uint8", "dist": "q4pair", "seed": 211 },
|
| 87 |
+
"scalesT": {
|
| 88 |
+
"shape": [128, 4],
|
| 89 |
+
"dtype": "float32",
|
| 90 |
+
"dist": "uniform",
|
| 91 |
+
"seed": 212,
|
| 92 |
+
"offset": 0.04,
|
| 93 |
+
"scale": 0.01,
|
| 94 |
+
"signed": false
|
| 95 |
+
}
|
| 96 |
+
},
|
| 97 |
+
"outputs": { "yT": { "shape": [64, 128], "dtype": "float32" } },
|
| 98 |
+
"bench": { "primary": true, "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 99 |
+
"attrs": { "K": 128, "N": 128, "block_size": 32 }
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"name": "matmul-nbits-q4-zero-bias-64x128x128",
|
| 103 |
+
"preset": "smoke",
|
| 104 |
+
"vars": { "M": 64, "K": 128, "N": 128, "bits": 4, "blockSize": 32 },
|
| 105 |
+
"inputs": {
|
| 106 |
+
"aT": { "shape": [64, 128], "dtype": "float32", "dist": "normal", "seed": 211, "scale": 0.2 },
|
| 107 |
+
"bT": { "shape": [128, 4, 16], "dtype": "uint8", "dist": "q4pair", "seed": 212 },
|
| 108 |
+
"scalesT": {
|
| 109 |
+
"shape": [128, 4],
|
| 110 |
+
"dtype": "float32",
|
| 111 |
+
"dist": "uniform",
|
| 112 |
+
"seed": 213,
|
| 113 |
+
"offset": 0.04,
|
| 114 |
+
"scale": 0.01,
|
| 115 |
+
"signed": false
|
| 116 |
+
},
|
| 117 |
+
"zeroPointsT": { "shape": [128, 4], "dtype": "float32", "dist": "randint", "seed": 214, "min": 6, "max": 10 },
|
| 118 |
+
"biasT": { "shape": [128], "dtype": "float32", "dist": "normal", "seed": 215, "scale": 0.05 }
|
| 119 |
+
},
|
| 120 |
+
"outputs": { "yT": { "shape": [64, 128], "dtype": "float32" } },
|
| 121 |
+
"bench": { "primary": true, "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 122 |
+
"attrs": { "K": 128, "N": 128, "bits": 4, "block_size": 32 }
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
"name": "qwen3-mlp-gate-decode-m1-q4g64",
|
| 126 |
+
"preset": "model",
|
| 127 |
+
"vars": { "M": 1, "K": 2560, "N": 9728, "bits": 4, "blockSize": 64 },
|
| 128 |
+
"inputs": {
|
| 129 |
+
"aT": { "shape": [1, 2560], "dtype": "float32", "dist": "normal", "seed": 350, "scale": 0.2 },
|
| 130 |
+
"bT": { "shape": [9728, 40, 32], "dtype": "uint8", "dist": "q4pair", "seed": 351 },
|
| 131 |
+
"scalesT": {
|
| 132 |
+
"shape": [9728, 40],
|
| 133 |
+
"dtype": "float32",
|
| 134 |
+
"dist": "uniform",
|
| 135 |
+
"seed": 352,
|
| 136 |
+
"offset": 0.04,
|
| 137 |
+
"scale": 0.01,
|
| 138 |
+
"signed": false
|
| 139 |
+
}
|
| 140 |
+
},
|
| 141 |
+
"outputs": { "yT": { "shape": [1, 9728], "dtype": "float32" } },
|
| 142 |
+
"bench": {
|
| 143 |
+
"metrics": [
|
| 144 |
+
{
|
| 145 |
+
"type": "bandwidth",
|
| 146 |
+
"value": "numel(shapes.bT) * 4 + (numel(shapes.aT) + numel(shapes.scalesT) + numel(shapes.yT)) * 4"
|
| 147 |
+
}
|
| 148 |
+
]
|
| 149 |
+
},
|
| 150 |
+
"attrs": { "K": 2560, "N": 9728, "bits": 4, "block_size": 64 }
|
| 151 |
+
},
|
| 152 |
+
{
|
| 153 |
+
"name": "qwen3-qproj-prefill-m512-q4g64",
|
| 154 |
+
"preset": "model",
|
| 155 |
+
"vars": { "M": 512, "K": 2560, "N": 4096, "bits": 4, "blockSize": 64 },
|
| 156 |
+
"inputs": {
|
| 157 |
+
"aT": { "shape": [512, 2560], "dtype": "float32", "dist": "normal", "seed": 353, "scale": 0.2 },
|
| 158 |
+
"bT": { "shape": [4096, 40, 32], "dtype": "uint8", "dist": "q4pair", "seed": 354 },
|
| 159 |
+
"scalesT": {
|
| 160 |
+
"shape": [4096, 40],
|
| 161 |
+
"dtype": "float32",
|
| 162 |
+
"dist": "uniform",
|
| 163 |
+
"seed": 355,
|
| 164 |
+
"offset": 0.04,
|
| 165 |
+
"scale": 0.01,
|
| 166 |
+
"signed": false
|
| 167 |
+
}
|
| 168 |
+
},
|
| 169 |
+
"outputs": { "yT": { "shape": [512, 4096], "dtype": "float32" } },
|
| 170 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 171 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 4, "block_size": 64 }
|
| 172 |
+
},
|
| 173 |
+
{
|
| 174 |
+
"name": "qwen3-qproj-prefill-m512-q4g64-zero-bias",
|
| 175 |
+
"preset": "model",
|
| 176 |
+
"vars": { "M": 512, "K": 2560, "N": 4096, "bits": 4, "blockSize": 64 },
|
| 177 |
+
"inputs": {
|
| 178 |
+
"aT": { "shape": [512, 2560], "dtype": "float32", "dist": "normal", "seed": 359, "scale": 0.2 },
|
| 179 |
+
"bT": { "shape": [4096, 40, 32], "dtype": "uint8", "dist": "q4pair", "seed": 360 },
|
| 180 |
+
"scalesT": {
|
| 181 |
+
"shape": [4096, 40],
|
| 182 |
+
"dtype": "float32",
|
| 183 |
+
"dist": "uniform",
|
| 184 |
+
"seed": 361,
|
| 185 |
+
"offset": 0.04,
|
| 186 |
+
"scale": 0.01,
|
| 187 |
+
"signed": false
|
| 188 |
+
},
|
| 189 |
+
"zeroPointsT": { "shape": [4096, 40], "dtype": "float32", "dist": "randint", "seed": 362, "min": 6, "max": 10 },
|
| 190 |
+
"biasT": { "shape": [4096], "dtype": "float32", "dist": "normal", "seed": 363, "scale": 0.05 }
|
| 191 |
+
},
|
| 192 |
+
"outputs": { "yT": { "shape": [512, 4096], "dtype": "float32" } },
|
| 193 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 194 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 4, "block_size": 64 }
|
| 195 |
+
},
|
| 196 |
+
{
|
| 197 |
+
"name": "llama-qproj-decode-m1-q4g32",
|
| 198 |
+
"preset": "model",
|
| 199 |
+
"vars": { "M": 1, "K": 4096, "N": 4096, "bits": 4, "blockSize": 32 },
|
| 200 |
+
"inputs": {
|
| 201 |
+
"aT": { "shape": [1, 4096], "dtype": "float32", "dist": "normal", "seed": 356, "scale": 0.2 },
|
| 202 |
+
"bT": { "shape": [4096, 128, 16], "dtype": "uint8", "dist": "q4pair", "seed": 357 },
|
| 203 |
+
"scalesT": {
|
| 204 |
+
"shape": [4096, 128],
|
| 205 |
+
"dtype": "float32",
|
| 206 |
+
"dist": "uniform",
|
| 207 |
+
"seed": 358,
|
| 208 |
+
"offset": 0.04,
|
| 209 |
+
"scale": 0.01,
|
| 210 |
+
"signed": false
|
| 211 |
+
}
|
| 212 |
+
},
|
| 213 |
+
"outputs": { "yT": { "shape": [1, 4096], "dtype": "float32" } },
|
| 214 |
+
"bench": {
|
| 215 |
+
"metrics": [
|
| 216 |
+
{
|
| 217 |
+
"type": "bandwidth",
|
| 218 |
+
"value": "numel(shapes.bT) * 4 + (numel(shapes.aT) + numel(shapes.scalesT) + numel(shapes.yT)) * 4"
|
| 219 |
+
}
|
| 220 |
+
]
|
| 221 |
+
},
|
| 222 |
+
"attrs": { "K": 4096, "N": 4096, "bits": 4, "block_size": 32 }
|
| 223 |
+
},
|
| 224 |
+
{
|
| 225 |
+
"name": "qwen3-qproj-decode-m1-q8g32",
|
| 226 |
+
"preset": "model",
|
| 227 |
+
"vars": { "M": 1, "K": 2560, "N": 4096, "bits": 8, "blockSize": 32 },
|
| 228 |
+
"inputs": {
|
| 229 |
+
"aT": { "shape": [1, 2560], "dtype": "float32", "dist": "normal", "seed": 350, "scale": 0.2 },
|
| 230 |
+
"bT": { "shape": [4096, 80, 32], "dtype": "uint8", "dist": "linearMod", "mod": 256, "step": 7 },
|
| 231 |
+
"scalesT": {
|
| 232 |
+
"shape": [4096, 80],
|
| 233 |
+
"dtype": "float32",
|
| 234 |
+
"dist": "uniform",
|
| 235 |
+
"seed": 352,
|
| 236 |
+
"offset": 0.04,
|
| 237 |
+
"scale": 0.01,
|
| 238 |
+
"signed": false
|
| 239 |
+
}
|
| 240 |
+
},
|
| 241 |
+
"outputs": { "yT": { "shape": [1, 4096], "dtype": "float32" } },
|
| 242 |
+
"bench": {
|
| 243 |
+
"metrics": [
|
| 244 |
+
{
|
| 245 |
+
"type": "bandwidth",
|
| 246 |
+
"value": "numel(shapes.bT) * 4 + (numel(shapes.aT) + numel(shapes.scalesT) + numel(shapes.yT)) * 4"
|
| 247 |
+
}
|
| 248 |
+
]
|
| 249 |
+
},
|
| 250 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 8, "block_size": 32 }
|
| 251 |
+
},
|
| 252 |
+
{
|
| 253 |
+
"name": "qwen3-qproj-prefill-m512-q8g32",
|
| 254 |
+
"preset": "model",
|
| 255 |
+
"vars": { "M": 512, "K": 2560, "N": 4096, "bits": 8, "blockSize": 32 },
|
| 256 |
+
"inputs": {
|
| 257 |
+
"aT": { "shape": [512, 2560], "dtype": "float32", "dist": "normal", "seed": 350, "scale": 0.2 },
|
| 258 |
+
"bT": { "shape": [4096, 80, 32], "dtype": "uint8", "dist": "linearMod", "mod": 256, "step": 7 },
|
| 259 |
+
"scalesT": {
|
| 260 |
+
"shape": [4096, 80],
|
| 261 |
+
"dtype": "float32",
|
| 262 |
+
"dist": "uniform",
|
| 263 |
+
"seed": 352,
|
| 264 |
+
"offset": 0.04,
|
| 265 |
+
"scale": 0.01,
|
| 266 |
+
"signed": false
|
| 267 |
+
}
|
| 268 |
+
},
|
| 269 |
+
"outputs": { "yT": { "shape": [512, 4096], "dtype": "float32" } },
|
| 270 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 271 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 8, "block_size": 32 }
|
| 272 |
+
},
|
| 273 |
+
{
|
| 274 |
+
"name": "qwen3-prefill-m512-q8g32-unaligned-n2052",
|
| 275 |
+
"preset": "edge",
|
| 276 |
+
"vars": { "M": 512, "K": 2560, "N": 2052, "bits": 8, "blockSize": 32 },
|
| 277 |
+
"inputs": {
|
| 278 |
+
"aT": { "shape": [512, 2560], "dtype": "float32", "dist": "normal", "seed": 350, "scale": 0.2 },
|
| 279 |
+
"bT": { "shape": [2052, 80, 32], "dtype": "uint8", "dist": "linearMod", "mod": 256, "step": 7 },
|
| 280 |
+
"scalesT": {
|
| 281 |
+
"shape": [2052, 80],
|
| 282 |
+
"dtype": "float32",
|
| 283 |
+
"dist": "uniform",
|
| 284 |
+
"seed": 352,
|
| 285 |
+
"offset": 0.04,
|
| 286 |
+
"scale": 0.01,
|
| 287 |
+
"signed": false
|
| 288 |
+
}
|
| 289 |
+
},
|
| 290 |
+
"outputs": { "yT": { "shape": [512, 2052], "dtype": "float32" } },
|
| 291 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 292 |
+
"attrs": { "K": 2560, "N": 2052, "bits": 8, "block_size": 32 }
|
| 293 |
+
},
|
| 294 |
+
{
|
| 295 |
+
"name": "qwen3-qproj-prefill-m512-q4g32-f16",
|
| 296 |
+
"preset": "model",
|
| 297 |
+
"vars": { "M": 512, "K": 2560, "N": 4096, "bits": 4, "blockSize": 32 },
|
| 298 |
+
"inputs": {
|
| 299 |
+
"aT": { "shape": [512, 2560], "dtype": "float16", "dist": "normal", "seed": 350, "scale": 0.2 },
|
| 300 |
+
"bT": { "shape": [4096, 80, 16], "dtype": "uint8", "dist": "q4pair", "seed": 351 },
|
| 301 |
+
"scalesT": {
|
| 302 |
+
"shape": [4096, 80],
|
| 303 |
+
"dtype": "float16",
|
| 304 |
+
"dist": "uniform",
|
| 305 |
+
"seed": 352,
|
| 306 |
+
"offset": 0.04,
|
| 307 |
+
"scale": 0.01,
|
| 308 |
+
"signed": false
|
| 309 |
+
}
|
| 310 |
+
},
|
| 311 |
+
"outputs": { "yT": { "shape": [512, 4096], "dtype": "float16" } },
|
| 312 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 313 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 4, "block_size": 32 }
|
| 314 |
+
},
|
| 315 |
+
{
|
| 316 |
+
"name": "qwen3-mlp-gate-decode-m1-q4g64-zero-bias-generic",
|
| 317 |
+
"preset": "smoke",
|
| 318 |
+
"vars": { "M": 1, "K": 2560, "N": 9728, "bits": 4, "blockSize": 64 },
|
| 319 |
+
"inputs": {
|
| 320 |
+
"aT": { "shape": [1, 2560], "dtype": "float32", "dist": "normal", "seed": 410, "scale": 0.2 },
|
| 321 |
+
"bT": { "shape": [9728, 40, 32], "dtype": "uint8", "dist": "q4pair", "seed": 411 },
|
| 322 |
+
"scalesT": {
|
| 323 |
+
"shape": [9728, 40],
|
| 324 |
+
"dtype": "float32",
|
| 325 |
+
"dist": "uniform",
|
| 326 |
+
"seed": 412,
|
| 327 |
+
"offset": 0.04,
|
| 328 |
+
"scale": 0.01,
|
| 329 |
+
"signed": false
|
| 330 |
+
},
|
| 331 |
+
"zeroPointsT": { "shape": [9728, 40], "dtype": "float32", "dist": "randint", "seed": 413, "min": 6, "max": 10 },
|
| 332 |
+
"biasT": { "shape": [9728], "dtype": "float32", "dist": "normal", "seed": 414, "scale": 0.05 }
|
| 333 |
+
},
|
| 334 |
+
"outputs": { "yT": { "shape": [1, 9728], "dtype": "float32" } },
|
| 335 |
+
"bench": {
|
| 336 |
+
"metrics": [
|
| 337 |
+
{
|
| 338 |
+
"type": "bandwidth",
|
| 339 |
+
"value": "numel(shapes.bT) * 4 + numel(shapes.zeroPointsT) * 4 + (numel(shapes.aT) + numel(shapes.scalesT) + numel(shapes.biasT) + numel(shapes.yT)) * 4"
|
| 340 |
+
}
|
| 341 |
+
]
|
| 342 |
+
},
|
| 343 |
+
"attrs": { "K": 2560, "N": 9728, "bits": 4, "block_size": 64 }
|
| 344 |
+
},
|
| 345 |
+
{
|
| 346 |
+
"name": "qwen3-qproj-prefill-m8-q4g64-zero-bias-floor-generic",
|
| 347 |
+
"preset": "smoke",
|
| 348 |
+
"vars": { "M": 8, "K": 2560, "N": 4096, "bits": 4, "blockSize": 64 },
|
| 349 |
+
"inputs": {
|
| 350 |
+
"aT": { "shape": [8, 2560], "dtype": "float32", "dist": "normal", "seed": 420, "scale": 0.2 },
|
| 351 |
+
"bT": { "shape": [4096, 40, 32], "dtype": "uint8", "dist": "q4pair", "seed": 421 },
|
| 352 |
+
"scalesT": {
|
| 353 |
+
"shape": [4096, 40],
|
| 354 |
+
"dtype": "float32",
|
| 355 |
+
"dist": "uniform",
|
| 356 |
+
"seed": 422,
|
| 357 |
+
"offset": 0.04,
|
| 358 |
+
"scale": 0.01,
|
| 359 |
+
"signed": false
|
| 360 |
+
},
|
| 361 |
+
"zeroPointsT": { "shape": [4096, 40], "dtype": "float32", "dist": "randint", "seed": 423, "min": 6, "max": 10 },
|
| 362 |
+
"biasT": { "shape": [4096], "dtype": "float32", "dist": "normal", "seed": 424, "scale": 0.05 }
|
| 363 |
+
},
|
| 364 |
+
"outputs": { "yT": { "shape": [8, 4096], "dtype": "float32" } },
|
| 365 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 366 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 4, "block_size": 64 }
|
| 367 |
+
},
|
| 368 |
+
{
|
| 369 |
+
"name": "qwen3-qproj-prefill-m8-q4g64-default-zero-tile4x4",
|
| 370 |
+
"preset": "smoke",
|
| 371 |
+
"vars": { "M": 8, "K": 2560, "N": 4096, "bits": 4, "blockSize": 64 },
|
| 372 |
+
"inputs": {
|
| 373 |
+
"aT": { "shape": [8, 2560], "dtype": "float32", "dist": "normal", "seed": 420, "scale": 0.2 },
|
| 374 |
+
"bT": { "shape": [4096, 40, 32], "dtype": "uint8", "dist": "q4pair", "seed": 421 },
|
| 375 |
+
"scalesT": {
|
| 376 |
+
"shape": [4096, 40],
|
| 377 |
+
"dtype": "float32",
|
| 378 |
+
"dist": "uniform",
|
| 379 |
+
"seed": 422,
|
| 380 |
+
"offset": 0.04,
|
| 381 |
+
"scale": 0.01,
|
| 382 |
+
"signed": false
|
| 383 |
+
}
|
| 384 |
+
},
|
| 385 |
+
"outputs": { "yT": { "shape": [8, 4096], "dtype": "float32" } },
|
| 386 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 387 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 4, "block_size": 64 }
|
| 388 |
+
},
|
| 389 |
+
{
|
| 390 |
+
"name": "qwen3-qproj-prefill-m32-q4g64-default-zero",
|
| 391 |
+
"preset": "model",
|
| 392 |
+
"vars": { "M": 32, "K": 2560, "N": 4096, "bits": 4, "blockSize": 64 },
|
| 393 |
+
"inputs": {
|
| 394 |
+
"aT": { "shape": [32, 2560], "dtype": "float32", "dist": "normal", "seed": 430, "scale": 0.2 },
|
| 395 |
+
"bT": { "shape": [4096, 40, 32], "dtype": "uint8", "dist": "q4pair", "seed": 431 },
|
| 396 |
+
"scalesT": {
|
| 397 |
+
"shape": [4096, 40],
|
| 398 |
+
"dtype": "float32",
|
| 399 |
+
"dist": "uniform",
|
| 400 |
+
"seed": 432,
|
| 401 |
+
"offset": 0.04,
|
| 402 |
+
"scale": 0.01,
|
| 403 |
+
"signed": false
|
| 404 |
+
}
|
| 405 |
+
},
|
| 406 |
+
"outputs": { "yT": { "shape": [32, 4096], "dtype": "float32" } },
|
| 407 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 408 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 4, "block_size": 64 }
|
| 409 |
+
},
|
| 410 |
+
{
|
| 411 |
+
"name": "qwen3-qproj-prefill-m64-q4g64-default-zero",
|
| 412 |
+
"preset": "model",
|
| 413 |
+
"vars": { "M": 64, "K": 2560, "N": 4096, "bits": 4, "blockSize": 64 },
|
| 414 |
+
"inputs": {
|
| 415 |
+
"aT": { "shape": [64, 2560], "dtype": "float32", "dist": "normal", "seed": 440, "scale": 0.2 },
|
| 416 |
+
"bT": { "shape": [4096, 40, 32], "dtype": "uint8", "dist": "q4pair", "seed": 441 },
|
| 417 |
+
"scalesT": {
|
| 418 |
+
"shape": [4096, 40],
|
| 419 |
+
"dtype": "float32",
|
| 420 |
+
"dist": "uniform",
|
| 421 |
+
"seed": 442,
|
| 422 |
+
"offset": 0.04,
|
| 423 |
+
"scale": 0.01,
|
| 424 |
+
"signed": false
|
| 425 |
+
}
|
| 426 |
+
},
|
| 427 |
+
"outputs": { "yT": { "shape": [64, 4096], "dtype": "float32" } },
|
| 428 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 429 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 4, "block_size": 64 }
|
| 430 |
+
},
|
| 431 |
+
{
|
| 432 |
+
"name": "qwen3-qproj-prefill-m128-q4g64-default-zero",
|
| 433 |
+
"preset": "model",
|
| 434 |
+
"vars": { "M": 128, "K": 2560, "N": 4096, "bits": 4, "blockSize": 64 },
|
| 435 |
+
"inputs": {
|
| 436 |
+
"aT": { "shape": [128, 2560], "dtype": "float32", "dist": "normal", "seed": 450, "scale": 0.2 },
|
| 437 |
+
"bT": { "shape": [4096, 40, 32], "dtype": "uint8", "dist": "q4pair", "seed": 451 },
|
| 438 |
+
"scalesT": {
|
| 439 |
+
"shape": [4096, 40],
|
| 440 |
+
"dtype": "float32",
|
| 441 |
+
"dist": "uniform",
|
| 442 |
+
"seed": 452,
|
| 443 |
+
"offset": 0.04,
|
| 444 |
+
"scale": 0.01,
|
| 445 |
+
"signed": false
|
| 446 |
+
}
|
| 447 |
+
},
|
| 448 |
+
"outputs": { "yT": { "shape": [128, 4096], "dtype": "float32" } },
|
| 449 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 450 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 4, "block_size": 64 }
|
| 451 |
+
},
|
| 452 |
+
{
|
| 453 |
+
"name": "qwen3-qproj-decode-m1-q4g32-f16-gemv",
|
| 454 |
+
"preset": "smoke",
|
| 455 |
+
"vars": { "M": 1, "K": 4096, "N": 4096, "bits": 4, "blockSize": 32 },
|
| 456 |
+
"inputs": {
|
| 457 |
+
"aT": { "shape": [1, 4096], "dtype": "float16", "dist": "normal", "seed": 430, "scale": 0.2 },
|
| 458 |
+
"bT": { "shape": [4096, 128, 16], "dtype": "uint8", "dist": "q4pair", "seed": 431 },
|
| 459 |
+
"scalesT": {
|
| 460 |
+
"shape": [4096, 128],
|
| 461 |
+
"dtype": "float16",
|
| 462 |
+
"dist": "uniform",
|
| 463 |
+
"seed": 432,
|
| 464 |
+
"offset": 0.04,
|
| 465 |
+
"scale": 0.01,
|
| 466 |
+
"signed": false
|
| 467 |
+
}
|
| 468 |
+
},
|
| 469 |
+
"outputs": { "yT": { "shape": [1, 4096], "dtype": "float16" } },
|
| 470 |
+
"bench": {
|
| 471 |
+
"metrics": [
|
| 472 |
+
{
|
| 473 |
+
"type": "bandwidth",
|
| 474 |
+
"value": "numel(shapes.bT) * 4 + (numel(shapes.aT) + numel(shapes.scalesT) + numel(shapes.yT)) * 2"
|
| 475 |
+
}
|
| 476 |
+
]
|
| 477 |
+
},
|
| 478 |
+
"attrs": { "K": 4096, "N": 4096, "bits": 4, "block_size": 32 }
|
| 479 |
+
},
|
| 480 |
+
{
|
| 481 |
+
"name": "qwen3-qproj-decode-m1-q4g32-f16-gemv-ncols8",
|
| 482 |
+
"tunables": { "GEMV_N_COLS": 8 },
|
| 483 |
+
"preset": "smoke",
|
| 484 |
+
"vars": { "M": 1, "K": 4096, "N": 4096, "bits": 4, "blockSize": 32 },
|
| 485 |
+
"inputs": {
|
| 486 |
+
"aT": { "shape": [1, 4096], "dtype": "float16", "dist": "normal", "seed": 430, "scale": 0.2 },
|
| 487 |
+
"bT": { "shape": [4096, 128, 16], "dtype": "uint8", "dist": "q4pair", "seed": 431 },
|
| 488 |
+
"scalesT": {
|
| 489 |
+
"shape": [4096, 128],
|
| 490 |
+
"dtype": "float16",
|
| 491 |
+
"dist": "uniform",
|
| 492 |
+
"seed": 432,
|
| 493 |
+
"offset": 0.04,
|
| 494 |
+
"scale": 0.01,
|
| 495 |
+
"signed": false
|
| 496 |
+
}
|
| 497 |
+
},
|
| 498 |
+
"outputs": { "yT": { "shape": [1, 4096], "dtype": "float16" } },
|
| 499 |
+
"bench": {
|
| 500 |
+
"metrics": [
|
| 501 |
+
{
|
| 502 |
+
"type": "bandwidth",
|
| 503 |
+
"value": "numel(shapes.bT) * 4 + (numel(shapes.aT) + numel(shapes.scalesT) + numel(shapes.yT)) * 2"
|
| 504 |
+
}
|
| 505 |
+
]
|
| 506 |
+
},
|
| 507 |
+
"attrs": { "K": 4096, "N": 4096, "bits": 4, "block_size": 32 }
|
| 508 |
+
},
|
| 509 |
+
{
|
| 510 |
+
"name": "matmul-nbits-q4-naive-fallback-tailK-m32-k2561-n4096",
|
| 511 |
+
"preset": "stress",
|
| 512 |
+
"vars": { "M": 32, "K": 2561, "N": 4096, "bits": 4, "blockSize": 32 },
|
| 513 |
+
"inputs": {
|
| 514 |
+
"aT": { "shape": [32, 2561], "dtype": "float32", "dist": "normal", "seed": 610, "scale": 0.2 },
|
| 515 |
+
"bT": { "shape": [4096, 81, 16], "dtype": "uint8", "dist": "q4pair", "seed": 611 },
|
| 516 |
+
"scalesT": {
|
| 517 |
+
"shape": [4096, 81],
|
| 518 |
+
"dtype": "float32",
|
| 519 |
+
"dist": "uniform",
|
| 520 |
+
"seed": 612,
|
| 521 |
+
"offset": 0.04,
|
| 522 |
+
"scale": 0.01,
|
| 523 |
+
"signed": false
|
| 524 |
+
}
|
| 525 |
+
},
|
| 526 |
+
"outputs": { "yT": { "shape": [32, 4096], "dtype": "float32" } },
|
| 527 |
+
"bench": { "primary": true, "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 528 |
+
"attrs": { "K": 2561, "N": 4096, "bits": 4, "block_size": 32 }
|
| 529 |
+
},
|
| 530 |
+
{
|
| 531 |
+
"name": "matmul-nbits-q8-naive-fallback-tailK-m48-k2561-n1021",
|
| 532 |
+
"preset": "stress",
|
| 533 |
+
"vars": { "M": 48, "K": 2561, "N": 1021, "bits": 8, "blockSize": 32 },
|
| 534 |
+
"inputs": {
|
| 535 |
+
"aT": { "shape": [48, 2561], "dtype": "float32", "dist": "normal", "seed": 620, "scale": 0.2 },
|
| 536 |
+
"bT": { "shape": [1021, 81, 32], "dtype": "uint8", "dist": "linearMod", "mod": 256, "step": 7 },
|
| 537 |
+
"scalesT": {
|
| 538 |
+
"shape": [1021, 81],
|
| 539 |
+
"dtype": "float32",
|
| 540 |
+
"dist": "uniform",
|
| 541 |
+
"seed": 622,
|
| 542 |
+
"offset": 0.04,
|
| 543 |
+
"scale": 0.01,
|
| 544 |
+
"signed": false
|
| 545 |
+
}
|
| 546 |
+
},
|
| 547 |
+
"outputs": { "yT": { "shape": [48, 1021], "dtype": "float32" } },
|
| 548 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 549 |
+
"attrs": { "K": 2561, "N": 1021, "bits": 8, "block_size": 32 }
|
| 550 |
+
},
|
| 551 |
+
{
|
| 552 |
+
"name": "matmul-nbits-q8-oddN-compact-fallback-m8-k64-n17",
|
| 553 |
+
"preset": "smoke",
|
| 554 |
+
"vars": { "M": 8, "K": 64, "N": 17, "bits": 8, "blockSize": 32 },
|
| 555 |
+
"inputs": {
|
| 556 |
+
"aT": { "shape": [8, 64], "dtype": "float32", "dist": "normal", "seed": 630, "scale": 0.2 },
|
| 557 |
+
"bT": { "shape": [17, 2, 32], "dtype": "uint8", "dist": "linearMod", "mod": 256, "step": 7 },
|
| 558 |
+
"scalesT": {
|
| 559 |
+
"shape": [17, 2],
|
| 560 |
+
"dtype": "float32",
|
| 561 |
+
"dist": "uniform",
|
| 562 |
+
"seed": 632,
|
| 563 |
+
"offset": 0.04,
|
| 564 |
+
"scale": 0.01,
|
| 565 |
+
"signed": false
|
| 566 |
+
}
|
| 567 |
+
},
|
| 568 |
+
"outputs": { "yT": { "shape": [8, 17], "dtype": "float32" } },
|
| 569 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 570 |
+
"attrs": { "K": 64, "N": 17, "bits": 8, "block_size": 32 }
|
| 571 |
+
},
|
| 572 |
+
{
|
| 573 |
+
"name": "rfdetr-qkvo-m1300-q4g64",
|
| 574 |
+
"preset": "smoke",
|
| 575 |
+
"vars": { "M": 1300, "K": 384, "N": 384, "bits": 4, "blockSize": 64 },
|
| 576 |
+
"inputs": {
|
| 577 |
+
"aT": { "shape": [1300, 384], "dtype": "float32", "dist": "normal", "seed": 353, "scale": 0.2 },
|
| 578 |
+
"bT": { "shape": [384, 6, 32], "dtype": "uint8", "dist": "q4pair", "seed": 354 },
|
| 579 |
+
"scalesT": {
|
| 580 |
+
"shape": [384, 6],
|
| 581 |
+
"dtype": "float32",
|
| 582 |
+
"dist": "uniform",
|
| 583 |
+
"seed": 355,
|
| 584 |
+
"offset": 0.04,
|
| 585 |
+
"scale": 0.01,
|
| 586 |
+
"signed": false
|
| 587 |
+
}
|
| 588 |
+
},
|
| 589 |
+
"outputs": { "yT": { "shape": [1300, 384], "dtype": "float32" } },
|
| 590 |
+
"tunableSpace": { "REGISTER_TILE_TALL_MIN_N": [256, 1024] },
|
| 591 |
+
"bench": { "primary": true, "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 592 |
+
"attrs": { "K": 384, "N": 384, "bits": 4, "block_size": 64 }
|
| 593 |
+
},
|
| 594 |
+
{
|
| 595 |
+
"name": "rfdetr-fc1-m1300-q4g64",
|
| 596 |
+
"preset": "smoke",
|
| 597 |
+
"vars": { "M": 1300, "K": 384, "N": 1536, "bits": 4, "blockSize": 64 },
|
| 598 |
+
"inputs": {
|
| 599 |
+
"aT": { "shape": [1300, 384], "dtype": "float32", "dist": "normal", "seed": 353, "scale": 0.2 },
|
| 600 |
+
"bT": { "shape": [1536, 6, 32], "dtype": "uint8", "dist": "q4pair", "seed": 354 },
|
| 601 |
+
"scalesT": {
|
| 602 |
+
"shape": [1536, 6],
|
| 603 |
+
"dtype": "float32",
|
| 604 |
+
"dist": "uniform",
|
| 605 |
+
"seed": 355,
|
| 606 |
+
"offset": 0.04,
|
| 607 |
+
"scale": 0.01,
|
| 608 |
+
"signed": false
|
| 609 |
+
}
|
| 610 |
+
},
|
| 611 |
+
"outputs": { "yT": { "shape": [1300, 1536], "dtype": "float32" } },
|
| 612 |
+
"bench": { "primary": true, "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 613 |
+
"attrs": { "K": 384, "N": 1536, "bits": 4, "block_size": 64 }
|
| 614 |
+
},
|
| 615 |
+
{
|
| 616 |
+
"name": "rfdetr-fc2-m1300-q4g64",
|
| 617 |
+
"preset": "smoke",
|
| 618 |
+
"vars": { "M": 1300, "K": 1536, "N": 384, "bits": 4, "blockSize": 64 },
|
| 619 |
+
"inputs": {
|
| 620 |
+
"aT": { "shape": [1300, 1536], "dtype": "float32", "dist": "normal", "seed": 353, "scale": 0.2 },
|
| 621 |
+
"bT": { "shape": [384, 24, 32], "dtype": "uint8", "dist": "q4pair", "seed": 354 },
|
| 622 |
+
"scalesT": {
|
| 623 |
+
"shape": [384, 24],
|
| 624 |
+
"dtype": "float32",
|
| 625 |
+
"dist": "uniform",
|
| 626 |
+
"seed": 355,
|
| 627 |
+
"offset": 0.04,
|
| 628 |
+
"scale": 0.01,
|
| 629 |
+
"signed": false
|
| 630 |
+
}
|
| 631 |
+
},
|
| 632 |
+
"outputs": { "yT": { "shape": [1300, 384], "dtype": "float32" } },
|
| 633 |
+
"tunableSpace": { "REGISTER_TILE_TALL_MIN_N": [256, 1024] },
|
| 634 |
+
"bench": { "primary": true, "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 635 |
+
"attrs": { "K": 1536, "N": 384, "bits": 4, "block_size": 64 }
|
| 636 |
+
},
|
| 637 |
+
{
|
| 638 |
+
"name": "qwen3-qproj-decode-m1-q8g32-zero-only-gemv",
|
| 639 |
+
"preset": "smoke",
|
| 640 |
+
"vars": { "M": 1, "K": 2560, "N": 4096, "bits": 8, "blockSize": 32 },
|
| 641 |
+
"inputs": {
|
| 642 |
+
"aT": { "shape": [1, 2560], "dtype": "float32", "dist": "normal", "seed": 360, "scale": 0.2 },
|
| 643 |
+
"bT": { "shape": [4096, 80, 32], "dtype": "uint8", "dist": "linearMod", "mod": 256, "step": 7 },
|
| 644 |
+
"scalesT": {
|
| 645 |
+
"shape": [4096, 80],
|
| 646 |
+
"dtype": "float32",
|
| 647 |
+
"dist": "uniform",
|
| 648 |
+
"seed": 362,
|
| 649 |
+
"offset": 0.04,
|
| 650 |
+
"scale": 0.01,
|
| 651 |
+
"signed": false
|
| 652 |
+
},
|
| 653 |
+
"zeroPointsT": {
|
| 654 |
+
"shape": [4096, 80],
|
| 655 |
+
"dtype": "float32",
|
| 656 |
+
"dist": "randint",
|
| 657 |
+
"seed": 363,
|
| 658 |
+
"min": 120,
|
| 659 |
+
"max": 140
|
| 660 |
+
}
|
| 661 |
+
},
|
| 662 |
+
"outputs": { "yT": { "shape": [1, 4096], "dtype": "float32" } },
|
| 663 |
+
"bench": {
|
| 664 |
+
"metrics": [
|
| 665 |
+
{
|
| 666 |
+
"type": "bandwidth",
|
| 667 |
+
"value": "numel(shapes.bT) * 4 + numel(shapes.zeroPointsT) * 4 + (numel(shapes.aT) + numel(shapes.scalesT) + numel(shapes.yT)) * 4"
|
| 668 |
+
}
|
| 669 |
+
]
|
| 670 |
+
},
|
| 671 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 8, "block_size": 32 }
|
| 672 |
+
},
|
| 673 |
+
{
|
| 674 |
+
"name": "qwen3-qproj-prefill-m512-q4g64-zero-only",
|
| 675 |
+
"preset": "model",
|
| 676 |
+
"vars": { "M": 512, "K": 2560, "N": 4096, "bits": 4, "blockSize": 64 },
|
| 677 |
+
"inputs": {
|
| 678 |
+
"aT": { "shape": [512, 2560], "dtype": "float32", "dist": "normal", "seed": 359, "scale": 0.2 },
|
| 679 |
+
"bT": { "shape": [4096, 40, 32], "dtype": "uint8", "dist": "q4pair", "seed": 360 },
|
| 680 |
+
"scalesT": {
|
| 681 |
+
"shape": [4096, 40],
|
| 682 |
+
"dtype": "float32",
|
| 683 |
+
"dist": "uniform",
|
| 684 |
+
"seed": 361,
|
| 685 |
+
"offset": 0.04,
|
| 686 |
+
"scale": 0.01,
|
| 687 |
+
"signed": false
|
| 688 |
+
},
|
| 689 |
+
"zeroPointsT": { "shape": [4096, 40], "dtype": "float32", "dist": "randint", "seed": 362, "min": 6, "max": 10 }
|
| 690 |
+
},
|
| 691 |
+
"outputs": { "yT": { "shape": [512, 4096], "dtype": "float32" } },
|
| 692 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 693 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 4, "block_size": 64 }
|
| 694 |
+
},
|
| 695 |
+
{
|
| 696 |
+
"name": "qwen3-qproj-prefill-m512-q4g64-al4-dp4a",
|
| 697 |
+
"preset": "model",
|
| 698 |
+
"vars": { "M": 512, "K": 2560, "N": 4096, "bits": 4, "blockSize": 64, "accuracyLevel": 4 },
|
| 699 |
+
"inputs": {
|
| 700 |
+
"aT": { "shape": [512, 2560], "dtype": "float32", "dist": "normal", "seed": 353, "scale": 0.2 },
|
| 701 |
+
"bT": { "shape": [4096, 40, 32], "dtype": "uint8", "dist": "q4pair", "seed": 354 },
|
| 702 |
+
"scalesT": {
|
| 703 |
+
"shape": [4096, 40],
|
| 704 |
+
"dtype": "float32",
|
| 705 |
+
"dist": "uniform",
|
| 706 |
+
"seed": 355,
|
| 707 |
+
"offset": 0.04,
|
| 708 |
+
"scale": 0.01,
|
| 709 |
+
"signed": false
|
| 710 |
+
}
|
| 711 |
+
},
|
| 712 |
+
"outputs": { "yT": { "shape": [512, 4096], "dtype": "float32" } },
|
| 713 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 714 |
+
"attrs": { "K": 2560, "N": 4096, "bits": 4, "block_size": 64, "accuracy_level": 4 }
|
| 715 |
+
},
|
| 716 |
+
{
|
| 717 |
+
"name": "mmnb-q4-dp4a-prefill-smoke-m128-k1024-n1024-al4",
|
| 718 |
+
"preset": "smoke",
|
| 719 |
+
"vars": { "M": 128, "K": 1024, "N": 1024, "bits": 4, "blockSize": 32, "accuracyLevel": 4 },
|
| 720 |
+
"inputs": {
|
| 721 |
+
"aT": { "shape": [128, 1024], "dtype": "float32", "dist": "normal", "seed": 353, "scale": 0.2 },
|
| 722 |
+
"bT": { "shape": [1024, 32, 16], "dtype": "uint8", "dist": "q4pair", "seed": 354 },
|
| 723 |
+
"scalesT": {
|
| 724 |
+
"shape": [1024, 32],
|
| 725 |
+
"dtype": "float32",
|
| 726 |
+
"dist": "uniform",
|
| 727 |
+
"seed": 355,
|
| 728 |
+
"offset": 0.04,
|
| 729 |
+
"scale": 0.01,
|
| 730 |
+
"signed": false
|
| 731 |
+
}
|
| 732 |
+
},
|
| 733 |
+
"outputs": { "yT": { "shape": [128, 1024], "dtype": "float32" } },
|
| 734 |
+
"bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] },
|
| 735 |
+
"attrs": { "K": 1024, "N": 1024, "bits": 4, "block_size": 32, "accuracy_level": 4 }
|
| 736 |
+
},
|
| 737 |
+
{
|
| 738 |
+
"name": "gemma-lmhead-decode-m1-q4g32-n262144-gemv-fold",
|
| 739 |
+
"preset": "smoke",
|
| 740 |
+
"vars": { "M": 1, "K": 128, "N": 262144, "bits": 4, "blockSize": 32 },
|
| 741 |
+
"inputs": {
|
| 742 |
+
"aT": { "shape": [1, 128], "dtype": "float32", "dist": "normal", "seed": 470, "scale": 0.2 },
|
| 743 |
+
"bT": { "shape": [262144, 4, 16], "dtype": "uint8", "dist": "linearMod", "mod": 256, "step": 7 },
|
| 744 |
+
"scalesT": {
|
| 745 |
+
"shape": [262144, 4],
|
| 746 |
+
"dtype": "float32",
|
| 747 |
+
"dist": "uniform",
|
| 748 |
+
"seed": 472,
|
| 749 |
+
"offset": 0.04,
|
| 750 |
+
"scale": 0.01,
|
| 751 |
+
"signed": false
|
| 752 |
+
}
|
| 753 |
+
},
|
| 754 |
+
"outputs": { "yT": { "shape": [1, 262144], "dtype": "float32" } },
|
| 755 |
+
"bench": {
|
| 756 |
+
"metrics": [
|
| 757 |
+
{
|
| 758 |
+
"type": "bandwidth",
|
| 759 |
+
"value": "numel(shapes.bT) * 4 + (numel(shapes.aT) + numel(shapes.scalesT) + numel(shapes.yT)) * 4"
|
| 760 |
+
}
|
| 761 |
+
]
|
| 762 |
+
},
|
| 763 |
+
"attrs": { "K": 128, "N": 262144, "bits": 4, "block_size": 32 }
|
| 764 |
+
},
|
| 765 |
+
{
|
| 766 |
+
"name": "gemma-lmhead-decode-m1-q4g32-n262144-gemv-fold-ncols8",
|
| 767 |
+
"tunables": { "GEMV_N_COLS": 8 },
|
| 768 |
+
"preset": "smoke",
|
| 769 |
+
"vars": { "M": 1, "K": 128, "N": 262144, "bits": 4, "blockSize": 32 },
|
| 770 |
+
"inputs": {
|
| 771 |
+
"aT": { "shape": [1, 128], "dtype": "float32", "dist": "normal", "seed": 470, "scale": 0.2 },
|
| 772 |
+
"bT": { "shape": [262144, 4, 16], "dtype": "uint8", "dist": "linearMod", "mod": 256, "step": 7 },
|
| 773 |
+
"scalesT": {
|
| 774 |
+
"shape": [262144, 4],
|
| 775 |
+
"dtype": "float32",
|
| 776 |
+
"dist": "uniform",
|
| 777 |
+
"seed": 472,
|
| 778 |
+
"offset": 0.04,
|
| 779 |
+
"scale": 0.01,
|
| 780 |
+
"signed": false
|
| 781 |
+
}
|
| 782 |
+
},
|
| 783 |
+
"outputs": { "yT": { "shape": [1, 262144], "dtype": "float32" } },
|
| 784 |
+
"bench": {
|
| 785 |
+
"metrics": [
|
| 786 |
+
{
|
| 787 |
+
"type": "bandwidth",
|
| 788 |
+
"value": "numel(shapes.bT) * 4 + (numel(shapes.aT) + numel(shapes.scalesT) + numel(shapes.yT)) * 4"
|
| 789 |
+
}
|
| 790 |
+
]
|
| 791 |
+
},
|
| 792 |
+
"attrs": { "K": 128, "N": 262144, "bits": 4, "block_size": 32 }
|
| 793 |
+
},
|
| 794 |
+
{
|
| 795 |
+
"name": "mmnb-prefill-m4-q4g32-n262144-tile4x4-fold",
|
| 796 |
+
"preset": "smoke",
|
| 797 |
+
"vars": { "M": 4, "K": 128, "N": 262144, "bits": 4, "blockSize": 32 },
|
| 798 |
+
"inputs": {
|
| 799 |
+
"aT": { "shape": [4, 128], "dtype": "float32", "dist": "normal", "seed": 470, "scale": 0.2 },
|
| 800 |
+
"bT": { "shape": [262144, 4, 16], "dtype": "uint8", "dist": "linearMod", "mod": 256, "step": 7 },
|
| 801 |
+
"scalesT": {
|
| 802 |
+
"shape": [262144, 4],
|
| 803 |
+
"dtype": "float32",
|
| 804 |
+
"dist": "uniform",
|
| 805 |
+
"seed": 472,
|
| 806 |
+
"offset": 0.04,
|
| 807 |
+
"scale": 0.01,
|
| 808 |
+
"signed": false
|
| 809 |
+
}
|
| 810 |
+
},
|
| 811 |
+
"outputs": { "yT": { "shape": [4, 262144], "dtype": "float32" } },
|
| 812 |
+
"bench": {
|
| 813 |
+
"metrics": [
|
| 814 |
+
{
|
| 815 |
+
"type": "bandwidth",
|
| 816 |
+
"value": "numel(shapes.bT) * 4 + (numel(shapes.aT) + numel(shapes.scalesT) + numel(shapes.yT)) * 4"
|
| 817 |
+
}
|
| 818 |
+
]
|
| 819 |
+
},
|
| 820 |
+
"attrs": { "K": 128, "N": 262144, "bits": 4, "block_size": 32 }
|
| 821 |
+
}
|
| 822 |
+
]
|
| 823 |
+
}
|
build/webgpu/manifest.json
ADDED
|
@@ -0,0 +1,1480 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"domain": "com.microsoft",
|
| 3 |
+
"name": "MatMulNBits",
|
| 4 |
+
"sinceVersion": 1,
|
| 5 |
+
"description": "Matrix multiplication with `B` block-quantized along K and dequantized as `(code - zero_point) * scale`. Each power-of-two `block_size` group has a scale and optional zero point; optional bias is added afterward. Two-, four-, and eight-bit codes are packed low-first, and `A` may have rank 2 or 3. This package supports standard unpacked zero points with the same dtype as `A`. Deprecated `g_idx`, prepacked weights, and bfloat16 tensors are not implemented.",
|
| 6 |
+
"inputs": [
|
| 7 |
+
{
|
| 8 |
+
"role": "A",
|
| 9 |
+
"dtype": "T1",
|
| 10 |
+
"description": "Float input matrix, not quantized. Rank 2 has shape `(M, K)` and rank 3 has shape `(batch, sequence, K)`; only the last axis is the reduction axis and the leading axes fold into the row count, so the ordinary activation needs no surrounding Reshape."
|
| 11 |
+
},
|
| 12 |
+
{
|
| 13 |
+
"role": "B",
|
| 14 |
+
"dtype": "uint8",
|
| 15 |
+
"rank": 3,
|
| 16 |
+
"description": "Bit-packed uint8 weight matrix of shape `(N, k_blocks, blob_size)`, where `k_blocks = ceil(K / block_size)` and `blob_size = block_size * bits / 8`. Codes are packed low-first along K."
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"role": "scales",
|
| 20 |
+
"dtype": "T1",
|
| 21 |
+
"rank": 2,
|
| 22 |
+
"description": "Per-block dequantization scale factors of shape `(N, k_blocks)`, with the same dtype as `A`."
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
"role": "zero_points",
|
| 26 |
+
"dtype": "T3",
|
| 27 |
+
"rank": 2,
|
| 28 |
+
"optional": true,
|
| 29 |
+
"description": "Standard unpacked per-block zero points with shape `(N, k_blocks)` and the same dtype as `A`. Omission uses `2^(bits - 1)`."
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
"role": "bias",
|
| 33 |
+
"dtype": "T1",
|
| 34 |
+
"rank": 1,
|
| 35 |
+
"optional": true,
|
| 36 |
+
"description": "Optional bias vector of shape `[N]` added to the output."
|
| 37 |
+
}
|
| 38 |
+
],
|
| 39 |
+
"outputs": [
|
| 40 |
+
{
|
| 41 |
+
"role": "Y",
|
| 42 |
+
"dtype": "T1",
|
| 43 |
+
"rank": "ranks.A",
|
| 44 |
+
"shape": "shapes.A[:-1] + [attrs.N]",
|
| 45 |
+
"description": "Result of A multiplied by the dequantized weight matrix, with optional bias, same dtype and rank as A: the leading axes of A with a trailing N."
|
| 46 |
+
}
|
| 47 |
+
],
|
| 48 |
+
"attributes": { "accuracy_level": 0, "bits": 4 },
|
| 49 |
+
"attributeDescriptions": {
|
| 50 |
+
"K": "Input feature dimension of the weight matrix.",
|
| 51 |
+
"N": "Output feature dimension of the weight matrix.",
|
| 52 |
+
"accuracy_level": "Minimum internal accuracy level: 0 (unset), 1 (float32), 2 (float16), 3 (bfloat16), or 4 (int8).",
|
| 53 |
+
"bits": "Bit width used to quantize B; this package supports 2, 4, and 8.",
|
| 54 |
+
"block_size": "Power-of-two quantization block size along K; it must be at least 16."
|
| 55 |
+
},
|
| 56 |
+
"attributeConstraints": {
|
| 57 |
+
"K": { "required": true },
|
| 58 |
+
"N": { "required": true },
|
| 59 |
+
"accuracy_level": { "values": [0, 1, 2, 3, 4] },
|
| 60 |
+
"bits": { "values": [2, 4, 8] },
|
| 61 |
+
"block_size": { "required": true }
|
| 62 |
+
},
|
| 63 |
+
"typeConstraints": { "T1": ["float32", "float16"], "T3": ["float32", "float16"] },
|
| 64 |
+
"args": {
|
| 65 |
+
"aT": { "kind": "tensor", "semantic": "A", "role": "input" },
|
| 66 |
+
"bT": { "kind": "tensor", "semantic": "B", "role": "input" },
|
| 67 |
+
"scalesT": { "kind": "tensor", "semantic": "scales", "role": "input" },
|
| 68 |
+
"zeroPointsT": { "kind": "tensor", "semantic": "zero_points", "role": "input", "required": false },
|
| 69 |
+
"biasT": { "kind": "tensor", "semantic": "bias", "role": "input", "required": false },
|
| 70 |
+
"yT": { "kind": "tensor", "semantic": "Y", "role": "output" }
|
| 71 |
+
},
|
| 72 |
+
"tunables": {
|
| 73 |
+
"REGISTER_TILE_TAILK_MIN_N": 256,
|
| 74 |
+
"WORKGROUP_SIZE": 64,
|
| 75 |
+
"GEMV_N_COLS": 4,
|
| 76 |
+
"REGISTER_TILE_MIN_N": 1024,
|
| 77 |
+
"REGISTER_TILE_TALL_MIN_M": 512,
|
| 78 |
+
"REGISTER_TILE_TALL_MIN_N": 256,
|
| 79 |
+
"REGISTER_TILE_MIN_WORKGROUPS": 64,
|
| 80 |
+
"REGISTER_TILE_LARGE_M": 64,
|
| 81 |
+
"REGISTER_TILE_BK32_MIN_M": 128,
|
| 82 |
+
"REGISTER_TILE_MIN_M": 16
|
| 83 |
+
},
|
| 84 |
+
"constants": {
|
| 85 |
+
"B_LEN": "attrs.N * kBlocksExpected * blobSizeExpected",
|
| 86 |
+
"SCALES_LEN": "attrs.N * kBlocksExpected",
|
| 87 |
+
"BIAS_LEN": "attrs.N"
|
| 88 |
+
},
|
| 89 |
+
"bindingSets": {
|
| 90 |
+
"dp4aQuantize": [
|
| 91 |
+
{ "name": "a", "arg": "aT", "buffer": { "type": "read-only-storage" }, "elementType": "f32" },
|
| 92 |
+
{ "name": "a_quant", "semantic": "aQuant", "buffer": { "type": "storage" }, "elementType": "u32" },
|
| 93 |
+
{ "name": "a_scales", "semantic": "aScales", "buffer": { "type": "storage" }, "elementType": "f32" }
|
| 94 |
+
],
|
| 95 |
+
"dp4aGemm": [
|
| 96 |
+
{ "name": "a_quant", "semantic": "aQuant", "buffer": { "type": "read-only-storage" }, "elementType": "u32" },
|
| 97 |
+
{ "name": "a_scales", "semantic": "aScales", "buffer": { "type": "read-only-storage" }, "elementType": "f32" },
|
| 98 |
+
{ "name": "b", "arg": "bT", "buffer": { "type": "read-only-storage" }, "elementType": "u32", "length": "$B_LEN" },
|
| 99 |
+
{
|
| 100 |
+
"name": "scales",
|
| 101 |
+
"arg": "scalesT",
|
| 102 |
+
"buffer": { "type": "read-only-storage" },
|
| 103 |
+
"elementType": "f32",
|
| 104 |
+
"length": "$SCALES_LEN"
|
| 105 |
+
},
|
| 106 |
+
{ "name": "y", "arg": "yT", "buffer": { "type": "storage" }, "elementType": "f32" }
|
| 107 |
+
],
|
| 108 |
+
"genericZeroBias": [
|
| 109 |
+
{
|
| 110 |
+
"name": "a",
|
| 111 |
+
"arg": "aT",
|
| 112 |
+
"semantic": "A",
|
| 113 |
+
"buffer": { "type": "read-only-storage" },
|
| 114 |
+
"elementType": "$aScalar"
|
| 115 |
+
},
|
| 116 |
+
{
|
| 117 |
+
"name": "b",
|
| 118 |
+
"arg": "bT",
|
| 119 |
+
"semantic": "B",
|
| 120 |
+
"buffer": { "type": "read-only-storage" },
|
| 121 |
+
"elementType": "$bScalar",
|
| 122 |
+
"length": "$B_LEN"
|
| 123 |
+
},
|
| 124 |
+
{
|
| 125 |
+
"name": "scales",
|
| 126 |
+
"arg": "scalesT",
|
| 127 |
+
"semantic": "scales",
|
| 128 |
+
"buffer": { "type": "read-only-storage" },
|
| 129 |
+
"elementType": "$scaleScalar",
|
| 130 |
+
"length": "$SCALES_LEN"
|
| 131 |
+
},
|
| 132 |
+
{
|
| 133 |
+
"name": "zero_points",
|
| 134 |
+
"arg": "zeroPointsT",
|
| 135 |
+
"semantic": "zero_points",
|
| 136 |
+
"buffer": { "type": "read-only-storage" },
|
| 137 |
+
"elementType": "$aScalar",
|
| 138 |
+
"length": "$SCALES_LEN"
|
| 139 |
+
},
|
| 140 |
+
{
|
| 141 |
+
"name": "bias",
|
| 142 |
+
"arg": "biasT",
|
| 143 |
+
"semantic": "bias",
|
| 144 |
+
"buffer": { "type": "read-only-storage" },
|
| 145 |
+
"elementType": "$aScalar",
|
| 146 |
+
"length": "$BIAS_LEN"
|
| 147 |
+
},
|
| 148 |
+
{ "name": "y", "arg": "yT", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$outputScalar" },
|
| 149 |
+
{
|
| 150 |
+
"name": "params",
|
| 151 |
+
"semantic": "kernel.params",
|
| 152 |
+
"buffer": { "type": "uniform" },
|
| 153 |
+
"struct": {
|
| 154 |
+
"name": "Params",
|
| 155 |
+
"fields": [
|
| 156 |
+
{ "name": "rows", "type": "u32", "value": "aRows" },
|
| 157 |
+
{ "name": "K", "type": "u32", "value": "attrs.K" },
|
| 158 |
+
{ "name": "N", "type": "u32", "value": "attrs.N" },
|
| 159 |
+
{ "name": "blockSize", "type": "u32", "value": "attrs.block_size" },
|
| 160 |
+
{ "name": "kBlocks", "type": "u32", "value": "dim(shapes.B, 1)" },
|
| 161 |
+
{ "name": "blobSize", "type": "u32", "value": "dim(shapes.B, 2)" }
|
| 162 |
+
]
|
| 163 |
+
}
|
| 164 |
+
}
|
| 165 |
+
],
|
| 166 |
+
"genericZeroOnly": [
|
| 167 |
+
{
|
| 168 |
+
"name": "a",
|
| 169 |
+
"arg": "aT",
|
| 170 |
+
"semantic": "A",
|
| 171 |
+
"buffer": { "type": "read-only-storage" },
|
| 172 |
+
"elementType": "$aScalar"
|
| 173 |
+
},
|
| 174 |
+
{
|
| 175 |
+
"name": "b",
|
| 176 |
+
"arg": "bT",
|
| 177 |
+
"semantic": "B",
|
| 178 |
+
"buffer": { "type": "read-only-storage" },
|
| 179 |
+
"elementType": "$bScalar",
|
| 180 |
+
"length": "$B_LEN"
|
| 181 |
+
},
|
| 182 |
+
{
|
| 183 |
+
"name": "scales",
|
| 184 |
+
"arg": "scalesT",
|
| 185 |
+
"semantic": "scales",
|
| 186 |
+
"buffer": { "type": "read-only-storage" },
|
| 187 |
+
"elementType": "$scaleScalar",
|
| 188 |
+
"length": "$SCALES_LEN"
|
| 189 |
+
},
|
| 190 |
+
{
|
| 191 |
+
"name": "zero_points",
|
| 192 |
+
"arg": "zeroPointsT",
|
| 193 |
+
"semantic": "zero_points",
|
| 194 |
+
"buffer": { "type": "read-only-storage" },
|
| 195 |
+
"elementType": "$aScalar",
|
| 196 |
+
"length": "$SCALES_LEN"
|
| 197 |
+
},
|
| 198 |
+
{ "name": "y", "arg": "yT", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$outputScalar" },
|
| 199 |
+
{
|
| 200 |
+
"name": "params",
|
| 201 |
+
"semantic": "kernel.params",
|
| 202 |
+
"buffer": { "type": "uniform" },
|
| 203 |
+
"struct": {
|
| 204 |
+
"name": "Params",
|
| 205 |
+
"fields": [
|
| 206 |
+
{ "name": "rows", "type": "u32", "value": "aRows" },
|
| 207 |
+
{ "name": "K", "type": "u32", "value": "attrs.K" },
|
| 208 |
+
{ "name": "N", "type": "u32", "value": "attrs.N" },
|
| 209 |
+
{ "name": "blockSize", "type": "u32", "value": "attrs.block_size" },
|
| 210 |
+
{ "name": "kBlocks", "type": "u32", "value": "dim(shapes.B, 1)" },
|
| 211 |
+
{ "name": "blobSize", "type": "u32", "value": "dim(shapes.B, 2)" }
|
| 212 |
+
]
|
| 213 |
+
}
|
| 214 |
+
}
|
| 215 |
+
],
|
| 216 |
+
"genericBiasOnly": [
|
| 217 |
+
{
|
| 218 |
+
"name": "a",
|
| 219 |
+
"arg": "aT",
|
| 220 |
+
"semantic": "A",
|
| 221 |
+
"buffer": { "type": "read-only-storage" },
|
| 222 |
+
"elementType": "$aScalar"
|
| 223 |
+
},
|
| 224 |
+
{
|
| 225 |
+
"name": "b",
|
| 226 |
+
"arg": "bT",
|
| 227 |
+
"semantic": "B",
|
| 228 |
+
"buffer": { "type": "read-only-storage" },
|
| 229 |
+
"elementType": "$bScalar",
|
| 230 |
+
"length": "$B_LEN"
|
| 231 |
+
},
|
| 232 |
+
{
|
| 233 |
+
"name": "scales",
|
| 234 |
+
"arg": "scalesT",
|
| 235 |
+
"semantic": "scales",
|
| 236 |
+
"buffer": { "type": "read-only-storage" },
|
| 237 |
+
"elementType": "$scaleScalar",
|
| 238 |
+
"length": "$SCALES_LEN"
|
| 239 |
+
},
|
| 240 |
+
{
|
| 241 |
+
"name": "bias",
|
| 242 |
+
"arg": "biasT",
|
| 243 |
+
"semantic": "bias",
|
| 244 |
+
"buffer": { "type": "read-only-storage" },
|
| 245 |
+
"elementType": "$aScalar",
|
| 246 |
+
"length": "$BIAS_LEN"
|
| 247 |
+
},
|
| 248 |
+
{ "name": "y", "arg": "yT", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$outputScalar" },
|
| 249 |
+
{
|
| 250 |
+
"name": "params",
|
| 251 |
+
"semantic": "kernel.params",
|
| 252 |
+
"buffer": { "type": "uniform" },
|
| 253 |
+
"struct": {
|
| 254 |
+
"name": "Params",
|
| 255 |
+
"fields": [
|
| 256 |
+
{ "name": "rows", "type": "u32", "value": "aRows" },
|
| 257 |
+
{ "name": "K", "type": "u32", "value": "attrs.K" },
|
| 258 |
+
{ "name": "N", "type": "u32", "value": "attrs.N" },
|
| 259 |
+
{ "name": "blockSize", "type": "u32", "value": "attrs.block_size" },
|
| 260 |
+
{ "name": "kBlocks", "type": "u32", "value": "dim(shapes.B, 1)" },
|
| 261 |
+
{ "name": "blobSize", "type": "u32", "value": "dim(shapes.B, 2)" }
|
| 262 |
+
]
|
| 263 |
+
}
|
| 264 |
+
}
|
| 265 |
+
],
|
| 266 |
+
"genericDefaultZero": [
|
| 267 |
+
{
|
| 268 |
+
"name": "a",
|
| 269 |
+
"arg": "aT",
|
| 270 |
+
"semantic": "A",
|
| 271 |
+
"buffer": { "type": "read-only-storage" },
|
| 272 |
+
"elementType": "$aScalar"
|
| 273 |
+
},
|
| 274 |
+
{
|
| 275 |
+
"name": "b",
|
| 276 |
+
"arg": "bT",
|
| 277 |
+
"semantic": "B",
|
| 278 |
+
"buffer": { "type": "read-only-storage" },
|
| 279 |
+
"elementType": "$bScalar",
|
| 280 |
+
"length": "$B_LEN"
|
| 281 |
+
},
|
| 282 |
+
{
|
| 283 |
+
"name": "scales",
|
| 284 |
+
"arg": "scalesT",
|
| 285 |
+
"semantic": "scales",
|
| 286 |
+
"buffer": { "type": "read-only-storage" },
|
| 287 |
+
"elementType": "$scaleScalar",
|
| 288 |
+
"length": "$SCALES_LEN"
|
| 289 |
+
},
|
| 290 |
+
{ "name": "y", "arg": "yT", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$outputScalar" },
|
| 291 |
+
{
|
| 292 |
+
"name": "params",
|
| 293 |
+
"semantic": "kernel.params",
|
| 294 |
+
"buffer": { "type": "uniform" },
|
| 295 |
+
"struct": {
|
| 296 |
+
"name": "Params",
|
| 297 |
+
"fields": [
|
| 298 |
+
{ "name": "rows", "type": "u32", "value": "aRows" },
|
| 299 |
+
{ "name": "K", "type": "u32", "value": "attrs.K" },
|
| 300 |
+
{ "name": "N", "type": "u32", "value": "attrs.N" },
|
| 301 |
+
{ "name": "blockSize", "type": "u32", "value": "attrs.block_size" },
|
| 302 |
+
{ "name": "kBlocks", "type": "u32", "value": "dim(shapes.B, 1)" },
|
| 303 |
+
{ "name": "blobSize", "type": "u32", "value": "dim(shapes.B, 2)" }
|
| 304 |
+
]
|
| 305 |
+
}
|
| 306 |
+
}
|
| 307 |
+
],
|
| 308 |
+
"gemvZeroBias": [
|
| 309 |
+
{
|
| 310 |
+
"name": "a",
|
| 311 |
+
"arg": "aT",
|
| 312 |
+
"semantic": "A",
|
| 313 |
+
"buffer": { "type": "read-only-storage" },
|
| 314 |
+
"elementType": "$aScalar"
|
| 315 |
+
},
|
| 316 |
+
{
|
| 317 |
+
"name": "b",
|
| 318 |
+
"arg": "bT",
|
| 319 |
+
"semantic": "B",
|
| 320 |
+
"buffer": { "type": "read-only-storage" },
|
| 321 |
+
"elementType": "$bScalar",
|
| 322 |
+
"length": "$B_LEN"
|
| 323 |
+
},
|
| 324 |
+
{
|
| 325 |
+
"name": "scales",
|
| 326 |
+
"arg": "scalesT",
|
| 327 |
+
"semantic": "scales",
|
| 328 |
+
"buffer": { "type": "read-only-storage" },
|
| 329 |
+
"elementType": "$scaleScalar",
|
| 330 |
+
"length": "$SCALES_LEN"
|
| 331 |
+
},
|
| 332 |
+
{
|
| 333 |
+
"name": "zero_points",
|
| 334 |
+
"arg": "zeroPointsT",
|
| 335 |
+
"semantic": "zero_points",
|
| 336 |
+
"buffer": { "type": "read-only-storage" },
|
| 337 |
+
"elementType": "$aScalar",
|
| 338 |
+
"length": "$SCALES_LEN"
|
| 339 |
+
},
|
| 340 |
+
{
|
| 341 |
+
"name": "bias",
|
| 342 |
+
"arg": "biasT",
|
| 343 |
+
"semantic": "bias",
|
| 344 |
+
"buffer": { "type": "read-only-storage" },
|
| 345 |
+
"elementType": "$aScalar",
|
| 346 |
+
"length": "$BIAS_LEN"
|
| 347 |
+
},
|
| 348 |
+
{ "name": "y", "arg": "yT", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$outputScalar" },
|
| 349 |
+
{
|
| 350 |
+
"name": "params",
|
| 351 |
+
"semantic": "kernel.params",
|
| 352 |
+
"buffer": { "type": "uniform" },
|
| 353 |
+
"struct": {
|
| 354 |
+
"name": "Params",
|
| 355 |
+
"fields": [
|
| 356 |
+
{ "name": "K", "type": "u32", "value": "attrs.K" },
|
| 357 |
+
{ "name": "N", "type": "u32", "value": "attrs.N" },
|
| 358 |
+
{ "name": "blockSize", "type": "u32", "value": "attrs.block_size" },
|
| 359 |
+
{ "name": "kBlocks", "type": "u32", "value": "dim(shapes.B, 1)" },
|
| 360 |
+
{ "name": "blobSize", "type": "u32", "value": "dim(shapes.B, 2)" }
|
| 361 |
+
]
|
| 362 |
+
}
|
| 363 |
+
}
|
| 364 |
+
],
|
| 365 |
+
"gemvZeroOnly": [
|
| 366 |
+
{
|
| 367 |
+
"name": "a",
|
| 368 |
+
"arg": "aT",
|
| 369 |
+
"semantic": "A",
|
| 370 |
+
"buffer": { "type": "read-only-storage" },
|
| 371 |
+
"elementType": "$aScalar"
|
| 372 |
+
},
|
| 373 |
+
{
|
| 374 |
+
"name": "b",
|
| 375 |
+
"arg": "bT",
|
| 376 |
+
"semantic": "B",
|
| 377 |
+
"buffer": { "type": "read-only-storage" },
|
| 378 |
+
"elementType": "$bScalar",
|
| 379 |
+
"length": "$B_LEN"
|
| 380 |
+
},
|
| 381 |
+
{
|
| 382 |
+
"name": "scales",
|
| 383 |
+
"arg": "scalesT",
|
| 384 |
+
"semantic": "scales",
|
| 385 |
+
"buffer": { "type": "read-only-storage" },
|
| 386 |
+
"elementType": "$scaleScalar",
|
| 387 |
+
"length": "$SCALES_LEN"
|
| 388 |
+
},
|
| 389 |
+
{
|
| 390 |
+
"name": "zero_points",
|
| 391 |
+
"arg": "zeroPointsT",
|
| 392 |
+
"semantic": "zero_points",
|
| 393 |
+
"buffer": { "type": "read-only-storage" },
|
| 394 |
+
"elementType": "$aScalar",
|
| 395 |
+
"length": "$SCALES_LEN"
|
| 396 |
+
},
|
| 397 |
+
{ "name": "y", "arg": "yT", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$outputScalar" },
|
| 398 |
+
{
|
| 399 |
+
"name": "params",
|
| 400 |
+
"semantic": "kernel.params",
|
| 401 |
+
"buffer": { "type": "uniform" },
|
| 402 |
+
"struct": {
|
| 403 |
+
"name": "Params",
|
| 404 |
+
"fields": [
|
| 405 |
+
{ "name": "K", "type": "u32", "value": "attrs.K" },
|
| 406 |
+
{ "name": "N", "type": "u32", "value": "attrs.N" },
|
| 407 |
+
{ "name": "blockSize", "type": "u32", "value": "attrs.block_size" },
|
| 408 |
+
{ "name": "kBlocks", "type": "u32", "value": "dim(shapes.B, 1)" },
|
| 409 |
+
{ "name": "blobSize", "type": "u32", "value": "dim(shapes.B, 2)" }
|
| 410 |
+
]
|
| 411 |
+
}
|
| 412 |
+
}
|
| 413 |
+
],
|
| 414 |
+
"gemvBiasOnly": [
|
| 415 |
+
{
|
| 416 |
+
"name": "a",
|
| 417 |
+
"arg": "aT",
|
| 418 |
+
"semantic": "A",
|
| 419 |
+
"buffer": { "type": "read-only-storage" },
|
| 420 |
+
"elementType": "$aScalar"
|
| 421 |
+
},
|
| 422 |
+
{
|
| 423 |
+
"name": "b",
|
| 424 |
+
"arg": "bT",
|
| 425 |
+
"semantic": "B",
|
| 426 |
+
"buffer": { "type": "read-only-storage" },
|
| 427 |
+
"elementType": "$bScalar",
|
| 428 |
+
"length": "$B_LEN"
|
| 429 |
+
},
|
| 430 |
+
{
|
| 431 |
+
"name": "scales",
|
| 432 |
+
"arg": "scalesT",
|
| 433 |
+
"semantic": "scales",
|
| 434 |
+
"buffer": { "type": "read-only-storage" },
|
| 435 |
+
"elementType": "$scaleScalar",
|
| 436 |
+
"length": "$SCALES_LEN"
|
| 437 |
+
},
|
| 438 |
+
{
|
| 439 |
+
"name": "bias",
|
| 440 |
+
"arg": "biasT",
|
| 441 |
+
"semantic": "bias",
|
| 442 |
+
"buffer": { "type": "read-only-storage" },
|
| 443 |
+
"elementType": "$aScalar",
|
| 444 |
+
"length": "$BIAS_LEN"
|
| 445 |
+
},
|
| 446 |
+
{ "name": "y", "arg": "yT", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$outputScalar" },
|
| 447 |
+
{
|
| 448 |
+
"name": "params",
|
| 449 |
+
"semantic": "kernel.params",
|
| 450 |
+
"buffer": { "type": "uniform" },
|
| 451 |
+
"struct": {
|
| 452 |
+
"name": "Params",
|
| 453 |
+
"fields": [
|
| 454 |
+
{ "name": "K", "type": "u32", "value": "attrs.K" },
|
| 455 |
+
{ "name": "N", "type": "u32", "value": "attrs.N" },
|
| 456 |
+
{ "name": "blockSize", "type": "u32", "value": "attrs.block_size" },
|
| 457 |
+
{ "name": "kBlocks", "type": "u32", "value": "dim(shapes.B, 1)" },
|
| 458 |
+
{ "name": "blobSize", "type": "u32", "value": "dim(shapes.B, 2)" }
|
| 459 |
+
]
|
| 460 |
+
}
|
| 461 |
+
}
|
| 462 |
+
],
|
| 463 |
+
"gemvDefaultZero": [
|
| 464 |
+
{
|
| 465 |
+
"name": "a",
|
| 466 |
+
"arg": "aT",
|
| 467 |
+
"semantic": "A",
|
| 468 |
+
"buffer": { "type": "read-only-storage" },
|
| 469 |
+
"elementType": "$aScalar"
|
| 470 |
+
},
|
| 471 |
+
{
|
| 472 |
+
"name": "b",
|
| 473 |
+
"arg": "bT",
|
| 474 |
+
"semantic": "B",
|
| 475 |
+
"buffer": { "type": "read-only-storage" },
|
| 476 |
+
"elementType": "$bScalar",
|
| 477 |
+
"length": "$B_LEN"
|
| 478 |
+
},
|
| 479 |
+
{
|
| 480 |
+
"name": "scales",
|
| 481 |
+
"arg": "scalesT",
|
| 482 |
+
"semantic": "scales",
|
| 483 |
+
"buffer": { "type": "read-only-storage" },
|
| 484 |
+
"elementType": "$scaleScalar",
|
| 485 |
+
"length": "$SCALES_LEN"
|
| 486 |
+
},
|
| 487 |
+
{ "name": "y", "arg": "yT", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$outputScalar" },
|
| 488 |
+
{
|
| 489 |
+
"name": "params",
|
| 490 |
+
"semantic": "kernel.params",
|
| 491 |
+
"buffer": { "type": "uniform" },
|
| 492 |
+
"struct": {
|
| 493 |
+
"name": "Params",
|
| 494 |
+
"fields": [
|
| 495 |
+
{ "name": "K", "type": "u32", "value": "attrs.K" },
|
| 496 |
+
{ "name": "N", "type": "u32", "value": "attrs.N" },
|
| 497 |
+
{ "name": "blockSize", "type": "u32", "value": "attrs.block_size" },
|
| 498 |
+
{ "name": "kBlocks", "type": "u32", "value": "dim(shapes.B, 1)" },
|
| 499 |
+
{ "name": "blobSize", "type": "u32", "value": "dim(shapes.B, 2)" }
|
| 500 |
+
]
|
| 501 |
+
}
|
| 502 |
+
}
|
| 503 |
+
],
|
| 504 |
+
"prefillZeroBias": [
|
| 505 |
+
{
|
| 506 |
+
"name": "a",
|
| 507 |
+
"arg": "aT",
|
| 508 |
+
"semantic": "A",
|
| 509 |
+
"buffer": { "type": "read-only-storage" },
|
| 510 |
+
"elementType": "$aScalar"
|
| 511 |
+
},
|
| 512 |
+
{
|
| 513 |
+
"name": "b",
|
| 514 |
+
"arg": "bT",
|
| 515 |
+
"semantic": "B",
|
| 516 |
+
"buffer": { "type": "read-only-storage" },
|
| 517 |
+
"elementType": "$bScalar",
|
| 518 |
+
"length": "$B_LEN"
|
| 519 |
+
},
|
| 520 |
+
{
|
| 521 |
+
"name": "scales",
|
| 522 |
+
"arg": "scalesT",
|
| 523 |
+
"semantic": "scales",
|
| 524 |
+
"buffer": { "type": "read-only-storage" },
|
| 525 |
+
"elementType": "$scaleScalar",
|
| 526 |
+
"length": "$SCALES_LEN"
|
| 527 |
+
},
|
| 528 |
+
{
|
| 529 |
+
"name": "zero_points",
|
| 530 |
+
"arg": "zeroPointsT",
|
| 531 |
+
"semantic": "zero_points",
|
| 532 |
+
"buffer": { "type": "read-only-storage" },
|
| 533 |
+
"elementType": "$aScalar",
|
| 534 |
+
"length": "$SCALES_LEN"
|
| 535 |
+
},
|
| 536 |
+
{
|
| 537 |
+
"name": "bias",
|
| 538 |
+
"arg": "biasT",
|
| 539 |
+
"semantic": "bias",
|
| 540 |
+
"buffer": { "type": "read-only-storage" },
|
| 541 |
+
"elementType": "$aScalar",
|
| 542 |
+
"length": "$BIAS_LEN"
|
| 543 |
+
},
|
| 544 |
+
{ "name": "y", "arg": "yT", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$outputScalar" }
|
| 545 |
+
],
|
| 546 |
+
"prefillZeroOnly": [
|
| 547 |
+
{
|
| 548 |
+
"name": "a",
|
| 549 |
+
"arg": "aT",
|
| 550 |
+
"semantic": "A",
|
| 551 |
+
"buffer": { "type": "read-only-storage" },
|
| 552 |
+
"elementType": "$aScalar"
|
| 553 |
+
},
|
| 554 |
+
{
|
| 555 |
+
"name": "b",
|
| 556 |
+
"arg": "bT",
|
| 557 |
+
"semantic": "B",
|
| 558 |
+
"buffer": { "type": "read-only-storage" },
|
| 559 |
+
"elementType": "$bScalar",
|
| 560 |
+
"length": "$B_LEN"
|
| 561 |
+
},
|
| 562 |
+
{
|
| 563 |
+
"name": "scales",
|
| 564 |
+
"arg": "scalesT",
|
| 565 |
+
"semantic": "scales",
|
| 566 |
+
"buffer": { "type": "read-only-storage" },
|
| 567 |
+
"elementType": "$scaleScalar",
|
| 568 |
+
"length": "$SCALES_LEN"
|
| 569 |
+
},
|
| 570 |
+
{
|
| 571 |
+
"name": "zero_points",
|
| 572 |
+
"arg": "zeroPointsT",
|
| 573 |
+
"semantic": "zero_points",
|
| 574 |
+
"buffer": { "type": "read-only-storage" },
|
| 575 |
+
"elementType": "$aScalar",
|
| 576 |
+
"length": "$SCALES_LEN"
|
| 577 |
+
},
|
| 578 |
+
{ "name": "y", "arg": "yT", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$outputScalar" }
|
| 579 |
+
],
|
| 580 |
+
"prefillBiasOnly": [
|
| 581 |
+
{
|
| 582 |
+
"name": "a",
|
| 583 |
+
"arg": "aT",
|
| 584 |
+
"semantic": "A",
|
| 585 |
+
"buffer": { "type": "read-only-storage" },
|
| 586 |
+
"elementType": "$aScalar"
|
| 587 |
+
},
|
| 588 |
+
{
|
| 589 |
+
"name": "b",
|
| 590 |
+
"arg": "bT",
|
| 591 |
+
"semantic": "B",
|
| 592 |
+
"buffer": { "type": "read-only-storage" },
|
| 593 |
+
"elementType": "$bScalar",
|
| 594 |
+
"length": "$B_LEN"
|
| 595 |
+
},
|
| 596 |
+
{
|
| 597 |
+
"name": "scales",
|
| 598 |
+
"arg": "scalesT",
|
| 599 |
+
"semantic": "scales",
|
| 600 |
+
"buffer": { "type": "read-only-storage" },
|
| 601 |
+
"elementType": "$scaleScalar",
|
| 602 |
+
"length": "$SCALES_LEN"
|
| 603 |
+
},
|
| 604 |
+
{
|
| 605 |
+
"name": "bias",
|
| 606 |
+
"arg": "biasT",
|
| 607 |
+
"semantic": "bias",
|
| 608 |
+
"buffer": { "type": "read-only-storage" },
|
| 609 |
+
"elementType": "$aScalar",
|
| 610 |
+
"length": "$BIAS_LEN"
|
| 611 |
+
},
|
| 612 |
+
{ "name": "y", "arg": "yT", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$outputScalar" }
|
| 613 |
+
],
|
| 614 |
+
"prefillDefaultZero": [
|
| 615 |
+
{
|
| 616 |
+
"name": "a",
|
| 617 |
+
"arg": "aT",
|
| 618 |
+
"semantic": "A",
|
| 619 |
+
"buffer": { "type": "read-only-storage" },
|
| 620 |
+
"elementType": "$aScalar"
|
| 621 |
+
},
|
| 622 |
+
{
|
| 623 |
+
"name": "b",
|
| 624 |
+
"arg": "bT",
|
| 625 |
+
"semantic": "B",
|
| 626 |
+
"buffer": { "type": "read-only-storage" },
|
| 627 |
+
"elementType": "$bScalar",
|
| 628 |
+
"length": "$B_LEN"
|
| 629 |
+
},
|
| 630 |
+
{
|
| 631 |
+
"name": "scales",
|
| 632 |
+
"arg": "scalesT",
|
| 633 |
+
"semantic": "scales",
|
| 634 |
+
"buffer": { "type": "read-only-storage" },
|
| 635 |
+
"elementType": "$scaleScalar",
|
| 636 |
+
"length": "$SCALES_LEN"
|
| 637 |
+
},
|
| 638 |
+
{ "name": "y", "arg": "yT", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$outputScalar" }
|
| 639 |
+
]
|
| 640 |
+
},
|
| 641 |
+
"derive": {
|
| 642 |
+
"deviceWorkgroupCap": "min(device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX)",
|
| 643 |
+
"narrowSubgroupRange": "has(device.adapterInfo, \"subgroupMinSize\") and has(device.adapterInfo, \"subgroupMaxSize\") and device.adapterInfo.subgroupMinSize < device.adapterInfo.subgroupMaxSize and device.adapterInfo.subgroupMaxSize <= 16",
|
| 644 |
+
"packedFeature": "device.wgslLanguageFeatures.has(\"packed_4x8_integer_dot_product\")",
|
| 645 |
+
"kBlocksExpected": "ceilDiv(attrs.K, attrs.block_size)",
|
| 646 |
+
"blobSizeExpected": "ceilDiv(attrs.block_size * attrs.bits, 8)",
|
| 647 |
+
"aRows": "numel(shapes.A) / max(1, attrs.K)",
|
| 648 |
+
"aRankOk": "(ranks.A == 2 or ranks.A == 3) and ranks.Y == ranks.A and dim(shapes.A, ranks.A - 1) == attrs.K and dim(shapes.Y, ranks.Y - 1) == attrs.N and dim(shapes.Y, 0) == dim(shapes.A, 0) and (ranks.A == 2 or dim(shapes.Y, 1) == dim(shapes.A, 1))",
|
| 649 |
+
"dispatchN4": "ceilDiv(attrs.N, 4)",
|
| 650 |
+
"gemvDispatchN": "ceilDiv(attrs.N, tunables.GEMV_N_COLS)",
|
| 651 |
+
"dispatchN32": "ceilDiv(attrs.N, 32)",
|
| 652 |
+
"dispatchN64": "ceilDiv(attrs.N, 64)",
|
| 653 |
+
"dispatchM32": "ceilDiv(aRows, 32)",
|
| 654 |
+
"dispatchM64": "ceilDiv(aRows, 64)",
|
| 655 |
+
"sgmatTileRows": "64 if aRows >= 64 else 32",
|
| 656 |
+
"sgmatWorkgroupSize": "256 if aRows >= 64 else 128",
|
| 657 |
+
"sgmatRowSubtiles": "4 if aRows >= 64 else 2",
|
| 658 |
+
"sgmatBLoadsPerRow": "sgmatRowSubtiles",
|
| 659 |
+
"sgmatBLoadWidth": "8 if aRows >= 64 else 16",
|
| 660 |
+
"sgmatNumSubgroups": "8 if aRows >= 64 else 4",
|
| 661 |
+
"sgmatWorkgroupStorageBytes": "24576 if aRows >= 64 else 16384",
|
| 662 |
+
"sgmatDispatchM": "dispatchM64 if aRows >= 64 else dispatchM32",
|
| 663 |
+
"tiledRegBK": "32 if aRows >= tunables.REGISTER_TILE_BK32_MIN_M else 16",
|
| 664 |
+
"aFloatOk": "(tensorDtypes.A == \"float32\" or tensorDtypes.A == \"float16\") and f16Ok(tensorDtypes.A)",
|
| 665 |
+
"portableWorkgroupSize": "min(tunables.WORKGROUP_SIZE, deviceWorkgroupCap)",
|
| 666 |
+
"bitsSupported": "attrs.bits == 2 or attrs.bits == 4 or attrs.bits == 8",
|
| 667 |
+
"blockSizeSupported": "attrs.block_size >= 16 and attrs.block_size == pow2ceil(attrs.block_size)",
|
| 668 |
+
"commonShapeValid": "aRankOk and ranks.B == 3 and ranks.scales == 2 and aFloatOk and blockSizeSupported and tensorDtypes.B == \"uint8\" and tensorDtypes.scales == tensorDtypes.A and tensorDtypes.Y == tensorDtypes.A and attrs.K > 0 and attrs.N > 0 and dim(shapes.B, 0) == attrs.N and dim(shapes.B, 1) == kBlocksExpected and dim(shapes.B, 2) == blobSizeExpected and dim(shapes.scales, 0) == attrs.N and dim(shapes.scales, 1) == dim(shapes.B, 1)",
|
| 669 |
+
"gemvShapeValid": "commonShapeValid and aRows == 1",
|
| 670 |
+
"zeroPointsValid": "present.zeroPointsT and ranks.zero_points == 2 and tensorDtypes.zero_points == tensorDtypes.A and dim(shapes.zero_points, 0) == attrs.N and dim(shapes.zero_points, 1) == dim(shapes.B, 1)",
|
| 671 |
+
"biasValid": "present.biasT and ranks.bias == 1 and tensorDtypes.bias == tensorDtypes.A and dim(shapes.bias, 0) == attrs.N",
|
| 672 |
+
"defaultEpilogue": "not present.zeroPointsT and not present.biasT",
|
| 673 |
+
"zeroBiasEpilogue": "zeroPointsValid and biasValid",
|
| 674 |
+
"zeroOnlyEpilogue": "zeroPointsValid and not present.biasT",
|
| 675 |
+
"biasOnlyEpilogue": "not present.zeroPointsT and biasValid",
|
| 676 |
+
"portableWorkgroupFits": "portableWorkgroupSize > 0 and portableWorkgroupSize * 64 <= device.limits.maxComputeWorkgroupStorageSize",
|
| 677 |
+
"tiledWorkgroupFits": "16 <= device.limits.maxComputeWorkgroupSizeX and 16 <= device.limits.maxComputeWorkgroupSizeY and 256 <= device.limits.maxComputeInvocationsPerWorkgroup and 4096 <= device.limits.maxComputeWorkgroupStorageSize",
|
| 678 |
+
"tiledRegWorkgroupFits": "tiledWorkgroupFits and 16384 <= device.limits.maxComputeWorkgroupStorageSize",
|
| 679 |
+
"mediumTiledRegWorkgroupFits": "tiledWorkgroupFits and 6144 <= device.limits.maxComputeWorkgroupStorageSize",
|
| 680 |
+
"sgmatWorkgroupFits": "sgmatWorkgroupSize <= deviceWorkgroupCap and sgmatWorkgroupStorageBytes <= device.limits.maxComputeWorkgroupStorageSize",
|
| 681 |
+
"registerTileShape": "aRows >= tunables.REGISTER_TILE_MIN_M and ((attrs.N >= tunables.REGISTER_TILE_MIN_N or (aRows >= tunables.REGISTER_TILE_TALL_MIN_M and attrs.N >= tunables.REGISTER_TILE_TALL_MIN_N) or (attrs.K % attrs.block_size != 0 and attrs.N >= tunables.REGISTER_TILE_TAILK_MIN_N)) and (attrs.K % attrs.block_size != 0 or aRows >= tunables.REGISTER_TILE_LARGE_M or dispatchM64 * dispatchN64 >= tunables.REGISTER_TILE_MIN_WORKGROUPS))",
|
| 682 |
+
"portableTile4Preferred": "registerTileShape and attrs.K % attrs.block_size == 0 and (not device.features.has(\"subgroups\") or narrowSubgroupRange) and has(device.adapterInfo, \"subgroupMinSize\") and device.adapterInfo.subgroupMinSize * 2 < portableWorkgroupSize",
|
| 683 |
+
"portableMediumRegisterPreferred": "portableTile4Preferred and aRows >= 128 and attrs.K >= 128",
|
| 684 |
+
"registerTilePreferred": "registerTileShape and not portableTile4Preferred",
|
| 685 |
+
"mediumRegisterEligible": "registerTilePreferred or portableMediumRegisterPreferred",
|
| 686 |
+
"largeTiledRegEligible": "registerTilePreferred and tiledRegWorkgroupFits and dispatchM64 <= device.limits.maxComputeWorkgroupsPerDimension",
|
| 687 |
+
"mediumTiledRegEligible": "mediumRegisterEligible and mediumTiledRegWorkgroupFits and dispatchM32 <= device.limits.maxComputeWorkgroupsPerDimension",
|
| 688 |
+
"tiledRegVariantEligible": "largeTiledRegEligible or mediumTiledRegEligible",
|
| 689 |
+
"tiledRegSelectedBK": "tiledRegBK if largeTiledRegEligible else 16",
|
| 690 |
+
"tiledRegSelectedTileRows": "64 if largeTiledRegEligible else 32",
|
| 691 |
+
"tiledRegSelectedThreadRows": "4 if largeTiledRegEligible else 2",
|
| 692 |
+
"tiledRegSelectedDispatchM": "dispatchM64 if largeTiledRegEligible else dispatchM32"
|
| 693 |
+
},
|
| 694 |
+
"variants": [
|
| 695 |
+
{
|
| 696 |
+
"id": "q4_dp4a_prefill",
|
| 697 |
+
"priority": 19,
|
| 698 |
+
"when": ["packedFeature", "commonShapeValid", "defaultEpilogue", "attrs.bits == 4", "attrs.accuracy_level == 4", "tensorDtypes.A == \"float32\"", "attrs.block_size % 32 == 0", "attrs.K % 128 == 0", "attrs.N % 16 == 0", "aRows >= 32", "ceilDiv(attrs.N, 64) <= device.limits.maxComputeWorkgroupsPerDimension", "ceilDiv(aRows, 64) <= device.limits.maxComputeWorkgroupsPerDimension", "16 <= device.limits.maxComputeWorkgroupSizeX", "16 <= device.limits.maxComputeWorkgroupSizeY", "64 <= device.limits.maxComputeWorkgroupSizeX", "256 <= device.limits.maxComputeInvocationsPerWorkgroup", "4608 <= device.limits.maxComputeWorkgroupStorageSize"],
|
| 699 |
+
"demoteWhen": ["has(device.adapterInfo, \"architecture\") and device.adapterInfo.architecture == \"maxwell\"", "device.features.has(\"chromium-experimental-subgroup-matrix\")", "device.adapterInfo.vendor == \"apple\""],
|
| 700 |
+
"constants": {
|
| 701 |
+
"M": "aRows",
|
| 702 |
+
"K": "attrs.K",
|
| 703 |
+
"N": "attrs.N",
|
| 704 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 705 |
+
"blockSize": "attrs.block_size",
|
| 706 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 707 |
+
"vec4Count": "aRows * attrs.K / 4",
|
| 708 |
+
"blockCount": "aRows * attrs.K / 128"
|
| 709 |
+
},
|
| 710 |
+
"intermediates": [
|
| 711 |
+
{ "id": "aQuant", "dtype": "uint32", "shape": "[aRows * attrs.K / 4]" },
|
| 712 |
+
{ "id": "aScales", "dtype": "float32", "shape": "[aRows * attrs.K / 128]" }
|
| 713 |
+
],
|
| 714 |
+
"passes": [
|
| 715 |
+
{
|
| 716 |
+
"id": "quantize",
|
| 717 |
+
"name": "MatMulNBits.Dp4aQuantizeA",
|
| 718 |
+
"shader": "matmul-nbits-dp4a-quantize.wgsl.jinja",
|
| 719 |
+
"bindings": "dp4aQuantize",
|
| 720 |
+
"dispatch": { "threads": "aRows * attrs.K / 4", "workgroupSize": 64 }
|
| 721 |
+
},
|
| 722 |
+
{
|
| 723 |
+
"id": "main",
|
| 724 |
+
"name": "MatMulNBits.Dp4aPrefill",
|
| 725 |
+
"shader": "matmul-nbits-q4-dp4a-prefill.wgsl.jinja",
|
| 726 |
+
"bindings": "dp4aGemm",
|
| 727 |
+
"dispatch": { "x": "ceilDiv(attrs.N, 64)", "y": "ceilDiv(aRows, 64)" }
|
| 728 |
+
}
|
| 729 |
+
]
|
| 730 |
+
},
|
| 731 |
+
{
|
| 732 |
+
"id": "gemv_default_zero",
|
| 733 |
+
"priority": 20,
|
| 734 |
+
"when": ["gemvShapeValid", "defaultEpilogue", "bitsSupported", "portableWorkgroupFits"],
|
| 735 |
+
"constants": {
|
| 736 |
+
"gemvNCols": "tunables.GEMV_N_COLS",
|
| 737 |
+
"hasZero": false,
|
| 738 |
+
"hasBias": false,
|
| 739 |
+
"workgroupSize": "portableWorkgroupSize",
|
| 740 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 741 |
+
"bScalar": "\"u32\"",
|
| 742 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 743 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 744 |
+
"bits": "attrs.bits",
|
| 745 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 746 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 747 |
+
},
|
| 748 |
+
"passes": [
|
| 749 |
+
{
|
| 750 |
+
"id": "main",
|
| 751 |
+
"shader": "matmul-nbits-gemv-q4.wgsl.jinja",
|
| 752 |
+
"bindings": "gemvDefaultZero",
|
| 753 |
+
"dispatch": { "workgroups": "gemvDispatchN" }
|
| 754 |
+
}
|
| 755 |
+
]
|
| 756 |
+
},
|
| 757 |
+
{
|
| 758 |
+
"id": "prefill_sgmat_default_zero",
|
| 759 |
+
"priority": 18,
|
| 760 |
+
"requires": {
|
| 761 |
+
"features": ["subgroups", "chromium-experimental-subgroup-matrix"],
|
| 762 |
+
"limits": { "maxComputeWorkgroupStorageSize": 16384 },
|
| 763 |
+
"subgroupMinSize": 32,
|
| 764 |
+
"subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
|
| 765 |
+
},
|
| 766 |
+
"when": ["commonShapeValid", "defaultEpilogue", "bitsSupported", "attrs.K % attrs.block_size == 0", "attrs.block_size % 16 == 0", "attrs.K % 32 == 0", "aRows >= 32", "has(device.adapterInfo, \"subgroupMinSize\")", "has(device.adapterInfo, \"subgroupMaxSize\")", "device.adapterInfo.subgroupMinSize == 32", "device.adapterInfo.subgroupMaxSize == 32", "dispatchN64 <= device.limits.maxComputeWorkgroupsPerDimension", "sgmatDispatchM <= device.limits.maxComputeWorkgroupsPerDimension", "portableWorkgroupFits", "sgmatWorkgroupFits"],
|
| 767 |
+
"constants": {
|
| 768 |
+
"hasZero": false,
|
| 769 |
+
"hasBias": false,
|
| 770 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 771 |
+
"bScalar": "\"u32\"",
|
| 772 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 773 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 774 |
+
"M": "aRows",
|
| 775 |
+
"K": "attrs.K",
|
| 776 |
+
"N": "attrs.N",
|
| 777 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 778 |
+
"blockSize": "attrs.block_size",
|
| 779 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 780 |
+
"bits": "attrs.bits",
|
| 781 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 782 |
+
"usesF16": "tensorDtypes.A == \"float16\"",
|
| 783 |
+
"tileRows": "sgmatTileRows",
|
| 784 |
+
"workgroupSize": "sgmatWorkgroupSize",
|
| 785 |
+
"rowSubtiles": "sgmatRowSubtiles",
|
| 786 |
+
"bLoadsPerRow": "sgmatBLoadsPerRow",
|
| 787 |
+
"bLoadWidth": "sgmatBLoadWidth",
|
| 788 |
+
"numSubgroups": "sgmatNumSubgroups"
|
| 789 |
+
},
|
| 790 |
+
"passes": [
|
| 791 |
+
{
|
| 792 |
+
"id": "main",
|
| 793 |
+
"shader": "matmul-nbits-q4-sgmat.wgsl.jinja",
|
| 794 |
+
"bindings": "prefillDefaultZero",
|
| 795 |
+
"dispatch": { "x": "dispatchN64", "y": "sgmatDispatchM" }
|
| 796 |
+
}
|
| 797 |
+
]
|
| 798 |
+
},
|
| 799 |
+
{
|
| 800 |
+
"id": "prefill_tiled_reg_default_zero",
|
| 801 |
+
"priority": 17,
|
| 802 |
+
"when": ["commonShapeValid", "defaultEpilogue", "bitsSupported", "dispatchN64 <= device.limits.maxComputeWorkgroupsPerDimension", "tiledRegVariantEligible"],
|
| 803 |
+
"constants": {
|
| 804 |
+
"hasZero": false,
|
| 805 |
+
"hasBias": false,
|
| 806 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 807 |
+
"bScalar": "\"u32\"",
|
| 808 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 809 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 810 |
+
"M": "aRows",
|
| 811 |
+
"K": "attrs.K",
|
| 812 |
+
"N": "attrs.N",
|
| 813 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 814 |
+
"blockSize": "attrs.block_size",
|
| 815 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 816 |
+
"bits": "attrs.bits",
|
| 817 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 818 |
+
"usesF16": "tensorDtypes.A == \"float16\"",
|
| 819 |
+
"bk": "tiledRegSelectedBK",
|
| 820 |
+
"tileRows": "tiledRegSelectedTileRows",
|
| 821 |
+
"tileCols": 64,
|
| 822 |
+
"threadRows": "tiledRegSelectedThreadRows",
|
| 823 |
+
"threadCols": 4,
|
| 824 |
+
"alignedBlockLoads": "aRows >= 128 and attrs.block_size % tiledRegSelectedBK == 0"
|
| 825 |
+
},
|
| 826 |
+
"passes": [
|
| 827 |
+
{
|
| 828 |
+
"id": "main",
|
| 829 |
+
"shader": "matmul-nbits-q4-prefill-tiled-reg.wgsl.jinja",
|
| 830 |
+
"bindings": "prefillDefaultZero",
|
| 831 |
+
"dispatch": { "x": "dispatchN64", "y": "tiledRegSelectedDispatchM" }
|
| 832 |
+
}
|
| 833 |
+
]
|
| 834 |
+
},
|
| 835 |
+
{
|
| 836 |
+
"id": "prefill_tiled_default_zero",
|
| 837 |
+
"priority": 16,
|
| 838 |
+
"when": ["commonShapeValid", "defaultEpilogue", "bitsSupported", "attrs.K % attrs.block_size == 0", "aRows >= 64", "dispatchN32 <= device.limits.maxComputeWorkgroupsPerDimension", "dispatchM32 <= device.limits.maxComputeWorkgroupsPerDimension", "tiledWorkgroupFits"],
|
| 839 |
+
"constants": {
|
| 840 |
+
"hasZero": false,
|
| 841 |
+
"hasBias": false,
|
| 842 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 843 |
+
"bScalar": "\"u32\"",
|
| 844 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 845 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 846 |
+
"M": "aRows",
|
| 847 |
+
"K": "attrs.K",
|
| 848 |
+
"N": "attrs.N",
|
| 849 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 850 |
+
"blockSize": "attrs.block_size",
|
| 851 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 852 |
+
"bits": "attrs.bits",
|
| 853 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 854 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 855 |
+
},
|
| 856 |
+
"passes": [
|
| 857 |
+
{
|
| 858 |
+
"id": "main",
|
| 859 |
+
"shader": "matmul-nbits-q4-prefill-tiled.wgsl.jinja",
|
| 860 |
+
"bindings": "prefillDefaultZero",
|
| 861 |
+
"dispatch": { "x": "dispatchN32", "y": "dispatchM32" }
|
| 862 |
+
}
|
| 863 |
+
]
|
| 864 |
+
},
|
| 865 |
+
{
|
| 866 |
+
"id": "prefill_tile4x4_default_zero",
|
| 867 |
+
"priority": 15,
|
| 868 |
+
"when": ["commonShapeValid", "defaultEpilogue", "bitsSupported", "attrs.K % attrs.block_size == 0", "aRows >= 2", "portableWorkgroupFits"],
|
| 869 |
+
"constants": {
|
| 870 |
+
"hasZero": false,
|
| 871 |
+
"hasBias": false,
|
| 872 |
+
"workgroupSize": "portableWorkgroupSize",
|
| 873 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 874 |
+
"bScalar": "\"u32\"",
|
| 875 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 876 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 877 |
+
"bits": "attrs.bits",
|
| 878 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 879 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 880 |
+
},
|
| 881 |
+
"passes": [
|
| 882 |
+
{
|
| 883 |
+
"id": "main",
|
| 884 |
+
"shader": "matmul-nbits-q4-prefill-tile4x4.wgsl.jinja",
|
| 885 |
+
"bindings": "genericDefaultZero",
|
| 886 |
+
"dispatch": {
|
| 887 |
+
"workgroups": "dispatchN4",
|
| 888 |
+
"y": "min(ceilDiv(aRows, 4), device.limits.maxComputeWorkgroupsPerDimension)"
|
| 889 |
+
}
|
| 890 |
+
}
|
| 891 |
+
]
|
| 892 |
+
},
|
| 893 |
+
{
|
| 894 |
+
"id": "default_zero",
|
| 895 |
+
"priority": 0,
|
| 896 |
+
"when": ["commonShapeValid", "defaultEpilogue", "bitsSupported", "portableWorkgroupFits"],
|
| 897 |
+
"constants": {
|
| 898 |
+
"hasZero": false,
|
| 899 |
+
"hasBias": false,
|
| 900 |
+
"workgroupSize": "portableWorkgroupSize",
|
| 901 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 902 |
+
"bScalar": "\"u32\"",
|
| 903 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 904 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 905 |
+
"bits": "attrs.bits",
|
| 906 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 907 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 908 |
+
},
|
| 909 |
+
"passes": [
|
| 910 |
+
{
|
| 911 |
+
"id": "main",
|
| 912 |
+
"shader": "matmul-nbits.wgsl.jinja",
|
| 913 |
+
"bindings": "genericDefaultZero",
|
| 914 |
+
"dispatch": { "threads": "numel(shapes.Y)", "workgroupSize": "constants.workgroupSize" }
|
| 915 |
+
}
|
| 916 |
+
]
|
| 917 |
+
},
|
| 918 |
+
{
|
| 919 |
+
"id": "gemv_zero_bias",
|
| 920 |
+
"priority": 20,
|
| 921 |
+
"when": ["gemvShapeValid", "zeroBiasEpilogue", "bitsSupported", "portableWorkgroupFits"],
|
| 922 |
+
"constants": {
|
| 923 |
+
"gemvNCols": "tunables.GEMV_N_COLS",
|
| 924 |
+
"hasZero": true,
|
| 925 |
+
"hasBias": true,
|
| 926 |
+
"workgroupSize": "portableWorkgroupSize",
|
| 927 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 928 |
+
"bScalar": "\"u32\"",
|
| 929 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 930 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 931 |
+
"bits": "attrs.bits",
|
| 932 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 933 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 934 |
+
},
|
| 935 |
+
"passes": [
|
| 936 |
+
{
|
| 937 |
+
"id": "main",
|
| 938 |
+
"shader": "matmul-nbits-gemv-q4.wgsl.jinja",
|
| 939 |
+
"bindings": "gemvZeroBias",
|
| 940 |
+
"dispatch": { "workgroups": "gemvDispatchN" }
|
| 941 |
+
}
|
| 942 |
+
]
|
| 943 |
+
},
|
| 944 |
+
{
|
| 945 |
+
"id": "prefill_sgmat_zero_bias",
|
| 946 |
+
"priority": 18,
|
| 947 |
+
"requires": {
|
| 948 |
+
"features": ["subgroups", "chromium-experimental-subgroup-matrix"],
|
| 949 |
+
"limits": { "maxComputeWorkgroupStorageSize": 16384 },
|
| 950 |
+
"subgroupMinSize": 32,
|
| 951 |
+
"subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
|
| 952 |
+
},
|
| 953 |
+
"when": ["commonShapeValid", "zeroBiasEpilogue", "bitsSupported", "attrs.K % attrs.block_size == 0", "attrs.block_size % 16 == 0", "attrs.K % 32 == 0", "aRows >= 32", "has(device.adapterInfo, \"subgroupMinSize\")", "has(device.adapterInfo, \"subgroupMaxSize\")", "device.adapterInfo.subgroupMinSize == 32", "device.adapterInfo.subgroupMaxSize == 32", "dispatchN64 <= device.limits.maxComputeWorkgroupsPerDimension", "sgmatDispatchM <= device.limits.maxComputeWorkgroupsPerDimension", "portableWorkgroupFits", "sgmatWorkgroupFits"],
|
| 954 |
+
"constants": {
|
| 955 |
+
"hasZero": true,
|
| 956 |
+
"hasBias": true,
|
| 957 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 958 |
+
"bScalar": "\"u32\"",
|
| 959 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 960 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 961 |
+
"M": "aRows",
|
| 962 |
+
"K": "attrs.K",
|
| 963 |
+
"N": "attrs.N",
|
| 964 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 965 |
+
"blockSize": "attrs.block_size",
|
| 966 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 967 |
+
"bits": "attrs.bits",
|
| 968 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 969 |
+
"usesF16": "tensorDtypes.A == \"float16\"",
|
| 970 |
+
"tileRows": "sgmatTileRows",
|
| 971 |
+
"workgroupSize": "sgmatWorkgroupSize",
|
| 972 |
+
"rowSubtiles": "sgmatRowSubtiles",
|
| 973 |
+
"bLoadsPerRow": "sgmatBLoadsPerRow",
|
| 974 |
+
"bLoadWidth": "sgmatBLoadWidth",
|
| 975 |
+
"numSubgroups": "sgmatNumSubgroups"
|
| 976 |
+
},
|
| 977 |
+
"passes": [
|
| 978 |
+
{
|
| 979 |
+
"id": "main",
|
| 980 |
+
"shader": "matmul-nbits-q4-sgmat.wgsl.jinja",
|
| 981 |
+
"bindings": "prefillZeroBias",
|
| 982 |
+
"dispatch": { "x": "dispatchN64", "y": "sgmatDispatchM" }
|
| 983 |
+
}
|
| 984 |
+
]
|
| 985 |
+
},
|
| 986 |
+
{
|
| 987 |
+
"id": "prefill_tiled_reg_zero_bias",
|
| 988 |
+
"priority": 17,
|
| 989 |
+
"when": ["commonShapeValid", "zeroBiasEpilogue", "bitsSupported", "dispatchN64 <= device.limits.maxComputeWorkgroupsPerDimension", "tiledRegVariantEligible"],
|
| 990 |
+
"constants": {
|
| 991 |
+
"hasZero": true,
|
| 992 |
+
"hasBias": true,
|
| 993 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 994 |
+
"bScalar": "\"u32\"",
|
| 995 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 996 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 997 |
+
"M": "aRows",
|
| 998 |
+
"K": "attrs.K",
|
| 999 |
+
"N": "attrs.N",
|
| 1000 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 1001 |
+
"blockSize": "attrs.block_size",
|
| 1002 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 1003 |
+
"bits": "attrs.bits",
|
| 1004 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1005 |
+
"usesF16": "tensorDtypes.A == \"float16\"",
|
| 1006 |
+
"bk": "tiledRegSelectedBK",
|
| 1007 |
+
"tileRows": "tiledRegSelectedTileRows",
|
| 1008 |
+
"tileCols": 64,
|
| 1009 |
+
"threadRows": "tiledRegSelectedThreadRows",
|
| 1010 |
+
"threadCols": 4,
|
| 1011 |
+
"alignedBlockLoads": "aRows >= 128 and attrs.block_size % tiledRegSelectedBK == 0"
|
| 1012 |
+
},
|
| 1013 |
+
"passes": [
|
| 1014 |
+
{
|
| 1015 |
+
"id": "main",
|
| 1016 |
+
"shader": "matmul-nbits-q4-prefill-tiled-reg.wgsl.jinja",
|
| 1017 |
+
"bindings": "prefillZeroBias",
|
| 1018 |
+
"dispatch": { "x": "dispatchN64", "y": "tiledRegSelectedDispatchM" }
|
| 1019 |
+
}
|
| 1020 |
+
]
|
| 1021 |
+
},
|
| 1022 |
+
{
|
| 1023 |
+
"id": "prefill_tiled_zero_bias",
|
| 1024 |
+
"priority": 16,
|
| 1025 |
+
"when": ["commonShapeValid", "zeroBiasEpilogue", "bitsSupported", "attrs.K % attrs.block_size == 0", "aRows >= 64", "dispatchN32 <= device.limits.maxComputeWorkgroupsPerDimension", "dispatchM32 <= device.limits.maxComputeWorkgroupsPerDimension", "tiledWorkgroupFits"],
|
| 1026 |
+
"constants": {
|
| 1027 |
+
"hasZero": true,
|
| 1028 |
+
"hasBias": true,
|
| 1029 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1030 |
+
"bScalar": "\"u32\"",
|
| 1031 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1032 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1033 |
+
"M": "aRows",
|
| 1034 |
+
"K": "attrs.K",
|
| 1035 |
+
"N": "attrs.N",
|
| 1036 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 1037 |
+
"blockSize": "attrs.block_size",
|
| 1038 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 1039 |
+
"bits": "attrs.bits",
|
| 1040 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1041 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 1042 |
+
},
|
| 1043 |
+
"passes": [
|
| 1044 |
+
{
|
| 1045 |
+
"id": "main",
|
| 1046 |
+
"shader": "matmul-nbits-q4-prefill-tiled.wgsl.jinja",
|
| 1047 |
+
"bindings": "prefillZeroBias",
|
| 1048 |
+
"dispatch": { "x": "dispatchN32", "y": "dispatchM32" }
|
| 1049 |
+
}
|
| 1050 |
+
]
|
| 1051 |
+
},
|
| 1052 |
+
{
|
| 1053 |
+
"id": "prefill_tile4x4_zero_bias",
|
| 1054 |
+
"priority": 15,
|
| 1055 |
+
"when": ["commonShapeValid", "zeroBiasEpilogue", "bitsSupported", "attrs.K % attrs.block_size == 0", "aRows >= 2", "portableWorkgroupFits"],
|
| 1056 |
+
"constants": {
|
| 1057 |
+
"hasZero": true,
|
| 1058 |
+
"hasBias": true,
|
| 1059 |
+
"workgroupSize": "portableWorkgroupSize",
|
| 1060 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1061 |
+
"bScalar": "\"u32\"",
|
| 1062 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1063 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1064 |
+
"bits": "attrs.bits",
|
| 1065 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1066 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 1067 |
+
},
|
| 1068 |
+
"passes": [
|
| 1069 |
+
{
|
| 1070 |
+
"id": "main",
|
| 1071 |
+
"shader": "matmul-nbits-q4-prefill-tile4x4.wgsl.jinja",
|
| 1072 |
+
"bindings": "genericZeroBias",
|
| 1073 |
+
"dispatch": {
|
| 1074 |
+
"workgroups": "dispatchN4",
|
| 1075 |
+
"y": "min(ceilDiv(aRows, 4), device.limits.maxComputeWorkgroupsPerDimension)"
|
| 1076 |
+
}
|
| 1077 |
+
}
|
| 1078 |
+
]
|
| 1079 |
+
},
|
| 1080 |
+
{
|
| 1081 |
+
"id": "zero_bias",
|
| 1082 |
+
"priority": 0,
|
| 1083 |
+
"when": ["commonShapeValid", "zeroBiasEpilogue", "bitsSupported", "portableWorkgroupFits"],
|
| 1084 |
+
"constants": {
|
| 1085 |
+
"hasZero": true,
|
| 1086 |
+
"hasBias": true,
|
| 1087 |
+
"workgroupSize": "portableWorkgroupSize",
|
| 1088 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1089 |
+
"bScalar": "\"u32\"",
|
| 1090 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1091 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1092 |
+
"bits": "attrs.bits",
|
| 1093 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1094 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 1095 |
+
},
|
| 1096 |
+
"passes": [
|
| 1097 |
+
{
|
| 1098 |
+
"id": "main",
|
| 1099 |
+
"shader": "matmul-nbits.wgsl.jinja",
|
| 1100 |
+
"bindings": "genericZeroBias",
|
| 1101 |
+
"dispatch": { "threads": "numel(shapes.Y)", "workgroupSize": "constants.workgroupSize" }
|
| 1102 |
+
}
|
| 1103 |
+
]
|
| 1104 |
+
},
|
| 1105 |
+
{
|
| 1106 |
+
"id": "gemv_zero_only",
|
| 1107 |
+
"priority": 20,
|
| 1108 |
+
"when": ["gemvShapeValid", "zeroOnlyEpilogue", "bitsSupported", "portableWorkgroupFits"],
|
| 1109 |
+
"constants": {
|
| 1110 |
+
"gemvNCols": "tunables.GEMV_N_COLS",
|
| 1111 |
+
"hasZero": true,
|
| 1112 |
+
"hasBias": false,
|
| 1113 |
+
"workgroupSize": "portableWorkgroupSize",
|
| 1114 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1115 |
+
"bScalar": "\"u32\"",
|
| 1116 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1117 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1118 |
+
"bits": "attrs.bits",
|
| 1119 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1120 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 1121 |
+
},
|
| 1122 |
+
"passes": [
|
| 1123 |
+
{
|
| 1124 |
+
"id": "main",
|
| 1125 |
+
"shader": "matmul-nbits-gemv-q4.wgsl.jinja",
|
| 1126 |
+
"bindings": "gemvZeroOnly",
|
| 1127 |
+
"dispatch": { "workgroups": "gemvDispatchN" }
|
| 1128 |
+
}
|
| 1129 |
+
]
|
| 1130 |
+
},
|
| 1131 |
+
{
|
| 1132 |
+
"id": "prefill_sgmat_zero_only",
|
| 1133 |
+
"priority": 18,
|
| 1134 |
+
"requires": {
|
| 1135 |
+
"features": ["subgroups", "chromium-experimental-subgroup-matrix"],
|
| 1136 |
+
"limits": { "maxComputeWorkgroupStorageSize": 16384 },
|
| 1137 |
+
"subgroupMinSize": 32,
|
| 1138 |
+
"subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
|
| 1139 |
+
},
|
| 1140 |
+
"when": ["commonShapeValid", "zeroOnlyEpilogue", "bitsSupported", "attrs.K % attrs.block_size == 0", "attrs.block_size % 16 == 0", "attrs.K % 32 == 0", "aRows >= 32", "has(device.adapterInfo, \"subgroupMinSize\")", "has(device.adapterInfo, \"subgroupMaxSize\")", "device.adapterInfo.subgroupMinSize == 32", "device.adapterInfo.subgroupMaxSize == 32", "dispatchN64 <= device.limits.maxComputeWorkgroupsPerDimension", "sgmatDispatchM <= device.limits.maxComputeWorkgroupsPerDimension", "portableWorkgroupFits", "sgmatWorkgroupFits"],
|
| 1141 |
+
"constants": {
|
| 1142 |
+
"hasZero": true,
|
| 1143 |
+
"hasBias": false,
|
| 1144 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1145 |
+
"bScalar": "\"u32\"",
|
| 1146 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1147 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1148 |
+
"M": "aRows",
|
| 1149 |
+
"K": "attrs.K",
|
| 1150 |
+
"N": "attrs.N",
|
| 1151 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 1152 |
+
"blockSize": "attrs.block_size",
|
| 1153 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 1154 |
+
"bits": "attrs.bits",
|
| 1155 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1156 |
+
"usesF16": "tensorDtypes.A == \"float16\"",
|
| 1157 |
+
"tileRows": "sgmatTileRows",
|
| 1158 |
+
"workgroupSize": "sgmatWorkgroupSize",
|
| 1159 |
+
"rowSubtiles": "sgmatRowSubtiles",
|
| 1160 |
+
"bLoadsPerRow": "sgmatBLoadsPerRow",
|
| 1161 |
+
"bLoadWidth": "sgmatBLoadWidth",
|
| 1162 |
+
"numSubgroups": "sgmatNumSubgroups"
|
| 1163 |
+
},
|
| 1164 |
+
"passes": [
|
| 1165 |
+
{
|
| 1166 |
+
"id": "main",
|
| 1167 |
+
"shader": "matmul-nbits-q4-sgmat.wgsl.jinja",
|
| 1168 |
+
"bindings": "prefillZeroOnly",
|
| 1169 |
+
"dispatch": { "x": "dispatchN64", "y": "sgmatDispatchM" }
|
| 1170 |
+
}
|
| 1171 |
+
]
|
| 1172 |
+
},
|
| 1173 |
+
{
|
| 1174 |
+
"id": "prefill_tiled_reg_zero_only",
|
| 1175 |
+
"priority": 17,
|
| 1176 |
+
"when": ["commonShapeValid", "zeroOnlyEpilogue", "bitsSupported", "dispatchN64 <= device.limits.maxComputeWorkgroupsPerDimension", "tiledRegVariantEligible"],
|
| 1177 |
+
"constants": {
|
| 1178 |
+
"hasZero": true,
|
| 1179 |
+
"hasBias": false,
|
| 1180 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1181 |
+
"bScalar": "\"u32\"",
|
| 1182 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1183 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1184 |
+
"M": "aRows",
|
| 1185 |
+
"K": "attrs.K",
|
| 1186 |
+
"N": "attrs.N",
|
| 1187 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 1188 |
+
"blockSize": "attrs.block_size",
|
| 1189 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 1190 |
+
"bits": "attrs.bits",
|
| 1191 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1192 |
+
"usesF16": "tensorDtypes.A == \"float16\"",
|
| 1193 |
+
"bk": "tiledRegSelectedBK",
|
| 1194 |
+
"tileRows": "tiledRegSelectedTileRows",
|
| 1195 |
+
"tileCols": 64,
|
| 1196 |
+
"threadRows": "tiledRegSelectedThreadRows",
|
| 1197 |
+
"threadCols": 4,
|
| 1198 |
+
"alignedBlockLoads": "aRows >= 128 and attrs.block_size % tiledRegSelectedBK == 0"
|
| 1199 |
+
},
|
| 1200 |
+
"passes": [
|
| 1201 |
+
{
|
| 1202 |
+
"id": "main",
|
| 1203 |
+
"shader": "matmul-nbits-q4-prefill-tiled-reg.wgsl.jinja",
|
| 1204 |
+
"bindings": "prefillZeroOnly",
|
| 1205 |
+
"dispatch": { "x": "dispatchN64", "y": "tiledRegSelectedDispatchM" }
|
| 1206 |
+
}
|
| 1207 |
+
]
|
| 1208 |
+
},
|
| 1209 |
+
{
|
| 1210 |
+
"id": "prefill_tiled_zero_only",
|
| 1211 |
+
"priority": 16,
|
| 1212 |
+
"when": ["commonShapeValid", "zeroOnlyEpilogue", "bitsSupported", "attrs.K % attrs.block_size == 0", "aRows >= 64", "dispatchN32 <= device.limits.maxComputeWorkgroupsPerDimension", "dispatchM32 <= device.limits.maxComputeWorkgroupsPerDimension", "tiledWorkgroupFits"],
|
| 1213 |
+
"constants": {
|
| 1214 |
+
"hasZero": true,
|
| 1215 |
+
"hasBias": false,
|
| 1216 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1217 |
+
"bScalar": "\"u32\"",
|
| 1218 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1219 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1220 |
+
"M": "aRows",
|
| 1221 |
+
"K": "attrs.K",
|
| 1222 |
+
"N": "attrs.N",
|
| 1223 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 1224 |
+
"blockSize": "attrs.block_size",
|
| 1225 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 1226 |
+
"bits": "attrs.bits",
|
| 1227 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1228 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 1229 |
+
},
|
| 1230 |
+
"passes": [
|
| 1231 |
+
{
|
| 1232 |
+
"id": "main",
|
| 1233 |
+
"shader": "matmul-nbits-q4-prefill-tiled.wgsl.jinja",
|
| 1234 |
+
"bindings": "prefillZeroOnly",
|
| 1235 |
+
"dispatch": { "x": "dispatchN32", "y": "dispatchM32" }
|
| 1236 |
+
}
|
| 1237 |
+
]
|
| 1238 |
+
},
|
| 1239 |
+
{
|
| 1240 |
+
"id": "prefill_tile4x4_zero_only",
|
| 1241 |
+
"priority": 15,
|
| 1242 |
+
"when": ["commonShapeValid", "zeroOnlyEpilogue", "bitsSupported", "attrs.K % attrs.block_size == 0", "aRows >= 2", "portableWorkgroupFits"],
|
| 1243 |
+
"constants": {
|
| 1244 |
+
"hasZero": true,
|
| 1245 |
+
"hasBias": false,
|
| 1246 |
+
"workgroupSize": "portableWorkgroupSize",
|
| 1247 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1248 |
+
"bScalar": "\"u32\"",
|
| 1249 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1250 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1251 |
+
"bits": "attrs.bits",
|
| 1252 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1253 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 1254 |
+
},
|
| 1255 |
+
"passes": [
|
| 1256 |
+
{
|
| 1257 |
+
"id": "main",
|
| 1258 |
+
"shader": "matmul-nbits-q4-prefill-tile4x4.wgsl.jinja",
|
| 1259 |
+
"bindings": "genericZeroOnly",
|
| 1260 |
+
"dispatch": {
|
| 1261 |
+
"workgroups": "dispatchN4",
|
| 1262 |
+
"y": "min(ceilDiv(aRows, 4), device.limits.maxComputeWorkgroupsPerDimension)"
|
| 1263 |
+
}
|
| 1264 |
+
}
|
| 1265 |
+
]
|
| 1266 |
+
},
|
| 1267 |
+
{
|
| 1268 |
+
"id": "zero_only",
|
| 1269 |
+
"priority": 0,
|
| 1270 |
+
"when": ["commonShapeValid", "zeroOnlyEpilogue", "bitsSupported", "portableWorkgroupFits"],
|
| 1271 |
+
"constants": {
|
| 1272 |
+
"hasZero": true,
|
| 1273 |
+
"hasBias": false,
|
| 1274 |
+
"workgroupSize": "portableWorkgroupSize",
|
| 1275 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1276 |
+
"bScalar": "\"u32\"",
|
| 1277 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1278 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1279 |
+
"bits": "attrs.bits",
|
| 1280 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1281 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 1282 |
+
},
|
| 1283 |
+
"passes": [
|
| 1284 |
+
{
|
| 1285 |
+
"id": "main",
|
| 1286 |
+
"shader": "matmul-nbits.wgsl.jinja",
|
| 1287 |
+
"bindings": "genericZeroOnly",
|
| 1288 |
+
"dispatch": { "threads": "numel(shapes.Y)", "workgroupSize": "constants.workgroupSize" }
|
| 1289 |
+
}
|
| 1290 |
+
]
|
| 1291 |
+
},
|
| 1292 |
+
{
|
| 1293 |
+
"id": "gemv_bias_only",
|
| 1294 |
+
"priority": 20,
|
| 1295 |
+
"when": ["gemvShapeValid", "biasOnlyEpilogue", "bitsSupported", "portableWorkgroupFits"],
|
| 1296 |
+
"constants": {
|
| 1297 |
+
"gemvNCols": "tunables.GEMV_N_COLS",
|
| 1298 |
+
"hasZero": false,
|
| 1299 |
+
"hasBias": true,
|
| 1300 |
+
"workgroupSize": "portableWorkgroupSize",
|
| 1301 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1302 |
+
"bScalar": "\"u32\"",
|
| 1303 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1304 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1305 |
+
"bits": "attrs.bits",
|
| 1306 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1307 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 1308 |
+
},
|
| 1309 |
+
"passes": [
|
| 1310 |
+
{
|
| 1311 |
+
"id": "main",
|
| 1312 |
+
"shader": "matmul-nbits-gemv-q4.wgsl.jinja",
|
| 1313 |
+
"bindings": "gemvBiasOnly",
|
| 1314 |
+
"dispatch": { "workgroups": "gemvDispatchN" }
|
| 1315 |
+
}
|
| 1316 |
+
]
|
| 1317 |
+
},
|
| 1318 |
+
{
|
| 1319 |
+
"id": "prefill_sgmat_bias_only",
|
| 1320 |
+
"priority": 18,
|
| 1321 |
+
"requires": {
|
| 1322 |
+
"features": ["subgroups", "chromium-experimental-subgroup-matrix"],
|
| 1323 |
+
"limits": { "maxComputeWorkgroupStorageSize": 16384 },
|
| 1324 |
+
"subgroupMinSize": 32,
|
| 1325 |
+
"subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
|
| 1326 |
+
},
|
| 1327 |
+
"when": ["commonShapeValid", "biasOnlyEpilogue", "bitsSupported", "attrs.K % attrs.block_size == 0", "attrs.block_size % 16 == 0", "attrs.K % 32 == 0", "aRows >= 32", "has(device.adapterInfo, \"subgroupMinSize\")", "has(device.adapterInfo, \"subgroupMaxSize\")", "device.adapterInfo.subgroupMinSize == 32", "device.adapterInfo.subgroupMaxSize == 32", "dispatchN64 <= device.limits.maxComputeWorkgroupsPerDimension", "sgmatDispatchM <= device.limits.maxComputeWorkgroupsPerDimension", "portableWorkgroupFits", "sgmatWorkgroupFits"],
|
| 1328 |
+
"constants": {
|
| 1329 |
+
"hasZero": false,
|
| 1330 |
+
"hasBias": true,
|
| 1331 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1332 |
+
"bScalar": "\"u32\"",
|
| 1333 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1334 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1335 |
+
"M": "aRows",
|
| 1336 |
+
"K": "attrs.K",
|
| 1337 |
+
"N": "attrs.N",
|
| 1338 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 1339 |
+
"blockSize": "attrs.block_size",
|
| 1340 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 1341 |
+
"bits": "attrs.bits",
|
| 1342 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1343 |
+
"usesF16": "tensorDtypes.A == \"float16\"",
|
| 1344 |
+
"tileRows": "sgmatTileRows",
|
| 1345 |
+
"workgroupSize": "sgmatWorkgroupSize",
|
| 1346 |
+
"rowSubtiles": "sgmatRowSubtiles",
|
| 1347 |
+
"bLoadsPerRow": "sgmatBLoadsPerRow",
|
| 1348 |
+
"bLoadWidth": "sgmatBLoadWidth",
|
| 1349 |
+
"numSubgroups": "sgmatNumSubgroups"
|
| 1350 |
+
},
|
| 1351 |
+
"passes": [
|
| 1352 |
+
{
|
| 1353 |
+
"id": "main",
|
| 1354 |
+
"shader": "matmul-nbits-q4-sgmat.wgsl.jinja",
|
| 1355 |
+
"bindings": "prefillBiasOnly",
|
| 1356 |
+
"dispatch": { "x": "dispatchN64", "y": "sgmatDispatchM" }
|
| 1357 |
+
}
|
| 1358 |
+
]
|
| 1359 |
+
},
|
| 1360 |
+
{
|
| 1361 |
+
"id": "prefill_tiled_reg_bias_only",
|
| 1362 |
+
"priority": 17,
|
| 1363 |
+
"when": ["commonShapeValid", "biasOnlyEpilogue", "bitsSupported", "dispatchN64 <= device.limits.maxComputeWorkgroupsPerDimension", "tiledRegVariantEligible"],
|
| 1364 |
+
"constants": {
|
| 1365 |
+
"hasZero": false,
|
| 1366 |
+
"hasBias": true,
|
| 1367 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1368 |
+
"bScalar": "\"u32\"",
|
| 1369 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1370 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1371 |
+
"M": "aRows",
|
| 1372 |
+
"K": "attrs.K",
|
| 1373 |
+
"N": "attrs.N",
|
| 1374 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 1375 |
+
"blockSize": "attrs.block_size",
|
| 1376 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 1377 |
+
"bits": "attrs.bits",
|
| 1378 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1379 |
+
"usesF16": "tensorDtypes.A == \"float16\"",
|
| 1380 |
+
"bk": "tiledRegSelectedBK",
|
| 1381 |
+
"tileRows": "tiledRegSelectedTileRows",
|
| 1382 |
+
"tileCols": 64,
|
| 1383 |
+
"threadRows": "tiledRegSelectedThreadRows",
|
| 1384 |
+
"threadCols": 4,
|
| 1385 |
+
"alignedBlockLoads": "aRows >= 128 and attrs.block_size % tiledRegSelectedBK == 0"
|
| 1386 |
+
},
|
| 1387 |
+
"passes": [
|
| 1388 |
+
{
|
| 1389 |
+
"id": "main",
|
| 1390 |
+
"shader": "matmul-nbits-q4-prefill-tiled-reg.wgsl.jinja",
|
| 1391 |
+
"bindings": "prefillBiasOnly",
|
| 1392 |
+
"dispatch": { "x": "dispatchN64", "y": "tiledRegSelectedDispatchM" }
|
| 1393 |
+
}
|
| 1394 |
+
]
|
| 1395 |
+
},
|
| 1396 |
+
{
|
| 1397 |
+
"id": "prefill_tiled_bias_only",
|
| 1398 |
+
"priority": 16,
|
| 1399 |
+
"when": ["commonShapeValid", "biasOnlyEpilogue", "bitsSupported", "attrs.K % attrs.block_size == 0", "aRows >= 64", "dispatchN32 <= device.limits.maxComputeWorkgroupsPerDimension", "dispatchM32 <= device.limits.maxComputeWorkgroupsPerDimension", "tiledWorkgroupFits"],
|
| 1400 |
+
"constants": {
|
| 1401 |
+
"hasZero": false,
|
| 1402 |
+
"hasBias": true,
|
| 1403 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1404 |
+
"bScalar": "\"u32\"",
|
| 1405 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1406 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1407 |
+
"M": "aRows",
|
| 1408 |
+
"K": "attrs.K",
|
| 1409 |
+
"N": "attrs.N",
|
| 1410 |
+
"kBlocks": "dim(shapes.B, 1)",
|
| 1411 |
+
"blockSize": "attrs.block_size",
|
| 1412 |
+
"blobSize": "dim(shapes.B, 2)",
|
| 1413 |
+
"bits": "attrs.bits",
|
| 1414 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1415 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 1416 |
+
},
|
| 1417 |
+
"passes": [
|
| 1418 |
+
{
|
| 1419 |
+
"id": "main",
|
| 1420 |
+
"shader": "matmul-nbits-q4-prefill-tiled.wgsl.jinja",
|
| 1421 |
+
"bindings": "prefillBiasOnly",
|
| 1422 |
+
"dispatch": { "x": "dispatchN32", "y": "dispatchM32" }
|
| 1423 |
+
}
|
| 1424 |
+
]
|
| 1425 |
+
},
|
| 1426 |
+
{
|
| 1427 |
+
"id": "prefill_tile4x4_bias_only",
|
| 1428 |
+
"priority": 15,
|
| 1429 |
+
"when": ["commonShapeValid", "biasOnlyEpilogue", "bitsSupported", "attrs.K % attrs.block_size == 0", "aRows >= 2", "portableWorkgroupFits"],
|
| 1430 |
+
"constants": {
|
| 1431 |
+
"hasZero": false,
|
| 1432 |
+
"hasBias": true,
|
| 1433 |
+
"workgroupSize": "portableWorkgroupSize",
|
| 1434 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1435 |
+
"bScalar": "\"u32\"",
|
| 1436 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1437 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1438 |
+
"bits": "attrs.bits",
|
| 1439 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1440 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 1441 |
+
},
|
| 1442 |
+
"passes": [
|
| 1443 |
+
{
|
| 1444 |
+
"id": "main",
|
| 1445 |
+
"shader": "matmul-nbits-q4-prefill-tile4x4.wgsl.jinja",
|
| 1446 |
+
"bindings": "genericBiasOnly",
|
| 1447 |
+
"dispatch": {
|
| 1448 |
+
"workgroups": "dispatchN4",
|
| 1449 |
+
"y": "min(ceilDiv(aRows, 4), device.limits.maxComputeWorkgroupsPerDimension)"
|
| 1450 |
+
}
|
| 1451 |
+
}
|
| 1452 |
+
]
|
| 1453 |
+
},
|
| 1454 |
+
{
|
| 1455 |
+
"id": "bias_only",
|
| 1456 |
+
"priority": 0,
|
| 1457 |
+
"when": ["commonShapeValid", "biasOnlyEpilogue", "bitsSupported", "portableWorkgroupFits"],
|
| 1458 |
+
"constants": {
|
| 1459 |
+
"hasZero": false,
|
| 1460 |
+
"hasBias": true,
|
| 1461 |
+
"workgroupSize": "portableWorkgroupSize",
|
| 1462 |
+
"aScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1463 |
+
"bScalar": "\"u32\"",
|
| 1464 |
+
"scaleScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1465 |
+
"outputScalar": "\"f16\" if tensorDtypes.A == \"float16\" else \"f32\"",
|
| 1466 |
+
"bits": "attrs.bits",
|
| 1467 |
+
"defaultZero": "\"2.0\" if attrs.bits == 2 else (\"8.0\" if attrs.bits == 4 else \"128.0\")",
|
| 1468 |
+
"usesF16": "tensorDtypes.A == \"float16\""
|
| 1469 |
+
},
|
| 1470 |
+
"passes": [
|
| 1471 |
+
{
|
| 1472 |
+
"id": "main",
|
| 1473 |
+
"shader": "matmul-nbits.wgsl.jinja",
|
| 1474 |
+
"bindings": "genericBiasOnly",
|
| 1475 |
+
"dispatch": { "threads": "numel(shapes.Y)", "workgroupSize": "constants.workgroupSize" }
|
| 1476 |
+
}
|
| 1477 |
+
]
|
| 1478 |
+
}
|
| 1479 |
+
]
|
| 1480 |
+
}
|
build/webgpu/matmul-nbits-dp4a-quantize.wgsl.jinja
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{ env.wgsl.resourceDeclarations }}
|
| 2 |
+
|
| 3 |
+
// Quantize A rows to signed int8 for the packed-integer-dot kernel: each
|
| 4 |
+
// 128-element block shares one scale (max_abs / 127) and stores 4 values per
|
| 5 |
+
// u32 via pack4x8snorm. All-zero blocks store zeros with a zero scale. K is a
|
| 6 |
+
// multiple of 128, so blocks never straddle rows and the flat layout is exact.
|
| 7 |
+
const VEC4_COUNT: u32 = {{ vec4Count }}u;
|
| 8 |
+
const BLOCK_COUNT: u32 = {{ blockCount }}u;
|
| 9 |
+
const WG: u32 = 64u;
|
| 10 |
+
|
| 11 |
+
var<workgroup> maxAbs: array<f32, WG>;
|
| 12 |
+
|
| 13 |
+
@compute @workgroup_size(WG)
|
| 14 |
+
fn main(
|
| 15 |
+
@builtin(workgroup_id) wid: vec3<u32>,
|
| 16 |
+
@builtin(num_workgroups) nwg: vec3<u32>,
|
| 17 |
+
@builtin(local_invocation_id) lid: vec3<u32>
|
| 18 |
+
) {
|
| 19 |
+
// 2D-folded dispatch: wid.y carries the high bits past the per-dimension limit.
|
| 20 |
+
let wgFlat = wid.x + wid.y * nwg.x;
|
| 21 |
+
let i = wgFlat * WG + lid.x;
|
| 22 |
+
var v = vec4<f32>(0.0);
|
| 23 |
+
if (i < VEC4_COUNT) {
|
| 24 |
+
v = vec4<f32>(f32(a[i * 4u]), f32(a[i * 4u + 1u]), f32(a[i * 4u + 2u]), f32(a[i * 4u + 3u]));
|
| 25 |
+
}
|
| 26 |
+
let av = abs(v);
|
| 27 |
+
maxAbs[lid.x] = max(max(av.x, av.y), max(av.z, av.w));
|
| 28 |
+
workgroupBarrier();
|
| 29 |
+
|
| 30 |
+
// Each 32-lane half of the workgroup covers one 128-element quant block.
|
| 31 |
+
let halfBase = (lid.x / 32u) * 32u;
|
| 32 |
+
var scale = 0.0;
|
| 33 |
+
for (var l = 0u; l < 32u; l = l + 1u) { scale = max(scale, maxAbs[halfBase + l]); }
|
| 34 |
+
|
| 35 |
+
if (i < VEC4_COUNT) {
|
| 36 |
+
if (scale > 0.0) {
|
| 37 |
+
a_quant[i] = pack4x8snorm(v / scale);
|
| 38 |
+
} else {
|
| 39 |
+
a_quant[i] = 0u;
|
| 40 |
+
}
|
| 41 |
+
}
|
| 42 |
+
let blockIdx = wgFlat * 2u + lid.x / 32u;
|
| 43 |
+
if (lid.x % 32u == 0u && blockIdx < BLOCK_COUNT) {
|
| 44 |
+
a_scales[blockIdx] = scale / 127.0;
|
| 45 |
+
}
|
| 46 |
+
}
|
build/webgpu/matmul-nbits-gemv-q4.wgsl.jinja
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% if usesF16 %}
|
| 2 |
+
enable f16;
|
| 3 |
+
{% endif %}
|
| 4 |
+
{{ env.wgsl.resourceDeclarations }}
|
| 5 |
+
// Each workgroup handles gemvNCols columns in groups of four, with one vec4
|
| 6 |
+
// accumulator and partial array per group. Every column after the first is
|
| 7 |
+
// bounds-guarded, so arbitrary N and group counts compose.
|
| 8 |
+
{% set nCols = gemvNCols %}
|
| 9 |
+
{% set groups = 2 if nCols == 8 else 1 %}
|
| 10 |
+
{% set comps = ["x", "y", "z", "w"] %}
|
| 11 |
+
|
| 12 |
+
const WG: u32 = {{ workgroupSize }}u;
|
| 13 |
+
const N_COLS: u32 = {{ nCols }}u;
|
| 14 |
+
|
| 15 |
+
{% for g in range(groups) %}
|
| 16 |
+
{% set sfx = "" if groups == 1 else g %}
|
| 17 |
+
var<workgroup> partials{{ sfx }}: array<vec4<f32>, {{ workgroupSize }}>;
|
| 18 |
+
{% endfor %}
|
| 19 |
+
|
| 20 |
+
// {{ bits }}-bit unpack: q2 packs four codes per byte, q4 two nibbles, q8 one byte/weight.
|
| 21 |
+
{% macro matmul_nbits_packed_code(fn="packed_weight", buffer="b", kBlocks="params.kBlocks", blobSize="params.blobSize", bits=4) %}
|
| 22 |
+
fn {{ fn }}(n: u32, block: u32, offset: u32) -> u32 {
|
| 23 |
+
{% if bits == 2 %}
|
| 24 |
+
let byte_index = offset / 4u;
|
| 25 |
+
let shift = (offset % 4u) * 2u;
|
| 26 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + byte_index;
|
| 27 |
+
return ({{ buffer }}[packed_index] >> shift) & 3u;
|
| 28 |
+
{% elif bits == 4 %}
|
| 29 |
+
let byte_index = offset / 2u;
|
| 30 |
+
let shift = (offset % 2u) * 4u;
|
| 31 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + byte_index;
|
| 32 |
+
return ({{ buffer }}[packed_index] >> shift) & 15u;
|
| 33 |
+
{% else %}
|
| 34 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + offset;
|
| 35 |
+
return {{ buffer }}[packed_index] & 255u;
|
| 36 |
+
{% endif %}
|
| 37 |
+
}
|
| 38 |
+
{%- endmacro %}
|
| 39 |
+
{{- matmul_nbits_packed_code(bits=bits) }}
|
| 40 |
+
|
| 41 |
+
// Per-(column, block) zero point. Symmetric weights use the baked default
|
| 42 |
+
// ({{ defaultZero }}); asymmetric weights carry one widened u32 per (col, block)
|
| 43 |
+
// in row-major [N, kBlocks] layout.
|
| 44 |
+
fn zero_point({% if hasZero %}n: u32, block: u32{% endif %}) -> f32 {
|
| 45 |
+
{% if hasZero %}
|
| 46 |
+
return f32(zero_points[n * params.kBlocks + block]);
|
| 47 |
+
{% else %}
|
| 48 |
+
return {{ defaultZero }};
|
| 49 |
+
{% endif %}
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
@compute @workgroup_size({{ workgroupSize }}, 1, 1)
|
| 53 |
+
fn main(
|
| 54 |
+
@builtin(workgroup_id) wid: vec3<u32>,
|
| 55 |
+
@builtin(num_workgroups) nwg: vec3<u32>,
|
| 56 |
+
@builtin(local_invocation_id) lid: vec3<u32>
|
| 57 |
+
) {
|
| 58 |
+
let tid = lid.x;
|
| 59 |
+
// 2D-folded dispatch: wid.y carries the high bits past the per-dimension
|
| 60 |
+
// limit (vocab-sized N). The fold over-dispatches, so the tail workgroups
|
| 61 |
+
// return before any barrier.
|
| 62 |
+
let col_base = (wid.x + wid.y * nwg.x) * N_COLS;
|
| 63 |
+
if (col_base >= params.N) {
|
| 64 |
+
return;
|
| 65 |
+
}
|
| 66 |
+
{% for g in range(groups) %}
|
| 67 |
+
{% set sfx = "" if groups == 1 else g %}
|
| 68 |
+
var acc{{ sfx }} = vec4<f32>(0.0);
|
| 69 |
+
{% endfor %}
|
| 70 |
+
|
| 71 |
+
for (var k = tid; k < params.K; k = k + WG) {
|
| 72 |
+
let block = k / params.blockSize;
|
| 73 |
+
let offset = k % params.blockSize;
|
| 74 |
+
let av = f32(a[k]);
|
| 75 |
+
{% for g in range(groups) %}
|
| 76 |
+
{% set sfx = "" if groups == 1 else g %}
|
| 77 |
+
{% for c in range(4) %}
|
| 78 |
+
{% set i = g * 4 + c %}
|
| 79 |
+
{% if i == 0 %}
|
| 80 |
+
let scale0 = f32(scales[(col_base + 0u) * params.kBlocks + block]);
|
| 81 |
+
let q0 = f32(packed_weight(col_base + 0u, block, offset)) - zero_point({% if hasZero %}col_base + 0u, block{% endif %});
|
| 82 |
+
acc{{ sfx }}.x = acc{{ sfx }}.x + av * q0 * scale0;
|
| 83 |
+
{% else %}
|
| 84 |
+
if (col_base + {{ i }}u < params.N) {
|
| 85 |
+
let scale{{ i }} = f32(scales[(col_base + {{ i }}u) * params.kBlocks + block]);
|
| 86 |
+
let q{{ i }} = f32(packed_weight(col_base + {{ i }}u, block, offset)) - zero_point({% if hasZero %}col_base + {{ i }}u, block{% endif %});
|
| 87 |
+
acc{{ sfx }}.{{ comps[c] }} = acc{{ sfx }}.{{ comps[c] }} + av * q{{ i }} * scale{{ i }};
|
| 88 |
+
}
|
| 89 |
+
{% endif %}
|
| 90 |
+
{% endfor %}
|
| 91 |
+
{% endfor %}
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
{% for g in range(groups) %}
|
| 95 |
+
{% set sfx = "" if groups == 1 else g %}
|
| 96 |
+
partials{{ sfx }}[tid] = acc{{ sfx }};
|
| 97 |
+
{% endfor %}
|
| 98 |
+
workgroupBarrier();
|
| 99 |
+
|
| 100 |
+
var stride = WG / 2u;
|
| 101 |
+
loop {
|
| 102 |
+
if (stride == 0u) {
|
| 103 |
+
break;
|
| 104 |
+
}
|
| 105 |
+
if (tid < stride) {
|
| 106 |
+
{% for g in range(groups) %}
|
| 107 |
+
{% set sfx = "" if groups == 1 else g %}
|
| 108 |
+
partials{{ sfx }}[tid] = partials{{ sfx }}[tid] + partials{{ sfx }}[tid + stride];
|
| 109 |
+
{% endfor %}
|
| 110 |
+
}
|
| 111 |
+
stride = stride / 2u;
|
| 112 |
+
workgroupBarrier();
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
if (tid == 0u) {
|
| 116 |
+
{% for g in range(groups) %}
|
| 117 |
+
{% set sfx = "" if groups == 1 else g %}
|
| 118 |
+
let total{{ sfx }} = partials{{ sfx }}[0];
|
| 119 |
+
{% endfor %}
|
| 120 |
+
{% for g in range(groups) %}
|
| 121 |
+
{% set sfx = "" if groups == 1 else g %}
|
| 122 |
+
{% for c in range(4) %}
|
| 123 |
+
{% set i = g * 4 + c %}
|
| 124 |
+
{% if hasBias %}
|
| 125 |
+
{% if i == 0 %}
|
| 126 |
+
y[col_base + 0u] = {{ outputScalar }}(total{{ sfx }}.x + f32(bias[col_base + 0u]));
|
| 127 |
+
{% else %}
|
| 128 |
+
if (col_base + {{ i }}u < params.N) {
|
| 129 |
+
y[col_base + {{ i }}u] = {{ outputScalar }}(total{{ sfx }}.{{ comps[c] }} + f32(bias[col_base + {{ i }}u]));
|
| 130 |
+
}
|
| 131 |
+
{% endif %}
|
| 132 |
+
{% else %}
|
| 133 |
+
{% if i == 0 %}
|
| 134 |
+
y[col_base + 0u] = {{ outputScalar }}(total{{ sfx }}.x);
|
| 135 |
+
{% else %}
|
| 136 |
+
if (col_base + {{ i }}u < params.N) {
|
| 137 |
+
y[col_base + {{ i }}u] = {{ outputScalar }}(total{{ sfx }}.{{ comps[c] }});
|
| 138 |
+
}
|
| 139 |
+
{% endif %}
|
| 140 |
+
{% endif %}
|
| 141 |
+
{% endfor %}
|
| 142 |
+
{% endfor %}
|
| 143 |
+
}
|
| 144 |
+
}
|
build/webgpu/matmul-nbits-q4-dp4a-prefill.wgsl.jinja
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{{ env.wgsl.resourceDeclarations }}
|
| 2 |
+
// Centralize the signed packed-int8 dot expression so unrolled callers cannot
|
| 3 |
+
// collide in lowering-generated temporaries.
|
| 4 |
+
fn dot4_packed(a_word: u32, b_word: u32) -> i32 {
|
| 5 |
+
return dot4I8Packed(a_word, b_word);
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
|
| 9 |
+
// com.microsoft.MatMulNBits q4 prefill with int8-quantized activations
|
| 10 |
+
// (accuracy_level 4). A arrives pre-quantized as packed int8 words with one
|
| 11 |
+
// scale per 128-element block; each weight nibble is rebiased by -8 and packed
|
| 12 |
+
// so the whole inner product runs on packed-integer dots. One 64x64 output
|
| 13 |
+
// tile per workgroup, 4x4 per thread, K stepped 32 elements (8 words) at a
|
| 14 |
+
// time — a step never straddles a weight block (blockSize % 32 == 0) or an
|
| 15 |
+
// activation block (128 % 32 == 0), so both scales are per-step constants.
|
| 16 |
+
const M: u32 = {{ M }}u;
|
| 17 |
+
const K: u32 = {{ K }}u;
|
| 18 |
+
const N: u32 = {{ N }}u;
|
| 19 |
+
const KBLOCKS: u32 = {{ kBlocks }}u;
|
| 20 |
+
const BLOCK_SIZE: u32 = {{ blockSize }}u;
|
| 21 |
+
const BLOB_SIZE: u32 = {{ blobSize }}u;
|
| 22 |
+
const K4: u32 = K / 4u;
|
| 23 |
+
const KSCALE: u32 = K / 128u;
|
| 24 |
+
|
| 25 |
+
var<workgroup> tA: array<array<u32, 8u>, 64u>;
|
| 26 |
+
var<workgroup> tB: array<array<u32, 8u>, 64u>;
|
| 27 |
+
var<workgroup> tAscale: array<f32, 64u>;
|
| 28 |
+
var<workgroup> tBscale: array<f32, 64u>;
|
| 29 |
+
|
| 30 |
+
@compute @workgroup_size(16, 16, 1)
|
| 31 |
+
fn main(
|
| 32 |
+
@builtin(workgroup_id) wg: vec3<u32>,
|
| 33 |
+
@builtin(local_invocation_id) lid: vec3<u32>
|
| 34 |
+
) {
|
| 35 |
+
let mBase = wg.y * 64u;
|
| 36 |
+
let nBase = wg.x * 64u;
|
| 37 |
+
let li = lid.y * 16u + lid.x;
|
| 38 |
+
|
| 39 |
+
var acc: array<f32, 16u>;
|
| 40 |
+
for (var t = 0u; t < 16u; t = t + 1u) { acc[t] = 0.0; }
|
| 41 |
+
|
| 42 |
+
let numTiles = K / 32u;
|
| 43 |
+
for (var kt = 0u; kt < numTiles; kt = kt + 1u) {
|
| 44 |
+
let kBase = kt * 32u;
|
| 45 |
+
let block = kBase / BLOCK_SIZE;
|
| 46 |
+
// Stage 64 rows x 8 packed A words and 64 cols x 8 packed B words; each of
|
| 47 |
+
// the 256 threads loads two of each.
|
| 48 |
+
for (var e = 0u; e < 2u; e = e + 1u) {
|
| 49 |
+
let idx = li + e * 256u;
|
| 50 |
+
let r = idx / 8u;
|
| 51 |
+
let w = idx % 8u;
|
| 52 |
+
let am = mBase + r;
|
| 53 |
+
tA[r][w] = select(0u, a_quant[am * K4 + kt * 8u + w], am < M);
|
| 54 |
+
let bn = nBase + r;
|
| 55 |
+
if (bn < N) {
|
| 56 |
+
// Two blob bytes hold this word's four sequential weights
|
| 57 |
+
// (low nibble = even k). Rebias by the implicit zero point 8.
|
| 58 |
+
let byteBase = (bn * KBLOCKS + block) * BLOB_SIZE + ((kBase % BLOCK_SIZE) + w * 4u) / 2u;
|
| 59 |
+
let b0 = b[byteBase];
|
| 60 |
+
let b1 = b[byteBase + 1u];
|
| 61 |
+
let quads = vec4<i32>(i32(b0 & 15u), i32((b0 >> 4u) & 15u), i32(b1 & 15u), i32((b1 >> 4u) & 15u));
|
| 62 |
+
tB[r][w] = pack4xI8(quads - vec4<i32>(8));
|
| 63 |
+
} else {
|
| 64 |
+
tB[r][w] = 0u;
|
| 65 |
+
}
|
| 66 |
+
}
|
| 67 |
+
if (li < 64u) {
|
| 68 |
+
let am = mBase + li;
|
| 69 |
+
tAscale[li] = select(0.0, a_scales[am * KSCALE + kBase / 128u], am < M);
|
| 70 |
+
let bn = nBase + li;
|
| 71 |
+
tBscale[li] = select(0.0, scales[bn * KBLOCKS + block], bn < N);
|
| 72 |
+
}
|
| 73 |
+
workgroupBarrier();
|
| 74 |
+
|
| 75 |
+
let aRow = lid.y * 4u;
|
| 76 |
+
let bCol = lid.x * 4u;
|
| 77 |
+
for (var i = 0u; i < 4u; i = i + 1u) {
|
| 78 |
+
let ar = aRow + i;
|
| 79 |
+
var aw: array<u32, 8u>;
|
| 80 |
+
for (var w = 0u; w < 8u; w = w + 1u) { aw[w] = tA[ar][w]; }
|
| 81 |
+
let sa = tAscale[ar];
|
| 82 |
+
for (var j = 0u; j < 4u; j = j + 1u) {
|
| 83 |
+
let bc = bCol + j;
|
| 84 |
+
var d = 0i;
|
| 85 |
+
for (var w = 0u; w < 8u; w = w + 1u) { d = d + dot4_packed(aw[w], tB[bc][w]); }
|
| 86 |
+
acc[i * 4u + j] = acc[i * 4u + j] + f32(d) * sa * tBscale[bc];
|
| 87 |
+
}
|
| 88 |
+
}
|
| 89 |
+
workgroupBarrier();
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
let m0 = mBase + lid.y * 4u;
|
| 93 |
+
let n0 = nBase + lid.x * 4u;
|
| 94 |
+
for (var i = 0u; i < 4u; i = i + 1u) {
|
| 95 |
+
let m = m0 + i;
|
| 96 |
+
if (m >= M) { continue; }
|
| 97 |
+
for (var j = 0u; j < 4u; j = j + 1u) {
|
| 98 |
+
let n = n0 + j;
|
| 99 |
+
if (n < N) {
|
| 100 |
+
y[m * N + n] = acc[i * 4u + j];
|
| 101 |
+
}
|
| 102 |
+
}
|
| 103 |
+
}
|
| 104 |
+
}
|
build/webgpu/matmul-nbits-q4-prefill-tile4x4.wgsl.jinja
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% if usesF16 %}
|
| 2 |
+
enable f16;
|
| 3 |
+
{% endif %}
|
| 4 |
+
{{ env.wgsl.resourceDeclarations }}
|
| 5 |
+
|
| 6 |
+
const WG: u32 = {{ workgroupSize }}u;
|
| 7 |
+
const TILE_M: u32 = 4u;
|
| 8 |
+
const TILE_N: u32 = 4u;
|
| 9 |
+
|
| 10 |
+
var<workgroup> partial0: array<vec4<f32>, {{ workgroupSize }}>;
|
| 11 |
+
var<workgroup> partial1: array<vec4<f32>, {{ workgroupSize }}>;
|
| 12 |
+
var<workgroup> partial2: array<vec4<f32>, {{ workgroupSize }}>;
|
| 13 |
+
var<workgroup> partial3: array<vec4<f32>, {{ workgroupSize }}>;
|
| 14 |
+
|
| 15 |
+
// {{ bits }}-bit unpack: q2 stores four codes per byte, q4 two, and q8 one.
|
| 16 |
+
{% macro matmul_nbits_packed_code(fn="packed_weight", buffer="b", kBlocks="params.kBlocks", blobSize="params.blobSize", bits=4) %}
|
| 17 |
+
fn {{ fn }}(n: u32, block: u32, offset: u32) -> u32 {
|
| 18 |
+
{% if bits == 2 %}
|
| 19 |
+
let byte_index = offset / 4u;
|
| 20 |
+
let shift = (offset % 4u) * 2u;
|
| 21 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + byte_index;
|
| 22 |
+
return ({{ buffer }}[packed_index] >> shift) & 3u;
|
| 23 |
+
{% elif bits == 4 %}
|
| 24 |
+
let byte_index = offset / 2u;
|
| 25 |
+
let shift = (offset % 2u) * 4u;
|
| 26 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + byte_index;
|
| 27 |
+
return ({{ buffer }}[packed_index] >> shift) & 15u;
|
| 28 |
+
{% else %}
|
| 29 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + offset;
|
| 30 |
+
return {{ buffer }}[packed_index] & 255u;
|
| 31 |
+
{% endif %}
|
| 32 |
+
}
|
| 33 |
+
{%- endmacro %}
|
| 34 |
+
{{- matmul_nbits_packed_code(bits=bits) }}
|
| 35 |
+
|
| 36 |
+
fn store_row(row: u32, col_base: u32, value: vec4<f32>) {
|
| 37 |
+
if (row >= params.rows) {
|
| 38 |
+
return;
|
| 39 |
+
}
|
| 40 |
+
let out_base = row * params.N + col_base;
|
| 41 |
+
// N need not be a multiple of TILE_N: the final column tile is partial, so
|
| 42 |
+
// guard lanes 1..3 against params.N (col_base itself is always < N). Without
|
| 43 |
+
// this an odd-N tail would spill into the next row. Lane 0 is unconditional.
|
| 44 |
+
y[out_base + 0u] = {{ outputScalar }}(value.x);
|
| 45 |
+
if (col_base + 1u < params.N) { y[out_base + 1u] = {{ outputScalar }}(value.y); }
|
| 46 |
+
if (col_base + 2u < params.N) { y[out_base + 2u] = {{ outputScalar }}(value.z); }
|
| 47 |
+
if (col_base + 3u < params.N) { y[out_base + 3u] = {{ outputScalar }}(value.w); }
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
@compute @workgroup_size({{ workgroupSize }}, 1, 1)
|
| 51 |
+
fn main(
|
| 52 |
+
@builtin(workgroup_id) wid: vec3<u32>,
|
| 53 |
+
@builtin(local_invocation_id) lid: vec3<u32>,
|
| 54 |
+
@builtin(num_workgroups) nwg: vec3<u32>
|
| 55 |
+
) {
|
| 56 |
+
let tid = lid.x;
|
| 57 |
+
// Column tiles fold into z past the per-dimension limit (vocab-sized N,
|
| 58 |
+
// where y already carries the row-tile grid-stride). Over-dispatched tail
|
| 59 |
+
// workgroups return before any barrier.
|
| 60 |
+
let col_base = (wid.x + wid.z * nwg.x) * TILE_N;
|
| 61 |
+
if (col_base >= params.N) {
|
| 62 |
+
return;
|
| 63 |
+
}
|
| 64 |
+
|
| 65 |
+
// Grid-stride over row tiles because dispatch y is device-clamped. This loop
|
| 66 |
+
// reduces to one iteration when the dispatch covers every tile directly.
|
| 67 |
+
for (var row_tile = wid.y; row_tile * TILE_M < params.rows; row_tile = row_tile + nwg.y) {
|
| 68 |
+
let row_base = row_tile * TILE_M;
|
| 69 |
+
|
| 70 |
+
var acc0 = vec4<f32>(0.0);
|
| 71 |
+
var acc1 = vec4<f32>(0.0);
|
| 72 |
+
var acc2 = vec4<f32>(0.0);
|
| 73 |
+
var acc3 = vec4<f32>(0.0);
|
| 74 |
+
|
| 75 |
+
for (var block: u32 = 0u; block < params.kBlocks; block = block + 1u) {
|
| 76 |
+
let scale = vec4<f32>(
|
| 77 |
+
f32(scales[(col_base + 0u) * params.kBlocks + block]),
|
| 78 |
+
f32(scales[(col_base + 1u) * params.kBlocks + block]),
|
| 79 |
+
f32(scales[(col_base + 2u) * params.kBlocks + block]),
|
| 80 |
+
f32(scales[(col_base + 3u) * params.kBlocks + block])
|
| 81 |
+
);
|
| 82 |
+
let block_k = block * params.blockSize;
|
| 83 |
+
|
| 84 |
+
for (var offset: u32 = tid; offset < params.blockSize; offset = offset + WG) {
|
| 85 |
+
let k = block_k + offset;
|
| 86 |
+
{% if hasZero %}
|
| 87 |
+
let zero = vec4<f32>(
|
| 88 |
+
f32(zero_points[(col_base + 0u) * params.kBlocks + block]),
|
| 89 |
+
f32(zero_points[(col_base + 1u) * params.kBlocks + block]),
|
| 90 |
+
f32(zero_points[(col_base + 2u) * params.kBlocks + block]),
|
| 91 |
+
f32(zero_points[(col_base + 3u) * params.kBlocks + block])
|
| 92 |
+
);
|
| 93 |
+
{% else %}
|
| 94 |
+
let zero = vec4<f32>({{ defaultZero }});
|
| 95 |
+
{% endif %}
|
| 96 |
+
let w = (vec4<f32>(
|
| 97 |
+
f32(packed_weight(col_base + 0u, block, offset)),
|
| 98 |
+
f32(packed_weight(col_base + 1u, block, offset)),
|
| 99 |
+
f32(packed_weight(col_base + 2u, block, offset)),
|
| 100 |
+
f32(packed_weight(col_base + 3u, block, offset))
|
| 101 |
+
) - zero) * scale;
|
| 102 |
+
|
| 103 |
+
var a0 = 0.0;
|
| 104 |
+
var a1 = 0.0;
|
| 105 |
+
var a2 = 0.0;
|
| 106 |
+
var a3 = 0.0;
|
| 107 |
+
if (row_base + 0u < params.rows) {
|
| 108 |
+
a0 = f32(a[(row_base + 0u) * params.K + k]);
|
| 109 |
+
}
|
| 110 |
+
if (row_base + 1u < params.rows) {
|
| 111 |
+
a1 = f32(a[(row_base + 1u) * params.K + k]);
|
| 112 |
+
}
|
| 113 |
+
if (row_base + 2u < params.rows) {
|
| 114 |
+
a2 = f32(a[(row_base + 2u) * params.K + k]);
|
| 115 |
+
}
|
| 116 |
+
if (row_base + 3u < params.rows) {
|
| 117 |
+
a3 = f32(a[(row_base + 3u) * params.K + k]);
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
acc0 = acc0 + a0 * w;
|
| 121 |
+
acc1 = acc1 + a1 * w;
|
| 122 |
+
acc2 = acc2 + a2 * w;
|
| 123 |
+
acc3 = acc3 + a3 * w;
|
| 124 |
+
}
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
// Sync before reusing the shared partial buffers: on a subsequent grid-stride
|
| 128 |
+
// iteration the previous iteration's tid==0 store may still be reading them.
|
| 129 |
+
workgroupBarrier();
|
| 130 |
+
partial0[tid] = acc0;
|
| 131 |
+
partial1[tid] = acc1;
|
| 132 |
+
partial2[tid] = acc2;
|
| 133 |
+
partial3[tid] = acc3;
|
| 134 |
+
workgroupBarrier();
|
| 135 |
+
|
| 136 |
+
var stride = WG / 2u;
|
| 137 |
+
loop {
|
| 138 |
+
if (stride == 0u) {
|
| 139 |
+
break;
|
| 140 |
+
}
|
| 141 |
+
if (tid < stride) {
|
| 142 |
+
partial0[tid] = partial0[tid] + partial0[tid + stride];
|
| 143 |
+
partial1[tid] = partial1[tid] + partial1[tid + stride];
|
| 144 |
+
partial2[tid] = partial2[tid] + partial2[tid + stride];
|
| 145 |
+
partial3[tid] = partial3[tid] + partial3[tid + stride];
|
| 146 |
+
}
|
| 147 |
+
stride = stride / 2u;
|
| 148 |
+
workgroupBarrier();
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
if (tid == 0u) {
|
| 152 |
+
{% if hasBias %}
|
| 153 |
+
let biasv = vec4<f32>(
|
| 154 |
+
f32(bias[col_base + 0u]),
|
| 155 |
+
f32(bias[col_base + 1u]),
|
| 156 |
+
f32(bias[col_base + 2u]),
|
| 157 |
+
f32(bias[col_base + 3u])
|
| 158 |
+
);
|
| 159 |
+
store_row(row_base + 0u, col_base, partial0[0] + biasv);
|
| 160 |
+
store_row(row_base + 1u, col_base, partial1[0] + biasv);
|
| 161 |
+
store_row(row_base + 2u, col_base, partial2[0] + biasv);
|
| 162 |
+
store_row(row_base + 3u, col_base, partial3[0] + biasv);
|
| 163 |
+
{% else %}
|
| 164 |
+
store_row(row_base + 0u, col_base, partial0[0]);
|
| 165 |
+
store_row(row_base + 1u, col_base, partial1[0]);
|
| 166 |
+
store_row(row_base + 2u, col_base, partial2[0]);
|
| 167 |
+
store_row(row_base + 3u, col_base, partial3[0]);
|
| 168 |
+
{% endif %}
|
| 169 |
+
}
|
| 170 |
+
}
|
| 171 |
+
}
|
build/webgpu/matmul-nbits-q4-prefill-tiled-reg.wgsl.jinja
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% if usesF16 %}
|
| 2 |
+
enable f16;
|
| 3 |
+
{% endif %}
|
| 4 |
+
{{ env.wgsl.resourceDeclarations }}
|
| 5 |
+
|
| 6 |
+
// com.microsoft.MatMulNBits q4/q8 prefill, no-subgroup-matrix tier — register-blocked.
|
| 7 |
+
// Y[M,N] = A[M,K] @ W[K,N] (+ bias), W[k,n] = (q(n,block,offset) - zero) * scale
|
| 8 |
+
// Dequantizes into a shared [BN][BK/4] tile with device-selected register
|
| 9 |
+
// blocking. Both tiles are indexed by their own output axis and group four K
|
| 10 |
+
// values per vector word, so the micro-tile accumulates through dot() and the
|
| 11 |
+
// column-owning loader writes whole words instead of a BN-strided column.
|
| 12 |
+
// The full geometry computes a 4x4 micro-tile over a 64x64 output tile. The
|
| 13 |
+
// portable geometry computes 2x4 over 32x64 to bound the per-lane accumulator
|
| 14 |
+
// set. K_TILE specializes the K tile. For standard 32/64-element quant blocks,
|
| 15 |
+
// one lane owns one output column and the full BK slice: scale and zero are
|
| 16 |
+
// loaded once, and each stored byte is read once for the K-adjacent codes it
|
| 17 |
+
// carries.
|
| 18 |
+
// Fully bounds-checked (any M/N; K % blockSize == 0).
|
| 19 |
+
const M: u32 = {{ M }}u;
|
| 20 |
+
const K: u32 = {{ K }}u;
|
| 21 |
+
const N: u32 = {{ N }}u;
|
| 22 |
+
const KBLOCKS: u32 = {{ kBlocks }}u;
|
| 23 |
+
const BLOCK_SIZE: u32 = {{ blockSize }}u;
|
| 24 |
+
const BLOB_SIZE: u32 = {{ blobSize }}u;
|
| 25 |
+
const BK: u32 = {{ bk }}u;
|
| 26 |
+
const BM: u32 = {{ tileRows }}u;
|
| 27 |
+
const BN: u32 = {{ tileCols }}u;
|
| 28 |
+
const TM: u32 = {{ threadRows }}u;
|
| 29 |
+
const TN: u32 = {{ threadCols }}u;
|
| 30 |
+
const WG_X: u32 = 16u;
|
| 31 |
+
const WG_Y: u32 = 16u;
|
| 32 |
+
const WG_THREADS: u32 = WG_X * WG_Y;
|
| 33 |
+
|
| 34 |
+
// When A uses f16 storage, staging tileA at f16 is bit-identical to widening it
|
| 35 |
+
// here. tileB stays f32 because the dequantized (code - zero)*scale product
|
| 36 |
+
// needs more mantissa than f16 provides.
|
| 37 |
+
{% set aTile = "f16" if usesF16 else "f32" %}
|
| 38 |
+
{% set aRead = "vec4<f32>(" if usesF16 else "" %}
|
| 39 |
+
{% set aReadEnd = ")" if usesF16 else "" %}
|
| 40 |
+
const K_VECS: u32 = BK / 4u;
|
| 41 |
+
var<workgroup> tileA: array<array<vec4<{{ aTile }}>, K_VECS>, BM>; // [BM][BK/4]
|
| 42 |
+
var<workgroup> tileB: array<array<vec4<f32>, K_VECS>, BN>; // [BN][BK/4]
|
| 43 |
+
{% if not alignedBlockLoads %}
|
| 44 |
+
|
| 45 |
+
// Generic unpack used only when a quant block does not contain a whole BK tile.
|
| 46 |
+
{% macro matmul_nbits_packed_code(fn="packed_weight", buffer="b", kBlocks="params.kBlocks", blobSize="params.blobSize", bits=4) %}
|
| 47 |
+
fn {{ fn }}(n: u32, block: u32, offset: u32) -> u32 {
|
| 48 |
+
{% if bits == 2 %}
|
| 49 |
+
let byte_index = offset / 4u;
|
| 50 |
+
let shift = (offset % 4u) * 2u;
|
| 51 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + byte_index;
|
| 52 |
+
return ({{ buffer }}[packed_index] >> shift) & 3u;
|
| 53 |
+
{% elif bits == 4 %}
|
| 54 |
+
let byte_index = offset / 2u;
|
| 55 |
+
let shift = (offset % 2u) * 4u;
|
| 56 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + byte_index;
|
| 57 |
+
return ({{ buffer }}[packed_index] >> shift) & 15u;
|
| 58 |
+
{% else %}
|
| 59 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + offset;
|
| 60 |
+
return {{ buffer }}[packed_index] & 255u;
|
| 61 |
+
{% endif %}
|
| 62 |
+
}
|
| 63 |
+
{%- endmacro %}
|
| 64 |
+
{{- matmul_nbits_packed_code(bits=bits, kBlocks="KBLOCKS", blobSize="BLOB_SIZE") }}
|
| 65 |
+
|
| 66 |
+
{% endif %}
|
| 67 |
+
{% macro zero_of(blockExpr) %}{% if hasZero %}f32(zero_points[bn * KBLOCKS + {{ blockExpr }}]){% else %}{{ defaultZero }}{% endif %}{% endmacro %}
|
| 68 |
+
|
| 69 |
+
@compute @workgroup_size(16, 16, 1)
|
| 70 |
+
fn main(
|
| 71 |
+
@builtin(workgroup_id) wg: vec3<u32>,
|
| 72 |
+
@builtin(local_invocation_id) lid: vec3<u32>
|
| 73 |
+
) {
|
| 74 |
+
let mBase = wg.y * BM;
|
| 75 |
+
let nBase = wg.x * BN;
|
| 76 |
+
let li = lid.y * WG_X + lid.x;
|
| 77 |
+
|
| 78 |
+
{% for i in range(threadRows) %}
|
| 79 |
+
{% for j in range(threadCols) %}
|
| 80 |
+
var acc{{ i }}{{ j }}: f32 = 0.0;
|
| 81 |
+
{% endfor %}
|
| 82 |
+
{% endfor %}
|
| 83 |
+
|
| 84 |
+
let numTiles = (K + BK - 1u) / BK;
|
| 85 |
+
for (var kt: u32 = 0u; kt < numTiles; kt = kt + 1u) {
|
| 86 |
+
let kBase = kt * BK;
|
| 87 |
+
// A and B may have different tile areas (32x64 portable geometry), so stage
|
| 88 |
+
// them independently. Every configured area is an exact WG_THREADS multiple.
|
| 89 |
+
for (var idx: u32 = li; idx < BM * K_VECS; idx = idx + WG_THREADS) {
|
| 90 |
+
let ar = idx / K_VECS;
|
| 91 |
+
let ac4 = idx % K_VECS;
|
| 92 |
+
let am = mBase + ar;
|
| 93 |
+
let ak = kBase + ac4 * 4u;
|
| 94 |
+
var aWord = vec4<{{ aTile }}>({{ aTile }}(0.0));
|
| 95 |
+
if (am < M) {
|
| 96 |
+
{% for component in range(4) %}
|
| 97 |
+
if (ak + {{ component }}u < K) { aWord[{{ component }}u] = {{ aTile }}(a[am * K + ak + {{ component }}u]); }
|
| 98 |
+
{% endfor %}
|
| 99 |
+
}
|
| 100 |
+
tileA[ar][ac4] = aWord;
|
| 101 |
+
}
|
| 102 |
+
{% if alignedBlockLoads %}
|
| 103 |
+
// Every lane materializes one vector word of one output column. BLOCK_SIZE is
|
| 104 |
+
// a multiple of BK, so the whole tile slice of a column shares one scale and
|
| 105 |
+
// zero point and each stored byte is read once for the codes it carries.
|
| 106 |
+
for (var idx: u32 = li; idx < BN * K_VECS; idx = idx + WG_THREADS) {
|
| 107 |
+
let bc = idx / K_VECS;
|
| 108 |
+
let kv = idx % K_VECS;
|
| 109 |
+
let bn = nBase + bc;
|
| 110 |
+
var word = vec4<f32>(0.0);
|
| 111 |
+
if (bn < N && kBase < K) {
|
| 112 |
+
let block = kBase / BLOCK_SIZE;
|
| 113 |
+
let offset0 = kBase % BLOCK_SIZE;
|
| 114 |
+
let scale = f32(scales[bn * KBLOCKS + block]);
|
| 115 |
+
let zero = {{ zero_of("block") }};
|
| 116 |
+
let blob_base = (bn * KBLOCKS + block) * BLOB_SIZE;
|
| 117 |
+
let kk = kv * 4u;
|
| 118 |
+
{% if bits == 2 %}
|
| 119 |
+
// Four 2-bit codes share a stored byte, and an aligned tile starts a
|
| 120 |
+
// word on a byte boundary, so one byte fills one vector word.
|
| 121 |
+
let packed = b[blob_base + (offset0 + kk) / 4u];
|
| 122 |
+
{% for component in range(4) %}
|
| 123 |
+
if (kBase + kk + {{ component }}u < K) {
|
| 124 |
+
word[{{ component }}u] = (f32((packed >> {{ component * 2 }}u) & 3u) - zero) * scale;
|
| 125 |
+
}
|
| 126 |
+
{% endfor %}
|
| 127 |
+
{% elif bits == 4 %}
|
| 128 |
+
// Two bytes carry the four K-adjacent codes of one vector word.
|
| 129 |
+
let byte_index = blob_base + (offset0 + kk) / 2u;
|
| 130 |
+
let packed0 = b[byte_index];
|
| 131 |
+
let packed1 = b[byte_index + 1u];
|
| 132 |
+
{% for component in range(4) %}
|
| 133 |
+
if (kBase + kk + {{ component }}u < K) {
|
| 134 |
+
word[{{ component }}u] = (f32(({{ "packed0" if component < 2 else "packed1" }} >> {{ (component % 2) * 4 }}u) & 15u) - zero) * scale;
|
| 135 |
+
}
|
| 136 |
+
{% endfor %}
|
| 137 |
+
{% else %}
|
| 138 |
+
let byte_index = blob_base + offset0 + kk;
|
| 139 |
+
{% for component in range(4) %}
|
| 140 |
+
if (kBase + kk + {{ component }}u < K) {
|
| 141 |
+
word[{{ component }}u] = (f32(b[byte_index + {{ component }}u] & 255u) - zero) * scale;
|
| 142 |
+
}
|
| 143 |
+
{% endfor %}
|
| 144 |
+
{% endif %}
|
| 145 |
+
}
|
| 146 |
+
tileB[bc][kv] = word;
|
| 147 |
+
}
|
| 148 |
+
{% else %}
|
| 149 |
+
// Quant blocks that do not contain a whole BK tile use the element-wise loader.
|
| 150 |
+
for (var idx: u32 = li; idx < BN * K_VECS; idx = idx + WG_THREADS) {
|
| 151 |
+
let bc = idx / K_VECS;
|
| 152 |
+
let br4 = idx % K_VECS;
|
| 153 |
+
let bk = kBase + br4 * 4u;
|
| 154 |
+
let bn = nBase + bc;
|
| 155 |
+
var word = vec4<f32>(0.0);
|
| 156 |
+
if (bn < N) {
|
| 157 |
+
{% for component in range(4) %}
|
| 158 |
+
if (bk + {{ component }}u < K) {
|
| 159 |
+
let block{{ component }} = (bk + {{ component }}u) / BLOCK_SIZE;
|
| 160 |
+
let offset{{ component }} = (bk + {{ component }}u) % BLOCK_SIZE;
|
| 161 |
+
let scale{{ component }} = f32(scales[bn * KBLOCKS + block{{ component }}]);
|
| 162 |
+
let zero{{ component }} = {{ zero_of("block" ~ component) }};
|
| 163 |
+
word[{{ component }}u] = (f32(packed_weight(bn, block{{ component }}, offset{{ component }})) - zero{{ component }}) * scale{{ component }};
|
| 164 |
+
}
|
| 165 |
+
{% endfor %}
|
| 166 |
+
}
|
| 167 |
+
tileB[bc][br4] = word;
|
| 168 |
+
}
|
| 169 |
+
{% endif %}
|
| 170 |
+
workgroupBarrier();
|
| 171 |
+
let aRow = lid.y * TM;
|
| 172 |
+
let bCol = lid.x * TN;
|
| 173 |
+
for (var kv: u32 = 0u; kv < K_VECS; kv = kv + 1u) {
|
| 174 |
+
{% for i in range(threadRows) %}
|
| 175 |
+
let av{{ i }} = {{ aRead }}tileA[aRow + {{ i }}u][kv]{{ aReadEnd }};
|
| 176 |
+
{% endfor %}
|
| 177 |
+
{% for j in range(threadCols) %}
|
| 178 |
+
let bv{{ j }} = tileB[bCol + {{ j }}u][kv];
|
| 179 |
+
{% endfor %}
|
| 180 |
+
{% for i in range(threadRows) %}
|
| 181 |
+
{% for j in range(threadCols) %}
|
| 182 |
+
acc{{ i }}{{ j }} = acc{{ i }}{{ j }} + dot(av{{ i }}, bv{{ j }});
|
| 183 |
+
{% endfor %}
|
| 184 |
+
{% endfor %}
|
| 185 |
+
}
|
| 186 |
+
workgroupBarrier();
|
| 187 |
+
}
|
| 188 |
+
|
| 189 |
+
let m0 = mBase + lid.y * TM;
|
| 190 |
+
let n0 = nBase + lid.x * TN;
|
| 191 |
+
{% for i in range(threadRows) %}
|
| 192 |
+
if (m0 + {{ i }}u < M) {
|
| 193 |
+
{% for j in range(threadCols) %}
|
| 194 |
+
if (n0 + {{ j }}u < N) {
|
| 195 |
+
y[(m0 + {{ i }}u) * N + n0 + {{ j }}u] = {{ outputScalar }}(acc{{ i }}{{ j }}{% if hasBias %} + f32(bias[n0 + {{ j }}u]){% endif %});
|
| 196 |
+
}
|
| 197 |
+
{% endfor %}
|
| 198 |
+
}
|
| 199 |
+
{% endfor %}
|
| 200 |
+
}
|
build/webgpu/matmul-nbits-q4-prefill-tiled.wgsl.jinja
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% if usesF16 %}
|
| 2 |
+
enable f16;
|
| 3 |
+
{% endif %}
|
| 4 |
+
{{ env.wgsl.resourceDeclarations }}
|
| 5 |
+
|
| 6 |
+
// com.microsoft.MatMulNBits q4/q8 prefill, no-subgroup-matrix tier:
|
| 7 |
+
// Y[M,N] = A[M,K] @ W[K,N] (+ bias), W[k,n] = (q(n,block,offset) - zero) * scale
|
| 8 |
+
// Register-blocked 32x32 shared-memory tiled GEMM (16x16 threads, each computes a
|
| 9 |
+
// 2x2 micro-tile, K stepped in BK=16 chunks). The B operand is dequantized from
|
| 10 |
+
// the packed blob straight into the shared B tile (no f32 weight matrix stored).
|
| 11 |
+
// Each staged operand is reused across the micro-tile, and f32 accumulation is
|
| 12 |
+
// exact for the 4/8-bit dequantized weight. Fully bounds-checked, so any M/N is
|
| 13 |
+
// supported when K % blockSize == 0.
|
| 14 |
+
const M: u32 = {{ M }}u;
|
| 15 |
+
const K: u32 = {{ K }}u;
|
| 16 |
+
const N: u32 = {{ N }}u;
|
| 17 |
+
const KBLOCKS: u32 = {{ kBlocks }}u;
|
| 18 |
+
const BLOCK_SIZE: u32 = {{ blockSize }}u;
|
| 19 |
+
const BLOB_SIZE: u32 = {{ blobSize }}u;
|
| 20 |
+
const BK: u32 = 16u;
|
| 21 |
+
const BM: u32 = 32u;
|
| 22 |
+
const BN: u32 = 32u;
|
| 23 |
+
|
| 24 |
+
// When A uses f16 storage, staging tileA at f16 is bit-identical to widening it
|
| 25 |
+
// here. tileB stays f32 because the dequantized (code - zero)*scale product
|
| 26 |
+
// needs more mantissa than f16 provides.
|
| 27 |
+
{% set aTile = "f16" if usesF16 else "f32" %}
|
| 28 |
+
{% set aRead = "f32(" if usesF16 else "" %}
|
| 29 |
+
{% set aReadEnd = ")" if usesF16 else "" %}
|
| 30 |
+
var<workgroup> tileA: array<array<{{ aTile }}, 16>, 32>;
|
| 31 |
+
var<workgroup> tileB: array<array<f32, 32>, 16>;
|
| 32 |
+
|
| 33 |
+
// {{ bits }}-bit unpack: q2 stores four codes per byte, q4 two, and q8 one.
|
| 34 |
+
{% macro matmul_nbits_packed_code(fn="packed_weight", buffer="b", kBlocks="params.kBlocks", blobSize="params.blobSize", bits=4) %}
|
| 35 |
+
fn {{ fn }}(n: u32, block: u32, offset: u32) -> u32 {
|
| 36 |
+
{% if bits == 2 %}
|
| 37 |
+
let byte_index = offset / 4u;
|
| 38 |
+
let shift = (offset % 4u) * 2u;
|
| 39 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + byte_index;
|
| 40 |
+
return ({{ buffer }}[packed_index] >> shift) & 3u;
|
| 41 |
+
{% elif bits == 4 %}
|
| 42 |
+
let byte_index = offset / 2u;
|
| 43 |
+
let shift = (offset % 2u) * 4u;
|
| 44 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + byte_index;
|
| 45 |
+
return ({{ buffer }}[packed_index] >> shift) & 15u;
|
| 46 |
+
{% else %}
|
| 47 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + offset;
|
| 48 |
+
return {{ buffer }}[packed_index] & 255u;
|
| 49 |
+
{% endif %}
|
| 50 |
+
}
|
| 51 |
+
{%- endmacro %}
|
| 52 |
+
{{- matmul_nbits_packed_code(bits=bits, kBlocks="KBLOCKS", blobSize="BLOB_SIZE") }}
|
| 53 |
+
|
| 54 |
+
@compute @workgroup_size(16, 16, 1)
|
| 55 |
+
fn main(
|
| 56 |
+
@builtin(workgroup_id) wg: vec3<u32>,
|
| 57 |
+
@builtin(local_invocation_id) lid: vec3<u32>
|
| 58 |
+
) {
|
| 59 |
+
let mBase = wg.y * BM;
|
| 60 |
+
let nBase = wg.x * BN;
|
| 61 |
+
let li = lid.y * 16u + lid.x;
|
| 62 |
+
|
| 63 |
+
var acc00: f32 = 0.0;
|
| 64 |
+
var acc01: f32 = 0.0;
|
| 65 |
+
var acc10: f32 = 0.0;
|
| 66 |
+
var acc11: f32 = 0.0;
|
| 67 |
+
let numTiles = (K + BK - 1u) / BK;
|
| 68 |
+
for (var kt: u32 = 0u; kt < numTiles; kt = kt + 1u) {
|
| 69 |
+
let kBase = kt * BK;
|
| 70 |
+
// Cooperative load: 32x16 A tile + 16x32 B tile, 256 threads x 2 each. The B
|
| 71 |
+
// tile is dequantized from the packed q blob during the load.
|
| 72 |
+
for (var e: u32 = 0u; e < 2u; e = e + 1u) {
|
| 73 |
+
let idx = li + e * 256u;
|
| 74 |
+
let ar = idx / BK;
|
| 75 |
+
let ac = idx % BK;
|
| 76 |
+
let am = mBase + ar;
|
| 77 |
+
let ak = kBase + ac;
|
| 78 |
+
if (am < M && ak < K) {
|
| 79 |
+
tileA[ar][ac] = {{ aTile }}(a[am * K + ak]);
|
| 80 |
+
} else {
|
| 81 |
+
tileA[ar][ac] = 0.0;
|
| 82 |
+
}
|
| 83 |
+
let br = idx / BN;
|
| 84 |
+
let bc = idx % BN;
|
| 85 |
+
let bk = kBase + br;
|
| 86 |
+
let bn = nBase + bc;
|
| 87 |
+
if (bk < K && bn < N) {
|
| 88 |
+
let block = bk / BLOCK_SIZE;
|
| 89 |
+
let offset = bk % BLOCK_SIZE;
|
| 90 |
+
let scale = f32(scales[bn * KBLOCKS + block]);
|
| 91 |
+
{% if hasZero %}
|
| 92 |
+
let zero = f32(zero_points[bn * KBLOCKS + block]);
|
| 93 |
+
{% else %}
|
| 94 |
+
let zero = {{ defaultZero }};
|
| 95 |
+
{% endif %}
|
| 96 |
+
tileB[br][bc] = (f32(packed_weight(bn, block, offset)) - zero) * scale;
|
| 97 |
+
} else {
|
| 98 |
+
tileB[br][bc] = 0.0;
|
| 99 |
+
}
|
| 100 |
+
}
|
| 101 |
+
workgroupBarrier();
|
| 102 |
+
for (var kk: u32 = 0u; kk < BK; kk = kk + 1u) {
|
| 103 |
+
let a0 = {{ aRead }}tileA[lid.y * 2u][kk]{{ aReadEnd }};
|
| 104 |
+
let a1 = {{ aRead }}tileA[lid.y * 2u + 1u][kk]{{ aReadEnd }};
|
| 105 |
+
let b0 = tileB[kk][lid.x * 2u];
|
| 106 |
+
let b1 = tileB[kk][lid.x * 2u + 1u];
|
| 107 |
+
acc00 = acc00 + a0 * b0;
|
| 108 |
+
acc01 = acc01 + a0 * b1;
|
| 109 |
+
acc10 = acc10 + a1 * b0;
|
| 110 |
+
acc11 = acc11 + a1 * b1;
|
| 111 |
+
}
|
| 112 |
+
workgroupBarrier();
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
let m0 = mBase + lid.y * 2u;
|
| 116 |
+
let m1 = m0 + 1u;
|
| 117 |
+
let n0 = nBase + lid.x * 2u;
|
| 118 |
+
let n1 = n0 + 1u;
|
| 119 |
+
{% if hasBias %}
|
| 120 |
+
if (m0 < M && n0 < N) { y[m0 * N + n0] = {{ outputScalar }}(acc00 + f32(bias[n0])); }
|
| 121 |
+
if (m0 < M && n1 < N) { y[m0 * N + n1] = {{ outputScalar }}(acc01 + f32(bias[n1])); }
|
| 122 |
+
if (m1 < M && n0 < N) { y[m1 * N + n0] = {{ outputScalar }}(acc10 + f32(bias[n0])); }
|
| 123 |
+
if (m1 < M && n1 < N) { y[m1 * N + n1] = {{ outputScalar }}(acc11 + f32(bias[n1])); }
|
| 124 |
+
{% else %}
|
| 125 |
+
if (m0 < M && n0 < N) { y[m0 * N + n0] = {{ outputScalar }}(acc00); }
|
| 126 |
+
if (m0 < M && n1 < N) { y[m0 * N + n1] = {{ outputScalar }}(acc01); }
|
| 127 |
+
if (m1 < M && n0 < N) { y[m1 * N + n0] = {{ outputScalar }}(acc10); }
|
| 128 |
+
if (m1 < M && n1 < N) { y[m1 * N + n1] = {{ outputScalar }}(acc11); }
|
| 129 |
+
{% endif %}
|
| 130 |
+
}
|
build/webgpu/matmul-nbits-q4-sgmat.wgsl.jinja
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// com.microsoft.MatMulNBits q4 prefill subgroup-matrix tier:
|
| 2 |
+
// Y[M,N] = A[M,K] @ W[K,N] + bias?, W[k,n] = (q4(n,block,offset) - zero) * scale
|
| 3 |
+
// Uses a 32x64 or 64x64 subgroup-matrix output tile with an M-tail row_limit guard; the
|
| 4 |
+
// B operand is materialized on the fly by dequantizing the packed q4 blob into
|
| 5 |
+
// the shared B tile, so no f32 weight matrix is stored. f32 operands and f32
|
| 6 |
+
// accumulation preserve precision; the dequantized weight is a 4-bit value, so
|
| 7 |
+
// f32 is exact for it.
|
| 8 |
+
// Alignment gates keep K % 32 == 0 and N % 64 == 0 so subgroupMatrixLoad never
|
| 9 |
+
// sees partial 8x8 tiles; M tails handled by row_limit + the loadSHMA zero-fill.
|
| 10 |
+
enable subgroups;
|
| 11 |
+
enable chromium_experimental_subgroup_matrix;
|
| 12 |
+
{% if usesF16 %}
|
| 13 |
+
enable f16;
|
| 14 |
+
{% endif %}
|
| 15 |
+
diagnostic(off, chromium.subgroup_matrix_uniformity);
|
| 16 |
+
|
| 17 |
+
{{ env.wgsl.resourceDeclarations }}
|
| 18 |
+
|
| 19 |
+
const M: u32 = {{ M }}u;
|
| 20 |
+
const K: u32 = {{ K }}u;
|
| 21 |
+
const N: u32 = {{ N }}u;
|
| 22 |
+
const KBLOCKS: u32 = {{ kBlocks }}u;
|
| 23 |
+
const BLOCK_SIZE: u32 = {{ blockSize }}u;
|
| 24 |
+
const BLOB_SIZE: u32 = {{ blobSize }}u;
|
| 25 |
+
const TILE_COLS: u32 = 64u;
|
| 26 |
+
const TILE_ROWS: u32 = {{ tileRows }}u;
|
| 27 |
+
const TILE_K: u32 = 32u;
|
| 28 |
+
const SUB_COLS: u32 = 32u;
|
| 29 |
+
const SUB_ROWS: u32 = 16u;
|
| 30 |
+
|
| 31 |
+
var<workgroup> tile_A: array<f32, {{ tileRows }} * 32>;
|
| 32 |
+
var<workgroup> tile_B: array<f32, 64 * 32>;
|
| 33 |
+
var<workgroup> scratch: array<array<array<f32, 64>, 4>, {{ numSubgroups }}>;
|
| 34 |
+
|
| 35 |
+
fn loadSHMA(tile_base: u32, k_idx: u32, row: u32, c_idx: u32) {
|
| 36 |
+
let a_global = tile_base + row;
|
| 37 |
+
let col = c_idx * 8u;
|
| 38 |
+
for (var col_offset = 0u; col_offset < 8u; col_offset = col_offset + 1u) {
|
| 39 |
+
let k = k_idx + col + col_offset;
|
| 40 |
+
if (a_global < M) {
|
| 41 |
+
tile_A[row * TILE_K + col + col_offset] = f32(a[a_global * K + k]);
|
| 42 |
+
} else {
|
| 43 |
+
tile_A[row * TILE_K + col + col_offset] = 0.0;
|
| 44 |
+
}
|
| 45 |
+
}
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
fn loadSHMB(tile_base: u32, k_idx: u32, row: u32, c_idx: u32) {
|
| 49 |
+
let n = tile_base + row; // output column
|
| 50 |
+
let col = c_idx * {{ bLoadWidth }}u;
|
| 51 |
+
// When N % 64 != 0 the last column-tile is padded past N. Those columns
|
| 52 |
+
// dequantize to 0 (so they contribute 0 to the matrix-multiply and are never
|
| 53 |
+
// stored), and their scale/zero/packed reads would be out of bounds — skip them.
|
| 54 |
+
let valid_n = n < N;
|
| 55 |
+
if (valid_n) {
|
| 56 |
+
// The aligned loader requires BLOCK_SIZE % 16 == 0. k_idx is 32-aligned and
|
| 57 |
+
// each lane owns an aligned 8/16-element slice, so the whole slice shares
|
| 58 |
+
// one scale/zero-point. Hoist those reads and unpack each q4 byte once.
|
| 59 |
+
let k0 = k_idx + col;
|
| 60 |
+
let block = k0 / BLOCK_SIZE;
|
| 61 |
+
let offset0 = k0 % BLOCK_SIZE;
|
| 62 |
+
let scale = f32(scales[n * KBLOCKS + block]);
|
| 63 |
+
{% if hasZero %}
|
| 64 |
+
let zero = f32(zero_points[n * KBLOCKS + block]);
|
| 65 |
+
{% else %}
|
| 66 |
+
let zero = {{ defaultZero }};
|
| 67 |
+
{% endif %}
|
| 68 |
+
{% if bits == 2 %}
|
| 69 |
+
// Four 2-bit codes share a stored byte; one code per iteration needs no assumption
|
| 70 |
+
// about where offset0 lands inside a byte.
|
| 71 |
+
for (var i = 0u; i < {{ bLoadWidth }}u; i = i + 1u) {
|
| 72 |
+
let code_offset = offset0 + i;
|
| 73 |
+
let packed_index = (n * KBLOCKS + block) * BLOB_SIZE + code_offset / 4u;
|
| 74 |
+
tile_B[row * TILE_K + col + i] = (f32((b[packed_index] >> ((code_offset % 4u) * 2u)) & 3u) - zero) * scale;
|
| 75 |
+
}
|
| 76 |
+
{% elif bits == 4 %}
|
| 77 |
+
for (var i = 0u; i < {{ bLoadWidth }}u; i = i + 2u) {
|
| 78 |
+
let packed_index = (n * KBLOCKS + block) * BLOB_SIZE + (offset0 + i) / 2u;
|
| 79 |
+
let packed = b[packed_index];
|
| 80 |
+
tile_B[row * TILE_K + col + i] = (f32(packed & 15u) - zero) * scale;
|
| 81 |
+
tile_B[row * TILE_K + col + i + 1u] = (f32((packed >> 4u) & 15u) - zero) * scale;
|
| 82 |
+
}
|
| 83 |
+
{% else %}
|
| 84 |
+
for (var i = 0u; i < {{ bLoadWidth }}u; i = i + 1u) {
|
| 85 |
+
let packed_index = (n * KBLOCKS + block) * BLOB_SIZE + offset0 + i;
|
| 86 |
+
tile_B[row * TILE_K + col + i] = (f32(b[packed_index] & 255u) - zero) * scale;
|
| 87 |
+
}
|
| 88 |
+
{% endif %}
|
| 89 |
+
} else {
|
| 90 |
+
for (var i = 0u; i < {{ bLoadWidth }}u; i = i + 1u) {
|
| 91 |
+
tile_B[row * TILE_K + col + i] = 0.0;
|
| 92 |
+
}
|
| 93 |
+
}
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
// Store one output column: slot ∈ {0,1,2,3} selects the 8-wide result block, cc
|
| 97 |
+
// ∈ {col, col+1} the lane pair. The absolute column is col_base + cc + slot*8;
|
| 98 |
+
// when N % 64 != 0 the padded tile columns (>= N) are skipped (the guard is
|
| 99 |
+
// always true for aligned N, so this is bit-identical there).
|
| 100 |
+
fn storeCol(offset: u32, col_base: u32, row: u32, cc: u32, slot: u32, src_slot: u32) {
|
| 101 |
+
let c = cc + slot * 8u;
|
| 102 |
+
if (col_base + c < N) {
|
| 103 |
+
{% if hasBias %}
|
| 104 |
+
y[offset + row * N + c] = {{ outputScalar }}(scratch[src_slot][slot][row * 8u + cc] + f32(bias[col_base + c]));
|
| 105 |
+
{% else %}
|
| 106 |
+
y[offset + row * N + c] = {{ outputScalar }}(scratch[src_slot][slot][row * 8u + cc]);
|
| 107 |
+
{% endif %}
|
| 108 |
+
}
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
fn storeOutput(offset: u32, col_base: u32, row: u32, col: u32, src_slot: u32, row_limit: i32) {
|
| 112 |
+
if (row_limit > 0 && row < u32(row_limit)) {
|
| 113 |
+
let col2 = col + 1u;
|
| 114 |
+
{% for blockCol in [0, 1, 2, 3] %}
|
| 115 |
+
storeCol(offset, col_base, row, col, {{ blockCol }}u, src_slot);
|
| 116 |
+
storeCol(offset, col_base, row, col2, {{ blockCol }}u, src_slot);
|
| 117 |
+
{% endfor %}
|
| 118 |
+
}
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
@compute @workgroup_size({{ workgroupSize }}, 1, 1)
|
| 122 |
+
fn main(
|
| 123 |
+
@builtin(workgroup_id) workgroup_id: vec3<u32>,
|
| 124 |
+
@builtin(local_invocation_index) local_idx: u32,
|
| 125 |
+
@builtin(subgroup_invocation_id) sg_id: u32,
|
| 126 |
+
@builtin(subgroup_size) sg_size: u32
|
| 127 |
+
) {
|
| 128 |
+
let a_global_base = workgroup_id.y * TILE_ROWS;
|
| 129 |
+
let b_global_base = workgroup_id.x * TILE_COLS;
|
| 130 |
+
|
| 131 |
+
let subtile_id = local_idx / sg_size;
|
| 132 |
+
let subtile_idx = subtile_id / {{ rowSubtiles }}u;
|
| 133 |
+
let subtile_idy = subtile_id % {{ rowSubtiles }}u;
|
| 134 |
+
let base_A = subtile_idy * SUB_ROWS;
|
| 135 |
+
let base_B = subtile_idx * SUB_COLS;
|
| 136 |
+
|
| 137 |
+
{% for row in [0, 1] %}{% for col in [0, 1, 2, 3] %}
|
| 138 |
+
var matC{{ row }}{{ col }}: subgroup_matrix_result<f32, 8, 8>;
|
| 139 |
+
{% endfor %}{% endfor %}
|
| 140 |
+
|
| 141 |
+
for (var kidx = 0u; kidx < K; kidx = kidx + TILE_K) {
|
| 142 |
+
loadSHMA(a_global_base, kidx, local_idx / 4u, local_idx % 4u);
|
| 143 |
+
loadSHMB(b_global_base, kidx, local_idx / {{ bLoadsPerRow }}u, local_idx % {{ bLoadsPerRow }}u);
|
| 144 |
+
workgroupBarrier();
|
| 145 |
+
|
| 146 |
+
for (var step = 0u; step < TILE_K; step = step + 8u) {
|
| 147 |
+
{% set operandScalar = "f32" %} let matrix_a_offset = subtile_idy * SUB_ROWS * TILE_K + step;
|
| 148 |
+
var matA0: subgroup_matrix_left<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_left<{{ operandScalar }}, 8, 8>>(&tile_A, matrix_a_offset, false, TILE_K);
|
| 149 |
+
var matA1: subgroup_matrix_left<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_left<{{ operandScalar }}, 8, 8>>(&tile_A, matrix_a_offset + 8u * TILE_K, false, TILE_K);
|
| 150 |
+
|
| 151 |
+
let matrix_b_offset = subtile_idx * SUB_COLS * TILE_K + step;
|
| 152 |
+
var matB0: subgroup_matrix_right<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_right<{{ operandScalar }}, 8, 8>>(&tile_B, matrix_b_offset, true, TILE_K);
|
| 153 |
+
var matB1: subgroup_matrix_right<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_right<{{ operandScalar }}, 8, 8>>(&tile_B, matrix_b_offset + 8u * TILE_K, true, TILE_K);
|
| 154 |
+
var matB2: subgroup_matrix_right<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_right<{{ operandScalar }}, 8, 8>>(&tile_B, matrix_b_offset + 16u * TILE_K, true, TILE_K);
|
| 155 |
+
var matB3: subgroup_matrix_right<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_right<{{ operandScalar }}, 8, 8>>(&tile_B, matrix_b_offset + 24u * TILE_K, true, TILE_K);
|
| 156 |
+
|
| 157 |
+
matC00 = subgroupMatrixMultiplyAccumulate(matA0, matB0, matC00);
|
| 158 |
+
matC01 = subgroupMatrixMultiplyAccumulate(matA0, matB1, matC01);
|
| 159 |
+
matC02 = subgroupMatrixMultiplyAccumulate(matA0, matB2, matC02);
|
| 160 |
+
matC03 = subgroupMatrixMultiplyAccumulate(matA0, matB3, matC03);
|
| 161 |
+
matC10 = subgroupMatrixMultiplyAccumulate(matA1, matB0, matC10);
|
| 162 |
+
matC11 = subgroupMatrixMultiplyAccumulate(matA1, matB1, matC11);
|
| 163 |
+
matC12 = subgroupMatrixMultiplyAccumulate(matA1, matB2, matC12);
|
| 164 |
+
matC13 = subgroupMatrixMultiplyAccumulate(matA1, matB3, matC13);
|
| 165 |
+
}
|
| 166 |
+
workgroupBarrier();
|
| 167 |
+
}
|
| 168 |
+
|
| 169 |
+
// The four scratch banks are reused across the two row-groups, and each is written
|
| 170 |
+
// by a collective subgroupMatrixStore then read across lanes by storeOutput. Barriers
|
| 171 |
+
// give the reads visibility of the store and stop the second row-group's store from
|
| 172 |
+
// clobbering the first's still-in-flight readback when a partial final M-tile
|
| 173 |
+
// diverges storeOutput's guard. Without both barriers the last valid row can be corrupted.
|
| 174 |
+
{% for col in [0, 1, 2, 3] %}
|
| 175 |
+
subgroupMatrixStore(&scratch[subtile_id][{{ col }}], 0u, matC0{{ col }}, false, 8u);
|
| 176 |
+
{% endfor %}
|
| 177 |
+
workgroupBarrier();
|
| 178 |
+
let row = sg_id / 4u;
|
| 179 |
+
let col = (sg_id % 4u) * 2u;
|
| 180 |
+
let col_base = b_global_base + base_B;
|
| 181 |
+
var matrix_c_offset = (a_global_base + base_A) * N + col_base;
|
| 182 |
+
var row_limit = i32(M) - i32(a_global_base + base_A);
|
| 183 |
+
storeOutput(matrix_c_offset, col_base, row, col, subtile_id, row_limit);
|
| 184 |
+
workgroupBarrier();
|
| 185 |
+
|
| 186 |
+
{% for col in [0, 1, 2, 3] %}
|
| 187 |
+
subgroupMatrixStore(&scratch[subtile_id][{{ col }}], 0u, matC1{{ col }}, false, 8u);
|
| 188 |
+
{% endfor %}
|
| 189 |
+
workgroupBarrier();
|
| 190 |
+
matrix_c_offset = matrix_c_offset + 8u * N;
|
| 191 |
+
row_limit = i32(M) - i32(a_global_base + base_A + 8u);
|
| 192 |
+
storeOutput(matrix_c_offset, col_base, row, col, subtile_id, row_limit);
|
| 193 |
+
}
|
build/webgpu/matmul-nbits.wgsl.jinja
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{% if usesF16 %}
|
| 2 |
+
enable f16;
|
| 3 |
+
{% endif %}
|
| 4 |
+
{{ env.wgsl.resourceDeclarations }}
|
| 5 |
+
|
| 6 |
+
const WG: u32 = {{ workgroupSize }}u;
|
| 7 |
+
|
| 8 |
+
// Unpack one {{ bits }}-bit quantized weight, low codes first along K. q2 packs four
|
| 9 |
+
// codes per stored byte, q4 two nibbles, and q8 is one byte per weight
|
| 10 |
+
// (blobSize == blockSize). `b` is bound u32-per-byte in every case, so all three
|
| 11 |
+
// index the stored byte directly.
|
| 12 |
+
{% macro matmul_nbits_packed_code(fn="packed_weight", buffer="b", kBlocks="params.kBlocks", blobSize="params.blobSize", bits=4) %}
|
| 13 |
+
fn {{ fn }}(n: u32, block: u32, offset: u32) -> u32 {
|
| 14 |
+
{% if bits == 2 %}
|
| 15 |
+
let byte_index = offset / 4u;
|
| 16 |
+
let shift = (offset % 4u) * 2u;
|
| 17 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + byte_index;
|
| 18 |
+
return ({{ buffer }}[packed_index] >> shift) & 3u;
|
| 19 |
+
{% elif bits == 4 %}
|
| 20 |
+
let byte_index = offset / 2u;
|
| 21 |
+
let shift = (offset % 2u) * 4u;
|
| 22 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + byte_index;
|
| 23 |
+
return ({{ buffer }}[packed_index] >> shift) & 15u;
|
| 24 |
+
{% else %}
|
| 25 |
+
let packed_index = (n * {{ kBlocks }} + block) * {{ blobSize }} + offset;
|
| 26 |
+
return {{ buffer }}[packed_index] & 255u;
|
| 27 |
+
{% endif %}
|
| 28 |
+
}
|
| 29 |
+
{%- endmacro %}
|
| 30 |
+
{{- matmul_nbits_packed_code(bits=bits) }}
|
| 31 |
+
|
| 32 |
+
@compute @workgroup_size(WG, 1, 1)
|
| 33 |
+
fn main(@builtin(global_invocation_id) gid: vec3<u32>, @builtin(num_workgroups) nwg: vec3<u32>) {
|
| 34 |
+
// 2D-folded flat output-element index: gid.y carries the high bits past the
|
| 35 |
+
// maxComputeWorkgroupsPerDimension dispatch limit. When nwg.y == 1 this
|
| 36 |
+
// reduces to gid.x; the index >= total guard drops the tail.
|
| 37 |
+
let index = gid.x + gid.y * nwg.x * WG;
|
| 38 |
+
let total = params.rows * params.N;
|
| 39 |
+
|
| 40 |
+
if (index >= total) {
|
| 41 |
+
return;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
let row = index / params.N;
|
| 45 |
+
let col = index % params.N;
|
| 46 |
+
|
| 47 |
+
{% if hasBias %}
|
| 48 |
+
var acc = f32(bias[col]);
|
| 49 |
+
{% else %}
|
| 50 |
+
var acc = 0.0;
|
| 51 |
+
{% endif %}
|
| 52 |
+
|
| 53 |
+
for (var k: u32 = 0u; k < params.K; k = k + 1u) {
|
| 54 |
+
let block = k / params.blockSize;
|
| 55 |
+
let offset = k % params.blockSize;
|
| 56 |
+
let q = packed_weight(col, block, offset);
|
| 57 |
+
|
| 58 |
+
{% if hasZero %}
|
| 59 |
+
let zero = f32(zero_points[col * params.kBlocks + block]);
|
| 60 |
+
{% else %}
|
| 61 |
+
let zero = {{ defaultZero }};
|
| 62 |
+
{% endif %}
|
| 63 |
+
|
| 64 |
+
let w = (f32(q) - zero) * f32(scales[col * params.kBlocks + block]);
|
| 65 |
+
acc = acc + f32(a[row * params.K + k]) * w;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
y[index] = {{ outputScalar }}(acc);
|
| 69 |
+
}
|
build/webgpu/metadata.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "com.microsoft.MatMulNBits",
|
| 3 |
+
"id": "_com_microsoft_matmulnbits_webgpu_81b817c",
|
| 4 |
+
"version": 1,
|
| 5 |
+
"license": "Apache-2.0",
|
| 6 |
+
"backend": { "type": "webgpu" },
|
| 7 |
+
"digest": {
|
| 8 |
+
"algorithm": "sha256",
|
| 9 |
+
"files": {
|
| 10 |
+
"bench.json": "BbpRtHBH/vkJDaybyRBNKhuUCpe4XMJtKmW3bhRcEZE=",
|
| 11 |
+
"manifest.json": "Gz92F8En4SeyVGrSZBtQghet4kVvjHxGIplFWSIq7AM=",
|
| 12 |
+
"matmul-nbits-dp4a-quantize.wgsl.jinja": "WEUGSDH5qWYg10f/mkAHxq8AkIkMW9R/Wn/Y23Q0Jw0=",
|
| 13 |
+
"matmul-nbits-gemv-q4.wgsl.jinja": "r9eGhKkZPaNaUHFcDZh1JpS+w6z4Wow/7wGrLMVVgsA=",
|
| 14 |
+
"matmul-nbits-q4-dp4a-prefill.wgsl.jinja": "qUrURZDpPzMpABnTgESkHgLCQiAWxEZ8wvzkAPTW2kI=",
|
| 15 |
+
"matmul-nbits-q4-prefill-tile4x4.wgsl.jinja": "HjZraSjOpaSl5Cjns4scselOIn+ibxFEu+9LTeUI0QI=",
|
| 16 |
+
"matmul-nbits-q4-prefill-tiled-reg.wgsl.jinja": "oU7BcxJnKIEfgnkWHPq77RrCmrE0iIm6ED7cgVfZUYs=",
|
| 17 |
+
"matmul-nbits-q4-prefill-tiled.wgsl.jinja": "TdetCiv5o88hvWCGNDewpFX+M+NZrz9rekU/d5kMZTM=",
|
| 18 |
+
"matmul-nbits-q4-sgmat.wgsl.jinja": "8E4yGRvezICz5ctdW4g2w/HBfLvqJF2hA+jOobcuJio=",
|
| 19 |
+
"matmul-nbits.wgsl.jinja": "DRkwODEER11pYQxt2ssS9YvFggO3CbUqQ9yag53J5lY=",
|
| 20 |
+
"test.json": "2mpJ5fx2GnlZycPygUyHbOM37n7X6VZmUMGHNkJa7qw="
|
| 21 |
+
}
|
| 22 |
+
},
|
| 23 |
+
"provenance": { "kernel": { "sha": "2e7068faf55e7f43df740015f6d1ee49391a41c5", "dirty": false } },
|
| 24 |
+
"webgpu": { "manifestSpec": "1.0", "specialized": true, "opPath": "ops/com.microsoft.MatMulNBits" }
|
| 25 |
+
}
|
build/webgpu/test.json
ADDED
|
@@ -0,0 +1,1967 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"op": "com.microsoft.MatMulNBits",
|
| 3 |
+
"fixtureArrays": {
|
| 4 |
+
"q4_prefill_tiled_reg_tailk_m32_k33_n4096_input_bT": [16, 50, 84, 118, 152, 186, 220, 254, 135, 119, 102, 85, 68, 51, 34, 17],
|
| 5 |
+
"q4_weight_cycle_b_t": [16, 50, 84, 118, 152, 186, 220, 254, 33, 67, 101, 135, 169, 203, 237, 15],
|
| 6 |
+
"quant_scale_cycle_t": [0.04, 0.055, 0.05, 0.065, 0.06, 0.075, 0.07, 0.085],
|
| 7 |
+
"mixed_weight_cycle_b_t": [17, 200, 91, 45, 233, 128, 7, 176, 250, 33, 142, 99, 210, 64, 188, 121],
|
| 8 |
+
"q8_zero_bias_gemv_m1_tail_n5_input_bT": [19, 56, 93, 130, 167, 204, 241, 22, 59, 96, 133, 170, 207, 244, 25, 62]
|
| 9 |
+
},
|
| 10 |
+
"cases": [
|
| 11 |
+
{
|
| 12 |
+
"name": "q4_zero_bias_prefill_tile4x4_large",
|
| 13 |
+
"inputs": {
|
| 14 |
+
"aT": {
|
| 15 |
+
"dtype": "float32",
|
| 16 |
+
"shape": [128, 128],
|
| 17 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 18 |
+
},
|
| 19 |
+
"bT": {
|
| 20 |
+
"dtype": "uint8",
|
| 21 |
+
"shape": [64, 4, 16],
|
| 22 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 23 |
+
},
|
| 24 |
+
"scalesT": {
|
| 25 |
+
"dtype": "float32",
|
| 26 |
+
"shape": [64, 4],
|
| 27 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 28 |
+
},
|
| 29 |
+
"zeroPointsT": {
|
| 30 |
+
"dtype": "float32",
|
| 31 |
+
"shape": [64, 4],
|
| 32 |
+
"data": { "kind": "cycle", "values": [6.0, 7.0, 8.0, 9.0] }
|
| 33 |
+
},
|
| 34 |
+
"biasT": {
|
| 35 |
+
"dtype": "float32",
|
| 36 |
+
"shape": [64],
|
| 37 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.1 }
|
| 38 |
+
}
|
| 39 |
+
},
|
| 40 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [128, 64], "tolerance": 0.0001 } },
|
| 41 |
+
"attrs": { "K": 128, "N": 64, "block_size": 32 }
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"name": "q4_zero_bias_prefill_tile4x4_small_m8",
|
| 45 |
+
"provenance": {
|
| 46 |
+
"notes": "Small-M (M=8) q4 prefill with bias and zero points. M<64 excludes prefill_tiled_zero_bias, while the row-guarded prefill_tile4x4_zero_bias route admits M>=2 when N is divisible by 4. This pins the tile4x4 lower-bound contract and its bias/zero-point arithmetic."
|
| 47 |
+
},
|
| 48 |
+
"inputs": {
|
| 49 |
+
"aT": {
|
| 50 |
+
"dtype": "float32",
|
| 51 |
+
"shape": [8, 128],
|
| 52 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 53 |
+
},
|
| 54 |
+
"bT": {
|
| 55 |
+
"dtype": "uint8",
|
| 56 |
+
"shape": [64, 4, 16],
|
| 57 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 58 |
+
},
|
| 59 |
+
"scalesT": {
|
| 60 |
+
"dtype": "float32",
|
| 61 |
+
"shape": [64, 4],
|
| 62 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 63 |
+
},
|
| 64 |
+
"zeroPointsT": {
|
| 65 |
+
"dtype": "float32",
|
| 66 |
+
"shape": [64, 4],
|
| 67 |
+
"data": { "kind": "cycle", "values": [6.0, 7.0, 8.0, 9.0] }
|
| 68 |
+
},
|
| 69 |
+
"biasT": {
|
| 70 |
+
"dtype": "float32",
|
| 71 |
+
"shape": [64],
|
| 72 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.1 }
|
| 73 |
+
}
|
| 74 |
+
},
|
| 75 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [8, 64], "tolerance": 0.0001 } },
|
| 76 |
+
"attrs": { "K": 128, "N": 64, "bits": 4, "block_size": 32 }
|
| 77 |
+
},
|
| 78 |
+
{
|
| 79 |
+
"name": "q8_zero_bias_prefill_tile4x4_small_m8",
|
| 80 |
+
"provenance": {
|
| 81 |
+
"notes": "q8 companion to q4_zero_bias_prefill_tile4x4_small_m8: the relaxed tile4x4 bias floor (M>=2) also makes prefill_tile4x4_zero_bias selectable for q8 prefill+bias at M in [2,64). Validates the q8 unpack branch + bias epilogue on the tile4x4 path at small M."
|
| 82 |
+
},
|
| 83 |
+
"inputs": {
|
| 84 |
+
"aT": {
|
| 85 |
+
"dtype": "float32",
|
| 86 |
+
"shape": [8, 128],
|
| 87 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 88 |
+
},
|
| 89 |
+
"bT": {
|
| 90 |
+
"dtype": "uint8",
|
| 91 |
+
"shape": [64, 4, 32],
|
| 92 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 93 |
+
},
|
| 94 |
+
"scalesT": {
|
| 95 |
+
"dtype": "float32",
|
| 96 |
+
"shape": [64, 4],
|
| 97 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 98 |
+
},
|
| 99 |
+
"zeroPointsT": {
|
| 100 |
+
"dtype": "float32",
|
| 101 |
+
"shape": [64, 4],
|
| 102 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0, 118.0, 144.0, 126.0] }
|
| 103 |
+
},
|
| 104 |
+
"biasT": {
|
| 105 |
+
"dtype": "float32",
|
| 106 |
+
"shape": [64],
|
| 107 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 108 |
+
}
|
| 109 |
+
},
|
| 110 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [8, 64], "tolerance": 0.001 } },
|
| 111 |
+
"attrs": { "K": 128, "N": 64, "bits": 8, "block_size": 32 }
|
| 112 |
+
},
|
| 113 |
+
{
|
| 114 |
+
"name": "ort_projection_q4_block16_tail_zero_bias",
|
| 115 |
+
"provenance": {
|
| 116 |
+
"source": "onnxruntime/test/contrib_ops/matmul_4bits_test.cc",
|
| 117 |
+
"test": "MatMulNBits.Float32_4b_Accuracy0",
|
| 118 |
+
"notes": "Rank-2 projection of ORT q4 block-size coverage with per-block zero points and bias."
|
| 119 |
+
},
|
| 120 |
+
"inputs": {
|
| 121 |
+
"aT": {
|
| 122 |
+
"dtype": "float32",
|
| 123 |
+
"shape": [2, 17],
|
| 124 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.19, "cosStep": 0.37 }
|
| 125 |
+
},
|
| 126 |
+
"bT": {
|
| 127 |
+
"dtype": "uint8",
|
| 128 |
+
"shape": [2, 2, 8],
|
| 129 |
+
"data": {
|
| 130 |
+
"kind": "values",
|
| 131 |
+
"values": [16, 50, 84, 118, 152, 186, 220, 254, 33, 0, 0, 0, 0, 0, 0, 0, 255, 238, 221, 204, 187, 170, 153, 136, 240, 0, 0, 0, 0, 0, 0, 0]
|
| 132 |
+
}
|
| 133 |
+
},
|
| 134 |
+
"scalesT": {
|
| 135 |
+
"dtype": "float32",
|
| 136 |
+
"shape": [2, 2],
|
| 137 |
+
"data": { "kind": "values", "values": [0.04, 0.08, 0.06, 0.12] }
|
| 138 |
+
},
|
| 139 |
+
"zeroPointsT": {
|
| 140 |
+
"dtype": "float32",
|
| 141 |
+
"shape": [2, 2],
|
| 142 |
+
"data": { "kind": "values", "values": [7.0, 1.0, 8.0, 0.0] }
|
| 143 |
+
},
|
| 144 |
+
"biasT": { "dtype": "float32", "shape": [2], "data": { "kind": "values", "values": [0.5, -1.0] } }
|
| 145 |
+
},
|
| 146 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [2, 2], "tolerance": 0.00001 } },
|
| 147 |
+
"attrs": { "K": 17, "N": 2, "bits": 4, "block_size": 16 }
|
| 148 |
+
},
|
| 149 |
+
{
|
| 150 |
+
"name": "ort_projection_q4_block32_tail_no_zero",
|
| 151 |
+
"provenance": {
|
| 152 |
+
"source": "onnxruntime/test/contrib_ops/matmul_4bits_test.cc",
|
| 153 |
+
"test": "MatMulNBits.Float32_4b_Accuracy0",
|
| 154 |
+
"notes": "Rank-2 deterministic projection of ORT q4 coverage with blockSize=32 and tail K."
|
| 155 |
+
},
|
| 156 |
+
"inputs": {
|
| 157 |
+
"aT": {
|
| 158 |
+
"dtype": "float32",
|
| 159 |
+
"shape": [2, 33],
|
| 160 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.13, "cosStep": 0.29, "scale": 0.75 }
|
| 161 |
+
},
|
| 162 |
+
"bT": {
|
| 163 |
+
"dtype": "uint8",
|
| 164 |
+
"shape": [2, 2, 16],
|
| 165 |
+
"data": {
|
| 166 |
+
"kind": "values",
|
| 167 |
+
"values": [16, 50, 84, 118, 152, 186, 220, 254, 16, 50, 84, 118, 152, 186, 220, 254, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 238, 221, 204, 187, 170, 153, 136, 119, 102, 85, 68, 51, 34, 17, 0, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
| 168 |
+
}
|
| 169 |
+
},
|
| 170 |
+
"scalesT": {
|
| 171 |
+
"dtype": "float32",
|
| 172 |
+
"shape": [2, 2],
|
| 173 |
+
"data": { "kind": "values", "values": [0.03, 0.06, 0.04, 0.07] }
|
| 174 |
+
}
|
| 175 |
+
},
|
| 176 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [2, 2], "tolerance": 0.00001 } },
|
| 177 |
+
"attrs": { "K": 33, "N": 2, "bits": 4, "block_size": 32 }
|
| 178 |
+
},
|
| 179 |
+
{
|
| 180 |
+
"name": "q4_block512_schema_legal_cpu_provider_gap_exact",
|
| 181 |
+
"provenance": {
|
| 182 |
+
"source": "onnxruntime/test/contrib_ops/matmul_4bits_test.cc",
|
| 183 |
+
"test": "MatMulNBits.UnsupportedBlockSize_512",
|
| 184 |
+
"notes": "The public schema permits every power-of-two block size of at least 16, and this package implements block_size=512. ORT's installed, pinned, and inspected current CPU providers instead restrict execution to 16, 32, 64, 128, or 256. With A=1, packed q4 codes=9, default zero point=8, and scale=0.25, the exact result is 512 * (9 - 8) * 0.25 = 128."
|
| 185 |
+
},
|
| 186 |
+
"inputs": {
|
| 187 |
+
"aT": { "dtype": "float32", "shape": [1, 512], "data": { "kind": "constant", "value": 1.0 } },
|
| 188 |
+
"bT": { "dtype": "uint8", "shape": [1, 1, 256], "data": { "kind": "constant", "value": 153 } },
|
| 189 |
+
"scalesT": { "dtype": "float32", "shape": [1, 1], "data": { "kind": "constant", "value": 0.25 } }
|
| 190 |
+
},
|
| 191 |
+
"outputs": {
|
| 192 |
+
"yT": { "dtype": "float32", "shape": [1, 1], "tolerance": 0, "data": { "kind": "values", "values": [128.0] } }
|
| 193 |
+
},
|
| 194 |
+
"attrs": { "K": 512, "N": 1, "bits": 4, "block_size": 512 }
|
| 195 |
+
},
|
| 196 |
+
{
|
| 197 |
+
"name": "q4_no_zero_prefill_sgmat_large",
|
| 198 |
+
"inputs": {
|
| 199 |
+
"aT": {
|
| 200 |
+
"shape": [128, 128],
|
| 201 |
+
"dtype": "float32",
|
| 202 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 203 |
+
},
|
| 204 |
+
"bT": {
|
| 205 |
+
"shape": [64, 4, 16],
|
| 206 |
+
"dtype": "uint8",
|
| 207 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 208 |
+
},
|
| 209 |
+
"scalesT": {
|
| 210 |
+
"shape": [64, 4],
|
| 211 |
+
"dtype": "float32",
|
| 212 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 213 |
+
}
|
| 214 |
+
},
|
| 215 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [128, 64], "tolerance": 0.0001 } },
|
| 216 |
+
"attrs": { "K": 128, "N": 64, "bits": 4, "block_size": 32 }
|
| 217 |
+
},
|
| 218 |
+
{
|
| 219 |
+
"name": "q4_no_zero_prefill_sgmat_m32_storage_floor",
|
| 220 |
+
"provenance": {
|
| 221 |
+
"notes": "The 32-row subgroup-matrix tile fits the WebGPU minimum 16 KiB workgroup-storage limit."
|
| 222 |
+
},
|
| 223 |
+
"inputs": {
|
| 224 |
+
"aT": {
|
| 225 |
+
"dtype": "float32",
|
| 226 |
+
"shape": [32, 32],
|
| 227 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 228 |
+
},
|
| 229 |
+
"bT": {
|
| 230 |
+
"dtype": "uint8",
|
| 231 |
+
"shape": [64, 1, 16],
|
| 232 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 233 |
+
},
|
| 234 |
+
"scalesT": {
|
| 235 |
+
"dtype": "float32",
|
| 236 |
+
"shape": [64, 1],
|
| 237 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065] }
|
| 238 |
+
}
|
| 239 |
+
},
|
| 240 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [32, 64], "tolerance": 0.0001 } },
|
| 241 |
+
"attrs": { "K": 32, "N": 64, "bits": 4, "block_size": 32 }
|
| 242 |
+
},
|
| 243 |
+
{
|
| 244 |
+
"name": "q4_zero_bias_prefill_sgmat_m32_storage_floor",
|
| 245 |
+
"provenance": { "notes": "Zero-point/bias sibling of the 32-row subgroup-matrix storage-floor regression." },
|
| 246 |
+
"inputs": {
|
| 247 |
+
"aT": {
|
| 248 |
+
"dtype": "float32",
|
| 249 |
+
"shape": [32, 32],
|
| 250 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 251 |
+
},
|
| 252 |
+
"bT": {
|
| 253 |
+
"dtype": "uint8",
|
| 254 |
+
"shape": [64, 1, 16],
|
| 255 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 256 |
+
},
|
| 257 |
+
"scalesT": {
|
| 258 |
+
"dtype": "float32",
|
| 259 |
+
"shape": [64, 1],
|
| 260 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065] }
|
| 261 |
+
},
|
| 262 |
+
"zeroPointsT": {
|
| 263 |
+
"dtype": "float32",
|
| 264 |
+
"shape": [64, 1],
|
| 265 |
+
"data": { "kind": "cycle", "values": [7.0, 8.0, 6.0, 9.0] }
|
| 266 |
+
},
|
| 267 |
+
"biasT": {
|
| 268 |
+
"dtype": "float32",
|
| 269 |
+
"shape": [64],
|
| 270 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 271 |
+
}
|
| 272 |
+
},
|
| 273 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [32, 64], "tolerance": 0.0001 } },
|
| 274 |
+
"attrs": { "K": 32, "N": 64, "bits": 4, "block_size": 32 }
|
| 275 |
+
},
|
| 276 |
+
{
|
| 277 |
+
"name": "q4_no_zero_prefill_g64_sgmat",
|
| 278 |
+
"provenance": {
|
| 279 |
+
"notes": "Compact blockSize=64 q4 default-zero prefill sibling for model g64 benchmarks. Full tier routes through prefill_sgmat_default_zero; no-MMA/no-subgroups/baseline route through prefill_tiled_default_zero."
|
| 280 |
+
},
|
| 281 |
+
"inputs": {
|
| 282 |
+
"aT": {
|
| 283 |
+
"shape": [64, 128],
|
| 284 |
+
"dtype": "float32",
|
| 285 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 286 |
+
},
|
| 287 |
+
"bT": {
|
| 288 |
+
"shape": [64, 2, 32],
|
| 289 |
+
"dtype": "uint8",
|
| 290 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 291 |
+
},
|
| 292 |
+
"scalesT": {
|
| 293 |
+
"shape": [64, 2],
|
| 294 |
+
"dtype": "float32",
|
| 295 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 296 |
+
}
|
| 297 |
+
},
|
| 298 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [64, 64], "tolerance": 0.0001 } },
|
| 299 |
+
"attrs": { "K": 128, "N": 64, "bits": 4, "block_size": 64 }
|
| 300 |
+
},
|
| 301 |
+
{
|
| 302 |
+
"name": "q8_no_zero_prefill_sgmat_large",
|
| 303 |
+
"inputs": {
|
| 304 |
+
"aT": {
|
| 305 |
+
"dtype": "float32",
|
| 306 |
+
"shape": [128, 128],
|
| 307 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 308 |
+
},
|
| 309 |
+
"bT": {
|
| 310 |
+
"dtype": "uint8",
|
| 311 |
+
"shape": [64, 4, 32],
|
| 312 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 313 |
+
},
|
| 314 |
+
"scalesT": {
|
| 315 |
+
"dtype": "float32",
|
| 316 |
+
"shape": [64, 4],
|
| 317 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 318 |
+
}
|
| 319 |
+
},
|
| 320 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [128, 64], "tolerance": 0.001 } },
|
| 321 |
+
"attrs": { "K": 128, "N": 64, "bits": 8, "block_size": 32 }
|
| 322 |
+
},
|
| 323 |
+
{
|
| 324 |
+
"name": "q8_no_zero_prefill_sgmat_m32_storage_floor",
|
| 325 |
+
"provenance": {
|
| 326 |
+
"notes": "q8 sibling proving the 32-row subgroup-matrix tile remains available at the 16 KiB storage floor."
|
| 327 |
+
},
|
| 328 |
+
"inputs": {
|
| 329 |
+
"aT": {
|
| 330 |
+
"dtype": "float32",
|
| 331 |
+
"shape": [32, 32],
|
| 332 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 333 |
+
},
|
| 334 |
+
"bT": {
|
| 335 |
+
"dtype": "uint8",
|
| 336 |
+
"shape": [64, 1, 32],
|
| 337 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 338 |
+
},
|
| 339 |
+
"scalesT": {
|
| 340 |
+
"dtype": "float32",
|
| 341 |
+
"shape": [64, 1],
|
| 342 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065] }
|
| 343 |
+
}
|
| 344 |
+
},
|
| 345 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [32, 64], "tolerance": 0.001 } },
|
| 346 |
+
"attrs": { "K": 32, "N": 64, "bits": 8, "block_size": 32 }
|
| 347 |
+
},
|
| 348 |
+
{
|
| 349 |
+
"name": "q8_zero_bias_prefill_sgmat_large",
|
| 350 |
+
"inputs": {
|
| 351 |
+
"aT": {
|
| 352 |
+
"dtype": "float32",
|
| 353 |
+
"shape": [128, 128],
|
| 354 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 355 |
+
},
|
| 356 |
+
"bT": {
|
| 357 |
+
"dtype": "uint8",
|
| 358 |
+
"shape": [64, 4, 32],
|
| 359 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 360 |
+
},
|
| 361 |
+
"scalesT": {
|
| 362 |
+
"dtype": "float32",
|
| 363 |
+
"shape": [64, 4],
|
| 364 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 365 |
+
},
|
| 366 |
+
"zeroPointsT": {
|
| 367 |
+
"dtype": "float32",
|
| 368 |
+
"shape": [64, 4],
|
| 369 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0, 118.0, 144.0, 126.0] }
|
| 370 |
+
},
|
| 371 |
+
"biasT": {
|
| 372 |
+
"dtype": "float32",
|
| 373 |
+
"shape": [64],
|
| 374 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 375 |
+
}
|
| 376 |
+
},
|
| 377 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [128, 64], "tolerance": 0.001 } },
|
| 378 |
+
"attrs": { "K": 128, "N": 64, "bits": 8, "block_size": 32 }
|
| 379 |
+
},
|
| 380 |
+
{
|
| 381 |
+
"name": "q8_zero_bias_prefill_sgmat_m32_storage_floor",
|
| 382 |
+
"provenance": { "notes": "q8 zero-point/bias sibling of the 32-row subgroup-matrix storage-floor regression." },
|
| 383 |
+
"inputs": {
|
| 384 |
+
"aT": {
|
| 385 |
+
"dtype": "float32",
|
| 386 |
+
"shape": [32, 32],
|
| 387 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 388 |
+
},
|
| 389 |
+
"bT": {
|
| 390 |
+
"dtype": "uint8",
|
| 391 |
+
"shape": [64, 1, 32],
|
| 392 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 393 |
+
},
|
| 394 |
+
"scalesT": {
|
| 395 |
+
"dtype": "float32",
|
| 396 |
+
"shape": [64, 1],
|
| 397 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065] }
|
| 398 |
+
},
|
| 399 |
+
"zeroPointsT": {
|
| 400 |
+
"dtype": "float32",
|
| 401 |
+
"shape": [64, 1],
|
| 402 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0] }
|
| 403 |
+
},
|
| 404 |
+
"biasT": {
|
| 405 |
+
"dtype": "float32",
|
| 406 |
+
"shape": [64],
|
| 407 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 408 |
+
}
|
| 409 |
+
},
|
| 410 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [32, 64], "tolerance": 0.001 } },
|
| 411 |
+
"attrs": { "K": 32, "N": 64, "bits": 8, "block_size": 32 }
|
| 412 |
+
},
|
| 413 |
+
{
|
| 414 |
+
"name": "q8_no_zero_prefill_tile4x4_unaligned",
|
| 415 |
+
"inputs": {
|
| 416 |
+
"aT": {
|
| 417 |
+
"dtype": "float32",
|
| 418 |
+
"shape": [8, 64],
|
| 419 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 420 |
+
},
|
| 421 |
+
"bT": {
|
| 422 |
+
"dtype": "uint8",
|
| 423 |
+
"shape": [12, 2, 32],
|
| 424 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 425 |
+
},
|
| 426 |
+
"scalesT": {
|
| 427 |
+
"dtype": "float32",
|
| 428 |
+
"shape": [12, 2],
|
| 429 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065] }
|
| 430 |
+
}
|
| 431 |
+
},
|
| 432 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [8, 12], "tolerance": 0.001 } },
|
| 433 |
+
"attrs": { "K": 64, "N": 12, "bits": 8, "block_size": 32 }
|
| 434 |
+
},
|
| 435 |
+
{
|
| 436 |
+
"name": "q4_f16_zero_points_prefill_sgmat",
|
| 437 |
+
"inputs": {
|
| 438 |
+
"aT": {
|
| 439 |
+
"dtype": "float16",
|
| 440 |
+
"shape": [128, 128],
|
| 441 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 442 |
+
},
|
| 443 |
+
"bT": {
|
| 444 |
+
"dtype": "uint8",
|
| 445 |
+
"shape": [64, 4, 16],
|
| 446 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 447 |
+
},
|
| 448 |
+
"scalesT": {
|
| 449 |
+
"dtype": "float16",
|
| 450 |
+
"shape": [64, 4],
|
| 451 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 452 |
+
},
|
| 453 |
+
"zeroPointsT": {
|
| 454 |
+
"dtype": "float16",
|
| 455 |
+
"shape": [64, 4],
|
| 456 |
+
"data": { "kind": "cycle", "values": [7.0, 8.0, 9.0, 6.0] }
|
| 457 |
+
},
|
| 458 |
+
"biasT": { "dtype": "float16", "shape": [64], "data": { "kind": "constant", "value": 0.0 } }
|
| 459 |
+
},
|
| 460 |
+
"outputs": { "yT": { "dtype": "float16", "shape": [128, 64], "tolerance": 0.05 } },
|
| 461 |
+
"attrs": { "K": 128, "N": 64, "bits": 4, "block_size": 32 }
|
| 462 |
+
},
|
| 463 |
+
{
|
| 464 |
+
"name": "q4_no_zero_prefill_sgmat_unaligned_n72",
|
| 465 |
+
"inputs": {
|
| 466 |
+
"aT": {
|
| 467 |
+
"shape": [128, 128],
|
| 468 |
+
"dtype": "float32",
|
| 469 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 470 |
+
},
|
| 471 |
+
"bT": {
|
| 472 |
+
"shape": [72, 4, 16],
|
| 473 |
+
"dtype": "uint8",
|
| 474 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 475 |
+
},
|
| 476 |
+
"scalesT": {
|
| 477 |
+
"shape": [72, 4],
|
| 478 |
+
"dtype": "float32",
|
| 479 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 480 |
+
}
|
| 481 |
+
},
|
| 482 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [128, 72], "tolerance": 0.0001 } },
|
| 483 |
+
"attrs": { "K": 128, "N": 72, "bits": 4, "block_size": 32 }
|
| 484 |
+
},
|
| 485 |
+
{
|
| 486 |
+
"name": "q8_no_zero_prefill_sgmat_unaligned_n72",
|
| 487 |
+
"inputs": {
|
| 488 |
+
"aT": {
|
| 489 |
+
"dtype": "float32",
|
| 490 |
+
"shape": [128, 128],
|
| 491 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 492 |
+
},
|
| 493 |
+
"bT": {
|
| 494 |
+
"dtype": "uint8",
|
| 495 |
+
"shape": [72, 4, 32],
|
| 496 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 497 |
+
},
|
| 498 |
+
"scalesT": {
|
| 499 |
+
"dtype": "float32",
|
| 500 |
+
"shape": [72, 4],
|
| 501 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 502 |
+
}
|
| 503 |
+
},
|
| 504 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [128, 72], "tolerance": 0.001 } },
|
| 505 |
+
"attrs": { "K": 128, "N": 72, "bits": 8, "block_size": 32 }
|
| 506 |
+
},
|
| 507 |
+
{
|
| 508 |
+
"name": "q8_no_zero_prefill_sgmat_unaligned_n72_m32",
|
| 509 |
+
"inputs": {
|
| 510 |
+
"aT": {
|
| 511 |
+
"dtype": "float32",
|
| 512 |
+
"shape": [32, 128],
|
| 513 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 514 |
+
},
|
| 515 |
+
"bT": {
|
| 516 |
+
"dtype": "uint8",
|
| 517 |
+
"shape": [72, 4, 32],
|
| 518 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 519 |
+
},
|
| 520 |
+
"scalesT": {
|
| 521 |
+
"dtype": "float32",
|
| 522 |
+
"shape": [72, 4],
|
| 523 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 524 |
+
}
|
| 525 |
+
},
|
| 526 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [32, 72], "tolerance": 0.001 } },
|
| 527 |
+
"attrs": { "K": 128, "N": 72, "bits": 8, "block_size": 32 }
|
| 528 |
+
},
|
| 529 |
+
{
|
| 530 |
+
"name": "q8_zero_bias_prefill_sgmat_unaligned_n72",
|
| 531 |
+
"inputs": {
|
| 532 |
+
"aT": {
|
| 533 |
+
"dtype": "float32",
|
| 534 |
+
"shape": [128, 128],
|
| 535 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 536 |
+
},
|
| 537 |
+
"bT": {
|
| 538 |
+
"dtype": "uint8",
|
| 539 |
+
"shape": [72, 4, 32],
|
| 540 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 541 |
+
},
|
| 542 |
+
"scalesT": {
|
| 543 |
+
"dtype": "float32",
|
| 544 |
+
"shape": [72, 4],
|
| 545 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 546 |
+
},
|
| 547 |
+
"zeroPointsT": {
|
| 548 |
+
"dtype": "float32",
|
| 549 |
+
"shape": [72, 4],
|
| 550 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0, 118.0, 144.0, 126.0] }
|
| 551 |
+
},
|
| 552 |
+
"biasT": {
|
| 553 |
+
"dtype": "float32",
|
| 554 |
+
"shape": [72],
|
| 555 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 556 |
+
}
|
| 557 |
+
},
|
| 558 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [128, 72], "tolerance": 0.001 } },
|
| 559 |
+
"attrs": { "K": 128, "N": 72, "bits": 8, "block_size": 32 }
|
| 560 |
+
},
|
| 561 |
+
{
|
| 562 |
+
"name": "q8_zero_bias_prefill_sgmat_unaligned_n65_m33",
|
| 563 |
+
"inputs": {
|
| 564 |
+
"aT": {
|
| 565 |
+
"dtype": "float32",
|
| 566 |
+
"shape": [33, 128],
|
| 567 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 568 |
+
},
|
| 569 |
+
"bT": {
|
| 570 |
+
"dtype": "uint8",
|
| 571 |
+
"shape": [65, 4, 32],
|
| 572 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 573 |
+
},
|
| 574 |
+
"scalesT": {
|
| 575 |
+
"dtype": "float32",
|
| 576 |
+
"shape": [65, 4],
|
| 577 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 578 |
+
},
|
| 579 |
+
"zeroPointsT": {
|
| 580 |
+
"dtype": "float32",
|
| 581 |
+
"shape": [65, 4],
|
| 582 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0, 118.0, 144.0, 126.0] }
|
| 583 |
+
},
|
| 584 |
+
"biasT": {
|
| 585 |
+
"dtype": "float32",
|
| 586 |
+
"shape": [65],
|
| 587 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 588 |
+
}
|
| 589 |
+
},
|
| 590 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [33, 65], "tolerance": 0.001 } },
|
| 591 |
+
"attrs": { "K": 128, "N": 65, "bits": 8, "block_size": 32 }
|
| 592 |
+
},
|
| 593 |
+
{
|
| 594 |
+
"name": "q8_zero_bias_prefill_sgmat_unaligned_n72_m32_bs16",
|
| 595 |
+
"inputs": {
|
| 596 |
+
"aT": {
|
| 597 |
+
"dtype": "float32",
|
| 598 |
+
"shape": [32, 128],
|
| 599 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 600 |
+
},
|
| 601 |
+
"bT": {
|
| 602 |
+
"dtype": "uint8",
|
| 603 |
+
"shape": [72, 8, 16],
|
| 604 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 605 |
+
},
|
| 606 |
+
"scalesT": {
|
| 607 |
+
"dtype": "float32",
|
| 608 |
+
"shape": [72, 8],
|
| 609 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 610 |
+
},
|
| 611 |
+
"zeroPointsT": {
|
| 612 |
+
"dtype": "float32",
|
| 613 |
+
"shape": [72, 8],
|
| 614 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0, 118.0, 144.0, 126.0] }
|
| 615 |
+
},
|
| 616 |
+
"biasT": {
|
| 617 |
+
"dtype": "float32",
|
| 618 |
+
"shape": [72],
|
| 619 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 620 |
+
}
|
| 621 |
+
},
|
| 622 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [32, 72], "tolerance": 0.001 } },
|
| 623 |
+
"attrs": { "K": 128, "N": 72, "bits": 8, "block_size": 16 }
|
| 624 |
+
},
|
| 625 |
+
{
|
| 626 |
+
"name": "empty_zero_dim",
|
| 627 |
+
"provenance": {
|
| 628 |
+
"notes": "Zero-length M (rows) axis of A (empty input). With M=0 the N/K-driven packed uint8 B[4,1,16] and scales[4,1] stay normal and Y=[0,N] is empty. K=32,N=4,bits=4,block_size=32."
|
| 629 |
+
},
|
| 630 |
+
"inputs": {
|
| 631 |
+
"aT": { "dtype": "float32", "shape": [0, 32], "data": { "kind": "values", "values": [] } },
|
| 632 |
+
"bT": { "dtype": "uint8", "shape": [4, 1, 16], "data": { "kind": "constant", "value": 17 } },
|
| 633 |
+
"scalesT": { "dtype": "float32", "shape": [4, 1], "data": { "kind": "constant", "value": 0.05 } }
|
| 634 |
+
},
|
| 635 |
+
"outputs": {
|
| 636 |
+
"yT": { "dtype": "float32", "shape": [0, 4], "tolerance": 0, "data": { "kind": "values", "values": [] } }
|
| 637 |
+
},
|
| 638 |
+
"attrs": { "K": 32, "N": 4, "bits": 4, "block_size": 32 }
|
| 639 |
+
},
|
| 640 |
+
{
|
| 641 |
+
"name": "empty_zero_dim_f16",
|
| 642 |
+
"provenance": { "notes": "f16 variant of the empty zero-M-axis case." },
|
| 643 |
+
"inputs": {
|
| 644 |
+
"aT": { "dtype": "float16", "shape": [0, 32], "data": { "kind": "values", "values": [] } },
|
| 645 |
+
"bT": { "dtype": "uint8", "shape": [4, 1, 16], "data": { "kind": "constant", "value": 17 } },
|
| 646 |
+
"scalesT": { "dtype": "float16", "shape": [4, 1], "data": { "kind": "constant", "value": 0.05 } }
|
| 647 |
+
},
|
| 648 |
+
"outputs": {
|
| 649 |
+
"yT": { "dtype": "float16", "shape": [0, 4], "tolerance": 0, "data": { "kind": "values", "values": [] } }
|
| 650 |
+
},
|
| 651 |
+
"attrs": { "K": 32, "N": 4, "bits": 4, "block_size": 32 }
|
| 652 |
+
},
|
| 653 |
+
{
|
| 654 |
+
"name": "q4_no_zero_prefill_reg_m512_n1024",
|
| 655 |
+
"inputs": {
|
| 656 |
+
"aT": {
|
| 657 |
+
"shape": [512, 128],
|
| 658 |
+
"dtype": "float32",
|
| 659 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 660 |
+
},
|
| 661 |
+
"bT": {
|
| 662 |
+
"shape": [1024, 4, 16],
|
| 663 |
+
"dtype": "uint8",
|
| 664 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 665 |
+
},
|
| 666 |
+
"scalesT": {
|
| 667 |
+
"shape": [1024, 4],
|
| 668 |
+
"dtype": "float32",
|
| 669 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 670 |
+
}
|
| 671 |
+
},
|
| 672 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [512, 1024], "tolerance": 0.0001 } },
|
| 673 |
+
"attrs": { "K": 128, "N": 1024, "bits": 4, "block_size": 32 }
|
| 674 |
+
},
|
| 675 |
+
{
|
| 676 |
+
"name": "q4_f16_prefill_reg_m512_n1024",
|
| 677 |
+
"inputs": {
|
| 678 |
+
"aT": {
|
| 679 |
+
"shape": [512, 128],
|
| 680 |
+
"dtype": "float16",
|
| 681 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 682 |
+
},
|
| 683 |
+
"bT": {
|
| 684 |
+
"shape": [1024, 4, 16],
|
| 685 |
+
"dtype": "uint8",
|
| 686 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 687 |
+
},
|
| 688 |
+
"scalesT": {
|
| 689 |
+
"shape": [1024, 4],
|
| 690 |
+
"dtype": "float16",
|
| 691 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 692 |
+
}
|
| 693 |
+
},
|
| 694 |
+
"outputs": { "yT": { "dtype": "float16", "shape": [512, 1024], "tolerance": 0.0001, "relTolerance": 0.001 } },
|
| 695 |
+
"provenance": {
|
| 696 |
+
"notes": "f16 activations on the register-tiled prefill path: this is the only shape class where the shared A/B tiles are staged in f16, so it is the fixture that covers that staging."
|
| 697 |
+
},
|
| 698 |
+
"attrs": { "K": 128, "N": 1024, "bits": 4, "block_size": 32 }
|
| 699 |
+
},
|
| 700 |
+
{
|
| 701 |
+
"name": "q4_zero_bias_prefill_reg_m512_n1024",
|
| 702 |
+
"inputs": {
|
| 703 |
+
"aT": {
|
| 704 |
+
"dtype": "float32",
|
| 705 |
+
"shape": [512, 128],
|
| 706 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 707 |
+
},
|
| 708 |
+
"bT": {
|
| 709 |
+
"dtype": "uint8",
|
| 710 |
+
"shape": [1024, 4, 16],
|
| 711 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 712 |
+
},
|
| 713 |
+
"scalesT": {
|
| 714 |
+
"dtype": "float32",
|
| 715 |
+
"shape": [1024, 4],
|
| 716 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 717 |
+
},
|
| 718 |
+
"zeroPointsT": {
|
| 719 |
+
"dtype": "float32",
|
| 720 |
+
"shape": [1024, 4],
|
| 721 |
+
"data": { "kind": "cycle", "values": [6.0, 7.0, 8.0, 9.0] }
|
| 722 |
+
},
|
| 723 |
+
"biasT": {
|
| 724 |
+
"dtype": "float32",
|
| 725 |
+
"shape": [1024],
|
| 726 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.1 }
|
| 727 |
+
}
|
| 728 |
+
},
|
| 729 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [512, 1024], "tolerance": 0.0001 } },
|
| 730 |
+
"attrs": { "K": 128, "N": 1024, "bits": 4, "block_size": 32 }
|
| 731 |
+
},
|
| 732 |
+
{
|
| 733 |
+
"name": "q8_no_zero_prefill_reg_m512_n1024",
|
| 734 |
+
"inputs": {
|
| 735 |
+
"aT": {
|
| 736 |
+
"dtype": "float32",
|
| 737 |
+
"shape": [512, 128],
|
| 738 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 739 |
+
},
|
| 740 |
+
"bT": {
|
| 741 |
+
"dtype": "uint8",
|
| 742 |
+
"shape": [1024, 4, 32],
|
| 743 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 744 |
+
},
|
| 745 |
+
"scalesT": {
|
| 746 |
+
"dtype": "float32",
|
| 747 |
+
"shape": [1024, 4],
|
| 748 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 749 |
+
}
|
| 750 |
+
},
|
| 751 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [512, 1024], "tolerance": 0.001 } },
|
| 752 |
+
"attrs": { "K": 128, "N": 1024, "bits": 8, "block_size": 32 }
|
| 753 |
+
},
|
| 754 |
+
{
|
| 755 |
+
"name": "q8_f16_prefill_reg_m512_n1024",
|
| 756 |
+
"inputs": {
|
| 757 |
+
"aT": {
|
| 758 |
+
"dtype": "float16",
|
| 759 |
+
"shape": [512, 128],
|
| 760 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 761 |
+
},
|
| 762 |
+
"bT": {
|
| 763 |
+
"dtype": "uint8",
|
| 764 |
+
"shape": [1024, 4, 32],
|
| 765 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 766 |
+
},
|
| 767 |
+
"scalesT": {
|
| 768 |
+
"dtype": "float16",
|
| 769 |
+
"shape": [1024, 4],
|
| 770 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 771 |
+
}
|
| 772 |
+
},
|
| 773 |
+
"outputs": { "yT": { "dtype": "float16", "shape": [512, 1024], "tolerance": 0.0001, "relTolerance": 0.001 } },
|
| 774 |
+
"provenance": {
|
| 775 |
+
"notes": "q8 sibling of q4_f16_prefill_reg_m512_n1024. 8-bit codes give the widest dequantized range, so the f16 tile store rounds hardest here."
|
| 776 |
+
},
|
| 777 |
+
"attrs": { "K": 128, "N": 1024, "bits": 8, "block_size": 32 }
|
| 778 |
+
},
|
| 779 |
+
{
|
| 780 |
+
"name": "q8_zero_bias_prefill_reg_m512_n1024",
|
| 781 |
+
"inputs": {
|
| 782 |
+
"aT": {
|
| 783 |
+
"dtype": "float32",
|
| 784 |
+
"shape": [512, 128],
|
| 785 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 786 |
+
},
|
| 787 |
+
"bT": {
|
| 788 |
+
"dtype": "uint8",
|
| 789 |
+
"shape": [1024, 4, 32],
|
| 790 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 791 |
+
},
|
| 792 |
+
"scalesT": {
|
| 793 |
+
"dtype": "float32",
|
| 794 |
+
"shape": [1024, 4],
|
| 795 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 796 |
+
},
|
| 797 |
+
"zeroPointsT": {
|
| 798 |
+
"dtype": "float32",
|
| 799 |
+
"shape": [1024, 4],
|
| 800 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0, 118.0, 144.0, 126.0] }
|
| 801 |
+
},
|
| 802 |
+
"biasT": {
|
| 803 |
+
"dtype": "float32",
|
| 804 |
+
"shape": [1024],
|
| 805 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 806 |
+
}
|
| 807 |
+
},
|
| 808 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [512, 1024], "tolerance": 0.001 } },
|
| 809 |
+
"attrs": { "K": 128, "N": 1024, "bits": 8, "block_size": 32 }
|
| 810 |
+
},
|
| 811 |
+
{
|
| 812 |
+
"name": "q4_no_zero_prefill_tile4x4_partial_row_tile_m6",
|
| 813 |
+
"provenance": {
|
| 814 |
+
"notes": "M=6 is not a multiple of TILE_M=4, so the tile4x4 kernel's second row-tile (row_base=4) has valid rows 4,5 and guarded rows 6,7. Verifies the store_row partial-row-tile guard writes rows 4,5 correctly and does not corrupt/OOB rows 6,7. N=8 (%4==0), K=64, blockSize=32 routes to prefill_tile4x4_default_zero."
|
| 815 |
+
},
|
| 816 |
+
"inputs": {
|
| 817 |
+
"aT": {
|
| 818 |
+
"dtype": "float32",
|
| 819 |
+
"shape": [6, 64],
|
| 820 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 821 |
+
},
|
| 822 |
+
"bT": {
|
| 823 |
+
"dtype": "uint8",
|
| 824 |
+
"shape": [8, 2, 16],
|
| 825 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 826 |
+
},
|
| 827 |
+
"scalesT": {
|
| 828 |
+
"dtype": "float32",
|
| 829 |
+
"shape": [8, 2],
|
| 830 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 831 |
+
}
|
| 832 |
+
},
|
| 833 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [6, 8], "tolerance": 0.0001 } },
|
| 834 |
+
"attrs": { "K": 64, "N": 8, "bits": 4, "block_size": 32 }
|
| 835 |
+
},
|
| 836 |
+
{
|
| 837 |
+
"name": "q4_gemv_default_zero_m1_tail_n7",
|
| 838 |
+
"provenance": {
|
| 839 |
+
"notes": "M=1 GEMV with N=7 (not a multiple of 4). Exercises the vec4 tail-column store guards (col_base+1/2/3 < N) in matmul-nbits-gemv-q4.wgsl.jinja; existing M==1 tests all use N=4. Routes to gemv_default_zero (prio 20)."
|
| 840 |
+
},
|
| 841 |
+
"inputs": {
|
| 842 |
+
"aT": {
|
| 843 |
+
"dtype": "float32",
|
| 844 |
+
"shape": [1, 32],
|
| 845 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.17, "cosStep": 0.31 }
|
| 846 |
+
},
|
| 847 |
+
"bT": {
|
| 848 |
+
"dtype": "uint8",
|
| 849 |
+
"shape": [7, 1, 16],
|
| 850 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 851 |
+
},
|
| 852 |
+
"scalesT": {
|
| 853 |
+
"dtype": "float32",
|
| 854 |
+
"shape": [7, 1],
|
| 855 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 856 |
+
}
|
| 857 |
+
},
|
| 858 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [1, 7], "tolerance": 0.00001 } },
|
| 859 |
+
"attrs": { "K": 32, "N": 7, "bits": 4, "block_size": 32 }
|
| 860 |
+
},
|
| 861 |
+
{
|
| 862 |
+
"name": "q4_gemv_default_zero_m1_n13_ncols8",
|
| 863 |
+
"tunables": { "GEMV_N_COLS": 8 },
|
| 864 |
+
"provenance": {
|
| 865 |
+
"notes": "GEMV_N_COLS=8 with N=13: two workgroups, first fully live, second with a partially live first group and one live column in the second."
|
| 866 |
+
},
|
| 867 |
+
"inputs": {
|
| 868 |
+
"aT": {
|
| 869 |
+
"dtype": "float32",
|
| 870 |
+
"shape": [1, 32],
|
| 871 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.17, "cosStep": 0.31 }
|
| 872 |
+
},
|
| 873 |
+
"bT": {
|
| 874 |
+
"dtype": "uint8",
|
| 875 |
+
"shape": [13, 1, 16],
|
| 876 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 877 |
+
},
|
| 878 |
+
"scalesT": {
|
| 879 |
+
"dtype": "float32",
|
| 880 |
+
"shape": [13, 1],
|
| 881 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 882 |
+
}
|
| 883 |
+
},
|
| 884 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [1, 13], "tolerance": 0.00001 } },
|
| 885 |
+
"attrs": { "K": 32, "N": 13, "bits": 4, "block_size": 32 }
|
| 886 |
+
},
|
| 887 |
+
{
|
| 888 |
+
"name": "q4_gemv_default_zero_m1_tail_n7_ncols8",
|
| 889 |
+
"tunables": { "GEMV_N_COLS": 8 },
|
| 890 |
+
"provenance": {
|
| 891 |
+
"notes": "GEMV_N_COLS=8 twin of tail_n7: one workgroup, second column group entirely tail-guarded (cols 4-6 active, 7 out of range)."
|
| 892 |
+
},
|
| 893 |
+
"inputs": {
|
| 894 |
+
"aT": {
|
| 895 |
+
"dtype": "float32",
|
| 896 |
+
"shape": [1, 32],
|
| 897 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.17, "cosStep": 0.31 }
|
| 898 |
+
},
|
| 899 |
+
"bT": {
|
| 900 |
+
"dtype": "uint8",
|
| 901 |
+
"shape": [7, 1, 16],
|
| 902 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 903 |
+
},
|
| 904 |
+
"scalesT": {
|
| 905 |
+
"dtype": "float32",
|
| 906 |
+
"shape": [7, 1],
|
| 907 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 908 |
+
}
|
| 909 |
+
},
|
| 910 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [1, 7], "tolerance": 0.00001 } },
|
| 911 |
+
"attrs": { "K": 32, "N": 7, "bits": 4, "block_size": 32 }
|
| 912 |
+
},
|
| 913 |
+
{
|
| 914 |
+
"name": "q8_zero_bias_gemv_m1_tail_n5",
|
| 915 |
+
"provenance": {
|
| 916 |
+
"notes": "M=1 q8 GEMV with N=5 (not a multiple of 4), WITH zero_points and bias. Exercises the vec4 tail-column store guards together with the q8 unpack and bias epilogue in matmul-nbits-gemv-q4.wgsl.jinja. Routes to gemv_zero_bias (prio 20)."
|
| 917 |
+
},
|
| 918 |
+
"inputs": {
|
| 919 |
+
"aT": {
|
| 920 |
+
"dtype": "float32",
|
| 921 |
+
"shape": [1, 16],
|
| 922 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.17, "cosStep": 0.31 }
|
| 923 |
+
},
|
| 924 |
+
"bT": {
|
| 925 |
+
"dtype": "uint8",
|
| 926 |
+
"shape": [5, 1, 16],
|
| 927 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q8_zero_bias_gemv_m1_tail_n5_input_bT" } }
|
| 928 |
+
},
|
| 929 |
+
"scalesT": {
|
| 930 |
+
"dtype": "float32",
|
| 931 |
+
"shape": [5, 1],
|
| 932 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06] }
|
| 933 |
+
},
|
| 934 |
+
"zeroPointsT": {
|
| 935 |
+
"dtype": "float32",
|
| 936 |
+
"shape": [5, 1],
|
| 937 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0] }
|
| 938 |
+
},
|
| 939 |
+
"biasT": {
|
| 940 |
+
"dtype": "float32",
|
| 941 |
+
"shape": [5],
|
| 942 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 943 |
+
}
|
| 944 |
+
},
|
| 945 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [1, 5], "tolerance": 0.00001 } },
|
| 946 |
+
"attrs": { "K": 16, "N": 5, "bits": 8, "block_size": 16 }
|
| 947 |
+
},
|
| 948 |
+
{
|
| 949 |
+
"name": "q8_zero_only_gemv_m1_tail_n5",
|
| 950 |
+
"provenance": {
|
| 951 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 952 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 953 |
+
"notes": "M=1 q8 GEMV with explicit zero points and no bias. This pins the zero-points-only binding layout and epilogue instead of relying on the combined zero-point-plus-bias case."
|
| 954 |
+
},
|
| 955 |
+
"inputs": {
|
| 956 |
+
"aT": {
|
| 957 |
+
"dtype": "float32",
|
| 958 |
+
"shape": [1, 16],
|
| 959 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.17, "cosStep": 0.31 }
|
| 960 |
+
},
|
| 961 |
+
"bT": {
|
| 962 |
+
"dtype": "uint8",
|
| 963 |
+
"shape": [5, 1, 16],
|
| 964 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q8_zero_bias_gemv_m1_tail_n5_input_bT" } }
|
| 965 |
+
},
|
| 966 |
+
"scalesT": {
|
| 967 |
+
"dtype": "float32",
|
| 968 |
+
"shape": [5, 1],
|
| 969 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06] }
|
| 970 |
+
},
|
| 971 |
+
"zeroPointsT": {
|
| 972 |
+
"dtype": "float32",
|
| 973 |
+
"shape": [5, 1],
|
| 974 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0] }
|
| 975 |
+
}
|
| 976 |
+
},
|
| 977 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [1, 5], "tolerance": 0.00001 } },
|
| 978 |
+
"attrs": { "K": 16, "N": 5, "bits": 8, "block_size": 16 }
|
| 979 |
+
},
|
| 980 |
+
{
|
| 981 |
+
"name": "q8_bias_only_gemv_m1_tail_n5",
|
| 982 |
+
"provenance": {
|
| 983 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 984 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 985 |
+
"notes": "M=1 q8 GEMV with bias and the schema-default zero point. This pins the bias-only binding layout and epilogue instead of relying on the combined zero-point-plus-bias case."
|
| 986 |
+
},
|
| 987 |
+
"inputs": {
|
| 988 |
+
"aT": {
|
| 989 |
+
"dtype": "float32",
|
| 990 |
+
"shape": [1, 16],
|
| 991 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.17, "cosStep": 0.31 }
|
| 992 |
+
},
|
| 993 |
+
"bT": {
|
| 994 |
+
"dtype": "uint8",
|
| 995 |
+
"shape": [5, 1, 16],
|
| 996 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q8_zero_bias_gemv_m1_tail_n5_input_bT" } }
|
| 997 |
+
},
|
| 998 |
+
"scalesT": {
|
| 999 |
+
"dtype": "float32",
|
| 1000 |
+
"shape": [5, 1],
|
| 1001 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06] }
|
| 1002 |
+
},
|
| 1003 |
+
"biasT": {
|
| 1004 |
+
"dtype": "float32",
|
| 1005 |
+
"shape": [5],
|
| 1006 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 1007 |
+
}
|
| 1008 |
+
},
|
| 1009 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [1, 5], "tolerance": 0.00001 } },
|
| 1010 |
+
"attrs": { "K": 16, "N": 5, "bits": 8, "block_size": 16 }
|
| 1011 |
+
},
|
| 1012 |
+
{
|
| 1013 |
+
"name": "q8_zero_bias_gemv_m1_tail_n5_ncols8",
|
| 1014 |
+
"tunables": { "GEMV_N_COLS": 8 },
|
| 1015 |
+
"provenance": {
|
| 1016 |
+
"notes": "GEMV_N_COLS=8 twin of tail_n5: q8 unpack + zero_points + bias epilogue with only one live column in the second group."
|
| 1017 |
+
},
|
| 1018 |
+
"inputs": {
|
| 1019 |
+
"aT": {
|
| 1020 |
+
"dtype": "float32",
|
| 1021 |
+
"shape": [1, 16],
|
| 1022 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.17, "cosStep": 0.31 }
|
| 1023 |
+
},
|
| 1024 |
+
"bT": {
|
| 1025 |
+
"dtype": "uint8",
|
| 1026 |
+
"shape": [5, 1, 16],
|
| 1027 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q8_zero_bias_gemv_m1_tail_n5_input_bT" } }
|
| 1028 |
+
},
|
| 1029 |
+
"scalesT": {
|
| 1030 |
+
"dtype": "float32",
|
| 1031 |
+
"shape": [5, 1],
|
| 1032 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06] }
|
| 1033 |
+
},
|
| 1034 |
+
"zeroPointsT": {
|
| 1035 |
+
"dtype": "float32",
|
| 1036 |
+
"shape": [5, 1],
|
| 1037 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0] }
|
| 1038 |
+
},
|
| 1039 |
+
"biasT": {
|
| 1040 |
+
"dtype": "float32",
|
| 1041 |
+
"shape": [5],
|
| 1042 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 1043 |
+
}
|
| 1044 |
+
},
|
| 1045 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [1, 5], "tolerance": 0.00001 } },
|
| 1046 |
+
"attrs": { "K": 16, "N": 5, "bits": 8, "block_size": 16 }
|
| 1047 |
+
},
|
| 1048 |
+
{
|
| 1049 |
+
"name": "q8_zero_bias_naive_fallback_tailK_m3_n6",
|
| 1050 |
+
"provenance": {
|
| 1051 |
+
"notes": "K=17,blockSize=16 gives a tail block; N=6 is below the register-tiled floor and the aligned tile paths are ineligible, while M=3 bypasses GEMV. With zero_points+bias present this routes to the priority-0 zero_bias scalar fallback and covers q8 unpack, per-block zero points, bias, and a partial K block."
|
| 1052 |
+
},
|
| 1053 |
+
"inputs": {
|
| 1054 |
+
"aT": {
|
| 1055 |
+
"dtype": "float32",
|
| 1056 |
+
"shape": [3, 17],
|
| 1057 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.13, "cosStep": 0.29, "scale": 0.75 }
|
| 1058 |
+
},
|
| 1059 |
+
"bT": {
|
| 1060 |
+
"dtype": "uint8",
|
| 1061 |
+
"shape": [6, 2, 16],
|
| 1062 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q8_zero_bias_gemv_m1_tail_n5_input_bT" } }
|
| 1063 |
+
},
|
| 1064 |
+
"scalesT": {
|
| 1065 |
+
"dtype": "float32",
|
| 1066 |
+
"shape": [6, 2],
|
| 1067 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06, 0.075] }
|
| 1068 |
+
},
|
| 1069 |
+
"zeroPointsT": {
|
| 1070 |
+
"dtype": "float32",
|
| 1071 |
+
"shape": [6, 2],
|
| 1072 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0, 118.0] }
|
| 1073 |
+
},
|
| 1074 |
+
"biasT": {
|
| 1075 |
+
"dtype": "float32",
|
| 1076 |
+
"shape": [6],
|
| 1077 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 1078 |
+
}
|
| 1079 |
+
},
|
| 1080 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [3, 6], "tolerance": 0.001 } },
|
| 1081 |
+
"attrs": { "K": 17, "N": 6, "bits": 8, "block_size": 16 }
|
| 1082 |
+
},
|
| 1083 |
+
{
|
| 1084 |
+
"name": "q4_prefill_tiled_reg_tailk_m32_k33_n4096",
|
| 1085 |
+
"provenance": {
|
| 1086 |
+
"notes": "Compact tail-block lock for the register-tiled prefill path used by the realistic K=2561 benchmark; the final 31 padded weights must not read past A."
|
| 1087 |
+
},
|
| 1088 |
+
"inputs": {
|
| 1089 |
+
"aT": {
|
| 1090 |
+
"dtype": "float32",
|
| 1091 |
+
"shape": [32, 33],
|
| 1092 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.13, "cosStep": 0.29, "scale": 0.35 }
|
| 1093 |
+
},
|
| 1094 |
+
"bT": {
|
| 1095 |
+
"dtype": "uint8",
|
| 1096 |
+
"shape": [4096, 2, 16],
|
| 1097 |
+
"data": {
|
| 1098 |
+
"kind": "cycle",
|
| 1099 |
+
"values": { "$ref": "#/fixtureArrays/q4_prefill_tiled_reg_tailk_m32_k33_n4096_input_bT" }
|
| 1100 |
+
}
|
| 1101 |
+
},
|
| 1102 |
+
"scalesT": {
|
| 1103 |
+
"dtype": "float32",
|
| 1104 |
+
"shape": [4096, 2],
|
| 1105 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1106 |
+
}
|
| 1107 |
+
},
|
| 1108 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [32, 4096], "tolerance": 0.001 } },
|
| 1109 |
+
"attrs": { "K": 33, "N": 4096, "bits": 4, "block_size": 32 }
|
| 1110 |
+
},
|
| 1111 |
+
{
|
| 1112 |
+
"name": "q4_prefill_tiled_reg_aligned_m32_k32_n4096_at_workgroup_floor",
|
| 1113 |
+
"provenance": {
|
| 1114 |
+
"source": "authored for route coverage",
|
| 1115 |
+
"notes": "Aligned-K twin of the tail-K case at the same M and N. A tail-K shape skips the register tile's workgroup floor entirely, so no fixture exercised that floor; this one sits exactly on it at 64 workgroups."
|
| 1116 |
+
},
|
| 1117 |
+
"inputs": {
|
| 1118 |
+
"aT": {
|
| 1119 |
+
"dtype": "float32",
|
| 1120 |
+
"shape": [32, 32],
|
| 1121 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.17, "cosStep": 0.31, "scale": 0.35 }
|
| 1122 |
+
},
|
| 1123 |
+
"bT": {
|
| 1124 |
+
"dtype": "uint8",
|
| 1125 |
+
"shape": [4096, 1, 16],
|
| 1126 |
+
"data": {
|
| 1127 |
+
"kind": "cycle",
|
| 1128 |
+
"values": { "$ref": "#/fixtureArrays/q4_prefill_tiled_reg_tailk_m32_k33_n4096_input_bT" }
|
| 1129 |
+
}
|
| 1130 |
+
},
|
| 1131 |
+
"scalesT": {
|
| 1132 |
+
"dtype": "float32",
|
| 1133 |
+
"shape": [4096, 1],
|
| 1134 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1135 |
+
}
|
| 1136 |
+
},
|
| 1137 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [32, 4096], "tolerance": 0.001 } },
|
| 1138 |
+
"attrs": { "K": 32, "N": 4096, "bits": 4, "block_size": 32 }
|
| 1139 |
+
},
|
| 1140 |
+
{
|
| 1141 |
+
"name": "q4_prefill_tiled_reg_tailk_m32_k33_n512_below_wide_n_floor",
|
| 1142 |
+
"provenance": {
|
| 1143 |
+
"notes": "Tail-block coverage below the ordinary wide register-tile N floor. K=33 exercises the padded final block, while N=512 keeps the case inside the relaxed band that the larger N=4096 case cannot distinguish."
|
| 1144 |
+
},
|
| 1145 |
+
"inputs": {
|
| 1146 |
+
"aT": {
|
| 1147 |
+
"dtype": "float32",
|
| 1148 |
+
"shape": [32, 33],
|
| 1149 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.13, "cosStep": 0.29, "scale": 0.35 }
|
| 1150 |
+
},
|
| 1151 |
+
"bT": {
|
| 1152 |
+
"dtype": "uint8",
|
| 1153 |
+
"shape": [512, 2, 16],
|
| 1154 |
+
"data": {
|
| 1155 |
+
"kind": "cycle",
|
| 1156 |
+
"values": { "$ref": "#/fixtureArrays/q4_prefill_tiled_reg_tailk_m32_k33_n4096_input_bT" }
|
| 1157 |
+
}
|
| 1158 |
+
},
|
| 1159 |
+
"scalesT": {
|
| 1160 |
+
"dtype": "float32",
|
| 1161 |
+
"shape": [512, 2],
|
| 1162 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1163 |
+
}
|
| 1164 |
+
},
|
| 1165 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [32, 512], "tolerance": 0.001 } },
|
| 1166 |
+
"attrs": { "K": 33, "N": 512, "bits": 4, "block_size": 32 }
|
| 1167 |
+
},
|
| 1168 |
+
{
|
| 1169 |
+
"name": "q4_f16_prefill_reg_tailk_m32_k33_n4096",
|
| 1170 |
+
"provenance": {
|
| 1171 |
+
"notes": "f16 activations through the register-tiled general (non-block-aligned) loader and the M=32 portable geometry, plus the padded tail K."
|
| 1172 |
+
},
|
| 1173 |
+
"inputs": {
|
| 1174 |
+
"aT": {
|
| 1175 |
+
"dtype": "float16",
|
| 1176 |
+
"shape": [32, 33],
|
| 1177 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.13, "cosStep": 0.29, "scale": 0.35 }
|
| 1178 |
+
},
|
| 1179 |
+
"bT": {
|
| 1180 |
+
"dtype": "uint8",
|
| 1181 |
+
"shape": [4096, 2, 16],
|
| 1182 |
+
"data": {
|
| 1183 |
+
"kind": "cycle",
|
| 1184 |
+
"values": { "$ref": "#/fixtureArrays/q4_prefill_tiled_reg_tailk_m32_k33_n4096_input_bT" }
|
| 1185 |
+
}
|
| 1186 |
+
},
|
| 1187 |
+
"scalesT": {
|
| 1188 |
+
"dtype": "float16",
|
| 1189 |
+
"shape": [4096, 2],
|
| 1190 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1191 |
+
}
|
| 1192 |
+
},
|
| 1193 |
+
"outputs": { "yT": { "dtype": "float16", "shape": [32, 4096], "tolerance": 0.0001, "relTolerance": 0.001 } },
|
| 1194 |
+
"attrs": { "K": 33, "N": 4096, "bits": 4, "block_size": 32 }
|
| 1195 |
+
},
|
| 1196 |
+
{
|
| 1197 |
+
"name": "q8_no_zero_prefill_odd_n_fallback",
|
| 1198 |
+
"provenance": {
|
| 1199 |
+
"notes": "M>1 q8 prefill with N=17 and no zero_points/bias. Odd N excludes subgroup-matrix execution; the portable tile4x4 tail guards handle the final output column used by the odd-column benchmark guardrail."
|
| 1200 |
+
},
|
| 1201 |
+
"inputs": {
|
| 1202 |
+
"aT": {
|
| 1203 |
+
"dtype": "float32",
|
| 1204 |
+
"shape": [8, 64],
|
| 1205 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1206 |
+
},
|
| 1207 |
+
"bT": {
|
| 1208 |
+
"dtype": "uint8",
|
| 1209 |
+
"shape": [17, 2, 32],
|
| 1210 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 1211 |
+
},
|
| 1212 |
+
"scalesT": {
|
| 1213 |
+
"dtype": "float32",
|
| 1214 |
+
"shape": [17, 2],
|
| 1215 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1216 |
+
}
|
| 1217 |
+
},
|
| 1218 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [8, 17], "tolerance": 0.001 } },
|
| 1219 |
+
"attrs": { "K": 64, "N": 17, "bits": 8, "block_size": 32 }
|
| 1220 |
+
},
|
| 1221 |
+
{
|
| 1222 |
+
"name": "q4_zero_only_prefill_sgmat_m32_storage_floor",
|
| 1223 |
+
"provenance": {
|
| 1224 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1225 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1226 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1227 |
+
},
|
| 1228 |
+
"inputs": {
|
| 1229 |
+
"aT": {
|
| 1230 |
+
"dtype": "float32",
|
| 1231 |
+
"shape": [32, 32],
|
| 1232 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1233 |
+
},
|
| 1234 |
+
"bT": {
|
| 1235 |
+
"dtype": "uint8",
|
| 1236 |
+
"shape": [64, 1, 16],
|
| 1237 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 1238 |
+
},
|
| 1239 |
+
"scalesT": {
|
| 1240 |
+
"dtype": "float32",
|
| 1241 |
+
"shape": [64, 1],
|
| 1242 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065] }
|
| 1243 |
+
},
|
| 1244 |
+
"zeroPointsT": {
|
| 1245 |
+
"dtype": "float32",
|
| 1246 |
+
"shape": [64, 1],
|
| 1247 |
+
"data": { "kind": "cycle", "values": [7.0, 8.0, 6.0, 9.0] }
|
| 1248 |
+
}
|
| 1249 |
+
},
|
| 1250 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [32, 64], "tolerance": 0.0001 } },
|
| 1251 |
+
"attrs": { "K": 32, "N": 64, "bits": 4, "block_size": 32 }
|
| 1252 |
+
},
|
| 1253 |
+
{
|
| 1254 |
+
"name": "q4_bias_only_prefill_sgmat_m32_storage_floor",
|
| 1255 |
+
"provenance": {
|
| 1256 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1257 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1258 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1259 |
+
},
|
| 1260 |
+
"inputs": {
|
| 1261 |
+
"aT": {
|
| 1262 |
+
"dtype": "float32",
|
| 1263 |
+
"shape": [32, 32],
|
| 1264 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1265 |
+
},
|
| 1266 |
+
"bT": {
|
| 1267 |
+
"dtype": "uint8",
|
| 1268 |
+
"shape": [64, 1, 16],
|
| 1269 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 1270 |
+
},
|
| 1271 |
+
"scalesT": {
|
| 1272 |
+
"dtype": "float32",
|
| 1273 |
+
"shape": [64, 1],
|
| 1274 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065] }
|
| 1275 |
+
},
|
| 1276 |
+
"biasT": {
|
| 1277 |
+
"dtype": "float32",
|
| 1278 |
+
"shape": [64],
|
| 1279 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 1280 |
+
}
|
| 1281 |
+
},
|
| 1282 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [32, 64], "tolerance": 0.0001 } },
|
| 1283 |
+
"attrs": { "K": 32, "N": 64, "bits": 4, "block_size": 32 }
|
| 1284 |
+
},
|
| 1285 |
+
{
|
| 1286 |
+
"name": "q8_zero_only_prefill_sgmat_large",
|
| 1287 |
+
"inputs": {
|
| 1288 |
+
"aT": {
|
| 1289 |
+
"dtype": "float32",
|
| 1290 |
+
"shape": [128, 128],
|
| 1291 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1292 |
+
},
|
| 1293 |
+
"bT": {
|
| 1294 |
+
"dtype": "uint8",
|
| 1295 |
+
"shape": [64, 4, 32],
|
| 1296 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 1297 |
+
},
|
| 1298 |
+
"scalesT": {
|
| 1299 |
+
"dtype": "float32",
|
| 1300 |
+
"shape": [64, 4],
|
| 1301 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1302 |
+
},
|
| 1303 |
+
"zeroPointsT": {
|
| 1304 |
+
"dtype": "float32",
|
| 1305 |
+
"shape": [64, 4],
|
| 1306 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0, 118.0, 144.0, 126.0] }
|
| 1307 |
+
}
|
| 1308 |
+
},
|
| 1309 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [128, 64], "tolerance": 0.001 } },
|
| 1310 |
+
"provenance": {
|
| 1311 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1312 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1313 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1314 |
+
},
|
| 1315 |
+
"attrs": { "K": 128, "N": 64, "bits": 8, "block_size": 32 }
|
| 1316 |
+
},
|
| 1317 |
+
{
|
| 1318 |
+
"name": "q8_bias_only_prefill_sgmat_large",
|
| 1319 |
+
"inputs": {
|
| 1320 |
+
"aT": {
|
| 1321 |
+
"dtype": "float32",
|
| 1322 |
+
"shape": [128, 128],
|
| 1323 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1324 |
+
},
|
| 1325 |
+
"bT": {
|
| 1326 |
+
"dtype": "uint8",
|
| 1327 |
+
"shape": [64, 4, 32],
|
| 1328 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 1329 |
+
},
|
| 1330 |
+
"scalesT": {
|
| 1331 |
+
"dtype": "float32",
|
| 1332 |
+
"shape": [64, 4],
|
| 1333 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1334 |
+
},
|
| 1335 |
+
"biasT": {
|
| 1336 |
+
"dtype": "float32",
|
| 1337 |
+
"shape": [64],
|
| 1338 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 1339 |
+
}
|
| 1340 |
+
},
|
| 1341 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [128, 64], "tolerance": 0.001 } },
|
| 1342 |
+
"provenance": {
|
| 1343 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1344 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1345 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1346 |
+
},
|
| 1347 |
+
"attrs": { "K": 128, "N": 64, "bits": 8, "block_size": 32 }
|
| 1348 |
+
},
|
| 1349 |
+
{
|
| 1350 |
+
"name": "q4_zero_only_prefill_reg_m512_n1024",
|
| 1351 |
+
"inputs": {
|
| 1352 |
+
"aT": {
|
| 1353 |
+
"dtype": "float32",
|
| 1354 |
+
"shape": [512, 128],
|
| 1355 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1356 |
+
},
|
| 1357 |
+
"bT": {
|
| 1358 |
+
"dtype": "uint8",
|
| 1359 |
+
"shape": [1024, 4, 16],
|
| 1360 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 1361 |
+
},
|
| 1362 |
+
"scalesT": {
|
| 1363 |
+
"dtype": "float32",
|
| 1364 |
+
"shape": [1024, 4],
|
| 1365 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1366 |
+
},
|
| 1367 |
+
"zeroPointsT": {
|
| 1368 |
+
"dtype": "float32",
|
| 1369 |
+
"shape": [1024, 4],
|
| 1370 |
+
"data": { "kind": "cycle", "values": [6.0, 7.0, 8.0, 9.0] }
|
| 1371 |
+
}
|
| 1372 |
+
},
|
| 1373 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [512, 1024], "tolerance": 0.0001 } },
|
| 1374 |
+
"provenance": {
|
| 1375 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1376 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1377 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1378 |
+
},
|
| 1379 |
+
"attrs": { "K": 128, "N": 1024, "bits": 4, "block_size": 32 }
|
| 1380 |
+
},
|
| 1381 |
+
{
|
| 1382 |
+
"name": "q4_bias_only_prefill_reg_m512_n1024",
|
| 1383 |
+
"inputs": {
|
| 1384 |
+
"aT": {
|
| 1385 |
+
"dtype": "float32",
|
| 1386 |
+
"shape": [512, 128],
|
| 1387 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1388 |
+
},
|
| 1389 |
+
"bT": {
|
| 1390 |
+
"dtype": "uint8",
|
| 1391 |
+
"shape": [1024, 4, 16],
|
| 1392 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 1393 |
+
},
|
| 1394 |
+
"scalesT": {
|
| 1395 |
+
"dtype": "float32",
|
| 1396 |
+
"shape": [1024, 4],
|
| 1397 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1398 |
+
},
|
| 1399 |
+
"biasT": {
|
| 1400 |
+
"dtype": "float32",
|
| 1401 |
+
"shape": [1024],
|
| 1402 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.1 }
|
| 1403 |
+
}
|
| 1404 |
+
},
|
| 1405 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [512, 1024], "tolerance": 0.0001 } },
|
| 1406 |
+
"provenance": {
|
| 1407 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1408 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1409 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1410 |
+
},
|
| 1411 |
+
"attrs": { "K": 128, "N": 1024, "bits": 4, "block_size": 32 }
|
| 1412 |
+
},
|
| 1413 |
+
{
|
| 1414 |
+
"name": "q8_zero_only_prefill_reg_m512_n1024",
|
| 1415 |
+
"inputs": {
|
| 1416 |
+
"aT": {
|
| 1417 |
+
"dtype": "float32",
|
| 1418 |
+
"shape": [512, 128],
|
| 1419 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1420 |
+
},
|
| 1421 |
+
"bT": {
|
| 1422 |
+
"dtype": "uint8",
|
| 1423 |
+
"shape": [1024, 4, 32],
|
| 1424 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 1425 |
+
},
|
| 1426 |
+
"scalesT": {
|
| 1427 |
+
"dtype": "float32",
|
| 1428 |
+
"shape": [1024, 4],
|
| 1429 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1430 |
+
},
|
| 1431 |
+
"zeroPointsT": {
|
| 1432 |
+
"dtype": "float32",
|
| 1433 |
+
"shape": [1024, 4],
|
| 1434 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0, 118.0, 144.0, 126.0] }
|
| 1435 |
+
}
|
| 1436 |
+
},
|
| 1437 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [512, 1024], "tolerance": 0.001 } },
|
| 1438 |
+
"provenance": {
|
| 1439 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1440 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1441 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1442 |
+
},
|
| 1443 |
+
"attrs": { "K": 128, "N": 1024, "bits": 8, "block_size": 32 }
|
| 1444 |
+
},
|
| 1445 |
+
{
|
| 1446 |
+
"name": "q8_bias_only_prefill_reg_m512_n1024",
|
| 1447 |
+
"inputs": {
|
| 1448 |
+
"aT": {
|
| 1449 |
+
"dtype": "float32",
|
| 1450 |
+
"shape": [512, 128],
|
| 1451 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1452 |
+
},
|
| 1453 |
+
"bT": {
|
| 1454 |
+
"dtype": "uint8",
|
| 1455 |
+
"shape": [1024, 4, 32],
|
| 1456 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 1457 |
+
},
|
| 1458 |
+
"scalesT": {
|
| 1459 |
+
"dtype": "float32",
|
| 1460 |
+
"shape": [1024, 4],
|
| 1461 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1462 |
+
},
|
| 1463 |
+
"biasT": {
|
| 1464 |
+
"dtype": "float32",
|
| 1465 |
+
"shape": [1024],
|
| 1466 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 1467 |
+
}
|
| 1468 |
+
},
|
| 1469 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [512, 1024], "tolerance": 0.001 } },
|
| 1470 |
+
"provenance": {
|
| 1471 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1472 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1473 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1474 |
+
},
|
| 1475 |
+
"attrs": { "K": 128, "N": 1024, "bits": 8, "block_size": 32 }
|
| 1476 |
+
},
|
| 1477 |
+
{
|
| 1478 |
+
"name": "q4_zero_only_prefill_tile4x4_small_m8",
|
| 1479 |
+
"provenance": {
|
| 1480 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1481 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1482 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1483 |
+
},
|
| 1484 |
+
"inputs": {
|
| 1485 |
+
"aT": {
|
| 1486 |
+
"dtype": "float32",
|
| 1487 |
+
"shape": [8, 128],
|
| 1488 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1489 |
+
},
|
| 1490 |
+
"bT": {
|
| 1491 |
+
"dtype": "uint8",
|
| 1492 |
+
"shape": [64, 4, 16],
|
| 1493 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 1494 |
+
},
|
| 1495 |
+
"scalesT": {
|
| 1496 |
+
"dtype": "float32",
|
| 1497 |
+
"shape": [64, 4],
|
| 1498 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1499 |
+
},
|
| 1500 |
+
"zeroPointsT": {
|
| 1501 |
+
"dtype": "float32",
|
| 1502 |
+
"shape": [64, 4],
|
| 1503 |
+
"data": { "kind": "cycle", "values": [6.0, 7.0, 8.0, 9.0] }
|
| 1504 |
+
}
|
| 1505 |
+
},
|
| 1506 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [8, 64], "tolerance": 0.0001 } },
|
| 1507 |
+
"attrs": { "K": 128, "N": 64, "bits": 4, "block_size": 32 }
|
| 1508 |
+
},
|
| 1509 |
+
{
|
| 1510 |
+
"name": "q4_bias_only_prefill_tile4x4_small_m8",
|
| 1511 |
+
"provenance": {
|
| 1512 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1513 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1514 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1515 |
+
},
|
| 1516 |
+
"inputs": {
|
| 1517 |
+
"aT": {
|
| 1518 |
+
"dtype": "float32",
|
| 1519 |
+
"shape": [8, 128],
|
| 1520 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1521 |
+
},
|
| 1522 |
+
"bT": {
|
| 1523 |
+
"dtype": "uint8",
|
| 1524 |
+
"shape": [64, 4, 16],
|
| 1525 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 1526 |
+
},
|
| 1527 |
+
"scalesT": {
|
| 1528 |
+
"dtype": "float32",
|
| 1529 |
+
"shape": [64, 4],
|
| 1530 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1531 |
+
},
|
| 1532 |
+
"biasT": {
|
| 1533 |
+
"dtype": "float32",
|
| 1534 |
+
"shape": [64],
|
| 1535 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.1 }
|
| 1536 |
+
}
|
| 1537 |
+
},
|
| 1538 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [8, 64], "tolerance": 0.0001 } },
|
| 1539 |
+
"attrs": { "K": 128, "N": 64, "bits": 4, "block_size": 32 }
|
| 1540 |
+
},
|
| 1541 |
+
{
|
| 1542 |
+
"name": "q8_zero_only_prefill_tile4x4_small_m8",
|
| 1543 |
+
"provenance": {
|
| 1544 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1545 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1546 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1547 |
+
},
|
| 1548 |
+
"inputs": {
|
| 1549 |
+
"aT": {
|
| 1550 |
+
"dtype": "float32",
|
| 1551 |
+
"shape": [8, 128],
|
| 1552 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1553 |
+
},
|
| 1554 |
+
"bT": {
|
| 1555 |
+
"dtype": "uint8",
|
| 1556 |
+
"shape": [64, 4, 32],
|
| 1557 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 1558 |
+
},
|
| 1559 |
+
"scalesT": {
|
| 1560 |
+
"dtype": "float32",
|
| 1561 |
+
"shape": [64, 4],
|
| 1562 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1563 |
+
},
|
| 1564 |
+
"zeroPointsT": {
|
| 1565 |
+
"dtype": "float32",
|
| 1566 |
+
"shape": [64, 4],
|
| 1567 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0, 118.0, 144.0, 126.0] }
|
| 1568 |
+
}
|
| 1569 |
+
},
|
| 1570 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [8, 64], "tolerance": 0.001 } },
|
| 1571 |
+
"attrs": { "K": 128, "N": 64, "bits": 8, "block_size": 32 }
|
| 1572 |
+
},
|
| 1573 |
+
{
|
| 1574 |
+
"name": "q8_bias_only_prefill_tile4x4_small_m8",
|
| 1575 |
+
"provenance": {
|
| 1576 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1577 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1578 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1579 |
+
},
|
| 1580 |
+
"inputs": {
|
| 1581 |
+
"aT": {
|
| 1582 |
+
"dtype": "float32",
|
| 1583 |
+
"shape": [8, 128],
|
| 1584 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1585 |
+
},
|
| 1586 |
+
"bT": {
|
| 1587 |
+
"dtype": "uint8",
|
| 1588 |
+
"shape": [64, 4, 32],
|
| 1589 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/mixed_weight_cycle_b_t" } }
|
| 1590 |
+
},
|
| 1591 |
+
"scalesT": {
|
| 1592 |
+
"dtype": "float32",
|
| 1593 |
+
"shape": [64, 4],
|
| 1594 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1595 |
+
},
|
| 1596 |
+
"biasT": {
|
| 1597 |
+
"dtype": "float32",
|
| 1598 |
+
"shape": [64],
|
| 1599 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41 }
|
| 1600 |
+
}
|
| 1601 |
+
},
|
| 1602 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [8, 64], "tolerance": 0.001 } },
|
| 1603 |
+
"attrs": { "K": 128, "N": 64, "bits": 8, "block_size": 32 }
|
| 1604 |
+
},
|
| 1605 |
+
{
|
| 1606 |
+
"name": "q4_zero_only_prefill_tile4x4_large",
|
| 1607 |
+
"inputs": {
|
| 1608 |
+
"aT": {
|
| 1609 |
+
"dtype": "float32",
|
| 1610 |
+
"shape": [128, 128],
|
| 1611 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1612 |
+
},
|
| 1613 |
+
"bT": {
|
| 1614 |
+
"dtype": "uint8",
|
| 1615 |
+
"shape": [64, 4, 16],
|
| 1616 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 1617 |
+
},
|
| 1618 |
+
"scalesT": {
|
| 1619 |
+
"dtype": "float32",
|
| 1620 |
+
"shape": [64, 4],
|
| 1621 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1622 |
+
},
|
| 1623 |
+
"zeroPointsT": {
|
| 1624 |
+
"dtype": "float32",
|
| 1625 |
+
"shape": [64, 4],
|
| 1626 |
+
"data": { "kind": "cycle", "values": [6.0, 7.0, 8.0, 9.0] }
|
| 1627 |
+
}
|
| 1628 |
+
},
|
| 1629 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [128, 64], "tolerance": 0.0001 } },
|
| 1630 |
+
"provenance": {
|
| 1631 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1632 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1633 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1634 |
+
},
|
| 1635 |
+
"attrs": { "K": 128, "N": 64, "bits": 4, "block_size": 32 }
|
| 1636 |
+
},
|
| 1637 |
+
{
|
| 1638 |
+
"name": "q4_bias_only_prefill_tile4x4_large",
|
| 1639 |
+
"inputs": {
|
| 1640 |
+
"aT": {
|
| 1641 |
+
"dtype": "float32",
|
| 1642 |
+
"shape": [128, 128],
|
| 1643 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1644 |
+
},
|
| 1645 |
+
"bT": {
|
| 1646 |
+
"dtype": "uint8",
|
| 1647 |
+
"shape": [64, 4, 16],
|
| 1648 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q4_weight_cycle_b_t" } }
|
| 1649 |
+
},
|
| 1650 |
+
"scalesT": {
|
| 1651 |
+
"dtype": "float32",
|
| 1652 |
+
"shape": [64, 4],
|
| 1653 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/quant_scale_cycle_t" } }
|
| 1654 |
+
},
|
| 1655 |
+
"biasT": {
|
| 1656 |
+
"dtype": "float32",
|
| 1657 |
+
"shape": [64],
|
| 1658 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.1 }
|
| 1659 |
+
}
|
| 1660 |
+
},
|
| 1661 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [128, 64], "tolerance": 0.0001 } },
|
| 1662 |
+
"provenance": {
|
| 1663 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/matmul_nbits.cc",
|
| 1664 |
+
"test": "independent has_zero_points/has_bias epilogues",
|
| 1665 |
+
"notes": "zero_points-only and bias-only inputs must stay on the fast kernels instead of falling to the naive per-element path."
|
| 1666 |
+
},
|
| 1667 |
+
"attrs": { "K": 128, "N": 64, "bits": 4, "block_size": 32 }
|
| 1668 |
+
},
|
| 1669 |
+
{
|
| 1670 |
+
"name": "q4_dp4a_prefill_al4_m64_k256_n64_b32",
|
| 1671 |
+
"inputs": {
|
| 1672 |
+
"aT": {
|
| 1673 |
+
"dtype": "float32",
|
| 1674 |
+
"shape": [64, 256],
|
| 1675 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.013, "cosStep": 0.021 }
|
| 1676 |
+
},
|
| 1677 |
+
"bT": {
|
| 1678 |
+
"dtype": "uint8",
|
| 1679 |
+
"shape": [64, 8, 16],
|
| 1680 |
+
"data": {
|
| 1681 |
+
"kind": "cycle",
|
| 1682 |
+
"values": [37, 201, 116, 88, 250, 13, 164, 95, 142, 7, 233, 60, 178, 121, 44, 209, 86, 155]
|
| 1683 |
+
}
|
| 1684 |
+
},
|
| 1685 |
+
"scalesT": { "dtype": "float32", "shape": [64, 8], "data": { "kind": "linspace", "start": 0.01, "end": 0.05 } }
|
| 1686 |
+
},
|
| 1687 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [64, 64], "tolerance": 0.03 } },
|
| 1688 |
+
"provenance": {
|
| 1689 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/dp4a_matmul_nbits.cc",
|
| 1690 |
+
"test": "accuracy_level=4 int8 activation quantization (DP4AMatMulQuantize + DP4AMatMulNBits)",
|
| 1691 |
+
"notes": "accuracy_level 4 permits int8 activation math: A is quantized per 128-element block (scale = max_abs / 127, values pack4x8snorm-rounded) and multiplied against the 4-bit weights with packed integer dots. The reference stays float, so tolerances absorb the permitted quantization error."
|
| 1692 |
+
},
|
| 1693 |
+
"attrs": { "K": 256, "N": 64, "bits": 4, "block_size": 32, "accuracy_level": 4 }
|
| 1694 |
+
},
|
| 1695 |
+
{
|
| 1696 |
+
"name": "q4_dp4a_prefill_al4_m48_k128_n16_b64",
|
| 1697 |
+
"inputs": {
|
| 1698 |
+
"aT": {
|
| 1699 |
+
"dtype": "float32",
|
| 1700 |
+
"shape": [48, 128],
|
| 1701 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.017, "cosStep": 0.027 }
|
| 1702 |
+
},
|
| 1703 |
+
"bT": {
|
| 1704 |
+
"dtype": "uint8",
|
| 1705 |
+
"shape": [16, 2, 32],
|
| 1706 |
+
"data": { "kind": "cycle", "values": [37, 201, 116, 88, 250, 13, 164, 95, 142, 7, 233] }
|
| 1707 |
+
},
|
| 1708 |
+
"scalesT": { "dtype": "float32", "shape": [16, 2], "data": { "kind": "linspace", "start": 0.02, "end": 0.06 } }
|
| 1709 |
+
},
|
| 1710 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [48, 16], "tolerance": 0.03 } },
|
| 1711 |
+
"provenance": {
|
| 1712 |
+
"source": "onnxruntime/contrib_ops/webgpu/quantization/dp4a_matmul_nbits.cc",
|
| 1713 |
+
"test": "accuracy_level=4 int8 activation quantization (DP4AMatMulQuantize + DP4AMatMulNBits)",
|
| 1714 |
+
"notes": "accuracy_level 4 permits int8 activation math: A is quantized per 128-element block (scale = max_abs / 127, values pack4x8snorm-rounded) and multiplied against the 4-bit weights with packed integer dots. The reference stays float, so tolerances absorb the permitted quantization error."
|
| 1715 |
+
},
|
| 1716 |
+
"attrs": { "K": 128, "N": 16, "bits": 4, "block_size": 64, "accuracy_level": 4 }
|
| 1717 |
+
},
|
| 1718 |
+
{
|
| 1719 |
+
"name": "q2_zero_bias_prefill_tile4x4_small_m8",
|
| 1720 |
+
"provenance": {
|
| 1721 |
+
"notes": "2-bit weights pack four codes per stored byte, low codes first along K, with a default zero point of 2. Small-M prefill on the 4x4 output tile."
|
| 1722 |
+
},
|
| 1723 |
+
"inputs": {
|
| 1724 |
+
"aT": {
|
| 1725 |
+
"dtype": "float32",
|
| 1726 |
+
"shape": [8, 128],
|
| 1727 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1728 |
+
},
|
| 1729 |
+
"bT": {
|
| 1730 |
+
"dtype": "uint8",
|
| 1731 |
+
"shape": [64, 4, 8],
|
| 1732 |
+
"data": { "kind": "cycle", "values": [27, 180, 75, 226, 33, 150, 201, 108, 57, 246, 129, 66, 195, 84, 237] }
|
| 1733 |
+
},
|
| 1734 |
+
"scalesT": {
|
| 1735 |
+
"dtype": "float32",
|
| 1736 |
+
"shape": [64, 4],
|
| 1737 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06, 0.075, 0.07] }
|
| 1738 |
+
},
|
| 1739 |
+
"zeroPointsT": {
|
| 1740 |
+
"dtype": "float32",
|
| 1741 |
+
"shape": [64, 4],
|
| 1742 |
+
"data": { "kind": "cycle", "values": [1.0, 2.0, 3.0, 0.0, 2.0] }
|
| 1743 |
+
},
|
| 1744 |
+
"biasT": {
|
| 1745 |
+
"dtype": "float32",
|
| 1746 |
+
"shape": [64],
|
| 1747 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.1 }
|
| 1748 |
+
}
|
| 1749 |
+
},
|
| 1750 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [8, 64], "tolerance": 0.001 } },
|
| 1751 |
+
"attrs": { "K": 128, "N": 64, "bits": 2, "block_size": 32 }
|
| 1752 |
+
},
|
| 1753 |
+
{
|
| 1754 |
+
"name": "q2_no_zero_prefill_sgmat_large",
|
| 1755 |
+
"provenance": {
|
| 1756 |
+
"notes": "2-bit weights pack four codes per stored byte, low codes first along K, with a default zero point of 2. Prefill wide enough for the subgroup-matrix tile."
|
| 1757 |
+
},
|
| 1758 |
+
"inputs": {
|
| 1759 |
+
"aT": {
|
| 1760 |
+
"dtype": "float32",
|
| 1761 |
+
"shape": [128, 128],
|
| 1762 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1763 |
+
},
|
| 1764 |
+
"bT": {
|
| 1765 |
+
"dtype": "uint8",
|
| 1766 |
+
"shape": [64, 4, 8],
|
| 1767 |
+
"data": { "kind": "cycle", "values": [27, 180, 75, 226, 33, 150, 201, 108, 57, 246, 129, 66, 195, 84, 237] }
|
| 1768 |
+
},
|
| 1769 |
+
"scalesT": {
|
| 1770 |
+
"dtype": "float32",
|
| 1771 |
+
"shape": [64, 4],
|
| 1772 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06, 0.075, 0.07] }
|
| 1773 |
+
}
|
| 1774 |
+
},
|
| 1775 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [128, 64], "tolerance": 0.001 } },
|
| 1776 |
+
"attrs": { "K": 128, "N": 64, "bits": 2, "block_size": 32 }
|
| 1777 |
+
},
|
| 1778 |
+
{
|
| 1779 |
+
"name": "q2_zero_bias_prefill_sgmat_m32_storage_floor",
|
| 1780 |
+
"provenance": {
|
| 1781 |
+
"notes": "2-bit weights pack four codes per stored byte, low codes first along K, with a default zero point of 2. Subgroup-matrix tile at the M=32 shared-storage floor."
|
| 1782 |
+
},
|
| 1783 |
+
"inputs": {
|
| 1784 |
+
"aT": {
|
| 1785 |
+
"dtype": "float32",
|
| 1786 |
+
"shape": [32, 32],
|
| 1787 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1788 |
+
},
|
| 1789 |
+
"bT": {
|
| 1790 |
+
"dtype": "uint8",
|
| 1791 |
+
"shape": [64, 1, 8],
|
| 1792 |
+
"data": { "kind": "cycle", "values": [27, 180, 75, 226, 33, 150, 201, 108, 57, 246, 129, 66, 195, 84, 237] }
|
| 1793 |
+
},
|
| 1794 |
+
"scalesT": {
|
| 1795 |
+
"dtype": "float32",
|
| 1796 |
+
"shape": [64, 1],
|
| 1797 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06, 0.075, 0.07] }
|
| 1798 |
+
},
|
| 1799 |
+
"zeroPointsT": {
|
| 1800 |
+
"dtype": "float32",
|
| 1801 |
+
"shape": [64, 1],
|
| 1802 |
+
"data": { "kind": "cycle", "values": [1.0, 2.0, 3.0, 0.0, 2.0] }
|
| 1803 |
+
},
|
| 1804 |
+
"biasT": {
|
| 1805 |
+
"dtype": "float32",
|
| 1806 |
+
"shape": [64],
|
| 1807 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.1 }
|
| 1808 |
+
}
|
| 1809 |
+
},
|
| 1810 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [32, 64], "tolerance": 0.001 } },
|
| 1811 |
+
"attrs": { "K": 32, "N": 64, "bits": 2, "block_size": 32 }
|
| 1812 |
+
},
|
| 1813 |
+
{
|
| 1814 |
+
"name": "q2_no_zero_prefill_reg_m512_n1024",
|
| 1815 |
+
"provenance": {
|
| 1816 |
+
"notes": "2-bit weights pack four codes per stored byte, low codes first along K, with a default zero point of 2. Register-tile prefill, whose loader unrolls by K and so needs its own unpack."
|
| 1817 |
+
},
|
| 1818 |
+
"inputs": {
|
| 1819 |
+
"aT": {
|
| 1820 |
+
"dtype": "float32",
|
| 1821 |
+
"shape": [512, 128],
|
| 1822 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1823 |
+
},
|
| 1824 |
+
"bT": {
|
| 1825 |
+
"dtype": "uint8",
|
| 1826 |
+
"shape": [1024, 4, 8],
|
| 1827 |
+
"data": { "kind": "cycle", "values": [27, 180, 75, 226, 33, 150, 201, 108, 57, 246, 129, 66, 195, 84, 237] }
|
| 1828 |
+
},
|
| 1829 |
+
"scalesT": {
|
| 1830 |
+
"dtype": "float32",
|
| 1831 |
+
"shape": [1024, 4],
|
| 1832 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06, 0.075, 0.07] }
|
| 1833 |
+
}
|
| 1834 |
+
},
|
| 1835 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [512, 1024], "tolerance": 0.001 } },
|
| 1836 |
+
"attrs": { "K": 128, "N": 1024, "bits": 2, "block_size": 32 }
|
| 1837 |
+
},
|
| 1838 |
+
{
|
| 1839 |
+
"name": "q2_zero_bias_prefill_reg_m512_n1024",
|
| 1840 |
+
"provenance": {
|
| 1841 |
+
"notes": "2-bit weights pack four codes per stored byte, low codes first along K, with a default zero point of 2. Register-tile prefill with zero points and bias."
|
| 1842 |
+
},
|
| 1843 |
+
"inputs": {
|
| 1844 |
+
"aT": {
|
| 1845 |
+
"dtype": "float32",
|
| 1846 |
+
"shape": [512, 128],
|
| 1847 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1848 |
+
},
|
| 1849 |
+
"bT": {
|
| 1850 |
+
"dtype": "uint8",
|
| 1851 |
+
"shape": [1024, 4, 8],
|
| 1852 |
+
"data": { "kind": "cycle", "values": [27, 180, 75, 226, 33, 150, 201, 108, 57, 246, 129, 66, 195, 84, 237] }
|
| 1853 |
+
},
|
| 1854 |
+
"scalesT": {
|
| 1855 |
+
"dtype": "float32",
|
| 1856 |
+
"shape": [1024, 4],
|
| 1857 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06, 0.075, 0.07] }
|
| 1858 |
+
},
|
| 1859 |
+
"zeroPointsT": {
|
| 1860 |
+
"dtype": "float32",
|
| 1861 |
+
"shape": [1024, 4],
|
| 1862 |
+
"data": { "kind": "cycle", "values": [1.0, 2.0, 3.0, 0.0, 2.0] }
|
| 1863 |
+
},
|
| 1864 |
+
"biasT": {
|
| 1865 |
+
"dtype": "float32",
|
| 1866 |
+
"shape": [1024],
|
| 1867 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.1 }
|
| 1868 |
+
}
|
| 1869 |
+
},
|
| 1870 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [512, 1024], "tolerance": 0.001 } },
|
| 1871 |
+
"attrs": { "K": 128, "N": 1024, "bits": 2, "block_size": 32 }
|
| 1872 |
+
},
|
| 1873 |
+
{
|
| 1874 |
+
"name": "q8_rank3_prefill_tile4x4",
|
| 1875 |
+
"provenance": { "notes": "Rank-3 A folding to eight rows, wide enough for the prefill output tile." },
|
| 1876 |
+
"inputs": {
|
| 1877 |
+
"aT": {
|
| 1878 |
+
"dtype": "float32",
|
| 1879 |
+
"shape": [2, 4, 128],
|
| 1880 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 0.35 }
|
| 1881 |
+
},
|
| 1882 |
+
"bT": {
|
| 1883 |
+
"dtype": "uint8",
|
| 1884 |
+
"shape": [64, 4, 32],
|
| 1885 |
+
"data": { "kind": "cycle", "values": [17, 200, 91, 45, 233, 128, 7, 176, 250, 33, 142, 99, 210, 64, 188] }
|
| 1886 |
+
},
|
| 1887 |
+
"scalesT": {
|
| 1888 |
+
"dtype": "float32",
|
| 1889 |
+
"shape": [64, 4],
|
| 1890 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06, 0.075, 0.07] }
|
| 1891 |
+
},
|
| 1892 |
+
"zeroPointsT": {
|
| 1893 |
+
"dtype": "float32",
|
| 1894 |
+
"shape": [64, 4],
|
| 1895 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0, 118.0, 144.0] }
|
| 1896 |
+
},
|
| 1897 |
+
"biasT": {
|
| 1898 |
+
"dtype": "float32",
|
| 1899 |
+
"shape": [64],
|
| 1900 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.1 }
|
| 1901 |
+
}
|
| 1902 |
+
},
|
| 1903 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [2, 4, 64], "tolerance": 0.001 } },
|
| 1904 |
+
"attrs": { "K": 128, "N": 64, "bits": 8, "block_size": 32 }
|
| 1905 |
+
},
|
| 1906 |
+
{
|
| 1907 |
+
"name": "q8_zero_only_naive_fallback_tailk_m3_n6",
|
| 1908 |
+
"provenance": {
|
| 1909 |
+
"notes": "K=17 leaves a partial final block and M=3 bypasses GEMV. With explicit zero points but no bias, the aligned prefill paths are ineligible and the zero-only scalar fallback handles the tail block."
|
| 1910 |
+
},
|
| 1911 |
+
"inputs": {
|
| 1912 |
+
"aT": {
|
| 1913 |
+
"dtype": "float32",
|
| 1914 |
+
"shape": [3, 17],
|
| 1915 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.13, "cosStep": 0.29, "scale": 0.75 }
|
| 1916 |
+
},
|
| 1917 |
+
"bT": {
|
| 1918 |
+
"dtype": "uint8",
|
| 1919 |
+
"shape": [6, 2, 16],
|
| 1920 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q8_zero_bias_gemv_m1_tail_n5_input_bT" } }
|
| 1921 |
+
},
|
| 1922 |
+
"scalesT": {
|
| 1923 |
+
"dtype": "float32",
|
| 1924 |
+
"shape": [6, 2],
|
| 1925 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06, 0.075] }
|
| 1926 |
+
},
|
| 1927 |
+
"zeroPointsT": {
|
| 1928 |
+
"dtype": "float32",
|
| 1929 |
+
"shape": [6, 2],
|
| 1930 |
+
"data": { "kind": "cycle", "values": [120.0, 132.0, 128.0, 140.0, 135.0, 118.0] }
|
| 1931 |
+
}
|
| 1932 |
+
},
|
| 1933 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [3, 6], "tolerance": 0.001 } },
|
| 1934 |
+
"attrs": { "K": 17, "N": 6, "bits": 8, "block_size": 16 }
|
| 1935 |
+
},
|
| 1936 |
+
{
|
| 1937 |
+
"name": "q8_bias_only_naive_fallback_tailk_m3_n6",
|
| 1938 |
+
"provenance": {
|
| 1939 |
+
"notes": "K=17 leaves a partial final block and M=3 bypasses GEMV. With bias and the schema-default zero point, the aligned prefill paths are ineligible and the bias-only scalar fallback handles the tail block."
|
| 1940 |
+
},
|
| 1941 |
+
"inputs": {
|
| 1942 |
+
"aT": {
|
| 1943 |
+
"dtype": "float32",
|
| 1944 |
+
"shape": [3, 17],
|
| 1945 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.13, "cosStep": 0.29, "scale": 0.75 }
|
| 1946 |
+
},
|
| 1947 |
+
"bT": {
|
| 1948 |
+
"dtype": "uint8",
|
| 1949 |
+
"shape": [6, 2, 16],
|
| 1950 |
+
"data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/q8_zero_bias_gemv_m1_tail_n5_input_bT" } }
|
| 1951 |
+
},
|
| 1952 |
+
"scalesT": {
|
| 1953 |
+
"dtype": "float32",
|
| 1954 |
+
"shape": [6, 2],
|
| 1955 |
+
"data": { "kind": "cycle", "values": [0.04, 0.055, 0.05, 0.065, 0.06, 0.075] }
|
| 1956 |
+
},
|
| 1957 |
+
"biasT": {
|
| 1958 |
+
"dtype": "float32",
|
| 1959 |
+
"shape": [6],
|
| 1960 |
+
"data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.2 }
|
| 1961 |
+
}
|
| 1962 |
+
},
|
| 1963 |
+
"outputs": { "yT": { "dtype": "float32", "shape": [3, 6], "tolerance": 0.001 } },
|
| 1964 |
+
"attrs": { "K": 17, "N": 6, "bits": 8, "block_size": 16 }
|
| 1965 |
+
}
|
| 1966 |
+
]
|
| 1967 |
+
}
|