Xenova HF Staff commited on
Commit
193bbf0
·
verified ·
1 Parent(s): 2294432

sync 6fdf6301e2bb

Browse files
README.md CHANGED
@@ -73,6 +73,8 @@ One implementation is selected per call from the device capabilities, the reques
73
  - `sgmat_exact_a1_bnone` — Exact integer products through bounded f32 subgroup-matrix partials accumulated with modular int32 additions. Tile height follows workgroup memory and invocation limits.
74
  - `sgmat_exact_a1_bscalar` — Exact integer products through bounded f32 subgroup-matrix partials accumulated with modular int32 additions. Tile height follows workgroup memory and invocation limits.
75
  - `sgmat_exact_a1_bcolumn` — Exact integer products through bounded f32 subgroup-matrix partials accumulated with modular int32 additions. Tile height follows workgroup memory and invocation limits.
 
 
76
 
77
  ## Device requirements
78
 
@@ -83,7 +85,7 @@ Some implementation variants require `subgroup-matrix`, `shader-f16`, and `subgr
83
  - [`metadata.json`](build/webgpu/metadata.json) — kernel metadata (id, digests, per-variant templates, provenance)
84
  - [`manifest.json`](build/webgpu/manifest.json) — the op contract (source of truth)
85
  - [`test.json`](build/webgpu/test.json) — correctness cases
86
- - [`bench.json`](build/webgpu/bench.json) — benchmark + tuning cases
87
  - [`matmul-integer-batched.wgsl.jinja`](build/webgpu/matmul-integer-batched.wgsl.jinja)
88
  - [`quant-dp4a-matmul.wgsl.jinja`](build/webgpu/quant-dp4a-matmul.wgsl.jinja)
89
  - [`quant-exact-matrix.wgsl.jinja`](build/webgpu/quant-exact-matrix.wgsl.jinja)
@@ -95,7 +97,7 @@ Some implementation variants require `subgroup-matrix`, `shader-f16`, and `subgr
95
  ## Use with `@huggingface/kernels`
96
 
97
  ```sh
98
- npm install --save-exact @huggingface/kernels@0.0.1-preview.2
99
  ```
100
 
101
  Required output shapes and logical data types are inferred from the supplied inputs and attributes; result tensors are allocated automatically.
 
73
  - `sgmat_exact_a1_bnone` — Exact integer products through bounded f32 subgroup-matrix partials accumulated with modular int32 additions. Tile height follows workgroup memory and invocation limits.
74
  - `sgmat_exact_a1_bscalar` — Exact integer products through bounded f32 subgroup-matrix partials accumulated with modular int32 additions. Tile height follows workgroup memory and invocation limits.
75
  - `sgmat_exact_a1_bcolumn` — Exact integer products through bounded f32 subgroup-matrix partials accumulated with modular int32 additions. Tile height follows workgroup memory and invocation limits.
76
+ - `dp4a_rank2_b_zero_point_per_column` — Packed-dot rank-2 matmul with per-column B zero points. Large prefill tiles use twice as many output-column lanes on variable 16–32-lane devices with sufficient workgroup capacity.
77
+ - `dp4a_rank2_a_zero_point_b_per_column` — Packed-dot rank-2 matmul with per-column B zero points. Large prefill tiles use twice as many output-column lanes on variable 16–32-lane devices with sufficient workgroup capacity.
78
 
79
  ## Device requirements
80
 
 
85
  - [`metadata.json`](build/webgpu/metadata.json) — kernel metadata (id, digests, per-variant templates, provenance)
86
  - [`manifest.json`](build/webgpu/manifest.json) — the op contract (source of truth)
87
  - [`test.json`](build/webgpu/test.json) — correctness cases
88
+ - [`bench.json`](build/webgpu/bench.json) — benchmark cases
89
  - [`matmul-integer-batched.wgsl.jinja`](build/webgpu/matmul-integer-batched.wgsl.jinja)
90
  - [`quant-dp4a-matmul.wgsl.jinja`](build/webgpu/quant-dp4a-matmul.wgsl.jinja)
91
  - [`quant-exact-matrix.wgsl.jinja`](build/webgpu/quant-exact-matrix.wgsl.jinja)
 
97
  ## Use with `@huggingface/kernels`
98
 
99
  ```sh
100
+ npm install --save-exact @huggingface/kernels@0.0.1-preview.3
101
  ```
102
 
103
  Required output shapes and logical data types are inferred from the supplied inputs and attributes; result tensors are allocated automatically.
build/webgpu/bench.json CHANGED
@@ -136,6 +136,32 @@
136
  "tunableSpace": { "TILE_M": [8, 16, 32], "TILE_N": [32, 64, 128], "KT_WORDS": [32, 64] },
137
  "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] }
138
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  {
140
  "name": "kfloor_k128_2048x128x2048_u8s8_naive",
141
  "preset": "smoke",
@@ -298,11 +324,11 @@
298
  "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.batch * args.M * args.K * args.N" }] }
299
  },
300
  {
301
- "name": "manifest-gap-rank2-u8s8-k63-dp4a-floor-m512n4096",
302
  "preset": "stress",
303
  "provenance": {
304
  "source": "synthetic benchmark",
305
- "notes": "Realistic narrow projection immediately below the rank-2 DP4A K >= 64 guard; the paired K64 case isolates the selector boundary."
306
  },
307
  "vars": { "M": 512, "K": 63, "N": 4096 },
308
  "inputs": {
 
136
  "tunableSpace": { "TILE_M": [8, 16, 32], "TILE_N": [32, 64, 128], "KT_WORDS": [32, 64] },
137
  "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] }
138
  },
139
+ {
140
+ "name": "percol_b_zp_no_azp_1024x4096x4096_u8s8_dp4a",
141
+ "preset": "model",
142
+ "vars": { "M": 1024, "K": 4096, "N": 4096 },
143
+ "inputs": {
144
+ "a": { "dtype": "uint8", "shape": [1024, 4096], "dist": "randint", "seed": 2339, "min": 0, "max": 255 },
145
+ "b": { "dtype": "int8", "shape": [4096, 4096], "dist": "randint", "seed": 1316, "min": -127, "max": 127 },
146
+ "b_zero_point": { "dtype": "int8", "shape": [4096], "dist": "randint", "seed": 1317, "min": -5, "max": 5 }
147
+ },
148
+ "outputs": { "y": { "dtype": "int32", "shape": [1024, 4096] } },
149
+ "tunableSpace": { "TILE_M": [8, 16, 32], "TILE_N": [32, 64, 128], "KT_WORDS": [32, 64] },
150
+ "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] }
151
+ },
152
+ {
153
+ "name": "percol_b_zp_no_azp_256x4096x4096_u8s8_dp4a",
154
+ "preset": "model",
155
+ "vars": { "M": 256, "K": 4096, "N": 4096 },
156
+ "inputs": {
157
+ "a": { "dtype": "uint8", "shape": [256, 4096], "dist": "randint", "seed": 1571, "min": 0, "max": 255 },
158
+ "b": { "dtype": "int8", "shape": [4096, 4096], "dist": "randint", "seed": 1316, "min": -127, "max": 127 },
159
+ "b_zero_point": { "dtype": "int8", "shape": [4096], "dist": "randint", "seed": 1317, "min": -5, "max": 5 }
160
+ },
161
+ "outputs": { "y": { "dtype": "int32", "shape": [256, 4096] } },
162
+ "tunableSpace": { "TILE_M": [8, 16, 32], "TILE_N": [32, 64, 128], "KT_WORDS": [32, 64] },
163
+ "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] }
164
+ },
165
  {
166
  "name": "kfloor_k128_2048x128x2048_u8s8_naive",
167
  "preset": "smoke",
 
324
  "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.batch * args.M * args.K * args.N" }] }
325
  },
326
  {
327
+ "name": "rank2-u8s8-k63-dp4a-floor-m512n4096",
328
  "preset": "stress",
329
  "provenance": {
330
  "source": "synthetic benchmark",
331
+ "notes": "Measures MatMulInteger over a 512x4096 uint8 by int8 output with an unaligned K=63 reduction length."
332
  },
333
  "vars": { "M": 512, "K": 63, "N": 4096 },
334
  "inputs": {
build/webgpu/manifest.json CHANGED
@@ -44,16 +44,25 @@
44
  "EXACT_MATRIX_MIN_INVOCATIONS": { "default": 16384 }
45
  },
46
  "derive": {
 
 
 
 
 
 
 
 
47
  "deviceWorkgroupCap": "min(device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX)",
48
  "wave32Adapter": "has(device.adapterInfo, \"subgroupMinSize\") and has(device.adapterInfo, \"subgroupMaxSize\") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",
49
  "canPinSubgroupSize32": "device.features.has(\"subgroups\") and device.features.has(\"subgroup-size-control\") and has(device.adapterInfo, \"subgroupMinSize\") and has(device.adapterInfo, \"subgroupMaxSize\") and device.adapterInfo.subgroupMinSize <= 32 and device.adapterInfo.subgroupMaxSize >= 32",
50
  "pinSubgroupSize32": "canPinSubgroupSize32 and not wave32Adapter",
51
  "wave32Effective": "wave32Adapter or pinSubgroupSize32",
 
52
  "sgmatTileN": "64",
53
  "sgmatTileK": "32",
54
  "sgmatColumnGroups": "2",
55
  "sgmatStorageRowGroups": "floor((device.limits.maxComputeWorkgroupStorageSize - sgmatTileN * sgmatTileK * 4) / (16 * sgmatTileK * 4))",
56
- "sgmatRowGroups": "max(1, min(4, floor(deviceWorkgroupCap / (32 * sgmatColumnGroups)), sgmatStorageRowGroups, max(floor(sgmatStorageRowGroups / 2), floor(dim(shapes.a, 0) / 16))))",
57
  "sgmatTileM": "16 * sgmatRowGroups",
58
  "sgmatSubgroups": "sgmatRowGroups * sgmatColumnGroups",
59
  "sgmatWorkgroup": "32 * sgmatSubgroups",
@@ -62,31 +71,31 @@
62
  "sgmatReuseStaging": "sgmatStagingBytes + sgmatScratchBytes > device.limits.maxComputeWorkgroupStorageSize",
63
  "sgmatSharedBytes": "sgmatStagingBytes + (0 if sgmatReuseStaging else sgmatScratchBytes)",
64
  "sgmatDeviceOk": "sgmatWorkgroup <= deviceWorkgroupCap and sgmatSharedBytes <= device.limits.maxComputeWorkgroupStorageSize",
65
- "precastSubgroups": "max(1, min(4, ceilDiv(dim(shapes.a, 0), 16), floor(deviceWorkgroupCap / 32), floor(device.limits.maxComputeWorkgroupStorageSize / (8 * 64 * 4))))",
66
  "precastTileM": "16 * precastSubgroups",
67
  "precastTileN": "4 * 8",
68
  "precastTileK": "4 * 8",
69
  "precastWorkgroup": "32 * precastSubgroups",
70
- "preparedK": "ceilDiv(dim(shapes.a, 1), precastTileK) * precastTileK",
71
- "preparedN": "ceilDiv(dim(shapes.b, 1), precastTileN) * precastTileN",
72
- "preparedElements": "ceilDiv(dim(shapes.a, 0), precastTileM) * precastTileM * preparedK",
73
- "preparedBElements": "preparedK * preparedN",
74
  "prepareWorkgroup": "min(256, deviceWorkgroupCap)",
75
  "prepareTotalElements": "preparedElements + preparedBElements",
76
  "prepareGroups": "ceilDiv(prepareTotalElements, 4 * prepareWorkgroup)",
77
  "prepareDispatchElements": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535)) * min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535)) * prepareWorkgroup * 4",
78
  "precastResourcesOk": "deviceWorkgroupCap >= precastWorkgroup and precastSubgroups * 8 * 64 * 4 <= device.limits.maxComputeWorkgroupStorageSize",
79
- "precastDispatchOk": "prepareTotalElements <= 4294967295 and prepareDispatchElements <= 4294967296 and ceilDiv(dim(shapes.b, 1), precastTileN) <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535) and ceilDiv(dim(shapes.a, 0), precastTileM) <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535) and prepareGroups <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535) * min(device.limits.maxComputeWorkgroupsPerDimension, 65535)",
80
  "precastF32BuffersOk": "preparedElements * 4 <= device.limits.maxStorageBufferBindingSize and preparedElements * 4 <= device.limits.maxBufferSize and preparedBElements * 4 <= device.limits.maxStorageBufferBindingSize and preparedBElements * 4 <= device.limits.maxBufferSize",
81
  "precastF16BuffersOk": "preparedElements * 2 <= device.limits.maxStorageBufferBindingSize and preparedElements * 2 <= device.limits.maxBufferSize and preparedBElements * 2 <= device.limits.maxStorageBufferBindingSize and preparedBElements * 2 <= device.limits.maxBufferSize",
82
  "precastWorthwhile": "dim(shapes.a, 0) >= 16 and dim(shapes.b, 1) >= 32 and dim(shapes.a, 1) >= 32 and floor(dim(shapes.a, 0) / 16) * floor(dim(shapes.b, 1) / 32) * 32 >= tunables.EXACT_MATRIX_MIN_INVOCATIONS",
83
  "portableWorkgroupCols": 16,
84
- "portableWorkgroupRows": "pow2ceil(min(16, max(4, pow2ceil(ceilDiv(dim(shapes.a, 0), 4))), floor(deviceWorkgroupCap / portableWorkgroupCols), device.limits.maxComputeWorkgroupSizeY) + 1) / 2",
85
  "portableTileM": "4 * portableWorkgroupRows",
86
  "portableTileN": "4 * portableWorkgroupCols",
87
  "portableTileK": 32,
88
  "portablePartialK": "floor(16777216 / (255 * 255) / portableTileK) * portableTileK",
89
- "portableGeometryOk": "portableWorkgroupRows >= 4 and portableWorkgroupCols <= device.limits.maxComputeWorkgroupSizeX and portablePartialK >= portableTileK and ceilDiv(dim(shapes.a, 0), portableTileM) <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535)",
90
  "rank2MatMulShapeOk": "ranks.a == 2 and ranks.b == 2 and ranks.y == 2 and dim(shapes.a, 1) == dim(shapes.b, 0) and dim(shapes.y, 0) == dim(shapes.a, 0) and dim(shapes.y, 1) == dim(shapes.b, 1)",
91
  "rank3ByRank3ShapeOk": "ranks.a == 3 and ranks.b == 3 and ranks.y == 3 and dim(shapes.a, 2) == dim(shapes.b, 1) and dim(shapes.y, 0) == max(dim(shapes.a, 0), dim(shapes.b, 0)) and (dim(shapes.a, 0) == dim(shapes.y, 0) or dim(shapes.a, 0) == 1) and (dim(shapes.b, 0) == dim(shapes.y, 0) or dim(shapes.b, 0) == 1) and dim(shapes.y, 1) == dim(shapes.a, 1) and dim(shapes.y, 2) == dim(shapes.b, 2)",
92
  "rank3ByRank2ShapeOk": "ranks.a == 3 and ranks.b == 2 and ranks.y == 3 and dim(shapes.a, 2) == dim(shapes.b, 0) and dim(shapes.y, 0) == dim(shapes.a, 0) and dim(shapes.y, 1) == dim(shapes.a, 1) and dim(shapes.y, 2) == dim(shapes.b, 1)",
@@ -99,6 +108,7 @@
99
  "requiredScalarBZeroOk": "present.b_zero_point and scalarBZeroOk",
100
  "rank2PerColumnBZeroOk": "ranks.b_zero_point == 1 and dim(shapes.b_zero_point, 0) == dim(shapes.y, 1)",
101
  "rank2Dp4aLargePrefill": "ranks.y == 2 and ranks.a == 2 and dim(shapes.y, 0) >= tunables.DP4A_LARGE_MIN_M and dim(shapes.y, 1) >= tunables.DP4A_LARGE_MIN_N and dim(shapes.a, 1) >= tunables.DP4A_LARGE_MIN_K",
 
102
  "rank2Dp4aWideShortK": "ranks.y == 2 and ranks.a == 2 and dim(shapes.y, 0) >= tunables.DP4A_SHORT_K_MIN_MN and dim(shapes.y, 1) >= tunables.DP4A_SHORT_K_MIN_MN and dim(shapes.a, 1) <= tunables.DP4A_SHORT_K_MAX",
103
  "rank2Dp4aMediumK": "ranks.y == 2 and ranks.a == 2 and dim(shapes.y, 0) >= tunables.DP4A_MEDIUM_K_MIN_MN and dim(shapes.y, 1) >= tunables.DP4A_MEDIUM_K_MIN_MN and dim(shapes.a, 1) > tunables.DP4A_SHORT_K_MAX and dim(shapes.a, 1) <= tunables.DP4A_MEDIUM_K_MAX",
104
  "rank2Dp4aTileM": "1 if ranks.y < 2 or dim(shapes.y, 0) == 1 else (tunables.DP4A_SHORT_K_TILE_M if rank2Dp4aWideShortK else (tunables.DP4A_MEDIUM_K_TILE_M if rank2Dp4aMediumK else (tunables.DP4A_LARGE_TILE_M if rank2Dp4aLargePrefill else tunables.DP4A_TILE_M)))",
@@ -127,25 +137,24 @@
127
  "rank4YBatchStride": "dim(shapes.y, 2) * dim(shapes.y, 3) if ranks.y >= 4 else 1",
128
  "aScalar": "\"u32\" if tensorDtypes.a == \"uint8\" else \"i32\"",
129
  "bScalar": "\"u32\" if tensorDtypes.b == \"uint8\" else \"i32\"",
130
- "aUnsigned": "tensorDtypes.a == \"uint8\"",
131
- "bUnsigned": "tensorDtypes.b == \"uint8\"",
132
- "aZeroPerRow": false,
133
- "hasBias": false,
134
  "sgmatM": "matrixM",
135
  "sgmatN": "matrixN",
136
  "sgmatK": "matrixK",
137
  "sgmatDispatchOk": "ceilDiv(sgmatN, sgmatTileN) <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535) and ceilDiv(sgmatM, sgmatTileM) <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535)",
138
  "sgmatParallelInvocations": "floor(sgmatM / sgmatTileM) * floor(sgmatN / sgmatTileN) * sgmatWorkgroup",
139
- "sgmatWorthwhile": "sgmatM >= sgmatTileM and sgmatN >= sgmatTileN / 2 and sgmatK >= sgmatTileK and sgmatParallelInvocations >= tunables.EXACT_MATRIX_MIN_INVOCATIONS"
 
 
 
 
140
  },
141
  "bindings": {
142
- "a": { "buffer": "read-only-storage", "elementType": "$aStorage" },
143
- "b": { "buffer": "read-only-storage", "elementType": "$bScalar" },
144
- "a_zero_point": { "buffer": "read-only-storage", "elementType": "$aScalar", "length": 1 },
145
- "b_zero_point": { "buffer": "read-only-storage", "elementType": "$bScalar" },
146
- "y": { "buffer": "storage", "elementType": "i32" },
147
  "params": {
148
- "buffer": "uniform",
149
  "struct": [
150
  { "name": "M", "type": "u32", "value": "matrixM" },
151
  { "name": "N", "type": "u32", "value": "matrixN" },
@@ -155,29 +164,26 @@
155
  { "name": "yBatchStride", "type": "u32", "value": 0 }
156
  ]
157
  },
158
- "a_2": { "name": "a", "buffer": "read-only-storage", "elementType": "$aScalar" },
159
- "a_3": { "name": "a", "buffer": "read-only-storage", "elementType": "$aVec4" },
160
- "params_3": {
161
  "name": "params",
162
- "buffer": "uniform",
163
  "struct": [
164
  { "name": "M", "type": "u32", "value": "matrixM" },
165
  { "name": "N", "type": "u32", "value": "matrixN" },
166
  { "name": "K", "type": "u32", "value": "matrixK" }
167
  ]
168
  },
169
- "params_4": {
170
  "name": "params",
171
- "buffer": "uniform",
172
  "struct": [
173
  { "name": "M", "type": "u32", "value": 1 },
174
  { "name": "N", "type": "u32", "value": 1 },
175
  { "name": "K", "type": "u32", "value": "dim(shapes.a, 0)" }
176
  ]
177
  },
178
- "params_5": {
179
  "name": "params",
180
- "buffer": "uniform",
181
  "struct": [
182
  { "name": "M", "type": "u32", "value": "batchM" },
183
  { "name": "N", "type": "u32", "value": "batchN" },
@@ -188,9 +194,8 @@
188
  { "name": "batchCount", "type": "u32", "value": "batchCount" }
189
  ]
190
  },
191
- "params_6": {
192
  "name": "params",
193
- "buffer": "uniform",
194
  "struct": [
195
  { "name": "M", "type": "u32", "value": "rank4M" },
196
  { "name": "N", "type": "u32", "value": "rank4N" },
@@ -219,9 +224,8 @@
219
  }
220
  ]
221
  },
222
- "params_7": {
223
  "name": "params",
224
- "buffer": "uniform",
225
  "struct": [
226
  { "name": "M", "type": "u32", "value": "batchM" },
227
  { "name": "N", "type": "u32", "value": "batchN" },
@@ -231,9 +235,8 @@
231
  { "name": "yBatchStride", "type": "u32", "value": "batchYStride" }
232
  ]
233
  },
234
- "params_8": {
235
  "name": "params",
236
- "buffer": "uniform",
237
  "struct": [
238
  { "name": "M", "type": "u32", "value": "rank4M" },
239
  { "name": "N", "type": "u32", "value": "rank4N" },
@@ -249,7 +252,6 @@
249
  "precast_f32_bFloat": { "name": "bFloat", "buffer": "storage", "elementType": "f32" },
250
  "precast_prepare_params": {
251
  "name": "params",
252
- "buffer": "uniform",
253
  "struct": [
254
  { "name": "M", "type": "u32", "value": "sgmatM" },
255
  { "name": "K", "type": "u32", "value": "sgmatK" },
@@ -291,20 +293,17 @@
291
  "sgmatRowGroups": "precastSubgroups",
292
  "sgmatSubgroups": "precastSubgroups",
293
  "sgmatWorkgroup": "precastWorkgroup",
294
- "sgmatSharedBytes": "sgmatSubgroups * 8 * 64 * 4",
295
  "precastScalar": "\"f16\"",
296
  "hasAZero": false,
297
  "hasBZero": false,
298
- "bZeroPerColumn": false,
299
- "bScalePerColumn": false,
300
- "requantize": false
301
  },
302
  "passes": [
303
  {
304
  "id": "prepare",
305
- "name": "ExactMatrix.PrepareOperands",
306
  "shader": "quant-exact-prepare.wgsl.jinja",
307
- "bindings": ["a_2", "precast_f16_aFloat", "b", "precast_f16_bFloat", "precast_prepare_params"],
308
  "dispatch": {
309
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
310
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -312,9 +311,9 @@
312
  },
313
  {
314
  "id": "main",
315
- "name": "ExactMatrix.Multiply",
316
  "shader": "quant-exact-matrix.wgsl.jinja",
317
- "bindings": ["precast_f16_a", "precast_f16_b", "y", "params_3"],
318
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
319
  }
320
  ],
@@ -327,6 +326,7 @@
327
  "id": "portable_precast_a0_bnone_f16",
328
  "priority": 39,
329
  "when": ["rank2MatMulShapeOk", "not present.a_zero_point", "not present.b_zero_point", "precastF16BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float16\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f16\" == \"f16\" or sgmatM >= portableTileN"],
 
330
  "requires": { "features": ["shader-f16"] },
331
  "derive": {
332
  "precastScalar": "\"f16\"",
@@ -334,8 +334,6 @@
334
  "hasAZero": false,
335
  "hasBZero": false,
336
  "bZeroPerColumn": false,
337
- "bScalePerColumn": false,
338
- "requantize": false,
339
  "M": "sgmatM",
340
  "N": "sgmatN",
341
  "K": "preparedK",
@@ -344,17 +342,14 @@
344
  "workgroupRows": "portableWorkgroupRows",
345
  "blockRows": "portableTileM",
346
  "blockCols": "portableTileN",
347
- "integerPartialK": "portablePartialK",
348
- "packedATile": true,
349
- "vec4BTile": true,
350
- "hasBias": false
351
  },
352
  "passes": [
353
  {
354
  "id": "prepare",
355
- "name": "ExactMatrix.PrepareOperands",
356
  "shader": "quant-exact-prepare.wgsl.jinja",
357
- "bindings": ["a_2", "precast_f16_aFloat", "b", "precast_f16_bFloat", "precast_prepare_params"],
358
  "dispatch": {
359
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
360
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -362,7 +357,7 @@
362
  },
363
  {
364
  "id": "main",
365
- "name": "ExactMatrix.PortableMultiply",
366
  "shader": "quant-exact-portable.wgsl.jinja",
367
  "bindings": ["portable_f16_a", "portable_f16_b", "y"],
368
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
@@ -389,20 +384,17 @@
389
  "sgmatRowGroups": "precastSubgroups",
390
  "sgmatSubgroups": "precastSubgroups",
391
  "sgmatWorkgroup": "precastWorkgroup",
392
- "sgmatSharedBytes": "sgmatSubgroups * 8 * 64 * 4",
393
  "precastScalar": "\"f32\"",
394
  "hasAZero": false,
395
  "hasBZero": false,
396
- "bZeroPerColumn": false,
397
- "bScalePerColumn": false,
398
- "requantize": false
399
  },
400
  "passes": [
401
  {
402
  "id": "prepare",
403
- "name": "ExactMatrix.PrepareOperands",
404
  "shader": "quant-exact-prepare.wgsl.jinja",
405
- "bindings": ["a_2", "precast_f32_aFloat", "b", "precast_f32_bFloat", "precast_prepare_params"],
406
  "dispatch": {
407
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
408
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -410,9 +402,9 @@
410
  },
411
  {
412
  "id": "main",
413
- "name": "ExactMatrix.Multiply",
414
  "shader": "quant-exact-matrix.wgsl.jinja",
415
- "bindings": ["precast_f32_a", "precast_f32_b", "y", "params_3"],
416
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
417
  }
418
  ],
@@ -425,6 +417,7 @@
425
  "id": "portable_precast_a0_bnone",
426
  "priority": 38,
427
  "when": ["rank2MatMulShapeOk", "not present.a_zero_point", "not present.b_zero_point", "precastF32BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float32\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f32\" == \"f16\" or sgmatM >= portableTileN"],
 
428
  "requires": { "features": [] },
429
  "derive": {
430
  "precastScalar": "\"f32\"",
@@ -432,8 +425,6 @@
432
  "hasAZero": false,
433
  "hasBZero": false,
434
  "bZeroPerColumn": false,
435
- "bScalePerColumn": false,
436
- "requantize": false,
437
  "M": "sgmatM",
438
  "N": "sgmatN",
439
  "K": "preparedK",
@@ -442,17 +433,14 @@
442
  "workgroupRows": "portableWorkgroupRows",
443
  "blockRows": "portableTileM",
444
  "blockCols": "portableTileN",
445
- "integerPartialK": "portablePartialK",
446
- "packedATile": true,
447
- "vec4BTile": true,
448
- "hasBias": false
449
  },
450
  "passes": [
451
  {
452
  "id": "prepare",
453
- "name": "ExactMatrix.PrepareOperands",
454
  "shader": "quant-exact-prepare.wgsl.jinja",
455
- "bindings": ["a_2", "precast_f32_aFloat", "b", "precast_f32_bFloat", "precast_prepare_params"],
456
  "dispatch": {
457
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
458
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -460,7 +448,7 @@
460
  },
461
  {
462
  "id": "main",
463
- "name": "ExactMatrix.PortableMultiply",
464
  "shader": "quant-exact-portable.wgsl.jinja",
465
  "bindings": ["portable_f32_a", "portable_f32_b", "y"],
466
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
@@ -487,20 +475,17 @@
487
  "sgmatRowGroups": "precastSubgroups",
488
  "sgmatSubgroups": "precastSubgroups",
489
  "sgmatWorkgroup": "precastWorkgroup",
490
- "sgmatSharedBytes": "sgmatSubgroups * 8 * 64 * 4",
491
  "precastScalar": "\"f16\"",
492
  "hasAZero": false,
493
  "hasBZero": true,
494
- "bZeroPerColumn": false,
495
- "bScalePerColumn": false,
496
- "requantize": false
497
  },
498
  "passes": [
499
  {
500
  "id": "prepare",
501
- "name": "ExactMatrix.PrepareOperands",
502
  "shader": "quant-exact-prepare.wgsl.jinja",
503
- "bindings": ["a_2", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
504
  "dispatch": {
505
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
506
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -508,9 +493,9 @@
508
  },
509
  {
510
  "id": "main",
511
- "name": "ExactMatrix.Multiply",
512
  "shader": "quant-exact-matrix.wgsl.jinja",
513
- "bindings": ["precast_f16_a", "precast_f16_b", "b_zero_point", "y", "params_3"],
514
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
515
  }
516
  ],
@@ -523,6 +508,7 @@
523
  "id": "portable_precast_a0_bscalar_f16",
524
  "priority": 39,
525
  "when": ["rank2MatMulShapeOk", "not present.a_zero_point", "requiredScalarBZeroOk", "precastF16BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float16\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f16\" == \"f16\" or sgmatM >= portableTileN"],
 
526
  "requires": { "features": ["shader-f16"] },
527
  "derive": {
528
  "precastScalar": "\"f16\"",
@@ -530,8 +516,6 @@
530
  "hasAZero": false,
531
  "hasBZero": true,
532
  "bZeroPerColumn": false,
533
- "bScalePerColumn": false,
534
- "requantize": false,
535
  "M": "sgmatM",
536
  "N": "sgmatN",
537
  "K": "preparedK",
@@ -540,17 +524,14 @@
540
  "workgroupRows": "portableWorkgroupRows",
541
  "blockRows": "portableTileM",
542
  "blockCols": "portableTileN",
543
- "integerPartialK": "portablePartialK",
544
- "packedATile": true,
545
- "vec4BTile": true,
546
- "hasBias": false
547
  },
548
  "passes": [
549
  {
550
  "id": "prepare",
551
- "name": "ExactMatrix.PrepareOperands",
552
  "shader": "quant-exact-prepare.wgsl.jinja",
553
- "bindings": ["a_2", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
554
  "dispatch": {
555
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
556
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -558,7 +539,7 @@
558
  },
559
  {
560
  "id": "main",
561
- "name": "ExactMatrix.PortableMultiply",
562
  "shader": "quant-exact-portable.wgsl.jinja",
563
  "bindings": ["portable_f16_a", "portable_f16_b", "y"],
564
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
@@ -585,20 +566,17 @@
585
  "sgmatRowGroups": "precastSubgroups",
586
  "sgmatSubgroups": "precastSubgroups",
587
  "sgmatWorkgroup": "precastWorkgroup",
588
- "sgmatSharedBytes": "sgmatSubgroups * 8 * 64 * 4",
589
  "precastScalar": "\"f32\"",
590
  "hasAZero": false,
591
  "hasBZero": true,
592
- "bZeroPerColumn": false,
593
- "bScalePerColumn": false,
594
- "requantize": false
595
  },
596
  "passes": [
597
  {
598
  "id": "prepare",
599
- "name": "ExactMatrix.PrepareOperands",
600
  "shader": "quant-exact-prepare.wgsl.jinja",
601
- "bindings": ["a_2", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
602
  "dispatch": {
603
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
604
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -606,9 +584,9 @@
606
  },
607
  {
608
  "id": "main",
609
- "name": "ExactMatrix.Multiply",
610
  "shader": "quant-exact-matrix.wgsl.jinja",
611
- "bindings": ["precast_f32_a", "precast_f32_b", "b_zero_point", "y", "params_3"],
612
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
613
  }
614
  ],
@@ -621,6 +599,7 @@
621
  "id": "portable_precast_a0_bscalar",
622
  "priority": 38,
623
  "when": ["rank2MatMulShapeOk", "not present.a_zero_point", "requiredScalarBZeroOk", "precastF32BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float32\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f32\" == \"f16\" or sgmatM >= portableTileN"],
 
624
  "requires": { "features": [] },
625
  "derive": {
626
  "precastScalar": "\"f32\"",
@@ -628,8 +607,6 @@
628
  "hasAZero": false,
629
  "hasBZero": true,
630
  "bZeroPerColumn": false,
631
- "bScalePerColumn": false,
632
- "requantize": false,
633
  "M": "sgmatM",
634
  "N": "sgmatN",
635
  "K": "preparedK",
@@ -638,17 +615,14 @@
638
  "workgroupRows": "portableWorkgroupRows",
639
  "blockRows": "portableTileM",
640
  "blockCols": "portableTileN",
641
- "integerPartialK": "portablePartialK",
642
- "packedATile": true,
643
- "vec4BTile": true,
644
- "hasBias": false
645
  },
646
  "passes": [
647
  {
648
  "id": "prepare",
649
- "name": "ExactMatrix.PrepareOperands",
650
  "shader": "quant-exact-prepare.wgsl.jinja",
651
- "bindings": ["a_2", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
652
  "dispatch": {
653
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
654
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -656,7 +630,7 @@
656
  },
657
  {
658
  "id": "main",
659
- "name": "ExactMatrix.PortableMultiply",
660
  "shader": "quant-exact-portable.wgsl.jinja",
661
  "bindings": ["portable_f32_a", "portable_f32_b", "y"],
662
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
@@ -683,20 +657,17 @@
683
  "sgmatRowGroups": "precastSubgroups",
684
  "sgmatSubgroups": "precastSubgroups",
685
  "sgmatWorkgroup": "precastWorkgroup",
686
- "sgmatSharedBytes": "sgmatSubgroups * 8 * 64 * 4",
687
  "precastScalar": "\"f16\"",
688
  "hasAZero": false,
689
  "hasBZero": true,
690
- "bZeroPerColumn": true,
691
- "bScalePerColumn": false,
692
- "requantize": false
693
  },
694
  "passes": [
695
  {
696
  "id": "prepare",
697
- "name": "ExactMatrix.PrepareOperands",
698
  "shader": "quant-exact-prepare.wgsl.jinja",
699
- "bindings": ["a_2", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
700
  "dispatch": {
701
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
702
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -704,9 +675,9 @@
704
  },
705
  {
706
  "id": "main",
707
- "name": "ExactMatrix.Multiply",
708
  "shader": "quant-exact-matrix.wgsl.jinja",
709
- "bindings": ["precast_f16_a", "precast_f16_b", "y", "params_3"],
710
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
711
  }
712
  ],
@@ -719,6 +690,7 @@
719
  "id": "portable_precast_a0_bcolumn_f16",
720
  "priority": 39,
721
  "when": ["rank2MatMulShapeOk", "not present.a_zero_point", "present.b_zero_point and rank2PerColumnBZeroOk", "precastF16BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float16\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f16\" == \"f16\" or sgmatM >= portableTileN"],
 
722
  "requires": { "features": ["shader-f16"] },
723
  "derive": {
724
  "precastScalar": "\"f16\"",
@@ -726,8 +698,6 @@
726
  "hasAZero": false,
727
  "hasBZero": true,
728
  "bZeroPerColumn": true,
729
- "bScalePerColumn": false,
730
- "requantize": false,
731
  "M": "sgmatM",
732
  "N": "sgmatN",
733
  "K": "preparedK",
@@ -736,17 +706,14 @@
736
  "workgroupRows": "portableWorkgroupRows",
737
  "blockRows": "portableTileM",
738
  "blockCols": "portableTileN",
739
- "integerPartialK": "portablePartialK",
740
- "packedATile": true,
741
- "vec4BTile": true,
742
- "hasBias": false
743
  },
744
  "passes": [
745
  {
746
  "id": "prepare",
747
- "name": "ExactMatrix.PrepareOperands",
748
  "shader": "quant-exact-prepare.wgsl.jinja",
749
- "bindings": ["a_2", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
750
  "dispatch": {
751
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
752
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -754,7 +721,7 @@
754
  },
755
  {
756
  "id": "main",
757
- "name": "ExactMatrix.PortableMultiply",
758
  "shader": "quant-exact-portable.wgsl.jinja",
759
  "bindings": ["portable_f16_a", "portable_f16_b", "y"],
760
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
@@ -781,20 +748,17 @@
781
  "sgmatRowGroups": "precastSubgroups",
782
  "sgmatSubgroups": "precastSubgroups",
783
  "sgmatWorkgroup": "precastWorkgroup",
784
- "sgmatSharedBytes": "sgmatSubgroups * 8 * 64 * 4",
785
  "precastScalar": "\"f32\"",
786
  "hasAZero": false,
787
  "hasBZero": true,
788
- "bZeroPerColumn": true,
789
- "bScalePerColumn": false,
790
- "requantize": false
791
  },
792
  "passes": [
793
  {
794
  "id": "prepare",
795
- "name": "ExactMatrix.PrepareOperands",
796
  "shader": "quant-exact-prepare.wgsl.jinja",
797
- "bindings": ["a_2", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
798
  "dispatch": {
799
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
800
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -802,9 +766,9 @@
802
  },
803
  {
804
  "id": "main",
805
- "name": "ExactMatrix.Multiply",
806
  "shader": "quant-exact-matrix.wgsl.jinja",
807
- "bindings": ["precast_f32_a", "precast_f32_b", "y", "params_3"],
808
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
809
  }
810
  ],
@@ -817,6 +781,7 @@
817
  "id": "portable_precast_a0_bcolumn",
818
  "priority": 38,
819
  "when": ["rank2MatMulShapeOk", "not present.a_zero_point", "present.b_zero_point and rank2PerColumnBZeroOk", "precastF32BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float32\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f32\" == \"f16\" or sgmatM >= portableTileN"],
 
820
  "requires": { "features": [] },
821
  "derive": {
822
  "precastScalar": "\"f32\"",
@@ -824,8 +789,6 @@
824
  "hasAZero": false,
825
  "hasBZero": true,
826
  "bZeroPerColumn": true,
827
- "bScalePerColumn": false,
828
- "requantize": false,
829
  "M": "sgmatM",
830
  "N": "sgmatN",
831
  "K": "preparedK",
@@ -834,17 +797,14 @@
834
  "workgroupRows": "portableWorkgroupRows",
835
  "blockRows": "portableTileM",
836
  "blockCols": "portableTileN",
837
- "integerPartialK": "portablePartialK",
838
- "packedATile": true,
839
- "vec4BTile": true,
840
- "hasBias": false
841
  },
842
  "passes": [
843
  {
844
  "id": "prepare",
845
- "name": "ExactMatrix.PrepareOperands",
846
  "shader": "quant-exact-prepare.wgsl.jinja",
847
- "bindings": ["a_2", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
848
  "dispatch": {
849
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
850
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -852,7 +812,7 @@
852
  },
853
  {
854
  "id": "main",
855
- "name": "ExactMatrix.PortableMultiply",
856
  "shader": "quant-exact-portable.wgsl.jinja",
857
  "bindings": ["portable_f32_a", "portable_f32_b", "y"],
858
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
@@ -879,20 +839,17 @@
879
  "sgmatRowGroups": "precastSubgroups",
880
  "sgmatSubgroups": "precastSubgroups",
881
  "sgmatWorkgroup": "precastWorkgroup",
882
- "sgmatSharedBytes": "sgmatSubgroups * 8 * 64 * 4",
883
  "precastScalar": "\"f16\"",
884
  "hasAZero": true,
885
  "hasBZero": false,
886
- "bZeroPerColumn": false,
887
- "bScalePerColumn": false,
888
- "requantize": false
889
  },
890
  "passes": [
891
  {
892
  "id": "prepare",
893
- "name": "ExactMatrix.PrepareOperands",
894
  "shader": "quant-exact-prepare.wgsl.jinja",
895
- "bindings": ["a_2", "a_zero_point", "precast_f16_aFloat", "b", "precast_f16_bFloat", "precast_prepare_params"],
896
  "dispatch": {
897
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
898
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -900,9 +857,9 @@
900
  },
901
  {
902
  "id": "main",
903
- "name": "ExactMatrix.Multiply",
904
  "shader": "quant-exact-matrix.wgsl.jinja",
905
- "bindings": ["precast_f16_a", "precast_f16_b", "a_zero_point", "y", "params_3"],
906
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
907
  }
908
  ],
@@ -915,6 +872,7 @@
915
  "id": "portable_precast_a1_bnone_f16",
916
  "priority": 39,
917
  "when": ["rank2MatMulShapeOk", "requiredScalarAZeroOk", "not present.b_zero_point", "precastF16BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float16\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f16\" == \"f16\" or sgmatM >= portableTileN"],
 
918
  "requires": { "features": ["shader-f16"] },
919
  "derive": {
920
  "precastScalar": "\"f16\"",
@@ -922,8 +880,6 @@
922
  "hasAZero": true,
923
  "hasBZero": false,
924
  "bZeroPerColumn": false,
925
- "bScalePerColumn": false,
926
- "requantize": false,
927
  "M": "sgmatM",
928
  "N": "sgmatN",
929
  "K": "preparedK",
@@ -932,17 +888,14 @@
932
  "workgroupRows": "portableWorkgroupRows",
933
  "blockRows": "portableTileM",
934
  "blockCols": "portableTileN",
935
- "integerPartialK": "portablePartialK",
936
- "packedATile": true,
937
- "vec4BTile": true,
938
- "hasBias": false
939
  },
940
  "passes": [
941
  {
942
  "id": "prepare",
943
- "name": "ExactMatrix.PrepareOperands",
944
  "shader": "quant-exact-prepare.wgsl.jinja",
945
- "bindings": ["a_2", "a_zero_point", "precast_f16_aFloat", "b", "precast_f16_bFloat", "precast_prepare_params"],
946
  "dispatch": {
947
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
948
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -950,7 +903,7 @@
950
  },
951
  {
952
  "id": "main",
953
- "name": "ExactMatrix.PortableMultiply",
954
  "shader": "quant-exact-portable.wgsl.jinja",
955
  "bindings": ["portable_f16_a", "portable_f16_b", "y"],
956
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
@@ -977,20 +930,17 @@
977
  "sgmatRowGroups": "precastSubgroups",
978
  "sgmatSubgroups": "precastSubgroups",
979
  "sgmatWorkgroup": "precastWorkgroup",
980
- "sgmatSharedBytes": "sgmatSubgroups * 8 * 64 * 4",
981
  "precastScalar": "\"f32\"",
982
  "hasAZero": true,
983
  "hasBZero": false,
984
- "bZeroPerColumn": false,
985
- "bScalePerColumn": false,
986
- "requantize": false
987
  },
988
  "passes": [
989
  {
990
  "id": "prepare",
991
- "name": "ExactMatrix.PrepareOperands",
992
  "shader": "quant-exact-prepare.wgsl.jinja",
993
- "bindings": ["a_2", "a_zero_point", "precast_f32_aFloat", "b", "precast_f32_bFloat", "precast_prepare_params"],
994
  "dispatch": {
995
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
996
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -998,9 +948,9 @@
998
  },
999
  {
1000
  "id": "main",
1001
- "name": "ExactMatrix.Multiply",
1002
  "shader": "quant-exact-matrix.wgsl.jinja",
1003
- "bindings": ["precast_f32_a", "precast_f32_b", "a_zero_point", "y", "params_3"],
1004
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
1005
  }
1006
  ],
@@ -1013,6 +963,7 @@
1013
  "id": "portable_precast_a1_bnone",
1014
  "priority": 38,
1015
  "when": ["rank2MatMulShapeOk", "requiredScalarAZeroOk", "not present.b_zero_point", "precastF32BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float32\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f32\" == \"f16\" or sgmatM >= portableTileN"],
 
1016
  "requires": { "features": [] },
1017
  "derive": {
1018
  "precastScalar": "\"f32\"",
@@ -1020,8 +971,6 @@
1020
  "hasAZero": true,
1021
  "hasBZero": false,
1022
  "bZeroPerColumn": false,
1023
- "bScalePerColumn": false,
1024
- "requantize": false,
1025
  "M": "sgmatM",
1026
  "N": "sgmatN",
1027
  "K": "preparedK",
@@ -1030,17 +979,14 @@
1030
  "workgroupRows": "portableWorkgroupRows",
1031
  "blockRows": "portableTileM",
1032
  "blockCols": "portableTileN",
1033
- "integerPartialK": "portablePartialK",
1034
- "packedATile": true,
1035
- "vec4BTile": true,
1036
- "hasBias": false
1037
  },
1038
  "passes": [
1039
  {
1040
  "id": "prepare",
1041
- "name": "ExactMatrix.PrepareOperands",
1042
  "shader": "quant-exact-prepare.wgsl.jinja",
1043
- "bindings": ["a_2", "a_zero_point", "precast_f32_aFloat", "b", "precast_f32_bFloat", "precast_prepare_params"],
1044
  "dispatch": {
1045
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1046
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -1048,7 +994,7 @@
1048
  },
1049
  {
1050
  "id": "main",
1051
- "name": "ExactMatrix.PortableMultiply",
1052
  "shader": "quant-exact-portable.wgsl.jinja",
1053
  "bindings": ["portable_f32_a", "portable_f32_b", "y"],
1054
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
@@ -1075,20 +1021,17 @@
1075
  "sgmatRowGroups": "precastSubgroups",
1076
  "sgmatSubgroups": "precastSubgroups",
1077
  "sgmatWorkgroup": "precastWorkgroup",
1078
- "sgmatSharedBytes": "sgmatSubgroups * 8 * 64 * 4",
1079
  "precastScalar": "\"f16\"",
1080
  "hasAZero": true,
1081
  "hasBZero": true,
1082
- "bZeroPerColumn": false,
1083
- "bScalePerColumn": false,
1084
- "requantize": false
1085
  },
1086
  "passes": [
1087
  {
1088
  "id": "prepare",
1089
- "name": "ExactMatrix.PrepareOperands",
1090
  "shader": "quant-exact-prepare.wgsl.jinja",
1091
- "bindings": ["a_2", "a_zero_point", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
1092
  "dispatch": {
1093
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1094
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -1096,9 +1039,9 @@
1096
  },
1097
  {
1098
  "id": "main",
1099
- "name": "ExactMatrix.Multiply",
1100
  "shader": "quant-exact-matrix.wgsl.jinja",
1101
- "bindings": ["precast_f16_a", "precast_f16_b", "a_zero_point", "b_zero_point", "y", "params_3"],
1102
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
1103
  }
1104
  ],
@@ -1111,6 +1054,7 @@
1111
  "id": "portable_precast_a1_bscalar_f16",
1112
  "priority": 39,
1113
  "when": ["rank2MatMulShapeOk", "requiredScalarAZeroOk", "requiredScalarBZeroOk", "precastF16BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float16\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f16\" == \"f16\" or sgmatM >= portableTileN"],
 
1114
  "requires": { "features": ["shader-f16"] },
1115
  "derive": {
1116
  "precastScalar": "\"f16\"",
@@ -1118,8 +1062,6 @@
1118
  "hasAZero": true,
1119
  "hasBZero": true,
1120
  "bZeroPerColumn": false,
1121
- "bScalePerColumn": false,
1122
- "requantize": false,
1123
  "M": "sgmatM",
1124
  "N": "sgmatN",
1125
  "K": "preparedK",
@@ -1128,17 +1070,14 @@
1128
  "workgroupRows": "portableWorkgroupRows",
1129
  "blockRows": "portableTileM",
1130
  "blockCols": "portableTileN",
1131
- "integerPartialK": "portablePartialK",
1132
- "packedATile": true,
1133
- "vec4BTile": true,
1134
- "hasBias": false
1135
  },
1136
  "passes": [
1137
  {
1138
  "id": "prepare",
1139
- "name": "ExactMatrix.PrepareOperands",
1140
  "shader": "quant-exact-prepare.wgsl.jinja",
1141
- "bindings": ["a_2", "a_zero_point", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
1142
  "dispatch": {
1143
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1144
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -1146,7 +1085,7 @@
1146
  },
1147
  {
1148
  "id": "main",
1149
- "name": "ExactMatrix.PortableMultiply",
1150
  "shader": "quant-exact-portable.wgsl.jinja",
1151
  "bindings": ["portable_f16_a", "portable_f16_b", "y"],
1152
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
@@ -1173,20 +1112,17 @@
1173
  "sgmatRowGroups": "precastSubgroups",
1174
  "sgmatSubgroups": "precastSubgroups",
1175
  "sgmatWorkgroup": "precastWorkgroup",
1176
- "sgmatSharedBytes": "sgmatSubgroups * 8 * 64 * 4",
1177
  "precastScalar": "\"f32\"",
1178
  "hasAZero": true,
1179
  "hasBZero": true,
1180
- "bZeroPerColumn": false,
1181
- "bScalePerColumn": false,
1182
- "requantize": false
1183
  },
1184
  "passes": [
1185
  {
1186
  "id": "prepare",
1187
- "name": "ExactMatrix.PrepareOperands",
1188
  "shader": "quant-exact-prepare.wgsl.jinja",
1189
- "bindings": ["a_2", "a_zero_point", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
1190
  "dispatch": {
1191
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1192
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -1194,9 +1130,9 @@
1194
  },
1195
  {
1196
  "id": "main",
1197
- "name": "ExactMatrix.Multiply",
1198
  "shader": "quant-exact-matrix.wgsl.jinja",
1199
- "bindings": ["precast_f32_a", "precast_f32_b", "a_zero_point", "b_zero_point", "y", "params_3"],
1200
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
1201
  }
1202
  ],
@@ -1209,6 +1145,7 @@
1209
  "id": "portable_precast_a1_bscalar",
1210
  "priority": 38,
1211
  "when": ["rank2MatMulShapeOk", "requiredScalarAZeroOk", "requiredScalarBZeroOk", "precastF32BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float32\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f32\" == \"f16\" or sgmatM >= portableTileN"],
 
1212
  "requires": { "features": [] },
1213
  "derive": {
1214
  "precastScalar": "\"f32\"",
@@ -1216,8 +1153,6 @@
1216
  "hasAZero": true,
1217
  "hasBZero": true,
1218
  "bZeroPerColumn": false,
1219
- "bScalePerColumn": false,
1220
- "requantize": false,
1221
  "M": "sgmatM",
1222
  "N": "sgmatN",
1223
  "K": "preparedK",
@@ -1226,17 +1161,14 @@
1226
  "workgroupRows": "portableWorkgroupRows",
1227
  "blockRows": "portableTileM",
1228
  "blockCols": "portableTileN",
1229
- "integerPartialK": "portablePartialK",
1230
- "packedATile": true,
1231
- "vec4BTile": true,
1232
- "hasBias": false
1233
  },
1234
  "passes": [
1235
  {
1236
  "id": "prepare",
1237
- "name": "ExactMatrix.PrepareOperands",
1238
  "shader": "quant-exact-prepare.wgsl.jinja",
1239
- "bindings": ["a_2", "a_zero_point", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
1240
  "dispatch": {
1241
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1242
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -1244,7 +1176,7 @@
1244
  },
1245
  {
1246
  "id": "main",
1247
- "name": "ExactMatrix.PortableMultiply",
1248
  "shader": "quant-exact-portable.wgsl.jinja",
1249
  "bindings": ["portable_f32_a", "portable_f32_b", "y"],
1250
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
@@ -1271,20 +1203,17 @@
1271
  "sgmatRowGroups": "precastSubgroups",
1272
  "sgmatSubgroups": "precastSubgroups",
1273
  "sgmatWorkgroup": "precastWorkgroup",
1274
- "sgmatSharedBytes": "sgmatSubgroups * 8 * 64 * 4",
1275
  "precastScalar": "\"f16\"",
1276
  "hasAZero": true,
1277
  "hasBZero": true,
1278
- "bZeroPerColumn": true,
1279
- "bScalePerColumn": false,
1280
- "requantize": false
1281
  },
1282
  "passes": [
1283
  {
1284
  "id": "prepare",
1285
- "name": "ExactMatrix.PrepareOperands",
1286
  "shader": "quant-exact-prepare.wgsl.jinja",
1287
- "bindings": ["a_2", "a_zero_point", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
1288
  "dispatch": {
1289
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1290
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -1292,9 +1221,9 @@
1292
  },
1293
  {
1294
  "id": "main",
1295
- "name": "ExactMatrix.Multiply",
1296
  "shader": "quant-exact-matrix.wgsl.jinja",
1297
- "bindings": ["precast_f16_a", "precast_f16_b", "a_zero_point", "y", "params_3"],
1298
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
1299
  }
1300
  ],
@@ -1307,6 +1236,7 @@
1307
  "id": "portable_precast_a1_bcolumn_f16",
1308
  "priority": 39,
1309
  "when": ["rank2MatMulShapeOk", "requiredScalarAZeroOk", "present.b_zero_point and rank2PerColumnBZeroOk", "precastF16BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float16\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f16\" == \"f16\" or sgmatM >= portableTileN"],
 
1310
  "requires": { "features": ["shader-f16"] },
1311
  "derive": {
1312
  "precastScalar": "\"f16\"",
@@ -1314,8 +1244,6 @@
1314
  "hasAZero": true,
1315
  "hasBZero": true,
1316
  "bZeroPerColumn": true,
1317
- "bScalePerColumn": false,
1318
- "requantize": false,
1319
  "M": "sgmatM",
1320
  "N": "sgmatN",
1321
  "K": "preparedK",
@@ -1324,17 +1252,14 @@
1324
  "workgroupRows": "portableWorkgroupRows",
1325
  "blockRows": "portableTileM",
1326
  "blockCols": "portableTileN",
1327
- "integerPartialK": "portablePartialK",
1328
- "packedATile": true,
1329
- "vec4BTile": true,
1330
- "hasBias": false
1331
  },
1332
  "passes": [
1333
  {
1334
  "id": "prepare",
1335
- "name": "ExactMatrix.PrepareOperands",
1336
  "shader": "quant-exact-prepare.wgsl.jinja",
1337
- "bindings": ["a_2", "a_zero_point", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
1338
  "dispatch": {
1339
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1340
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -1342,7 +1267,7 @@
1342
  },
1343
  {
1344
  "id": "main",
1345
- "name": "ExactMatrix.PortableMultiply",
1346
  "shader": "quant-exact-portable.wgsl.jinja",
1347
  "bindings": ["portable_f16_a", "portable_f16_b", "y"],
1348
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
@@ -1369,20 +1294,17 @@
1369
  "sgmatRowGroups": "precastSubgroups",
1370
  "sgmatSubgroups": "precastSubgroups",
1371
  "sgmatWorkgroup": "precastWorkgroup",
1372
- "sgmatSharedBytes": "sgmatSubgroups * 8 * 64 * 4",
1373
  "precastScalar": "\"f32\"",
1374
  "hasAZero": true,
1375
  "hasBZero": true,
1376
- "bZeroPerColumn": true,
1377
- "bScalePerColumn": false,
1378
- "requantize": false
1379
  },
1380
  "passes": [
1381
  {
1382
  "id": "prepare",
1383
- "name": "ExactMatrix.PrepareOperands",
1384
  "shader": "quant-exact-prepare.wgsl.jinja",
1385
- "bindings": ["a_2", "a_zero_point", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
1386
  "dispatch": {
1387
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1388
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -1390,9 +1312,9 @@
1390
  },
1391
  {
1392
  "id": "main",
1393
- "name": "ExactMatrix.Multiply",
1394
  "shader": "quant-exact-matrix.wgsl.jinja",
1395
- "bindings": ["precast_f32_a", "precast_f32_b", "a_zero_point", "y", "params_3"],
1396
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
1397
  }
1398
  ],
@@ -1405,6 +1327,7 @@
1405
  "id": "portable_precast_a1_bcolumn",
1406
  "priority": 38,
1407
  "when": ["rank2MatMulShapeOk", "requiredScalarAZeroOk", "present.b_zero_point and rank2PerColumnBZeroOk", "precastF32BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float32\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f32\" == \"f16\" or sgmatM >= portableTileN"],
 
1408
  "requires": { "features": [] },
1409
  "derive": {
1410
  "precastScalar": "\"f32\"",
@@ -1412,8 +1335,6 @@
1412
  "hasAZero": true,
1413
  "hasBZero": true,
1414
  "bZeroPerColumn": true,
1415
- "bScalePerColumn": false,
1416
- "requantize": false,
1417
  "M": "sgmatM",
1418
  "N": "sgmatN",
1419
  "K": "preparedK",
@@ -1422,17 +1343,14 @@
1422
  "workgroupRows": "portableWorkgroupRows",
1423
  "blockRows": "portableTileM",
1424
  "blockCols": "portableTileN",
1425
- "integerPartialK": "portablePartialK",
1426
- "packedATile": true,
1427
- "vec4BTile": true,
1428
- "hasBias": false
1429
  },
1430
  "passes": [
1431
  {
1432
  "id": "prepare",
1433
- "name": "ExactMatrix.PrepareOperands",
1434
  "shader": "quant-exact-prepare.wgsl.jinja",
1435
- "bindings": ["a_2", "a_zero_point", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
1436
  "dispatch": {
1437
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1438
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
@@ -1440,7 +1358,7 @@
1440
  },
1441
  {
1442
  "id": "main",
1443
- "name": "ExactMatrix.PortableMultiply",
1444
  "shader": "quant-exact-portable.wgsl.jinja",
1445
  "bindings": ["portable_f32_a", "portable_f32_b", "y"],
1446
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
@@ -1459,13 +1377,13 @@
1459
  "features": ["subgroups", "chromium-experimental-subgroup-matrix"],
1460
  "subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
1461
  },
1462
- "derive": { "hasAZero": false, "hasBZero": false, "bZeroPerColumn": false, "requantize": false },
1463
  "passes": [
1464
  {
1465
  "id": "main",
1466
  "name": "MatMulInteger.ExactMatrix",
1467
  "shader": "quant-exact-matrix.wgsl.jinja",
1468
- "bindings": ["a_2", "b", "y", "params_3"],
1469
  "dispatch": { "x": "ceilDiv(matrixN, sgmatTileN)", "y": "ceilDiv(matrixM, sgmatTileM)" }
1470
  }
1471
  ]
@@ -1478,13 +1396,13 @@
1478
  "features": ["subgroups", "chromium-experimental-subgroup-matrix"],
1479
  "subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
1480
  },
1481
- "derive": { "hasAZero": false, "hasBZero": true, "bZeroPerColumn": false, "requantize": false },
1482
  "passes": [
1483
  {
1484
  "id": "main",
1485
  "name": "MatMulInteger.ExactMatrix",
1486
  "shader": "quant-exact-matrix.wgsl.jinja",
1487
- "bindings": ["a_2", "b", "b_zero_point", "y", "params_3"],
1488
  "dispatch": { "x": "ceilDiv(matrixN, sgmatTileN)", "y": "ceilDiv(matrixM, sgmatTileM)" }
1489
  }
1490
  ]
@@ -1497,13 +1415,13 @@
1497
  "features": ["subgroups", "chromium-experimental-subgroup-matrix"],
1498
  "subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
1499
  },
1500
- "derive": { "hasAZero": false, "hasBZero": true, "bZeroPerColumn": true, "requantize": false },
1501
  "passes": [
1502
  {
1503
  "id": "main",
1504
  "name": "MatMulInteger.ExactMatrix",
1505
  "shader": "quant-exact-matrix.wgsl.jinja",
1506
- "bindings": ["a_2", "b", "b_zero_point", "y", "params_3"],
1507
  "dispatch": { "x": "ceilDiv(matrixN, sgmatTileN)", "y": "ceilDiv(matrixM, sgmatTileM)" }
1508
  }
1509
  ]
@@ -1516,13 +1434,13 @@
1516
  "features": ["subgroups", "chromium-experimental-subgroup-matrix"],
1517
  "subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
1518
  },
1519
- "derive": { "hasAZero": true, "hasBZero": false, "bZeroPerColumn": false, "requantize": false },
1520
  "passes": [
1521
  {
1522
  "id": "main",
1523
  "name": "MatMulInteger.ExactMatrix",
1524
  "shader": "quant-exact-matrix.wgsl.jinja",
1525
- "bindings": ["a_2", "b", "a_zero_point", "y", "params_3"],
1526
  "dispatch": { "x": "ceilDiv(matrixN, sgmatTileN)", "y": "ceilDiv(matrixM, sgmatTileM)" }
1527
  }
1528
  ]
@@ -1535,13 +1453,13 @@
1535
  "features": ["subgroups", "chromium-experimental-subgroup-matrix"],
1536
  "subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
1537
  },
1538
- "derive": { "hasAZero": true, "hasBZero": true, "bZeroPerColumn": false, "requantize": false },
1539
  "passes": [
1540
  {
1541
  "id": "main",
1542
  "name": "MatMulInteger.ExactMatrix",
1543
  "shader": "quant-exact-matrix.wgsl.jinja",
1544
- "bindings": ["a_2", "b", "a_zero_point", "b_zero_point", "y", "params_3"],
1545
  "dispatch": { "x": "ceilDiv(matrixN, sgmatTileN)", "y": "ceilDiv(matrixM, sgmatTileM)" }
1546
  }
1547
  ]
@@ -1554,13 +1472,13 @@
1554
  "features": ["subgroups", "chromium-experimental-subgroup-matrix"],
1555
  "subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
1556
  },
1557
- "derive": { "hasAZero": true, "hasBZero": true, "bZeroPerColumn": true, "requantize": false },
1558
  "passes": [
1559
  {
1560
  "id": "main",
1561
  "name": "MatMulInteger.ExactMatrix",
1562
  "shader": "quant-exact-matrix.wgsl.jinja",
1563
- "bindings": ["a_2", "b", "a_zero_point", "b_zero_point", "y", "params_3"],
1564
  "dispatch": { "x": "ceilDiv(matrixN, sgmatTileN)", "y": "ceilDiv(matrixM, sgmatTileM)" }
1565
  }
1566
  ]
@@ -1575,12 +1493,7 @@
1575
  "hasAZero": true,
1576
  "hasBZero": true,
1577
  "bZeroPerColumn": false,
1578
- "requant": "\"none\"",
1579
- "scaleScalar": "\"f32\"",
1580
- "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL",
1581
- "tileM": "rank2Dp4aTileM",
1582
- "tileN": "rank2Dp4aTileN",
1583
- "ktWords": "rank2Dp4aKtWords"
1584
  },
1585
  "passes": [
1586
  {
@@ -1605,12 +1518,7 @@
1605
  "hasAZero": false,
1606
  "hasBZero": false,
1607
  "bZeroPerColumn": false,
1608
- "requant": "\"none\"",
1609
- "scaleScalar": "\"f32\"",
1610
- "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL",
1611
- "tileM": "rank2Dp4aTileM",
1612
- "tileN": "rank2Dp4aTileN",
1613
- "ktWords": "rank2Dp4aKtWords"
1614
  },
1615
  "passes": [
1616
  {
@@ -1634,8 +1542,6 @@
1634
  "hasAZero": true,
1635
  "hasBZero": true,
1636
  "bZeroPerColumn": false,
1637
- "requant": "\"none\"",
1638
- "scaleScalar": "\"f32\"",
1639
  "tileM": 8,
1640
  "tileN": 64,
1641
  "ktWords": 32
@@ -1646,7 +1552,7 @@
1646
  "name": "MatMulInteger.Dp4aBatched3x2Tail",
1647
  "shader": "quant-dp4a-matmul.wgsl.jinja",
1648
  "bindings": [
1649
- "a_2",
1650
  "b",
1651
  "a_zero_point",
1652
  "b_zero_point",
@@ -1676,12 +1582,7 @@
1676
  "hasAZero": true,
1677
  "hasBZero": true,
1678
  "bZeroPerColumn": false,
1679
- "requant": "\"none\"",
1680
- "scaleScalar": "\"f32\"",
1681
- "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL",
1682
- "tileM": "rank2Dp4aTileM",
1683
- "tileN": "rank2Dp4aTileN",
1684
- "ktWords": "rank2Dp4aKtWords"
1685
  },
1686
  "passes": [
1687
  {
@@ -1705,19 +1606,14 @@
1705
  "hasAZero": true,
1706
  "hasBZero": false,
1707
  "bZeroPerColumn": false,
1708
- "requant": "\"none\"",
1709
- "scaleScalar": "\"f32\"",
1710
- "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL",
1711
- "tileM": "rank2Dp4aTileM",
1712
- "tileN": "rank2Dp4aTileN",
1713
- "ktWords": "rank2Dp4aKtWords"
1714
  },
1715
  "passes": [
1716
  {
1717
  "id": "main",
1718
  "name": "MatMulInteger.Dp4a",
1719
  "shader": "quant-dp4a-matmul.wgsl.jinja",
1720
- "bindings": ["a_3", "b", "a_zero_point", "y", "params"],
1721
  "dispatch": {
1722
  "x": "ceilDiv(dim(shapes.y, 1), rank2Dp4aTileN)",
1723
  "y": "ceilDiv(dim(shapes.y, 0), rank2Dp4aTileM)"
@@ -1734,12 +1630,7 @@
1734
  "hasAZero": false,
1735
  "hasBZero": true,
1736
  "bZeroPerColumn": false,
1737
- "requant": "\"none\"",
1738
- "scaleScalar": "\"f32\"",
1739
- "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL",
1740
- "tileM": "rank2Dp4aTileM",
1741
- "tileN": "rank2Dp4aTileN",
1742
- "ktWords": "rank2Dp4aKtWords"
1743
  },
1744
  "passes": [
1745
  {
@@ -1763,19 +1654,14 @@
1763
  "hasAZero": false,
1764
  "hasBZero": false,
1765
  "bZeroPerColumn": false,
1766
- "requant": "\"none\"",
1767
- "scaleScalar": "\"f32\"",
1768
- "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL",
1769
- "tileM": "rank2Dp4aTileM",
1770
- "tileN": "rank2Dp4aTileN",
1771
- "ktWords": "rank2Dp4aKtWords"
1772
  },
1773
  "passes": [
1774
  {
1775
  "id": "main",
1776
  "name": "MatMulInteger.Dp4a",
1777
  "shader": "quant-dp4a-matmul.wgsl.jinja",
1778
- "bindings": ["a_3", "b", "y", "params"],
1779
  "dispatch": {
1780
  "x": "ceilDiv(dim(shapes.y, 1), rank2Dp4aTileN)",
1781
  "y": "ceilDiv(dim(shapes.y, 0), rank2Dp4aTileM)"
@@ -1800,11 +1686,9 @@
1800
  "hasAZero": false,
1801
  "hasBZero": true,
1802
  "bZeroPerColumn": true,
1803
- "requant": "\"none\"",
1804
- "scaleScalar": "\"f32\"",
1805
  "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL",
1806
- "tileM": "rank2Dp4aTileM if dim(shapes.y, 0) == 1 else tunables.TILE_M",
1807
- "tileN": "rank2Dp4aTileN if dim(shapes.y, 0) == 1 else tunables.TILE_N",
1808
  "ktWords": "rank2Dp4aKtWords if dim(shapes.y, 0) == 1 else tunables.KT_WORDS"
1809
  },
1810
  "passes": [
@@ -1813,10 +1697,7 @@
1813
  "name": "MatMulInteger.Dp4aBPerColumn",
1814
  "shader": "quant-dp4a-matmul.wgsl.jinja",
1815
  "bindings": ["a", "b", "b_zero_point", "y", "params"],
1816
- "dispatch": {
1817
- "x": "ceilDiv(dim(shapes.y, 1), rank2Dp4aTileN if dim(shapes.y, 0) == 1 else tunables.TILE_N)",
1818
- "y": "ceilDiv(dim(shapes.y, 0), rank2Dp4aTileM if dim(shapes.y, 0) == 1 else tunables.TILE_M)"
1819
- }
1820
  }
1821
  ]
1822
  },
@@ -1837,11 +1718,9 @@
1837
  "hasAZero": true,
1838
  "hasBZero": true,
1839
  "bZeroPerColumn": true,
1840
- "requant": "\"none\"",
1841
- "scaleScalar": "\"f32\"",
1842
  "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL",
1843
- "tileM": "rank2Dp4aTileM if dim(shapes.y, 0) == 1 else tunables.TILE_M",
1844
- "tileN": "rank2Dp4aTileN if dim(shapes.y, 0) == 1 else tunables.TILE_N",
1845
  "ktWords": "rank2Dp4aKtWords if dim(shapes.y, 0) == 1 else tunables.KT_WORDS"
1846
  },
1847
  "passes": [
@@ -1850,10 +1729,7 @@
1850
  "name": "MatMulInteger.Dp4aAScalarBPerColumn",
1851
  "shader": "quant-dp4a-matmul.wgsl.jinja",
1852
  "bindings": ["a", "b", "a_zero_point", "b_zero_point", "y", "params"],
1853
- "dispatch": {
1854
- "x": "ceilDiv(dim(shapes.y, 1), rank2Dp4aTileN if dim(shapes.y, 0) == 1 else tunables.TILE_N)",
1855
- "y": "ceilDiv(dim(shapes.y, 0), rank2Dp4aTileM if dim(shapes.y, 0) == 1 else tunables.TILE_M)"
1856
- }
1857
  }
1858
  ]
1859
  },
@@ -1866,11 +1742,11 @@
1866
  "id": "main",
1867
  "name": "MatMulInteger",
1868
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1869
- "bindings": ["a_2", "b", "a_zero_point", "b_zero_point", "y", "params_3"],
1870
  "dispatch": {
1871
  "x": "ceil(matrixN / tunables.WORKGROUP_SIZE_X)",
1872
  "y": "min(ceilDiv((matrixM), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)",
1873
- "z": "ceilDiv(ceilDiv((matrixM), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)"
1874
  }
1875
  }
1876
  ]
@@ -1884,11 +1760,11 @@
1884
  "id": "main",
1885
  "name": "MatMulInteger",
1886
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1887
- "bindings": ["a_2", "b", "a_zero_point", "y", "params_3"],
1888
  "dispatch": {
1889
  "x": "ceil(matrixN / tunables.WORKGROUP_SIZE_X)",
1890
  "y": "min(ceilDiv((matrixM), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)",
1891
- "z": "ceilDiv(ceilDiv((matrixM), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)"
1892
  }
1893
  }
1894
  ]
@@ -1902,11 +1778,11 @@
1902
  "id": "main",
1903
  "name": "MatMulInteger",
1904
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1905
- "bindings": ["a_2", "b", "b_zero_point", "y", "params_3"],
1906
  "dispatch": {
1907
  "x": "ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_X)",
1908
  "y": "min(ceilDiv((dim(shapes.y, 0)), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)",
1909
- "z": "ceilDiv(ceilDiv((dim(shapes.y, 0)), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)"
1910
  }
1911
  }
1912
  ]
@@ -1920,7 +1796,7 @@
1920
  "id": "main",
1921
  "name": "MatMulInteger",
1922
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1923
- "bindings": ["a_2", "b", "b_zero_point", "y", "params_4"],
1924
  "dispatch": { "x": 1 }
1925
  }
1926
  ]
@@ -1934,7 +1810,7 @@
1934
  "id": "main",
1935
  "name": "MatMulInteger",
1936
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1937
- "bindings": ["a_2", "b", "y", "params_4"],
1938
  "dispatch": { "x": 1 }
1939
  }
1940
  ]
@@ -1948,11 +1824,11 @@
1948
  "id": "main",
1949
  "name": "MatMulInteger",
1950
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1951
- "bindings": ["a_2", "b", "y", "params_3"],
1952
  "dispatch": {
1953
  "x": "ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_X)",
1954
  "y": "min(ceilDiv((dim(shapes.y, 0)), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)",
1955
- "z": "ceilDiv(ceilDiv((dim(shapes.y, 0)), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)"
1956
  }
1957
  }
1958
  ]
@@ -1966,11 +1842,11 @@
1966
  "id": "main",
1967
  "name": "MatMulInteger.PerColumn",
1968
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1969
- "bindings": ["a_2", "b", "a_zero_point", "b_zero_point", "y", "params_3"],
1970
  "dispatch": {
1971
  "x": "ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_X)",
1972
  "y": "min(ceilDiv((dim(shapes.y, 0)), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)",
1973
- "z": "ceilDiv(ceilDiv((dim(shapes.y, 0)), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)"
1974
  }
1975
  }
1976
  ]
@@ -1984,11 +1860,11 @@
1984
  "id": "main",
1985
  "name": "MatMulInteger.PerColumnNoAZero",
1986
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1987
- "bindings": ["a_2", "b", "b_zero_point", "y", "params_3"],
1988
  "dispatch": {
1989
  "x": "ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_X)",
1990
  "y": "min(ceilDiv((dim(shapes.y, 0)), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)",
1991
- "z": "ceilDiv(ceilDiv((dim(shapes.y, 0)), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)"
1992
  }
1993
  }
1994
  ]
@@ -1996,13 +1872,13 @@
1996
  {
1997
  "id": "rank3_by_rank3_scalar_zero_points",
1998
  "when": ["present.a_zero_point", "present.b_zero_point", "(rank3ByRank3ShapeOk or rank3ByRank2ShapeOk)", "scalarAZeroOk and scalarBZeroOk"],
1999
- "derive": { "hasAZero": true, "hasBZero": true, "bZeroPerColumn": false, "bZeroBatchedPerColumn": false },
2000
  "passes": [
2001
  {
2002
  "id": "main",
2003
  "name": "MatMulInteger.Batched3x3",
2004
  "shader": "matmul-integer-batched.wgsl.jinja",
2005
- "bindings": ["a_2", "b", "a_zero_point", "b_zero_point", "y", "params_5"],
2006
  "dispatch": {
2007
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2008
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2014,13 +1890,13 @@
2014
  {
2015
  "id": "rank3_by_rank3_no_zero_points",
2016
  "when": ["not present.a_zero_point", "not present.b_zero_point", "(rank3ByRank3ShapeOk or rank3ByRank2ShapeOk)", "true"],
2017
- "derive": { "hasAZero": false, "hasBZero": false, "bZeroPerColumn": false, "bZeroBatchedPerColumn": false },
2018
  "passes": [
2019
  {
2020
  "id": "main",
2021
  "name": "MatMulInteger.Batched3x3",
2022
  "shader": "matmul-integer-batched.wgsl.jinja",
2023
- "bindings": ["a_2", "b", "y", "params_5"],
2024
  "dispatch": {
2025
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2026
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2032,13 +1908,13 @@
2032
  {
2033
  "id": "rank3_by_rank3_a_zero_point_only",
2034
  "when": ["present.a_zero_point", "not present.b_zero_point", "(rank3ByRank3ShapeOk or rank3ByRank2ShapeOk)", "scalarAZeroOk"],
2035
- "derive": { "hasAZero": true, "hasBZero": false, "bZeroPerColumn": false, "bZeroBatchedPerColumn": false },
2036
  "passes": [
2037
  {
2038
  "id": "main",
2039
  "name": "MatMulInteger.Batched3x3",
2040
  "shader": "matmul-integer-batched.wgsl.jinja",
2041
- "bindings": ["a_2", "b", "a_zero_point", "y", "params_5"],
2042
  "dispatch": {
2043
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2044
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2050,13 +1926,13 @@
2050
  {
2051
  "id": "rank3_by_rank3_b_zero_point_only",
2052
  "when": ["not present.a_zero_point", "present.b_zero_point", "(rank3ByRank3ShapeOk or rank3ByRank2ShapeOk)", "scalarBZeroOk"],
2053
- "derive": { "hasAZero": false, "hasBZero": true, "bZeroPerColumn": false, "bZeroBatchedPerColumn": false },
2054
  "passes": [
2055
  {
2056
  "id": "main",
2057
  "name": "MatMulInteger.Batched3x3",
2058
  "shader": "matmul-integer-batched.wgsl.jinja",
2059
- "bindings": ["a_2", "b", "b_zero_point", "y", "params_5"],
2060
  "dispatch": {
2061
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2062
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2068,13 +1944,13 @@
2068
  {
2069
  "id": "rank3_by_rank3_b_zero_point_per_column_batched",
2070
  "when": ["present.a_zero_point", "present.b_zero_point", "rank3ByRank3ShapeOk", "scalarAZeroOk and ranks.b_zero_point == 3 and dim(shapes.b_zero_point, 0) == dim(shapes.y, 0) and dim(shapes.b_zero_point, 1) == 1 and dim(shapes.b_zero_point, 2) == dim(shapes.y, 2)"],
2071
- "derive": { "hasAZero": true, "hasBZero": true, "bZeroPerColumn": false, "bZeroBatchedPerColumn": true },
2072
  "passes": [
2073
  {
2074
  "id": "main",
2075
  "name": "MatMulInteger.Batched3x3PerColumn",
2076
  "shader": "matmul-integer-batched.wgsl.jinja",
2077
- "bindings": ["a_2", "b", "a_zero_point", "b_zero_point", "y", "params_5"],
2078
  "dispatch": {
2079
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2080
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2086,13 +1962,13 @@
2086
  {
2087
  "id": "rank3_by_rank3_b_zero_point_per_column_batched_no_azp",
2088
  "when": ["not present.a_zero_point", "present.b_zero_point", "rank3ByRank3ShapeOk", "ranks.b_zero_point == 3 and dim(shapes.b_zero_point, 0) == dim(shapes.y, 0) and dim(shapes.b_zero_point, 1) == 1 and dim(shapes.b_zero_point, 2) == dim(shapes.y, 2)"],
2089
- "derive": { "hasAZero": false, "hasBZero": true, "bZeroPerColumn": false, "bZeroBatchedPerColumn": true },
2090
  "passes": [
2091
  {
2092
  "id": "main",
2093
  "name": "MatMulInteger.Batched3x3PerColumn",
2094
  "shader": "matmul-integer-batched.wgsl.jinja",
2095
- "bindings": ["a_2", "b", "b_zero_point", "y", "params_5"],
2096
  "dispatch": {
2097
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2098
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2104,13 +1980,13 @@
2104
  {
2105
  "id": "rank2_by_rank3_scalar_zero_points",
2106
  "when": ["present.a_zero_point", "present.b_zero_point", "ranks.a == 2 and ranks.b == 3 and ranks.y == 3 and dim(shapes.a, 1) == dim(shapes.b, 1) and dim(shapes.y, 0) == dim(shapes.b, 0) and dim(shapes.y, 1) == dim(shapes.a, 0) and dim(shapes.y, 2) == dim(shapes.b, 2)", "scalarAZeroOk and scalarBZeroOk"],
2107
- "derive": { "hasAZero": true, "hasBZero": true, "bZeroPerColumn": false, "bZeroBatchedPerColumn": false },
2108
  "passes": [
2109
  {
2110
  "id": "main",
2111
  "name": "MatMulInteger.Batched2x3",
2112
  "shader": "matmul-integer-batched.wgsl.jinja",
2113
- "bindings": ["a_2", "b", "a_zero_point", "b_zero_point", "y", "params_5"],
2114
  "dispatch": {
2115
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2116
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2122,13 +1998,13 @@
2122
  {
2123
  "id": "rank2_by_rank3_a_zero_point_only",
2124
  "when": ["present.a_zero_point", "not present.b_zero_point", "ranks.a == 2 and ranks.b == 3 and ranks.y == 3 and dim(shapes.a, 1) == dim(shapes.b, 1) and dim(shapes.y, 0) == dim(shapes.b, 0) and dim(shapes.y, 1) == dim(shapes.a, 0) and dim(shapes.y, 2) == dim(shapes.b, 2)", "scalarAZeroOk"],
2125
- "derive": { "hasAZero": true, "hasBZero": false, "bZeroPerColumn": false, "bZeroBatchedPerColumn": false },
2126
  "passes": [
2127
  {
2128
  "id": "main",
2129
  "name": "MatMulInteger.Batched2x3",
2130
  "shader": "matmul-integer-batched.wgsl.jinja",
2131
- "bindings": ["a_2", "b", "a_zero_point", "y", "params_5"],
2132
  "dispatch": {
2133
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2134
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2140,13 +2016,13 @@
2140
  {
2141
  "id": "rank2_by_rank3_b_zero_point_only",
2142
  "when": ["not present.a_zero_point", "present.b_zero_point", "ranks.a == 2 and ranks.b == 3 and ranks.y == 3 and dim(shapes.a, 1) == dim(shapes.b, 1) and dim(shapes.y, 0) == dim(shapes.b, 0) and dim(shapes.y, 1) == dim(shapes.a, 0) and dim(shapes.y, 2) == dim(shapes.b, 2)", "scalarBZeroOk"],
2143
- "derive": { "hasAZero": false, "hasBZero": true, "bZeroPerColumn": false, "bZeroBatchedPerColumn": false },
2144
  "passes": [
2145
  {
2146
  "id": "main",
2147
  "name": "MatMulInteger.Batched2x3",
2148
  "shader": "matmul-integer-batched.wgsl.jinja",
2149
- "bindings": ["a_2", "b", "b_zero_point", "y", "params_5"],
2150
  "dispatch": {
2151
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2152
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2158,13 +2034,13 @@
2158
  {
2159
  "id": "rank2_by_rank3_no_zero_points",
2160
  "when": ["not present.a_zero_point", "not present.b_zero_point", "ranks.a == 2 and ranks.b == 3 and ranks.y == 3 and dim(shapes.a, 1) == dim(shapes.b, 1) and dim(shapes.y, 0) == dim(shapes.b, 0) and dim(shapes.y, 1) == dim(shapes.a, 0) and dim(shapes.y, 2) == dim(shapes.b, 2)", "true"],
2161
- "derive": { "hasAZero": false, "hasBZero": false, "bZeroPerColumn": false, "bZeroBatchedPerColumn": false },
2162
  "passes": [
2163
  {
2164
  "id": "main",
2165
  "name": "MatMulInteger.Batched2x3",
2166
  "shader": "matmul-integer-batched.wgsl.jinja",
2167
- "bindings": ["a_2", "b", "y", "params_5"],
2168
  "dispatch": {
2169
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2170
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2183,7 +2059,7 @@
2183
  "name": "MatMulInteger.Batched4",
2184
  "shader": "quant-matmul-accumulate-rank4.wgsl.jinja",
2185
  "derive": { "outputToScratch": false },
2186
- "bindings": ["a_2", "b", "a_zero_point", "b_zero_point", "y", "params_6"],
2187
  "dispatch": {
2188
  "x": "ceil(dim(shapes.y, 3) / tunables.WORKGROUP_SIZE_X)",
2189
  "y": "min(ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2202,7 +2078,7 @@
2202
  "name": "MatMulInteger.Batched4",
2203
  "shader": "quant-matmul-accumulate-rank4.wgsl.jinja",
2204
  "derive": { "outputToScratch": false },
2205
- "bindings": ["a_2", "b", "a_zero_point", "y", "params_6"],
2206
  "dispatch": {
2207
  "x": "ceil(dim(shapes.y, 3) / tunables.WORKGROUP_SIZE_X)",
2208
  "y": "min(ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2221,7 +2097,7 @@
2221
  "name": "MatMulInteger.Batched4",
2222
  "shader": "quant-matmul-accumulate-rank4.wgsl.jinja",
2223
  "derive": { "outputToScratch": false },
2224
- "bindings": ["a_2", "b", "b_zero_point", "y", "params_6"],
2225
  "dispatch": {
2226
  "x": "ceil(dim(shapes.y, 3) / tunables.WORKGROUP_SIZE_X)",
2227
  "y": "min(ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2240,7 +2116,7 @@
2240
  "name": "MatMulInteger.Batched4",
2241
  "shader": "quant-matmul-accumulate-rank4.wgsl.jinja",
2242
  "derive": { "outputToScratch": false },
2243
- "bindings": ["a_2", "b", "y", "params_6"],
2244
  "dispatch": {
2245
  "x": "ceil(dim(shapes.y, 3) / tunables.WORKGROUP_SIZE_X)",
2246
  "y": "min(ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
@@ -2258,8 +2134,6 @@
2258
  "hasAZero": true,
2259
  "hasBZero": true,
2260
  "bZeroPerColumn": false,
2261
- "requant": "\"none\"",
2262
- "scaleScalar": "\"f32\"",
2263
  "tileM": 8,
2264
  "tileN": 64,
2265
  "ktWords": 32
@@ -2269,7 +2143,7 @@
2269
  "id": "main",
2270
  "name": "MatMulInteger.Dp4aBatched3x3",
2271
  "shader": "quant-dp4a-matmul.wgsl.jinja",
2272
- "bindings": ["a_3", "b", "a_zero_point", "b_zero_point", "y", "params_7"],
2273
  "dispatch": { "x": "ceil(dim(shapes.y, 2) / 64)", "y": "ceil(dim(shapes.y, 1) / 8)", "z": "dim(shapes.y, 0)" }
2274
  }
2275
  ]
@@ -2283,8 +2157,6 @@
2283
  "hasAZero": true,
2284
  "hasBZero": true,
2285
  "bZeroPerColumn": false,
2286
- "requant": "\"none\"",
2287
- "scaleScalar": "\"f32\"",
2288
  "tileM": 8,
2289
  "tileN": 64,
2290
  "ktWords": 32
@@ -2294,7 +2166,7 @@
2294
  "id": "main",
2295
  "name": "MatMulInteger.Dp4aBatched4Scalar",
2296
  "shader": "quant-dp4a-matmul.wgsl.jinja",
2297
- "bindings": ["a_3", "b", "a_zero_point", "b_zero_point", "y", "params_8"],
2298
  "dispatch": {
2299
  "x": "ceil(dim(shapes.y, 3) / 64)",
2300
  "y": "ceil(dim(shapes.y, 2) / 8)",
@@ -2312,8 +2184,6 @@
2312
  "hasAZero": false,
2313
  "hasBZero": false,
2314
  "bZeroPerColumn": false,
2315
- "requant": "\"none\"",
2316
- "scaleScalar": "\"f32\"",
2317
  "tileM": 8,
2318
  "tileN": 64,
2319
  "ktWords": 32
@@ -2323,7 +2193,7 @@
2323
  "id": "main",
2324
  "name": "MatMulInteger.Dp4aBatched4NoZero",
2325
  "shader": "quant-dp4a-matmul.wgsl.jinja",
2326
- "bindings": ["a_3", "b", "y", "params_8"],
2327
  "dispatch": {
2328
  "x": "ceil(dim(shapes.y, 3) / 64)",
2329
  "y": "ceil(dim(shapes.y, 2) / 8)",
 
44
  "EXACT_MATRIX_MIN_INVOCATIONS": { "default": 16384 }
45
  },
46
  "derive": {
47
+ "precastRows": "dim(shapes.a, 0)",
48
+ "precastContraction": "dim(shapes.a, 1)",
49
+ "precastCols": "dim(shapes.b, 1)",
50
+ "precastBatches": 1,
51
+ "sgmatTileRows": "dim(shapes.a, 0)",
52
+ "aUnsigned": "tensorDtypes.a == \"uint8\"",
53
+ "bUnsigned": "tensorDtypes.b == \"uint8\"",
54
+ "aZeroPerRow": false,
55
  "deviceWorkgroupCap": "min(device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX)",
56
  "wave32Adapter": "has(device.adapterInfo, \"subgroupMinSize\") and has(device.adapterInfo, \"subgroupMaxSize\") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",
57
  "canPinSubgroupSize32": "device.features.has(\"subgroups\") and device.features.has(\"subgroup-size-control\") and has(device.adapterInfo, \"subgroupMinSize\") and has(device.adapterInfo, \"subgroupMaxSize\") and device.adapterInfo.subgroupMinSize <= 32 and device.adapterInfo.subgroupMaxSize >= 32",
58
  "pinSubgroupSize32": "canPinSubgroupSize32 and not wave32Adapter",
59
  "wave32Effective": "wave32Adapter or pinSubgroupSize32",
60
+ "variableSubgroup16To32": "device.features.has(\"subgroups\") and has(device.adapterInfo, \"subgroupMinSize\") and has(device.adapterInfo, \"subgroupMaxSize\") and device.adapterInfo.subgroupMinSize == 16 and device.adapterInfo.subgroupMaxSize == 32",
61
  "sgmatTileN": "64",
62
  "sgmatTileK": "32",
63
  "sgmatColumnGroups": "2",
64
  "sgmatStorageRowGroups": "floor((device.limits.maxComputeWorkgroupStorageSize - sgmatTileN * sgmatTileK * 4) / (16 * sgmatTileK * 4))",
65
+ "sgmatRowGroups": "max(1, min(4, floor(deviceWorkgroupCap / (32 * sgmatColumnGroups)), sgmatStorageRowGroups, max(floor(sgmatStorageRowGroups / 2), floor(sgmatTileRows / 16))))",
66
  "sgmatTileM": "16 * sgmatRowGroups",
67
  "sgmatSubgroups": "sgmatRowGroups * sgmatColumnGroups",
68
  "sgmatWorkgroup": "32 * sgmatSubgroups",
 
71
  "sgmatReuseStaging": "sgmatStagingBytes + sgmatScratchBytes > device.limits.maxComputeWorkgroupStorageSize",
72
  "sgmatSharedBytes": "sgmatStagingBytes + (0 if sgmatReuseStaging else sgmatScratchBytes)",
73
  "sgmatDeviceOk": "sgmatWorkgroup <= deviceWorkgroupCap and sgmatSharedBytes <= device.limits.maxComputeWorkgroupStorageSize",
74
+ "precastSubgroups": "max(1, min(4, ceilDiv(precastRows, 16), floor(deviceWorkgroupCap / 32), floor(device.limits.maxComputeWorkgroupStorageSize / (8 * 64 * 4))))",
75
  "precastTileM": "16 * precastSubgroups",
76
  "precastTileN": "4 * 8",
77
  "precastTileK": "4 * 8",
78
  "precastWorkgroup": "32 * precastSubgroups",
79
+ "preparedK": "ceilDiv(precastContraction, precastTileK) * precastTileK",
80
+ "preparedN": "ceilDiv(precastCols, precastTileN) * precastTileN",
81
+ "preparedElements": "ceilDiv(precastRows, precastTileM) * precastTileM * preparedK",
82
+ "preparedBElements": "precastBatches * preparedK * preparedN",
83
  "prepareWorkgroup": "min(256, deviceWorkgroupCap)",
84
  "prepareTotalElements": "preparedElements + preparedBElements",
85
  "prepareGroups": "ceilDiv(prepareTotalElements, 4 * prepareWorkgroup)",
86
  "prepareDispatchElements": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535)) * min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535)) * prepareWorkgroup * 4",
87
  "precastResourcesOk": "deviceWorkgroupCap >= precastWorkgroup and precastSubgroups * 8 * 64 * 4 <= device.limits.maxComputeWorkgroupStorageSize",
88
+ "precastDispatchOk": "prepareTotalElements <= 4294967295 and prepareDispatchElements <= 4294967296 and ceilDiv(precastCols, precastTileN) <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535) and ceilDiv(precastRows, precastTileM) <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535) and prepareGroups <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535) * min(device.limits.maxComputeWorkgroupsPerDimension, 65535)",
89
  "precastF32BuffersOk": "preparedElements * 4 <= device.limits.maxStorageBufferBindingSize and preparedElements * 4 <= device.limits.maxBufferSize and preparedBElements * 4 <= device.limits.maxStorageBufferBindingSize and preparedBElements * 4 <= device.limits.maxBufferSize",
90
  "precastF16BuffersOk": "preparedElements * 2 <= device.limits.maxStorageBufferBindingSize and preparedElements * 2 <= device.limits.maxBufferSize and preparedBElements * 2 <= device.limits.maxStorageBufferBindingSize and preparedBElements * 2 <= device.limits.maxBufferSize",
91
  "precastWorthwhile": "dim(shapes.a, 0) >= 16 and dim(shapes.b, 1) >= 32 and dim(shapes.a, 1) >= 32 and floor(dim(shapes.a, 0) / 16) * floor(dim(shapes.b, 1) / 32) * 32 >= tunables.EXACT_MATRIX_MIN_INVOCATIONS",
92
  "portableWorkgroupCols": 16,
93
+ "portableWorkgroupRows": "pow2ceil(min(16, max(4, pow2ceil(ceilDiv(precastRows, 4))), floor(deviceWorkgroupCap / portableWorkgroupCols), device.limits.maxComputeWorkgroupSizeY) + 1) / 2",
94
  "portableTileM": "4 * portableWorkgroupRows",
95
  "portableTileN": "4 * portableWorkgroupCols",
96
  "portableTileK": 32,
97
  "portablePartialK": "floor(16777216 / (255 * 255) / portableTileK) * portableTileK",
98
+ "portableGeometryOk": "portableWorkgroupRows >= 4 and portableWorkgroupCols <= device.limits.maxComputeWorkgroupSizeX and portablePartialK >= portableTileK and ceilDiv(precastRows, portableTileM) <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535)",
99
  "rank2MatMulShapeOk": "ranks.a == 2 and ranks.b == 2 and ranks.y == 2 and dim(shapes.a, 1) == dim(shapes.b, 0) and dim(shapes.y, 0) == dim(shapes.a, 0) and dim(shapes.y, 1) == dim(shapes.b, 1)",
100
  "rank3ByRank3ShapeOk": "ranks.a == 3 and ranks.b == 3 and ranks.y == 3 and dim(shapes.a, 2) == dim(shapes.b, 1) and dim(shapes.y, 0) == max(dim(shapes.a, 0), dim(shapes.b, 0)) and (dim(shapes.a, 0) == dim(shapes.y, 0) or dim(shapes.a, 0) == 1) and (dim(shapes.b, 0) == dim(shapes.y, 0) or dim(shapes.b, 0) == 1) and dim(shapes.y, 1) == dim(shapes.a, 1) and dim(shapes.y, 2) == dim(shapes.b, 2)",
101
  "rank3ByRank2ShapeOk": "ranks.a == 3 and ranks.b == 2 and ranks.y == 3 and dim(shapes.a, 2) == dim(shapes.b, 0) and dim(shapes.y, 0) == dim(shapes.a, 0) and dim(shapes.y, 1) == dim(shapes.a, 1) and dim(shapes.y, 2) == dim(shapes.b, 1)",
 
108
  "requiredScalarBZeroOk": "present.b_zero_point and scalarBZeroOk",
109
  "rank2PerColumnBZeroOk": "ranks.b_zero_point == 1 and dim(shapes.b_zero_point, 0) == dim(shapes.y, 1)",
110
  "rank2Dp4aLargePrefill": "ranks.y == 2 and ranks.a == 2 and dim(shapes.y, 0) >= tunables.DP4A_LARGE_MIN_M and dim(shapes.y, 1) >= tunables.DP4A_LARGE_MIN_N and dim(shapes.a, 1) >= tunables.DP4A_LARGE_MIN_K",
111
+ "perColumnDp4aUseNarrowTile": "variableSubgroup16To32 and rank2Dp4aLargePrefill and not present.a_zero_point",
112
  "rank2Dp4aWideShortK": "ranks.y == 2 and ranks.a == 2 and dim(shapes.y, 0) >= tunables.DP4A_SHORT_K_MIN_MN and dim(shapes.y, 1) >= tunables.DP4A_SHORT_K_MIN_MN and dim(shapes.a, 1) <= tunables.DP4A_SHORT_K_MAX",
113
  "rank2Dp4aMediumK": "ranks.y == 2 and ranks.a == 2 and dim(shapes.y, 0) >= tunables.DP4A_MEDIUM_K_MIN_MN and dim(shapes.y, 1) >= tunables.DP4A_MEDIUM_K_MIN_MN and dim(shapes.a, 1) > tunables.DP4A_SHORT_K_MAX and dim(shapes.a, 1) <= tunables.DP4A_MEDIUM_K_MAX",
114
  "rank2Dp4aTileM": "1 if ranks.y < 2 or dim(shapes.y, 0) == 1 else (tunables.DP4A_SHORT_K_TILE_M if rank2Dp4aWideShortK else (tunables.DP4A_MEDIUM_K_TILE_M if rank2Dp4aMediumK else (tunables.DP4A_LARGE_TILE_M if rank2Dp4aLargePrefill else tunables.DP4A_TILE_M)))",
 
137
  "rank4YBatchStride": "dim(shapes.y, 2) * dim(shapes.y, 3) if ranks.y >= 4 else 1",
138
  "aScalar": "\"u32\" if tensorDtypes.a == \"uint8\" else \"i32\"",
139
  "bScalar": "\"u32\" if tensorDtypes.b == \"uint8\" else \"i32\"",
 
 
 
 
140
  "sgmatM": "matrixM",
141
  "sgmatN": "matrixN",
142
  "sgmatK": "matrixK",
143
  "sgmatDispatchOk": "ceilDiv(sgmatN, sgmatTileN) <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535) and ceilDiv(sgmatM, sgmatTileM) <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535)",
144
  "sgmatParallelInvocations": "floor(sgmatM / sgmatTileM) * floor(sgmatN / sgmatTileN) * sgmatWorkgroup",
145
+ "sgmatWorthwhile": "sgmatM >= sgmatTileM and sgmatN >= sgmatTileN / 2 and sgmatK >= sgmatTileK and sgmatParallelInvocations >= tunables.EXACT_MATRIX_MIN_INVOCATIONS",
146
+ "preferPackedDot": "variableSubgroup16To32 and device.wgslLanguageFeatures.has(\"packed_4x8_integer_dot_product\") and rank2MatMulShapeOk and rank2Dp4aDispatchOk and device.limits.maxComputeInvocationsPerWorkgroup >= 128 and device.limits.maxComputeWorkgroupSizeX >= 128 and device.limits.maxComputeWorkgroupStorageSize >= 8448 and matrixM >= tunables.DP4A_LARGE_MIN_M and matrixN >= tunables.DP4A_LARGE_MIN_N and matrixK > tunables.DP4A_MEDIUM_K_MAX / 2 and matrixK % 4 == 0 and matrixM * matrixN * matrixK >= 4 * tunables.DP4A_LARGE_MIN_M * tunables.DP4A_LARGE_MIN_N * tunables.DP4A_MEDIUM_K_MAX",
147
+ "tileM": "rank2Dp4aTileM",
148
+ "tileN": "rank2Dp4aTileN",
149
+ "ktWords": "rank2Dp4aKtWords"
150
  },
151
  "bindings": {
152
+ "a": { "elementType": "$aStorage" },
153
+ "b": { "elementType": "$bScalar" },
154
+ "a_zero_point": { "elementType": "$aScalar", "length": 1 },
155
+ "b_zero_point": { "elementType": "$bScalar" },
156
+ "y": { "elementType": "i32" },
157
  "params": {
 
158
  "struct": [
159
  { "name": "M", "type": "u32", "value": "matrixM" },
160
  { "name": "N", "type": "u32", "value": "matrixN" },
 
164
  { "name": "yBatchStride", "type": "u32", "value": 0 }
165
  ]
166
  },
167
+ "a_main": { "name": "a", "elementType": "$aScalar" },
168
+ "a_a_vec4": { "name": "a", "elementType": "$aVec4" },
169
+ "params_main": {
170
  "name": "params",
 
171
  "struct": [
172
  { "name": "M", "type": "u32", "value": "matrixM" },
173
  { "name": "N", "type": "u32", "value": "matrixN" },
174
  { "name": "K", "type": "u32", "value": "matrixK" }
175
  ]
176
  },
177
+ "params_m_n_k": {
178
  "name": "params",
 
179
  "struct": [
180
  { "name": "M", "type": "u32", "value": 1 },
181
  { "name": "N", "type": "u32", "value": 1 },
182
  { "name": "K", "type": "u32", "value": "dim(shapes.a, 0)" }
183
  ]
184
  },
185
+ "params__uniform": {
186
  "name": "params",
 
187
  "struct": [
188
  { "name": "M", "type": "u32", "value": "batchM" },
189
  { "name": "N", "type": "u32", "value": "batchN" },
 
194
  { "name": "batchCount", "type": "u32", "value": "batchCount" }
195
  ]
196
  },
197
+ "params_rank4_no_zero_points": {
198
  "name": "params",
 
199
  "struct": [
200
  { "name": "M", "type": "u32", "value": "rank4M" },
201
  { "name": "N", "type": "u32", "value": "rank4N" },
 
224
  }
225
  ]
226
  },
227
+ "params_quant_dp4a_matmul": {
228
  "name": "params",
 
229
  "struct": [
230
  { "name": "M", "type": "u32", "value": "batchM" },
231
  { "name": "N", "type": "u32", "value": "batchN" },
 
235
  { "name": "yBatchStride", "type": "u32", "value": "batchYStride" }
236
  ]
237
  },
238
+ "params_dp4a_rank4_no_zero_points": {
239
  "name": "params",
 
240
  "struct": [
241
  { "name": "M", "type": "u32", "value": "rank4M" },
242
  { "name": "N", "type": "u32", "value": "rank4N" },
 
252
  "precast_f32_bFloat": { "name": "bFloat", "buffer": "storage", "elementType": "f32" },
253
  "precast_prepare_params": {
254
  "name": "params",
 
255
  "struct": [
256
  { "name": "M", "type": "u32", "value": "sgmatM" },
257
  { "name": "K", "type": "u32", "value": "sgmatK" },
 
293
  "sgmatRowGroups": "precastSubgroups",
294
  "sgmatSubgroups": "precastSubgroups",
295
  "sgmatWorkgroup": "precastWorkgroup",
 
296
  "precastScalar": "\"f16\"",
297
  "hasAZero": false,
298
  "hasBZero": false,
299
+ "bZeroPerColumn": false
 
 
300
  },
301
  "passes": [
302
  {
303
  "id": "prepare",
304
+ "name": "MatMulInteger.ExactPrepareOperands",
305
  "shader": "quant-exact-prepare.wgsl.jinja",
306
+ "bindings": ["a_main", "precast_f16_aFloat", "b", "precast_f16_bFloat", "precast_prepare_params"],
307
  "dispatch": {
308
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
309
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
311
  },
312
  {
313
  "id": "main",
314
+ "name": "MatMulInteger.ExactMultiply",
315
  "shader": "quant-exact-matrix.wgsl.jinja",
316
+ "bindings": ["precast_f16_a", "precast_f16_b", "y", "params_main"],
317
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
318
  }
319
  ],
 
326
  "id": "portable_precast_a0_bnone_f16",
327
  "priority": 39,
328
  "when": ["rank2MatMulShapeOk", "not present.a_zero_point", "not present.b_zero_point", "precastF16BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float16\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f16\" == \"f16\" or sgmatM >= portableTileN"],
329
+ "demoteWhen": ["preferPackedDot"],
330
  "requires": { "features": ["shader-f16"] },
331
  "derive": {
332
  "precastScalar": "\"f16\"",
 
334
  "hasAZero": false,
335
  "hasBZero": false,
336
  "bZeroPerColumn": false,
 
 
337
  "M": "sgmatM",
338
  "N": "sgmatN",
339
  "K": "preparedK",
 
342
  "workgroupRows": "portableWorkgroupRows",
343
  "blockRows": "portableTileM",
344
  "blockCols": "portableTileN",
345
+ "integerPartialK": "portablePartialK"
 
 
 
346
  },
347
  "passes": [
348
  {
349
  "id": "prepare",
350
+ "name": "MatMulInteger.ExactPrepareOperands",
351
  "shader": "quant-exact-prepare.wgsl.jinja",
352
+ "bindings": ["a_main", "precast_f16_aFloat", "b", "precast_f16_bFloat", "precast_prepare_params"],
353
  "dispatch": {
354
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
355
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
357
  },
358
  {
359
  "id": "main",
360
+ "name": "MatMulInteger.ExactPortableMultiply",
361
  "shader": "quant-exact-portable.wgsl.jinja",
362
  "bindings": ["portable_f16_a", "portable_f16_b", "y"],
363
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
 
384
  "sgmatRowGroups": "precastSubgroups",
385
  "sgmatSubgroups": "precastSubgroups",
386
  "sgmatWorkgroup": "precastWorkgroup",
 
387
  "precastScalar": "\"f32\"",
388
  "hasAZero": false,
389
  "hasBZero": false,
390
+ "bZeroPerColumn": false
 
 
391
  },
392
  "passes": [
393
  {
394
  "id": "prepare",
395
+ "name": "MatMulInteger.ExactPrepareOperands",
396
  "shader": "quant-exact-prepare.wgsl.jinja",
397
+ "bindings": ["a_main", "precast_f32_aFloat", "b", "precast_f32_bFloat", "precast_prepare_params"],
398
  "dispatch": {
399
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
400
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
402
  },
403
  {
404
  "id": "main",
405
+ "name": "MatMulInteger.ExactMultiply",
406
  "shader": "quant-exact-matrix.wgsl.jinja",
407
+ "bindings": ["precast_f32_a", "precast_f32_b", "y", "params_main"],
408
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
409
  }
410
  ],
 
417
  "id": "portable_precast_a0_bnone",
418
  "priority": 38,
419
  "when": ["rank2MatMulShapeOk", "not present.a_zero_point", "not present.b_zero_point", "precastF32BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float32\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f32\" == \"f16\" or sgmatM >= portableTileN"],
420
+ "demoteWhen": ["preferPackedDot"],
421
  "requires": { "features": [] },
422
  "derive": {
423
  "precastScalar": "\"f32\"",
 
425
  "hasAZero": false,
426
  "hasBZero": false,
427
  "bZeroPerColumn": false,
 
 
428
  "M": "sgmatM",
429
  "N": "sgmatN",
430
  "K": "preparedK",
 
433
  "workgroupRows": "portableWorkgroupRows",
434
  "blockRows": "portableTileM",
435
  "blockCols": "portableTileN",
436
+ "integerPartialK": "portablePartialK"
 
 
 
437
  },
438
  "passes": [
439
  {
440
  "id": "prepare",
441
+ "name": "MatMulInteger.ExactPrepareOperands",
442
  "shader": "quant-exact-prepare.wgsl.jinja",
443
+ "bindings": ["a_main", "precast_f32_aFloat", "b", "precast_f32_bFloat", "precast_prepare_params"],
444
  "dispatch": {
445
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
446
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
448
  },
449
  {
450
  "id": "main",
451
+ "name": "MatMulInteger.ExactPortableMultiply",
452
  "shader": "quant-exact-portable.wgsl.jinja",
453
  "bindings": ["portable_f32_a", "portable_f32_b", "y"],
454
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
 
475
  "sgmatRowGroups": "precastSubgroups",
476
  "sgmatSubgroups": "precastSubgroups",
477
  "sgmatWorkgroup": "precastWorkgroup",
 
478
  "precastScalar": "\"f16\"",
479
  "hasAZero": false,
480
  "hasBZero": true,
481
+ "bZeroPerColumn": false
 
 
482
  },
483
  "passes": [
484
  {
485
  "id": "prepare",
486
+ "name": "MatMulInteger.ExactPrepareOperands",
487
  "shader": "quant-exact-prepare.wgsl.jinja",
488
+ "bindings": ["a_main", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
489
  "dispatch": {
490
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
491
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
493
  },
494
  {
495
  "id": "main",
496
+ "name": "MatMulInteger.ExactMultiply",
497
  "shader": "quant-exact-matrix.wgsl.jinja",
498
+ "bindings": ["precast_f16_a", "precast_f16_b", "b_zero_point", "y", "params_main"],
499
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
500
  }
501
  ],
 
508
  "id": "portable_precast_a0_bscalar_f16",
509
  "priority": 39,
510
  "when": ["rank2MatMulShapeOk", "not present.a_zero_point", "requiredScalarBZeroOk", "precastF16BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float16\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f16\" == \"f16\" or sgmatM >= portableTileN"],
511
+ "demoteWhen": ["preferPackedDot"],
512
  "requires": { "features": ["shader-f16"] },
513
  "derive": {
514
  "precastScalar": "\"f16\"",
 
516
  "hasAZero": false,
517
  "hasBZero": true,
518
  "bZeroPerColumn": false,
 
 
519
  "M": "sgmatM",
520
  "N": "sgmatN",
521
  "K": "preparedK",
 
524
  "workgroupRows": "portableWorkgroupRows",
525
  "blockRows": "portableTileM",
526
  "blockCols": "portableTileN",
527
+ "integerPartialK": "portablePartialK"
 
 
 
528
  },
529
  "passes": [
530
  {
531
  "id": "prepare",
532
+ "name": "MatMulInteger.ExactPrepareOperands",
533
  "shader": "quant-exact-prepare.wgsl.jinja",
534
+ "bindings": ["a_main", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
535
  "dispatch": {
536
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
537
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
539
  },
540
  {
541
  "id": "main",
542
+ "name": "MatMulInteger.ExactPortableMultiply",
543
  "shader": "quant-exact-portable.wgsl.jinja",
544
  "bindings": ["portable_f16_a", "portable_f16_b", "y"],
545
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
 
566
  "sgmatRowGroups": "precastSubgroups",
567
  "sgmatSubgroups": "precastSubgroups",
568
  "sgmatWorkgroup": "precastWorkgroup",
 
569
  "precastScalar": "\"f32\"",
570
  "hasAZero": false,
571
  "hasBZero": true,
572
+ "bZeroPerColumn": false
 
 
573
  },
574
  "passes": [
575
  {
576
  "id": "prepare",
577
+ "name": "MatMulInteger.ExactPrepareOperands",
578
  "shader": "quant-exact-prepare.wgsl.jinja",
579
+ "bindings": ["a_main", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
580
  "dispatch": {
581
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
582
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
584
  },
585
  {
586
  "id": "main",
587
+ "name": "MatMulInteger.ExactMultiply",
588
  "shader": "quant-exact-matrix.wgsl.jinja",
589
+ "bindings": ["precast_f32_a", "precast_f32_b", "b_zero_point", "y", "params_main"],
590
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
591
  }
592
  ],
 
599
  "id": "portable_precast_a0_bscalar",
600
  "priority": 38,
601
  "when": ["rank2MatMulShapeOk", "not present.a_zero_point", "requiredScalarBZeroOk", "precastF32BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float32\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f32\" == \"f16\" or sgmatM >= portableTileN"],
602
+ "demoteWhen": ["preferPackedDot"],
603
  "requires": { "features": [] },
604
  "derive": {
605
  "precastScalar": "\"f32\"",
 
607
  "hasAZero": false,
608
  "hasBZero": true,
609
  "bZeroPerColumn": false,
 
 
610
  "M": "sgmatM",
611
  "N": "sgmatN",
612
  "K": "preparedK",
 
615
  "workgroupRows": "portableWorkgroupRows",
616
  "blockRows": "portableTileM",
617
  "blockCols": "portableTileN",
618
+ "integerPartialK": "portablePartialK"
 
 
 
619
  },
620
  "passes": [
621
  {
622
  "id": "prepare",
623
+ "name": "MatMulInteger.ExactPrepareOperands",
624
  "shader": "quant-exact-prepare.wgsl.jinja",
625
+ "bindings": ["a_main", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
626
  "dispatch": {
627
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
628
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
630
  },
631
  {
632
  "id": "main",
633
+ "name": "MatMulInteger.ExactPortableMultiply",
634
  "shader": "quant-exact-portable.wgsl.jinja",
635
  "bindings": ["portable_f32_a", "portable_f32_b", "y"],
636
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
 
657
  "sgmatRowGroups": "precastSubgroups",
658
  "sgmatSubgroups": "precastSubgroups",
659
  "sgmatWorkgroup": "precastWorkgroup",
 
660
  "precastScalar": "\"f16\"",
661
  "hasAZero": false,
662
  "hasBZero": true,
663
+ "bZeroPerColumn": true
 
 
664
  },
665
  "passes": [
666
  {
667
  "id": "prepare",
668
+ "name": "MatMulInteger.ExactPrepareOperands",
669
  "shader": "quant-exact-prepare.wgsl.jinja",
670
+ "bindings": ["a_main", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
671
  "dispatch": {
672
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
673
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
675
  },
676
  {
677
  "id": "main",
678
+ "name": "MatMulInteger.ExactMultiply",
679
  "shader": "quant-exact-matrix.wgsl.jinja",
680
+ "bindings": ["precast_f16_a", "precast_f16_b", "y", "params_main"],
681
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
682
  }
683
  ],
 
690
  "id": "portable_precast_a0_bcolumn_f16",
691
  "priority": 39,
692
  "when": ["rank2MatMulShapeOk", "not present.a_zero_point", "present.b_zero_point and rank2PerColumnBZeroOk", "precastF16BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float16\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f16\" == \"f16\" or sgmatM >= portableTileN"],
693
+ "demoteWhen": ["preferPackedDot"],
694
  "requires": { "features": ["shader-f16"] },
695
  "derive": {
696
  "precastScalar": "\"f16\"",
 
698
  "hasAZero": false,
699
  "hasBZero": true,
700
  "bZeroPerColumn": true,
 
 
701
  "M": "sgmatM",
702
  "N": "sgmatN",
703
  "K": "preparedK",
 
706
  "workgroupRows": "portableWorkgroupRows",
707
  "blockRows": "portableTileM",
708
  "blockCols": "portableTileN",
709
+ "integerPartialK": "portablePartialK"
 
 
 
710
  },
711
  "passes": [
712
  {
713
  "id": "prepare",
714
+ "name": "MatMulInteger.ExactPrepareOperands",
715
  "shader": "quant-exact-prepare.wgsl.jinja",
716
+ "bindings": ["a_main", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
717
  "dispatch": {
718
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
719
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
721
  },
722
  {
723
  "id": "main",
724
+ "name": "MatMulInteger.ExactPortableMultiply",
725
  "shader": "quant-exact-portable.wgsl.jinja",
726
  "bindings": ["portable_f16_a", "portable_f16_b", "y"],
727
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
 
748
  "sgmatRowGroups": "precastSubgroups",
749
  "sgmatSubgroups": "precastSubgroups",
750
  "sgmatWorkgroup": "precastWorkgroup",
 
751
  "precastScalar": "\"f32\"",
752
  "hasAZero": false,
753
  "hasBZero": true,
754
+ "bZeroPerColumn": true
 
 
755
  },
756
  "passes": [
757
  {
758
  "id": "prepare",
759
+ "name": "MatMulInteger.ExactPrepareOperands",
760
  "shader": "quant-exact-prepare.wgsl.jinja",
761
+ "bindings": ["a_main", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
762
  "dispatch": {
763
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
764
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
766
  },
767
  {
768
  "id": "main",
769
+ "name": "MatMulInteger.ExactMultiply",
770
  "shader": "quant-exact-matrix.wgsl.jinja",
771
+ "bindings": ["precast_f32_a", "precast_f32_b", "y", "params_main"],
772
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
773
  }
774
  ],
 
781
  "id": "portable_precast_a0_bcolumn",
782
  "priority": 38,
783
  "when": ["rank2MatMulShapeOk", "not present.a_zero_point", "present.b_zero_point and rank2PerColumnBZeroOk", "precastF32BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float32\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f32\" == \"f16\" or sgmatM >= portableTileN"],
784
+ "demoteWhen": ["preferPackedDot"],
785
  "requires": { "features": [] },
786
  "derive": {
787
  "precastScalar": "\"f32\"",
 
789
  "hasAZero": false,
790
  "hasBZero": true,
791
  "bZeroPerColumn": true,
 
 
792
  "M": "sgmatM",
793
  "N": "sgmatN",
794
  "K": "preparedK",
 
797
  "workgroupRows": "portableWorkgroupRows",
798
  "blockRows": "portableTileM",
799
  "blockCols": "portableTileN",
800
+ "integerPartialK": "portablePartialK"
 
 
 
801
  },
802
  "passes": [
803
  {
804
  "id": "prepare",
805
+ "name": "MatMulInteger.ExactPrepareOperands",
806
  "shader": "quant-exact-prepare.wgsl.jinja",
807
+ "bindings": ["a_main", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
808
  "dispatch": {
809
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
810
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
812
  },
813
  {
814
  "id": "main",
815
+ "name": "MatMulInteger.ExactPortableMultiply",
816
  "shader": "quant-exact-portable.wgsl.jinja",
817
  "bindings": ["portable_f32_a", "portable_f32_b", "y"],
818
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
 
839
  "sgmatRowGroups": "precastSubgroups",
840
  "sgmatSubgroups": "precastSubgroups",
841
  "sgmatWorkgroup": "precastWorkgroup",
 
842
  "precastScalar": "\"f16\"",
843
  "hasAZero": true,
844
  "hasBZero": false,
845
+ "bZeroPerColumn": false
 
 
846
  },
847
  "passes": [
848
  {
849
  "id": "prepare",
850
+ "name": "MatMulInteger.ExactPrepareOperands",
851
  "shader": "quant-exact-prepare.wgsl.jinja",
852
+ "bindings": ["a_main", "a_zero_point", "precast_f16_aFloat", "b", "precast_f16_bFloat", "precast_prepare_params"],
853
  "dispatch": {
854
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
855
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
857
  },
858
  {
859
  "id": "main",
860
+ "name": "MatMulInteger.ExactMultiply",
861
  "shader": "quant-exact-matrix.wgsl.jinja",
862
+ "bindings": ["precast_f16_a", "precast_f16_b", "a_zero_point", "y", "params_main"],
863
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
864
  }
865
  ],
 
872
  "id": "portable_precast_a1_bnone_f16",
873
  "priority": 39,
874
  "when": ["rank2MatMulShapeOk", "requiredScalarAZeroOk", "not present.b_zero_point", "precastF16BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float16\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f16\" == \"f16\" or sgmatM >= portableTileN"],
875
+ "demoteWhen": ["preferPackedDot"],
876
  "requires": { "features": ["shader-f16"] },
877
  "derive": {
878
  "precastScalar": "\"f16\"",
 
880
  "hasAZero": true,
881
  "hasBZero": false,
882
  "bZeroPerColumn": false,
 
 
883
  "M": "sgmatM",
884
  "N": "sgmatN",
885
  "K": "preparedK",
 
888
  "workgroupRows": "portableWorkgroupRows",
889
  "blockRows": "portableTileM",
890
  "blockCols": "portableTileN",
891
+ "integerPartialK": "portablePartialK"
 
 
 
892
  },
893
  "passes": [
894
  {
895
  "id": "prepare",
896
+ "name": "MatMulInteger.ExactPrepareOperands",
897
  "shader": "quant-exact-prepare.wgsl.jinja",
898
+ "bindings": ["a_main", "a_zero_point", "precast_f16_aFloat", "b", "precast_f16_bFloat", "precast_prepare_params"],
899
  "dispatch": {
900
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
901
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
903
  },
904
  {
905
  "id": "main",
906
+ "name": "MatMulInteger.ExactPortableMultiply",
907
  "shader": "quant-exact-portable.wgsl.jinja",
908
  "bindings": ["portable_f16_a", "portable_f16_b", "y"],
909
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
 
930
  "sgmatRowGroups": "precastSubgroups",
931
  "sgmatSubgroups": "precastSubgroups",
932
  "sgmatWorkgroup": "precastWorkgroup",
 
933
  "precastScalar": "\"f32\"",
934
  "hasAZero": true,
935
  "hasBZero": false,
936
+ "bZeroPerColumn": false
 
 
937
  },
938
  "passes": [
939
  {
940
  "id": "prepare",
941
+ "name": "MatMulInteger.ExactPrepareOperands",
942
  "shader": "quant-exact-prepare.wgsl.jinja",
943
+ "bindings": ["a_main", "a_zero_point", "precast_f32_aFloat", "b", "precast_f32_bFloat", "precast_prepare_params"],
944
  "dispatch": {
945
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
946
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
948
  },
949
  {
950
  "id": "main",
951
+ "name": "MatMulInteger.ExactMultiply",
952
  "shader": "quant-exact-matrix.wgsl.jinja",
953
+ "bindings": ["precast_f32_a", "precast_f32_b", "a_zero_point", "y", "params_main"],
954
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
955
  }
956
  ],
 
963
  "id": "portable_precast_a1_bnone",
964
  "priority": 38,
965
  "when": ["rank2MatMulShapeOk", "requiredScalarAZeroOk", "not present.b_zero_point", "precastF32BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float32\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f32\" == \"f16\" or sgmatM >= portableTileN"],
966
+ "demoteWhen": ["preferPackedDot"],
967
  "requires": { "features": [] },
968
  "derive": {
969
  "precastScalar": "\"f32\"",
 
971
  "hasAZero": true,
972
  "hasBZero": false,
973
  "bZeroPerColumn": false,
 
 
974
  "M": "sgmatM",
975
  "N": "sgmatN",
976
  "K": "preparedK",
 
979
  "workgroupRows": "portableWorkgroupRows",
980
  "blockRows": "portableTileM",
981
  "blockCols": "portableTileN",
982
+ "integerPartialK": "portablePartialK"
 
 
 
983
  },
984
  "passes": [
985
  {
986
  "id": "prepare",
987
+ "name": "MatMulInteger.ExactPrepareOperands",
988
  "shader": "quant-exact-prepare.wgsl.jinja",
989
+ "bindings": ["a_main", "a_zero_point", "precast_f32_aFloat", "b", "precast_f32_bFloat", "precast_prepare_params"],
990
  "dispatch": {
991
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
992
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
994
  },
995
  {
996
  "id": "main",
997
+ "name": "MatMulInteger.ExactPortableMultiply",
998
  "shader": "quant-exact-portable.wgsl.jinja",
999
  "bindings": ["portable_f32_a", "portable_f32_b", "y"],
1000
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
 
1021
  "sgmatRowGroups": "precastSubgroups",
1022
  "sgmatSubgroups": "precastSubgroups",
1023
  "sgmatWorkgroup": "precastWorkgroup",
 
1024
  "precastScalar": "\"f16\"",
1025
  "hasAZero": true,
1026
  "hasBZero": true,
1027
+ "bZeroPerColumn": false
 
 
1028
  },
1029
  "passes": [
1030
  {
1031
  "id": "prepare",
1032
+ "name": "MatMulInteger.ExactPrepareOperands",
1033
  "shader": "quant-exact-prepare.wgsl.jinja",
1034
+ "bindings": ["a_main", "a_zero_point", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
1035
  "dispatch": {
1036
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1037
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
1039
  },
1040
  {
1041
  "id": "main",
1042
+ "name": "MatMulInteger.ExactMultiply",
1043
  "shader": "quant-exact-matrix.wgsl.jinja",
1044
+ "bindings": ["precast_f16_a", "precast_f16_b", "a_zero_point", "b_zero_point", "y", "params_main"],
1045
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
1046
  }
1047
  ],
 
1054
  "id": "portable_precast_a1_bscalar_f16",
1055
  "priority": 39,
1056
  "when": ["rank2MatMulShapeOk", "requiredScalarAZeroOk", "requiredScalarBZeroOk", "precastF16BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float16\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f16\" == \"f16\" or sgmatM >= portableTileN"],
1057
+ "demoteWhen": ["preferPackedDot"],
1058
  "requires": { "features": ["shader-f16"] },
1059
  "derive": {
1060
  "precastScalar": "\"f16\"",
 
1062
  "hasAZero": true,
1063
  "hasBZero": true,
1064
  "bZeroPerColumn": false,
 
 
1065
  "M": "sgmatM",
1066
  "N": "sgmatN",
1067
  "K": "preparedK",
 
1070
  "workgroupRows": "portableWorkgroupRows",
1071
  "blockRows": "portableTileM",
1072
  "blockCols": "portableTileN",
1073
+ "integerPartialK": "portablePartialK"
 
 
 
1074
  },
1075
  "passes": [
1076
  {
1077
  "id": "prepare",
1078
+ "name": "MatMulInteger.ExactPrepareOperands",
1079
  "shader": "quant-exact-prepare.wgsl.jinja",
1080
+ "bindings": ["a_main", "a_zero_point", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
1081
  "dispatch": {
1082
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1083
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
1085
  },
1086
  {
1087
  "id": "main",
1088
+ "name": "MatMulInteger.ExactPortableMultiply",
1089
  "shader": "quant-exact-portable.wgsl.jinja",
1090
  "bindings": ["portable_f16_a", "portable_f16_b", "y"],
1091
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
 
1112
  "sgmatRowGroups": "precastSubgroups",
1113
  "sgmatSubgroups": "precastSubgroups",
1114
  "sgmatWorkgroup": "precastWorkgroup",
 
1115
  "precastScalar": "\"f32\"",
1116
  "hasAZero": true,
1117
  "hasBZero": true,
1118
+ "bZeroPerColumn": false
 
 
1119
  },
1120
  "passes": [
1121
  {
1122
  "id": "prepare",
1123
+ "name": "MatMulInteger.ExactPrepareOperands",
1124
  "shader": "quant-exact-prepare.wgsl.jinja",
1125
+ "bindings": ["a_main", "a_zero_point", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
1126
  "dispatch": {
1127
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1128
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
1130
  },
1131
  {
1132
  "id": "main",
1133
+ "name": "MatMulInteger.ExactMultiply",
1134
  "shader": "quant-exact-matrix.wgsl.jinja",
1135
+ "bindings": ["precast_f32_a", "precast_f32_b", "a_zero_point", "b_zero_point", "y", "params_main"],
1136
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
1137
  }
1138
  ],
 
1145
  "id": "portable_precast_a1_bscalar",
1146
  "priority": 38,
1147
  "when": ["rank2MatMulShapeOk", "requiredScalarAZeroOk", "requiredScalarBZeroOk", "precastF32BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float32\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f32\" == \"f16\" or sgmatM >= portableTileN"],
1148
+ "demoteWhen": ["preferPackedDot"],
1149
  "requires": { "features": [] },
1150
  "derive": {
1151
  "precastScalar": "\"f32\"",
 
1153
  "hasAZero": true,
1154
  "hasBZero": true,
1155
  "bZeroPerColumn": false,
 
 
1156
  "M": "sgmatM",
1157
  "N": "sgmatN",
1158
  "K": "preparedK",
 
1161
  "workgroupRows": "portableWorkgroupRows",
1162
  "blockRows": "portableTileM",
1163
  "blockCols": "portableTileN",
1164
+ "integerPartialK": "portablePartialK"
 
 
 
1165
  },
1166
  "passes": [
1167
  {
1168
  "id": "prepare",
1169
+ "name": "MatMulInteger.ExactPrepareOperands",
1170
  "shader": "quant-exact-prepare.wgsl.jinja",
1171
+ "bindings": ["a_main", "a_zero_point", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
1172
  "dispatch": {
1173
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1174
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
1176
  },
1177
  {
1178
  "id": "main",
1179
+ "name": "MatMulInteger.ExactPortableMultiply",
1180
  "shader": "quant-exact-portable.wgsl.jinja",
1181
  "bindings": ["portable_f32_a", "portable_f32_b", "y"],
1182
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
 
1203
  "sgmatRowGroups": "precastSubgroups",
1204
  "sgmatSubgroups": "precastSubgroups",
1205
  "sgmatWorkgroup": "precastWorkgroup",
 
1206
  "precastScalar": "\"f16\"",
1207
  "hasAZero": true,
1208
  "hasBZero": true,
1209
+ "bZeroPerColumn": true
 
 
1210
  },
1211
  "passes": [
1212
  {
1213
  "id": "prepare",
1214
+ "name": "MatMulInteger.ExactPrepareOperands",
1215
  "shader": "quant-exact-prepare.wgsl.jinja",
1216
+ "bindings": ["a_main", "a_zero_point", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
1217
  "dispatch": {
1218
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1219
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
1221
  },
1222
  {
1223
  "id": "main",
1224
+ "name": "MatMulInteger.ExactMultiply",
1225
  "shader": "quant-exact-matrix.wgsl.jinja",
1226
+ "bindings": ["precast_f16_a", "precast_f16_b", "a_zero_point", "y", "params_main"],
1227
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
1228
  }
1229
  ],
 
1236
  "id": "portable_precast_a1_bcolumn_f16",
1237
  "priority": 39,
1238
  "when": ["rank2MatMulShapeOk", "requiredScalarAZeroOk", "present.b_zero_point and rank2PerColumnBZeroOk", "precastF16BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float16\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f16\" == \"f16\" or sgmatM >= portableTileN"],
1239
+ "demoteWhen": ["preferPackedDot"],
1240
  "requires": { "features": ["shader-f16"] },
1241
  "derive": {
1242
  "precastScalar": "\"f16\"",
 
1244
  "hasAZero": true,
1245
  "hasBZero": true,
1246
  "bZeroPerColumn": true,
 
 
1247
  "M": "sgmatM",
1248
  "N": "sgmatN",
1249
  "K": "preparedK",
 
1252
  "workgroupRows": "portableWorkgroupRows",
1253
  "blockRows": "portableTileM",
1254
  "blockCols": "portableTileN",
1255
+ "integerPartialK": "portablePartialK"
 
 
 
1256
  },
1257
  "passes": [
1258
  {
1259
  "id": "prepare",
1260
+ "name": "MatMulInteger.ExactPrepareOperands",
1261
  "shader": "quant-exact-prepare.wgsl.jinja",
1262
+ "bindings": ["a_main", "a_zero_point", "precast_f16_aFloat", "b", "b_zero_point", "precast_f16_bFloat", "precast_prepare_params"],
1263
  "dispatch": {
1264
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1265
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
1267
  },
1268
  {
1269
  "id": "main",
1270
+ "name": "MatMulInteger.ExactPortableMultiply",
1271
  "shader": "quant-exact-portable.wgsl.jinja",
1272
  "bindings": ["portable_f16_a", "portable_f16_b", "y"],
1273
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
 
1294
  "sgmatRowGroups": "precastSubgroups",
1295
  "sgmatSubgroups": "precastSubgroups",
1296
  "sgmatWorkgroup": "precastWorkgroup",
 
1297
  "precastScalar": "\"f32\"",
1298
  "hasAZero": true,
1299
  "hasBZero": true,
1300
+ "bZeroPerColumn": true
 
 
1301
  },
1302
  "passes": [
1303
  {
1304
  "id": "prepare",
1305
+ "name": "MatMulInteger.ExactPrepareOperands",
1306
  "shader": "quant-exact-prepare.wgsl.jinja",
1307
+ "bindings": ["a_main", "a_zero_point", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
1308
  "dispatch": {
1309
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1310
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
1312
  },
1313
  {
1314
  "id": "main",
1315
+ "name": "MatMulInteger.ExactMultiply",
1316
  "shader": "quant-exact-matrix.wgsl.jinja",
1317
+ "bindings": ["precast_f32_a", "precast_f32_b", "a_zero_point", "y", "params_main"],
1318
  "dispatch": { "x": "ceilDiv(sgmatN, sgmatTileN)", "y": "ceilDiv(sgmatM, sgmatTileM)" }
1319
  }
1320
  ],
 
1327
  "id": "portable_precast_a1_bcolumn",
1328
  "priority": 38,
1329
  "when": ["rank2MatMulShapeOk", "requiredScalarAZeroOk", "present.b_zero_point and rank2PerColumnBZeroOk", "precastF32BuffersOk", "precastDispatchOk", "precastWorthwhile", "portableGeometryOk", "(portableTileM + portableTileN) * portableTileK * dtypeBytes(\"float32\") <= device.limits.maxComputeWorkgroupStorageSize", "\"f32\" == \"f16\" or sgmatM >= portableTileN"],
1330
+ "demoteWhen": ["preferPackedDot"],
1331
  "requires": { "features": [] },
1332
  "derive": {
1333
  "precastScalar": "\"f32\"",
 
1335
  "hasAZero": true,
1336
  "hasBZero": true,
1337
  "bZeroPerColumn": true,
 
 
1338
  "M": "sgmatM",
1339
  "N": "sgmatN",
1340
  "K": "preparedK",
 
1343
  "workgroupRows": "portableWorkgroupRows",
1344
  "blockRows": "portableTileM",
1345
  "blockCols": "portableTileN",
1346
+ "integerPartialK": "portablePartialK"
 
 
 
1347
  },
1348
  "passes": [
1349
  {
1350
  "id": "prepare",
1351
+ "name": "MatMulInteger.ExactPrepareOperands",
1352
  "shader": "quant-exact-prepare.wgsl.jinja",
1353
+ "bindings": ["a_main", "a_zero_point", "precast_f32_aFloat", "b", "b_zero_point", "precast_f32_bFloat", "precast_prepare_params"],
1354
  "dispatch": {
1355
  "x": "min(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
1356
  "y": "ceilDiv(prepareGroups, min(device.limits.maxComputeWorkgroupsPerDimension, 65535))"
 
1358
  },
1359
  {
1360
  "id": "main",
1361
+ "name": "MatMulInteger.ExactPortableMultiply",
1362
  "shader": "quant-exact-portable.wgsl.jinja",
1363
  "bindings": ["portable_f32_a", "portable_f32_b", "y"],
1364
  "dispatch": { "x": "ceilDiv(sgmatN, portableTileN)", "y": "ceilDiv(sgmatM, portableTileM)" }
 
1377
  "features": ["subgroups", "chromium-experimental-subgroup-matrix"],
1378
  "subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
1379
  },
1380
+ "derive": { "hasAZero": false, "hasBZero": false, "bZeroPerColumn": false },
1381
  "passes": [
1382
  {
1383
  "id": "main",
1384
  "name": "MatMulInteger.ExactMatrix",
1385
  "shader": "quant-exact-matrix.wgsl.jinja",
1386
+ "bindings": ["a_main", "b", "y", "params_main"],
1387
  "dispatch": { "x": "ceilDiv(matrixN, sgmatTileN)", "y": "ceilDiv(matrixM, sgmatTileM)" }
1388
  }
1389
  ]
 
1396
  "features": ["subgroups", "chromium-experimental-subgroup-matrix"],
1397
  "subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
1398
  },
1399
+ "derive": { "hasAZero": false, "hasBZero": true, "bZeroPerColumn": false },
1400
  "passes": [
1401
  {
1402
  "id": "main",
1403
  "name": "MatMulInteger.ExactMatrix",
1404
  "shader": "quant-exact-matrix.wgsl.jinja",
1405
+ "bindings": ["a_main", "b", "b_zero_point", "y", "params_main"],
1406
  "dispatch": { "x": "ceilDiv(matrixN, sgmatTileN)", "y": "ceilDiv(matrixM, sgmatTileM)" }
1407
  }
1408
  ]
 
1415
  "features": ["subgroups", "chromium-experimental-subgroup-matrix"],
1416
  "subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
1417
  },
1418
+ "derive": { "hasAZero": false, "hasBZero": true, "bZeroPerColumn": true },
1419
  "passes": [
1420
  {
1421
  "id": "main",
1422
  "name": "MatMulInteger.ExactMatrix",
1423
  "shader": "quant-exact-matrix.wgsl.jinja",
1424
+ "bindings": ["a_main", "b", "b_zero_point", "y", "params_main"],
1425
  "dispatch": { "x": "ceilDiv(matrixN, sgmatTileN)", "y": "ceilDiv(matrixM, sgmatTileM)" }
1426
  }
1427
  ]
 
1434
  "features": ["subgroups", "chromium-experimental-subgroup-matrix"],
1435
  "subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
1436
  },
1437
+ "derive": { "hasAZero": true, "hasBZero": false, "bZeroPerColumn": false },
1438
  "passes": [
1439
  {
1440
  "id": "main",
1441
  "name": "MatMulInteger.ExactMatrix",
1442
  "shader": "quant-exact-matrix.wgsl.jinja",
1443
+ "bindings": ["a_main", "b", "a_zero_point", "y", "params_main"],
1444
  "dispatch": { "x": "ceilDiv(matrixN, sgmatTileN)", "y": "ceilDiv(matrixM, sgmatTileM)" }
1445
  }
1446
  ]
 
1453
  "features": ["subgroups", "chromium-experimental-subgroup-matrix"],
1454
  "subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
1455
  },
1456
+ "derive": { "hasAZero": true, "hasBZero": true, "bZeroPerColumn": false },
1457
  "passes": [
1458
  {
1459
  "id": "main",
1460
  "name": "MatMulInteger.ExactMatrix",
1461
  "shader": "quant-exact-matrix.wgsl.jinja",
1462
+ "bindings": ["a_main", "b", "a_zero_point", "b_zero_point", "y", "params_main"],
1463
  "dispatch": { "x": "ceilDiv(matrixN, sgmatTileN)", "y": "ceilDiv(matrixM, sgmatTileM)" }
1464
  }
1465
  ]
 
1472
  "features": ["subgroups", "chromium-experimental-subgroup-matrix"],
1473
  "subgroupMatrixConfigs": [{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }]
1474
  },
1475
+ "derive": { "hasAZero": true, "hasBZero": true, "bZeroPerColumn": true },
1476
  "passes": [
1477
  {
1478
  "id": "main",
1479
  "name": "MatMulInteger.ExactMatrix",
1480
  "shader": "quant-exact-matrix.wgsl.jinja",
1481
+ "bindings": ["a_main", "b", "a_zero_point", "b_zero_point", "y", "params_main"],
1482
  "dispatch": { "x": "ceilDiv(matrixN, sgmatTileN)", "y": "ceilDiv(matrixM, sgmatTileM)" }
1483
  }
1484
  ]
 
1493
  "hasAZero": true,
1494
  "hasBZero": true,
1495
  "bZeroPerColumn": false,
1496
+ "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL"
 
 
 
 
 
1497
  },
1498
  "passes": [
1499
  {
 
1518
  "hasAZero": false,
1519
  "hasBZero": false,
1520
  "bZeroPerColumn": false,
1521
+ "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL"
 
 
 
 
 
1522
  },
1523
  "passes": [
1524
  {
 
1542
  "hasAZero": true,
1543
  "hasBZero": true,
1544
  "bZeroPerColumn": false,
 
 
1545
  "tileM": 8,
1546
  "tileN": 64,
1547
  "ktWords": 32
 
1552
  "name": "MatMulInteger.Dp4aBatched3x2Tail",
1553
  "shader": "quant-dp4a-matmul.wgsl.jinja",
1554
  "bindings": [
1555
+ "a_main",
1556
  "b",
1557
  "a_zero_point",
1558
  "b_zero_point",
 
1582
  "hasAZero": true,
1583
  "hasBZero": true,
1584
  "bZeroPerColumn": false,
1585
+ "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL"
 
 
 
 
 
1586
  },
1587
  "passes": [
1588
  {
 
1606
  "hasAZero": true,
1607
  "hasBZero": false,
1608
  "bZeroPerColumn": false,
1609
+ "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL"
 
 
 
 
 
1610
  },
1611
  "passes": [
1612
  {
1613
  "id": "main",
1614
  "name": "MatMulInteger.Dp4a",
1615
  "shader": "quant-dp4a-matmul.wgsl.jinja",
1616
+ "bindings": ["a_a_vec4", "b", "a_zero_point", "y", "params"],
1617
  "dispatch": {
1618
  "x": "ceilDiv(dim(shapes.y, 1), rank2Dp4aTileN)",
1619
  "y": "ceilDiv(dim(shapes.y, 0), rank2Dp4aTileM)"
 
1630
  "hasAZero": false,
1631
  "hasBZero": true,
1632
  "bZeroPerColumn": false,
1633
+ "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL"
 
 
 
 
 
1634
  },
1635
  "passes": [
1636
  {
 
1654
  "hasAZero": false,
1655
  "hasBZero": false,
1656
  "bZeroPerColumn": false,
1657
+ "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL"
 
 
 
 
 
1658
  },
1659
  "passes": [
1660
  {
1661
  "id": "main",
1662
  "name": "MatMulInteger.Dp4a",
1663
  "shader": "quant-dp4a-matmul.wgsl.jinja",
1664
+ "bindings": ["a_a_vec4", "b", "y", "params"],
1665
  "dispatch": {
1666
  "x": "ceilDiv(dim(shapes.y, 1), rank2Dp4aTileN)",
1667
  "y": "ceilDiv(dim(shapes.y, 0), rank2Dp4aTileM)"
 
1686
  "hasAZero": false,
1687
  "hasBZero": true,
1688
  "bZeroPerColumn": true,
 
 
1689
  "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL",
1690
+ "tileM": "rank2Dp4aTileM if dim(shapes.y, 0) == 1 else (16 if perColumnDp4aUseNarrowTile else tunables.TILE_M)",
1691
+ "tileN": "rank2Dp4aTileN if dim(shapes.y, 0) == 1 else (2 * tunables.TILE_N if variableSubgroup16To32 and rank2Dp4aLargePrefill and 2 * tunables.TILE_N <= deviceWorkgroupCap else tunables.TILE_N)",
1692
  "ktWords": "rank2Dp4aKtWords if dim(shapes.y, 0) == 1 else tunables.KT_WORDS"
1693
  },
1694
  "passes": [
 
1697
  "name": "MatMulInteger.Dp4aBPerColumn",
1698
  "shader": "quant-dp4a-matmul.wgsl.jinja",
1699
  "bindings": ["a", "b", "b_zero_point", "y", "params"],
1700
+ "dispatch": { "x": "ceilDiv(dim(shapes.y, 1), tileN)", "y": "ceilDiv(dim(shapes.y, 0), tileM)" }
 
 
 
1701
  }
1702
  ]
1703
  },
 
1718
  "hasAZero": true,
1719
  "hasBZero": true,
1720
  "bZeroPerColumn": true,
 
 
1721
  "gemvKUnroll": "tunables.DP4A_GEMV_K_UNROLL",
1722
+ "tileM": "rank2Dp4aTileM if dim(shapes.y, 0) == 1 else (16 if perColumnDp4aUseNarrowTile else tunables.TILE_M)",
1723
+ "tileN": "rank2Dp4aTileN if dim(shapes.y, 0) == 1 else (2 * tunables.TILE_N if variableSubgroup16To32 and rank2Dp4aLargePrefill and 2 * tunables.TILE_N <= deviceWorkgroupCap else tunables.TILE_N)",
1724
  "ktWords": "rank2Dp4aKtWords if dim(shapes.y, 0) == 1 else tunables.KT_WORDS"
1725
  },
1726
  "passes": [
 
1729
  "name": "MatMulInteger.Dp4aAScalarBPerColumn",
1730
  "shader": "quant-dp4a-matmul.wgsl.jinja",
1731
  "bindings": ["a", "b", "a_zero_point", "b_zero_point", "y", "params"],
1732
+ "dispatch": { "x": "ceilDiv(dim(shapes.y, 1), tileN)", "y": "ceilDiv(dim(shapes.y, 0), tileM)" }
 
 
 
1733
  }
1734
  ]
1735
  },
 
1742
  "id": "main",
1743
  "name": "MatMulInteger",
1744
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1745
+ "bindings": ["a_main", "b", "a_zero_point", "b_zero_point", "y", "params_main"],
1746
  "dispatch": {
1747
  "x": "ceil(matrixN / tunables.WORKGROUP_SIZE_X)",
1748
  "y": "min(ceilDiv((matrixM), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)",
1749
+ "z": 1
1750
  }
1751
  }
1752
  ]
 
1760
  "id": "main",
1761
  "name": "MatMulInteger",
1762
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1763
+ "bindings": ["a_main", "b", "a_zero_point", "y", "params_main"],
1764
  "dispatch": {
1765
  "x": "ceil(matrixN / tunables.WORKGROUP_SIZE_X)",
1766
  "y": "min(ceilDiv((matrixM), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)",
1767
+ "z": 1
1768
  }
1769
  }
1770
  ]
 
1778
  "id": "main",
1779
  "name": "MatMulInteger",
1780
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1781
+ "bindings": ["a_main", "b", "b_zero_point", "y", "params_main"],
1782
  "dispatch": {
1783
  "x": "ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_X)",
1784
  "y": "min(ceilDiv((dim(shapes.y, 0)), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)",
1785
+ "z": 1
1786
  }
1787
  }
1788
  ]
 
1796
  "id": "main",
1797
  "name": "MatMulInteger",
1798
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1799
+ "bindings": ["a_main", "b", "b_zero_point", "y", "params_m_n_k"],
1800
  "dispatch": { "x": 1 }
1801
  }
1802
  ]
 
1810
  "id": "main",
1811
  "name": "MatMulInteger",
1812
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1813
+ "bindings": ["a_main", "b", "y", "params_m_n_k"],
1814
  "dispatch": { "x": 1 }
1815
  }
1816
  ]
 
1824
  "id": "main",
1825
  "name": "MatMulInteger",
1826
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1827
+ "bindings": ["a_main", "b", "y", "params_main"],
1828
  "dispatch": {
1829
  "x": "ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_X)",
1830
  "y": "min(ceilDiv((dim(shapes.y, 0)), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)",
1831
+ "z": 1
1832
  }
1833
  }
1834
  ]
 
1842
  "id": "main",
1843
  "name": "MatMulInteger.PerColumn",
1844
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1845
+ "bindings": ["a_main", "b", "a_zero_point", "b_zero_point", "y", "params_main"],
1846
  "dispatch": {
1847
  "x": "ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_X)",
1848
  "y": "min(ceilDiv((dim(shapes.y, 0)), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)",
1849
+ "z": 1
1850
  }
1851
  }
1852
  ]
 
1860
  "id": "main",
1861
  "name": "MatMulInteger.PerColumnNoAZero",
1862
  "shader": "quant-matmul-accumulate-rank2.wgsl.jinja",
1863
+ "bindings": ["a_main", "b", "b_zero_point", "y", "params_main"],
1864
  "dispatch": {
1865
  "x": "ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_X)",
1866
  "y": "min(ceilDiv((dim(shapes.y, 0)), (tunables.WORKGROUP_SIZE_Y)), DISPATCH_FOLD_WIDTH)",
1867
+ "z": 1
1868
  }
1869
  }
1870
  ]
 
1872
  {
1873
  "id": "rank3_by_rank3_scalar_zero_points",
1874
  "when": ["present.a_zero_point", "present.b_zero_point", "(rank3ByRank3ShapeOk or rank3ByRank2ShapeOk)", "scalarAZeroOk and scalarBZeroOk"],
1875
+ "derive": { "hasAZero": true, "hasBZero": true, "bZeroBatchedPerColumn": false },
1876
  "passes": [
1877
  {
1878
  "id": "main",
1879
  "name": "MatMulInteger.Batched3x3",
1880
  "shader": "matmul-integer-batched.wgsl.jinja",
1881
+ "bindings": ["a_main", "b", "a_zero_point", "b_zero_point", "y", "params__uniform"],
1882
  "dispatch": {
1883
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
1884
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
1890
  {
1891
  "id": "rank3_by_rank3_no_zero_points",
1892
  "when": ["not present.a_zero_point", "not present.b_zero_point", "(rank3ByRank3ShapeOk or rank3ByRank2ShapeOk)", "true"],
1893
+ "derive": { "hasAZero": false, "hasBZero": false, "bZeroBatchedPerColumn": false },
1894
  "passes": [
1895
  {
1896
  "id": "main",
1897
  "name": "MatMulInteger.Batched3x3",
1898
  "shader": "matmul-integer-batched.wgsl.jinja",
1899
+ "bindings": ["a_main", "b", "y", "params__uniform"],
1900
  "dispatch": {
1901
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
1902
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
1908
  {
1909
  "id": "rank3_by_rank3_a_zero_point_only",
1910
  "when": ["present.a_zero_point", "not present.b_zero_point", "(rank3ByRank3ShapeOk or rank3ByRank2ShapeOk)", "scalarAZeroOk"],
1911
+ "derive": { "hasAZero": true, "hasBZero": false, "bZeroBatchedPerColumn": false },
1912
  "passes": [
1913
  {
1914
  "id": "main",
1915
  "name": "MatMulInteger.Batched3x3",
1916
  "shader": "matmul-integer-batched.wgsl.jinja",
1917
+ "bindings": ["a_main", "b", "a_zero_point", "y", "params__uniform"],
1918
  "dispatch": {
1919
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
1920
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
1926
  {
1927
  "id": "rank3_by_rank3_b_zero_point_only",
1928
  "when": ["not present.a_zero_point", "present.b_zero_point", "(rank3ByRank3ShapeOk or rank3ByRank2ShapeOk)", "scalarBZeroOk"],
1929
+ "derive": { "hasAZero": false, "hasBZero": true, "bZeroBatchedPerColumn": false },
1930
  "passes": [
1931
  {
1932
  "id": "main",
1933
  "name": "MatMulInteger.Batched3x3",
1934
  "shader": "matmul-integer-batched.wgsl.jinja",
1935
+ "bindings": ["a_main", "b", "b_zero_point", "y", "params__uniform"],
1936
  "dispatch": {
1937
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
1938
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
1944
  {
1945
  "id": "rank3_by_rank3_b_zero_point_per_column_batched",
1946
  "when": ["present.a_zero_point", "present.b_zero_point", "rank3ByRank3ShapeOk", "scalarAZeroOk and ranks.b_zero_point == 3 and dim(shapes.b_zero_point, 0) == dim(shapes.y, 0) and dim(shapes.b_zero_point, 1) == 1 and dim(shapes.b_zero_point, 2) == dim(shapes.y, 2)"],
1947
+ "derive": { "hasAZero": true, "hasBZero": true, "bZeroBatchedPerColumn": true },
1948
  "passes": [
1949
  {
1950
  "id": "main",
1951
  "name": "MatMulInteger.Batched3x3PerColumn",
1952
  "shader": "matmul-integer-batched.wgsl.jinja",
1953
+ "bindings": ["a_main", "b", "a_zero_point", "b_zero_point", "y", "params__uniform"],
1954
  "dispatch": {
1955
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
1956
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
1962
  {
1963
  "id": "rank3_by_rank3_b_zero_point_per_column_batched_no_azp",
1964
  "when": ["not present.a_zero_point", "present.b_zero_point", "rank3ByRank3ShapeOk", "ranks.b_zero_point == 3 and dim(shapes.b_zero_point, 0) == dim(shapes.y, 0) and dim(shapes.b_zero_point, 1) == 1 and dim(shapes.b_zero_point, 2) == dim(shapes.y, 2)"],
1965
+ "derive": { "hasAZero": false, "hasBZero": true, "bZeroBatchedPerColumn": true },
1966
  "passes": [
1967
  {
1968
  "id": "main",
1969
  "name": "MatMulInteger.Batched3x3PerColumn",
1970
  "shader": "matmul-integer-batched.wgsl.jinja",
1971
+ "bindings": ["a_main", "b", "b_zero_point", "y", "params__uniform"],
1972
  "dispatch": {
1973
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
1974
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
1980
  {
1981
  "id": "rank2_by_rank3_scalar_zero_points",
1982
  "when": ["present.a_zero_point", "present.b_zero_point", "ranks.a == 2 and ranks.b == 3 and ranks.y == 3 and dim(shapes.a, 1) == dim(shapes.b, 1) and dim(shapes.y, 0) == dim(shapes.b, 0) and dim(shapes.y, 1) == dim(shapes.a, 0) and dim(shapes.y, 2) == dim(shapes.b, 2)", "scalarAZeroOk and scalarBZeroOk"],
1983
+ "derive": { "hasAZero": true, "hasBZero": true, "bZeroBatchedPerColumn": false },
1984
  "passes": [
1985
  {
1986
  "id": "main",
1987
  "name": "MatMulInteger.Batched2x3",
1988
  "shader": "matmul-integer-batched.wgsl.jinja",
1989
+ "bindings": ["a_main", "b", "a_zero_point", "b_zero_point", "y", "params__uniform"],
1990
  "dispatch": {
1991
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
1992
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
1998
  {
1999
  "id": "rank2_by_rank3_a_zero_point_only",
2000
  "when": ["present.a_zero_point", "not present.b_zero_point", "ranks.a == 2 and ranks.b == 3 and ranks.y == 3 and dim(shapes.a, 1) == dim(shapes.b, 1) and dim(shapes.y, 0) == dim(shapes.b, 0) and dim(shapes.y, 1) == dim(shapes.a, 0) and dim(shapes.y, 2) == dim(shapes.b, 2)", "scalarAZeroOk"],
2001
+ "derive": { "hasAZero": true, "hasBZero": false, "bZeroBatchedPerColumn": false },
2002
  "passes": [
2003
  {
2004
  "id": "main",
2005
  "name": "MatMulInteger.Batched2x3",
2006
  "shader": "matmul-integer-batched.wgsl.jinja",
2007
+ "bindings": ["a_main", "b", "a_zero_point", "y", "params__uniform"],
2008
  "dispatch": {
2009
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2010
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
2016
  {
2017
  "id": "rank2_by_rank3_b_zero_point_only",
2018
  "when": ["not present.a_zero_point", "present.b_zero_point", "ranks.a == 2 and ranks.b == 3 and ranks.y == 3 and dim(shapes.a, 1) == dim(shapes.b, 1) and dim(shapes.y, 0) == dim(shapes.b, 0) and dim(shapes.y, 1) == dim(shapes.a, 0) and dim(shapes.y, 2) == dim(shapes.b, 2)", "scalarBZeroOk"],
2019
+ "derive": { "hasAZero": false, "hasBZero": true, "bZeroBatchedPerColumn": false },
2020
  "passes": [
2021
  {
2022
  "id": "main",
2023
  "name": "MatMulInteger.Batched2x3",
2024
  "shader": "matmul-integer-batched.wgsl.jinja",
2025
+ "bindings": ["a_main", "b", "b_zero_point", "y", "params__uniform"],
2026
  "dispatch": {
2027
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2028
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
2034
  {
2035
  "id": "rank2_by_rank3_no_zero_points",
2036
  "when": ["not present.a_zero_point", "not present.b_zero_point", "ranks.a == 2 and ranks.b == 3 and ranks.y == 3 and dim(shapes.a, 1) == dim(shapes.b, 1) and dim(shapes.y, 0) == dim(shapes.b, 0) and dim(shapes.y, 1) == dim(shapes.a, 0) and dim(shapes.y, 2) == dim(shapes.b, 2)", "true"],
2037
+ "derive": { "hasAZero": false, "hasBZero": false, "bZeroBatchedPerColumn": false },
2038
  "passes": [
2039
  {
2040
  "id": "main",
2041
  "name": "MatMulInteger.Batched2x3",
2042
  "shader": "matmul-integer-batched.wgsl.jinja",
2043
+ "bindings": ["a_main", "b", "y", "params__uniform"],
2044
  "dispatch": {
2045
  "x": "ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_X)",
2046
  "y": "min(ceil(dim(shapes.y, 1) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
2059
  "name": "MatMulInteger.Batched4",
2060
  "shader": "quant-matmul-accumulate-rank4.wgsl.jinja",
2061
  "derive": { "outputToScratch": false },
2062
+ "bindings": ["a_main", "b", "a_zero_point", "b_zero_point", "y", "params_rank4_no_zero_points"],
2063
  "dispatch": {
2064
  "x": "ceil(dim(shapes.y, 3) / tunables.WORKGROUP_SIZE_X)",
2065
  "y": "min(ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
2078
  "name": "MatMulInteger.Batched4",
2079
  "shader": "quant-matmul-accumulate-rank4.wgsl.jinja",
2080
  "derive": { "outputToScratch": false },
2081
+ "bindings": ["a_main", "b", "a_zero_point", "y", "params_rank4_no_zero_points"],
2082
  "dispatch": {
2083
  "x": "ceil(dim(shapes.y, 3) / tunables.WORKGROUP_SIZE_X)",
2084
  "y": "min(ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
2097
  "name": "MatMulInteger.Batched4",
2098
  "shader": "quant-matmul-accumulate-rank4.wgsl.jinja",
2099
  "derive": { "outputToScratch": false },
2100
+ "bindings": ["a_main", "b", "b_zero_point", "y", "params_rank4_no_zero_points"],
2101
  "dispatch": {
2102
  "x": "ceil(dim(shapes.y, 3) / tunables.WORKGROUP_SIZE_X)",
2103
  "y": "min(ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
2116
  "name": "MatMulInteger.Batched4",
2117
  "shader": "quant-matmul-accumulate-rank4.wgsl.jinja",
2118
  "derive": { "outputToScratch": false },
2119
+ "bindings": ["a_main", "b", "y", "params_rank4_no_zero_points"],
2120
  "dispatch": {
2121
  "x": "ceil(dim(shapes.y, 3) / tunables.WORKGROUP_SIZE_X)",
2122
  "y": "min(ceil(dim(shapes.y, 2) / tunables.WORKGROUP_SIZE_Y), min(device.limits.maxComputeWorkgroupsPerDimension, 65535))",
 
2134
  "hasAZero": true,
2135
  "hasBZero": true,
2136
  "bZeroPerColumn": false,
 
 
2137
  "tileM": 8,
2138
  "tileN": 64,
2139
  "ktWords": 32
 
2143
  "id": "main",
2144
  "name": "MatMulInteger.Dp4aBatched3x3",
2145
  "shader": "quant-dp4a-matmul.wgsl.jinja",
2146
+ "bindings": ["a_a_vec4", "b", "a_zero_point", "b_zero_point", "y", "params_quant_dp4a_matmul"],
2147
  "dispatch": { "x": "ceil(dim(shapes.y, 2) / 64)", "y": "ceil(dim(shapes.y, 1) / 8)", "z": "dim(shapes.y, 0)" }
2148
  }
2149
  ]
 
2157
  "hasAZero": true,
2158
  "hasBZero": true,
2159
  "bZeroPerColumn": false,
 
 
2160
  "tileM": 8,
2161
  "tileN": 64,
2162
  "ktWords": 32
 
2166
  "id": "main",
2167
  "name": "MatMulInteger.Dp4aBatched4Scalar",
2168
  "shader": "quant-dp4a-matmul.wgsl.jinja",
2169
+ "bindings": ["a_a_vec4", "b", "a_zero_point", "b_zero_point", "y", "params_dp4a_rank4_no_zero_points"],
2170
  "dispatch": {
2171
  "x": "ceil(dim(shapes.y, 3) / 64)",
2172
  "y": "ceil(dim(shapes.y, 2) / 8)",
 
2184
  "hasAZero": false,
2185
  "hasBZero": false,
2186
  "bZeroPerColumn": false,
 
 
2187
  "tileM": 8,
2188
  "tileN": 64,
2189
  "ktWords": 32
 
2193
  "id": "main",
2194
  "name": "MatMulInteger.Dp4aBatched4NoZero",
2195
  "shader": "quant-dp4a-matmul.wgsl.jinja",
2196
+ "bindings": ["a_a_vec4", "b", "y", "params_dp4a_rank4_no_zero_points"],
2197
  "dispatch": {
2198
  "x": "ceil(dim(shapes.y, 3) / 64)",
2199
  "y": "ceil(dim(shapes.y, 2) / 8)",
build/webgpu/matmul-integer-batched.wgsl.jinja CHANGED
@@ -26,9 +26,8 @@ fn {{ fn_name }}() -> i32 {
26
  {% else %}
27
  return 0;
28
  {% endif %}
29
- }
30
- {%- endmacro %}
31
- {%- macro quant_read_batched_column_zero(fn_name, buffer_name, is_unsigned, present=true, batched_per_column=false) %}
32
  fn {{ fn_name }}({% if batched_per_column %}batch: u32, col: u32{% endif %}) -> i32 {
33
  {% if present %}
34
  {% if batched_per_column %}
@@ -47,9 +46,7 @@ fn {{ fn_name }}({% if batched_per_column %}batch: u32, col: u32{% endif %}) ->
47
  {% else %}
48
  return 0;
49
  {% endif %}
50
- }
51
- {%- endmacro %}
52
-
53
 
54
  // b_zero_point lookup. Per-column-per-batch (b_zp shape [batch,1,N]) indexes
55
  // batch*N + col; per-column (shape [N]) indexes col; otherwise scalar [0].
 
26
  {% else %}
27
  return 0;
28
  {% endif %}
29
+ }{% endmacro %}
30
+ {% macro quant_read_batched_column_zero(fn_name, buffer_name, is_unsigned, present=true, batched_per_column=false) %}
 
31
  fn {{ fn_name }}({% if batched_per_column %}batch: u32, col: u32{% endif %}) -> i32 {
32
  {% if present %}
33
  {% if batched_per_column %}
 
46
  {% else %}
47
  return 0;
48
  {% endif %}
49
+ }{% endmacro %}
 
 
50
 
51
  // b_zero_point lookup. Per-column-per-batch (b_zp shape [batch,1,N]) indexes
52
  // batch*N + col; per-column (shape [N]) indexes col; otherwise scalar [0].
build/webgpu/metadata.json CHANGED
@@ -1,27 +1,27 @@
1
  {
2
  "name": "ai.onnx.MatMulInteger",
3
- "id": "_ai_onnx_matmulinteger_webgpu_6f2ef1c",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "backend": { "type": "webgpu" },
7
  "digest": {
8
  "algorithm": "sha256",
9
  "files": {
10
- "bench.json": "oZ95YN2Dm5Bwzz2Zt4UkOCHxJyia3aXTiAzZ+QnFRoo=",
11
- "manifest.json": "B1e4/D6YPkD3jYTM1UmR3Ikz8VpTGxK95JNzlqEGhZI=",
12
- "matmul-integer-batched.wgsl.jinja": "pKWtzKeL62KPieYc+I4FzUkq7JlCuZg3n7/JNjoWTHo=",
13
- "quant-dp4a-matmul.wgsl.jinja": "uOf2BCHfSx0u60XKY89imRx6cjw+Ey0V4o/sbrrSeu4=",
14
- "quant-exact-matrix.wgsl.jinja": "efr11+suguVwWDMoNI3JqosWvEXa3vbMbeA0b7at14A=",
15
- "quant-exact-portable.wgsl.jinja": "DaqBS74omKoDp+d77Uxv95rECoElAArVImPpDA4v5jY=",
16
- "quant-exact-prepare.wgsl.jinja": "JeFBHxhxPiMqRbSJ/tfqFsgb4T5o3q3/RZGPcHDn6rk=",
17
- "quant-matmul-accumulate-rank2.wgsl.jinja": "S7SS4pG+oB2O1EmKrPiNg9VHkqQwJ8mrA5M68wciLE0=",
18
- "quant-matmul-accumulate-rank4.wgsl.jinja": "JBwbT3KMpqRNRXwjkCBPkpRCjLd0BfOn5hAUBm3b33o=",
19
- "test.json": "RFp6aUPoekPtgawzlEd6e+iSWtmo0UsVU+PLYdU92z4="
20
  }
21
  },
22
- "provenance": { "kernel": { "sha": "91d990483a174128daf7673f3f37a7c890493ae1", "dirty": false } },
23
  "webgpu": {
24
- "manifestSpec": "2.0",
25
  "variants": {
26
  "sgmat_precast_a0_bnone_f16": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
27
  "portable_precast_a0_bnone_f16": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
 
1
  {
2
  "name": "ai.onnx.MatMulInteger",
3
+ "id": "_ai_onnx_matmulinteger_webgpu_ffd4ac7",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "backend": { "type": "webgpu" },
7
  "digest": {
8
  "algorithm": "sha256",
9
  "files": {
10
+ "bench.json": "tGrApvNDS+q1wEoCX8hzU2NZ/wLXNvgC7s/8RnC42bg=",
11
+ "manifest.json": "YjPF3+WTy+o5h++04mLYvGAGSCb8BRQyuQVbZwo+lwg=",
12
+ "matmul-integer-batched.wgsl.jinja": "+21TfArUYYejHfn+7LTkSuf3dDTKm9cvvFdVqxq9Tac=",
13
+ "quant-dp4a-matmul.wgsl.jinja": "TQnfQK5DnJq8MI2GLS2mTKjA/0//3+ffrNddL8exb74=",
14
+ "quant-exact-matrix.wgsl.jinja": "cUkyPJwYCVavMtTYH2bXieCoV5zVWXfMAkiQyEXh66g=",
15
+ "quant-exact-portable.wgsl.jinja": "YhuWQbbMqQyiADZIkF1Sv7fbpQEgw55btuB5lPDAq34=",
16
+ "quant-exact-prepare.wgsl.jinja": "qiO6Zu0/94h+r9sLOFAJYm8dNQL9rv6TiJh/O8DYYq0=",
17
+ "quant-matmul-accumulate-rank2.wgsl.jinja": "3iUfINfSvyh5QmhBJGtyqbfBxFIsvMsytuXs2xNrxEg=",
18
+ "quant-matmul-accumulate-rank4.wgsl.jinja": "sj5qOkUomLu0WuRoeRBVcZ1YzLkL5uqHKxFCnM+AsIE=",
19
+ "test.json": "9MIc0cTdv/jJKQ2uUB0ugz11YwJn+/JkmK1wrfh3eQQ="
20
  }
21
  },
22
+ "provenance": { "kernel": { "sha": "6fdf6301e2bbcc2f03bf1eaf493b7ad55ef33afc", "dirty": false } },
23
  "webgpu": {
24
+ "manifestSpec": "2.1",
25
  "variants": {
26
  "sgmat_precast_a0_bnone_f16": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
27
  "portable_precast_a0_bnone_f16": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
build/webgpu/quant-dp4a-matmul.wgsl.jinja CHANGED
@@ -1,3 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  {% if not env.device.wgslLanguageFeatures.has("packed_4x8_integer_dot_product") %}
2
  // Runtime source-compatible fallbacks for the packed 4x8 integer built-ins used
3
  // by quantized kernels. Native implementations remain unshadowed when the
@@ -19,7 +35,6 @@
19
  {% endif %}
20
  {{ env.wgsl.resourceDeclarations }}
21
 
22
-
23
  const TILE_M: u32 = {{ tileM }}u;
24
  const TILE_N: u32 = {{ tileN }}u;
25
  const KT_WORDS: u32 = {{ ktWords }}u;
@@ -70,7 +85,6 @@ fn pack_b(b0: {{ bScalar }}, b1: {{ bScalar }}, b2: {{ bScalar }}, b3: {{ bScala
70
  fn dot4_packed(a_word: u32, b_word: u32) -> i32 {
71
  return dot4I8Packed(a_word, b_word);
72
  }
73
-
74
  {% if needsBSum %}
75
 
76
  fn sum4_b(b0: {{ bScalar }}, b1: {{ bScalar }}, b2: {{ bScalar }}, b3: {{ bScalar }}) -> i32 {
@@ -83,31 +97,11 @@ fn sum4_b(b0: {{ bScalar }}, b1: {{ bScalar }}, b2: {{ bScalar }}, b3: {{ bScala
83
 
84
  {% endif %}
85
  {% if hasAZero %}
86
- fn read_a_zero() -> i32 {
87
- {% if aUnsigned %}
88
- return i32(a_zero_point[0]);
89
- {% else %}
90
- return a_zero_point[0];
91
- {% endif %}
92
- }
93
 
94
  {% endif %}
95
  {% if hasBZero %}
96
- fn read_b_zero({% if bZeroPerColumn %}col: u32{% endif %}) -> i32 {
97
- {% if bZeroPerColumn %}
98
- {% if bUnsigned %}
99
- return i32(b_zero_point[col]);
100
- {% else %}
101
- return b_zero_point[col];
102
- {% endif %}
103
- {% else %}
104
- {% if bUnsigned %}
105
- return i32(b_zero_point[0]);
106
- {% else %}
107
- return b_zero_point[0];
108
- {% endif %}
109
- {% endif %}
110
- }
111
 
112
  {% endif %}
113
  @compute @workgroup_size(TILE_N, 1, 1)
 
1
+ {% macro quant_read_column_zero(fn_name, buffer_name, is_unsigned, present=true, per_column=false, param_name="col", return_type="i32") %}
2
+ fn {{ fn_name }}({% if per_column %}{{ param_name }}: u32{% endif %}) -> {{ return_type }} {
3
+ {% if per_column %}
4
+ {% if is_unsigned %}
5
+ return i32({{ buffer_name }}[{{ param_name }}]);
6
+ {% else %}
7
+ return {{ buffer_name }}[{{ param_name }}];
8
+ {% endif %}
9
+ {% else %}
10
+ {% if is_unsigned %}
11
+ return i32({{ buffer_name }}[0]);
12
+ {% else %}
13
+ return {{ buffer_name }}[0];
14
+ {% endif %}
15
+ {% endif %}
16
+ }{% endmacro %}
17
  {% if not env.device.wgslLanguageFeatures.has("packed_4x8_integer_dot_product") %}
18
  // Runtime source-compatible fallbacks for the packed 4x8 integer built-ins used
19
  // by quantized kernels. Native implementations remain unshadowed when the
 
35
  {% endif %}
36
  {{ env.wgsl.resourceDeclarations }}
37
 
 
38
  const TILE_M: u32 = {{ tileM }}u;
39
  const TILE_N: u32 = {{ tileN }}u;
40
  const KT_WORDS: u32 = {{ ktWords }}u;
 
85
  fn dot4_packed(a_word: u32, b_word: u32) -> i32 {
86
  return dot4I8Packed(a_word, b_word);
87
  }
 
88
  {% if needsBSum %}
89
 
90
  fn sum4_b(b0: {{ bScalar }}, b1: {{ bScalar }}, b2: {{ bScalar }}, b3: {{ bScalar }}) -> i32 {
 
97
 
98
  {% endif %}
99
  {% if hasAZero %}
100
+ {{ quant_read_column_zero("read_a_zero", "a_zero_point", aUnsigned, per_column=aZeroPerRow, param_name="row") }}
 
 
 
 
 
 
101
 
102
  {% endif %}
103
  {% if hasBZero %}
104
+ {{ quant_read_column_zero("read_b_zero", "b_zero_point", bUnsigned, per_column=bZeroPerColumn) }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
  {% endif %}
107
  @compute @workgroup_size(TILE_N, 1, 1)
build/webgpu/quant-exact-matrix.wgsl.jinja CHANGED
@@ -1,13 +1,12 @@
 
1
  {% set precastOperands = precastOperands | default(false) %}
2
  {% set precastScalar = precastScalar | default("f32") %}
3
- {% if (precastOperands and precastScalar == "f16") or (requantize and scaleScalar == "f16") %}enable f16;{% endif %}
4
  enable subgroups;
5
  {% if pinSubgroupSize32 %}
6
  enable subgroup_size_control;
7
  {% endif %}
8
  enable chromium_experimental_subgroup_matrix;
9
  diagnostic(off, chromium.subgroup_matrix_uniformity);
10
-
11
  {{ env.wgsl.resourceDeclarations }}
12
 
13
  // Adjusted byte integers fit exactly in f32. Each bounded f32 dot product
@@ -32,7 +31,7 @@ var<workgroup> scratch: array<array<array<f32, 64>, 4>, {{ sgmatSubgroups }}>;
32
  fn main(@builtin(workgroup_id) wid: vec3<u32>,
33
  @builtin(local_invocation_index) tid: u32,
34
  @builtin(subgroup_invocation_id) lane: u32,
35
- @builtin(subgroup_size) subgroup_size: u32) {
36
  let subgroup = tid / subgroup_size;
37
  let base_A = (subgroup % {{ sgmatRowGroups }}u) * 16u;
38
  let base_B = (subgroup / {{ sgmatRowGroups }}u) * 32u;
@@ -56,7 +55,7 @@ fn main(@builtin(workgroup_id) wid: vec3<u32>,
56
  let k = kb + index % TILE_K;
57
  var value = f32(0.0);
58
  if (m < params.M && k < params.K) {
59
- value = f32(i32(a[m * params.K + k]){% if hasAZero %} - i32(a_zero_point[0]){% endif %});
60
  }
61
  tile_A[index] = value;
62
  }
 
1
+ {% set matrixZeroPerRow = false %}
2
  {% set precastOperands = precastOperands | default(false) %}
3
  {% set precastScalar = precastScalar | default("f32") %}
 
4
  enable subgroups;
5
  {% if pinSubgroupSize32 %}
6
  enable subgroup_size_control;
7
  {% endif %}
8
  enable chromium_experimental_subgroup_matrix;
9
  diagnostic(off, chromium.subgroup_matrix_uniformity);
 
10
  {{ env.wgsl.resourceDeclarations }}
11
 
12
  // Adjusted byte integers fit exactly in f32. Each bounded f32 dot product
 
31
  fn main(@builtin(workgroup_id) wid: vec3<u32>,
32
  @builtin(local_invocation_index) tid: u32,
33
  @builtin(subgroup_invocation_id) lane: u32,
34
+ @builtin(subgroup_size) subgroup_size: u32) {
35
  let subgroup = tid / subgroup_size;
36
  let base_A = (subgroup % {{ sgmatRowGroups }}u) * 16u;
37
  let base_B = (subgroup / {{ sgmatRowGroups }}u) * 32u;
 
55
  let k = kb + index % TILE_K;
56
  var value = f32(0.0);
57
  if (m < params.M && k < params.K) {
58
+ value = f32(i32(a[m * params.K + k]){% if hasAZero %} - i32(a_zero_point[{{ "m" if matrixZeroPerRow else "0" }}]){% endif %});
59
  }
60
  tile_A[index] = value;
61
  }
build/webgpu/quant-exact-portable.wgsl.jinja CHANGED
@@ -1,5 +1,3 @@
1
- {% if precastScalar == "f16" or (requantize and scaleScalar == "f16") %}enable f16;{% endif %}
2
- {% set exactIntegerPartials = true %}
3
 
4
  // Both integer-output and requantizing consumers share the vector GEMM body.
5
  // Its callback stores scalar outputs so padded operands also cover column tails.
@@ -7,14 +5,14 @@ fn store_integer_result(value: i32, output_index: u32) {
7
  y[output_index] = value;
8
  }
9
 
10
- {% set exactIntegerPartialsValue = exactIntegerPartials is defined and exactIntegerPartials %}
11
  {% set preparedNValue = preparedN | default(0) %}
12
  {% set integerPartialKValue = integerPartialK | default(0) %}
13
  {{ env.wgsl.resourceDeclarations }}
14
  {% set kTileValue = kTile %}
15
  {% set blockRowsValue = blockRows if blockRows is defined else 128 %}
16
  {% set blockColsValue = blockCols if blockCols is defined else 64 %}
17
- {% set accumulatorScalarValue = accumulatorScalar if accumulatorScalar is defined else "f32" %}
18
  {% set workgroupColsValue = workgroupCols if workgroupCols is defined else 16 %}
19
  {% set workgroupRowsValue = workgroupRows if workgroupRows is defined else 16 %}
20
  {% set laneCount = workgroupColsValue * workgroupRowsValue %}
@@ -23,7 +21,6 @@ fn store_integer_result(value: i32, output_index: u32) {
23
  {% set threadCols = threadColVectors * 4 %}
24
  {% set aVectorCount = (blockRowsValue * kTileValue / (4 * laneCount))|int %}
25
  {% set bVectorCount = (kTileValue * blockColsValue / (4 * laneCount))|int %}
26
- {% set batchStridesValue = batchStrides if batchStrides is defined else false %}
27
 
28
  // High-intensity matrix multiplication for the large, untransposed layout:
29
  // Y[M,N] = alpha * A[M,K] @ B[K,N].
@@ -59,8 +56,8 @@ fn main(
59
  let li = lid.y * {{ workgroupColsValue }}u + lid.x;
60
  let mBase = wg.y * BM;
61
  let nBase = wg.x * BN;
62
- {% set aOff = "aBatch + " if batchStridesValue else "" %}
63
- {% set bOff = "bBatch + " if batchStridesValue else "" %}
64
 
65
  {% for i in range(threadRows) %}
66
  {% for j in range(threadColVectors) %}
 
 
 
1
 
2
  // Both integer-output and requantizing consumers share the vector GEMM body.
3
  // Its callback stores scalar outputs so padded operands also cover column tails.
 
5
  y[output_index] = value;
6
  }
7
 
8
+ {% set exactIntegerPartialsValue = true %}
9
  {% set preparedNValue = preparedN | default(0) %}
10
  {% set integerPartialKValue = integerPartialK | default(0) %}
11
  {{ env.wgsl.resourceDeclarations }}
12
  {% set kTileValue = kTile %}
13
  {% set blockRowsValue = blockRows if blockRows is defined else 128 %}
14
  {% set blockColsValue = blockCols if blockCols is defined else 64 %}
15
+ {% set accumulatorScalarValue = "f32" %}
16
  {% set workgroupColsValue = workgroupCols if workgroupCols is defined else 16 %}
17
  {% set workgroupRowsValue = workgroupRows if workgroupRows is defined else 16 %}
18
  {% set laneCount = workgroupColsValue * workgroupRowsValue %}
 
21
  {% set threadCols = threadColVectors * 4 %}
22
  {% set aVectorCount = (blockRowsValue * kTileValue / (4 * laneCount))|int %}
23
  {% set bVectorCount = (kTileValue * blockColsValue / (4 * laneCount))|int %}
 
24
 
25
  // High-intensity matrix multiplication for the large, untransposed layout:
26
  // Y[M,N] = alpha * A[M,K] @ B[K,N].
 
56
  let li = lid.y * {{ workgroupColsValue }}u + lid.x;
57
  let mBase = wg.y * BM;
58
  let nBase = wg.x * BN;
59
+ {% set aOff = "" %}
60
+ {% set bOff = "" %}
61
 
62
  {% for i in range(threadRows) %}
63
  {% for j in range(threadColVectors) %}
build/webgpu/quant-exact-prepare.wgsl.jinja CHANGED
@@ -1,4 +1,5 @@
1
- {% if precastScalar == "f16" %}enable f16;{% endif %}
 
2
  {{ env.wgsl.resourceDeclarations }}
3
  @compute @workgroup_size({{ prepareWorkgroup }})
4
  fn main(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_index) tid: u32) {
@@ -11,15 +12,15 @@ fn main(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_index)
11
  {
12
  var value = 0.0;
13
  if (m < params.M && k + {{ h }}u < params.K) {
14
- value = f32(i32(a[m * params.K + k + {{ h }}u]){% if hasAZero %} - i32(a_zero_point[0]){% endif %});
15
  }
16
  aFloat[offset + {{ h }}u] = {% if precastScalar == "f16" %}f16(value){% else %}value{% endif %};
17
  }
18
  {% endfor %}
19
  } else {
20
  let bOffset = offset - params.aCount;
21
- let k = bOffset / params.paddedN;
22
- let n = bOffset % params.paddedN;
23
  {% for h in range(4) %}
24
  {
25
  var value = 0.0;
 
1
+ {% set prepareBatchB = false %}
2
+ {% set prepareZeroPerRow = false %}
3
  {{ env.wgsl.resourceDeclarations }}
4
  @compute @workgroup_size({{ prepareWorkgroup }})
5
  fn main(@builtin(workgroup_id) wid: vec3<u32>, @builtin(local_invocation_index) tid: u32) {
 
12
  {
13
  var value = 0.0;
14
  if (m < params.M && k + {{ h }}u < params.K) {
15
+ value = f32(i32(a[m * params.K + k + {{ h }}u]){% if hasAZero %} - i32(a_zero_point[{{ "m" if prepareZeroPerRow else "0" }}]){% endif %});
16
  }
17
  aFloat[offset + {{ h }}u] = {% if precastScalar == "f16" %}f16(value){% else %}value{% endif %};
18
  }
19
  {% endfor %}
20
  } else {
21
  let bOffset = offset - params.aCount;
22
+ let k = {{ "localOffset" if prepareBatchB else "bOffset" }} / params.paddedN;
23
+ let n = {{ "localOffset" if prepareBatchB else "bOffset" }} % params.paddedN;
24
  {% for h in range(4) %}
25
  {
26
  var value = 0.0;
build/webgpu/quant-matmul-accumulate-rank2.wgsl.jinja CHANGED
@@ -26,16 +26,15 @@ fn {{ fn_name }}() -> i32 {
26
  {% else %}
27
  return 0;
28
  {% endif %}
29
- }
30
- {%- endmacro %}
31
- {%- macro quant_read_column_zero(fn_name, buffer_name, is_unsigned, present=true, per_column=false) %}
32
- fn {{ fn_name }}({% if per_column %}col: u32{% endif %}) -> i32 {
33
  {% if present %}
34
  {% if per_column %}
35
  {% if is_unsigned %}
36
- return i32({{ buffer_name }}[col]);
37
  {% else %}
38
- return {{ buffer_name }}[col];
39
  {% endif %}
40
  {% else %}
41
  {% if is_unsigned %}
@@ -47,8 +46,8 @@ fn {{ fn_name }}({% if per_column %}col: u32{% endif %}) -> i32 {
47
  {% else %}
48
  return 0;
49
  {% endif %}
50
- }
51
- {%- endmacro %}{{ quant_read_scalar_zero("read_a_zero", "a_zero_point", aUnsigned, hasAZero) }}
52
  {{ quant_read_column_zero("read_b_zero", "b_zero_point", bUnsigned, hasBZero, bZeroPerColumn) }}
53
 
54
  @compute @workgroup_size({{ tunables.WORKGROUP_SIZE_X }}, {{ tunables.WORKGROUP_SIZE_Y }})
 
26
  {% else %}
27
  return 0;
28
  {% endif %}
29
+ }{% endmacro %}
30
+ {% macro quant_read_column_zero(fn_name, buffer_name, is_unsigned, present=true, per_column=false, param_name="col", return_type="i32") %}
31
+ fn {{ fn_name }}({% if per_column %}{{ param_name }}: u32{% endif %}) -> {{ return_type }} {
 
32
  {% if present %}
33
  {% if per_column %}
34
  {% if is_unsigned %}
35
+ return i32({{ buffer_name }}[{{ param_name }}]);
36
  {% else %}
37
+ return {{ buffer_name }}[{{ param_name }}];
38
  {% endif %}
39
  {% else %}
40
  {% if is_unsigned %}
 
46
  {% else %}
47
  return 0;
48
  {% endif %}
49
+ }{% endmacro %}
50
+ {{ quant_read_scalar_zero("read_a_zero", "a_zero_point", aUnsigned, hasAZero) }}
51
  {{ quant_read_column_zero("read_b_zero", "b_zero_point", bUnsigned, hasBZero, bZeroPerColumn) }}
52
 
53
  @compute @workgroup_size({{ tunables.WORKGROUP_SIZE_X }}, {{ tunables.WORKGROUP_SIZE_Y }})
build/webgpu/quant-matmul-accumulate-rank4.wgsl.jinja CHANGED
@@ -26,9 +26,7 @@ fn {{ fn_name }}() -> i32 {
26
  {% else %}
27
  return 0;
28
  {% endif %}
29
- }
30
- {%- endmacro %}
31
-
32
 
33
  {{ quant_read_scalar_zero("read_a_zero", "a_zero_point", aUnsigned, true if outputToScratch else hasAZero) }}
34
  {{ quant_read_scalar_zero("read_b_zero", "b_zero_point", bUnsigned, hasBZero) }}
 
26
  {% else %}
27
  return 0;
28
  {% endif %}
29
+ }{% endmacro %}
 
 
30
 
31
  {{ quant_read_scalar_zero("read_a_zero", "a_zero_point", aUnsigned, true if outputToScratch else hasAZero) }}
32
  {{ quant_read_scalar_zero("read_b_zero", "b_zero_point", bUnsigned, hasBZero) }}
build/webgpu/test.json CHANGED
@@ -1040,7 +1040,7 @@
1040
  "name": "percol_b_zero_point_no_azp_below_dp4a_floor",
1041
  "provenance": {
1042
  "source": "onnxruntime/test/providers/cpu/math/matmul_integer_test.cc",
1043
- "notes": "Per-column weight zero-point with NO a_zero_point below the dp4a floor: K=8 misses the K >= 64 guard and numel(Y)=12 misses the 8192-element guard, so dp4a_rank2_b_zero_point_per_column is ineligible and the naive per-column kernel runs. b_zero_point rank-1 size N=3 == dim(Y,1); the absent a_zero_point defaults to 0."
1044
  },
1045
  "inputs": {
1046
  "a": {
@@ -1083,10 +1083,41 @@
1083
  "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
1084
  "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1085
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1086
  {
1087
  "name": "k258_unaligned_k_scalar_zp_u8u8",
1088
  "provenance": {
1089
- "notes": "K=258 is intentionally not divisible by four. The large output would otherwise admit packed accumulation, so this case verifies that the scalar route handles the unaligned reduction tail and applies scalar zero points exactly."
1090
  },
1091
  "inputs": {
1092
  "a": {
@@ -1108,7 +1139,7 @@
1108
  {
1109
  "name": "large_accumulator_dp4a_k1024_u8u8_maxmag",
1110
  "provenance": {
1111
- "notes": "Confirms the dp4a path and the naive path agree at large int32 accumulation. M=64,K=1024,N=128 -> numel(Y)=8192 and K%4==0 and K>=256, so this selects the dp4a (dot4I8Packed) kernel. Inputs include the max-magnitude bytes (255 for u8) so per-row accumulation reaches ~1024*255*255~=66.6M, well within int32, exercising the bias/zero-point fold (ca,cb,kcc) in quant-dp4a-matmul at large magnitude."
1112
  },
1113
  "inputs": {
1114
  "a": {
@@ -1304,7 +1335,7 @@
1304
  {
1305
  "name": "dp4a_tail_k130_rank2_u8u8_scalar_zp_exact",
1306
  "provenance": {
1307
- "notes": "Exactness lock for the shared DP4A two-lane final word; full words must remain branch-free while raw-bias padding keeps the missing lanes neutral."
1308
  },
1309
  "inputs": {
1310
  "a": {
@@ -1332,7 +1363,7 @@
1332
  {
1333
  "name": "dp4a_tail_k131_rank2_s8s8_scalar_zp_exact",
1334
  "provenance": {
1335
- "notes": "Exactness lock for the shared signed DP4A three-lane final word and its single raw-zero padding lane."
1336
  },
1337
  "inputs": {
1338
  "a": {
@@ -1356,9 +1387,7 @@
1356
  },
1357
  {
1358
  "name": "dp4a_tail_k129_batched3_by_rank2_exact",
1359
- "provenance": {
1360
- "notes": "Compact correctness lock for realistic adapter widths with a one-element K tail; sized to select the packed tail kernel."
1361
- },
1362
  "inputs": {
1363
  "a": {
1364
  "dtype": "uint8",
@@ -1512,7 +1541,7 @@
1512
  {
1513
  "name": "dp4a_gemv_no_zero_s8s8_m1_k64_n512",
1514
  "provenance": {
1515
- "notes": "M=1, N=512, and K=64 select the packed signed GEMV path. Omitting both zero points makes the B-sum correction and its running row sum unnecessary."
1516
  },
1517
  "inputs": {
1518
  "a": {
@@ -1692,7 +1721,7 @@
1692
  {
1693
  "name": "exact_precast_padding_m65_k33_n33_a0_bnone",
1694
  "provenance": {
1695
- "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. The original integer partial and requantization contract is unchanged."
1696
  },
1697
  "inputs": {
1698
  "a": {
@@ -1712,7 +1741,7 @@
1712
  {
1713
  "name": "exact_precast_padding_m65_k33_n33_a0_bscalar",
1714
  "provenance": {
1715
- "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. The original integer partial and requantization contract is unchanged."
1716
  },
1717
  "inputs": {
1718
  "a": {
@@ -1733,7 +1762,7 @@
1733
  {
1734
  "name": "exact_precast_padding_m65_k33_n33_a0_bcolumn",
1735
  "provenance": {
1736
- "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. The original integer partial and requantization contract is unchanged."
1737
  },
1738
  "inputs": {
1739
  "a": {
@@ -1754,7 +1783,7 @@
1754
  {
1755
  "name": "exact_precast_padding_m65_k33_n33_a1_bnone",
1756
  "provenance": {
1757
- "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. The original integer partial and requantization contract is unchanged."
1758
  },
1759
  "inputs": {
1760
  "a": {
@@ -1775,7 +1804,7 @@
1775
  {
1776
  "name": "exact_precast_padding_m65_k33_n33_a1_bscalar",
1777
  "provenance": {
1778
- "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. The original integer partial and requantization contract is unchanged."
1779
  },
1780
  "inputs": {
1781
  "a": {
@@ -1797,7 +1826,7 @@
1797
  {
1798
  "name": "exact_precast_padding_m65_k33_n33_a1_bcolumn",
1799
  "provenance": {
1800
- "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. The original integer partial and requantization contract is unchanged."
1801
  },
1802
  "inputs": {
1803
  "a": {
@@ -1819,7 +1848,7 @@
1819
  {
1820
  "name": "exact_precast_padding_m129_k65_n63_a0_bnone",
1821
  "provenance": {
1822
- "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. The original integer partial and requantization contract is unchanged."
1823
  },
1824
  "inputs": {
1825
  "a": {
@@ -1839,7 +1868,7 @@
1839
  {
1840
  "name": "exact_precast_padding_m129_k65_n63_a0_bscalar",
1841
  "provenance": {
1842
- "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. The original integer partial and requantization contract is unchanged."
1843
  },
1844
  "inputs": {
1845
  "a": {
@@ -1860,7 +1889,7 @@
1860
  {
1861
  "name": "exact_precast_padding_m129_k65_n63_a0_bcolumn",
1862
  "provenance": {
1863
- "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. The original integer partial and requantization contract is unchanged."
1864
  },
1865
  "inputs": {
1866
  "a": {
@@ -1881,7 +1910,7 @@
1881
  {
1882
  "name": "exact_precast_padding_m129_k65_n63_a1_bnone",
1883
  "provenance": {
1884
- "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. The original integer partial and requantization contract is unchanged."
1885
  },
1886
  "inputs": {
1887
  "a": {
@@ -1902,7 +1931,7 @@
1902
  {
1903
  "name": "exact_precast_padding_m129_k65_n63_a1_bscalar",
1904
  "provenance": {
1905
- "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. The original integer partial and requantization contract is unchanged."
1906
  },
1907
  "inputs": {
1908
  "a": {
@@ -1924,7 +1953,7 @@
1924
  {
1925
  "name": "exact_precast_padding_m129_k65_n63_a1_bcolumn",
1926
  "provenance": {
1927
- "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. The original integer partial and requantization contract is unchanged."
1928
  },
1929
  "inputs": {
1930
  "a": {
@@ -2266,6 +2295,52 @@
2266
  },
2267
  "outputs": { "y": { "dtype": "int32", "shape": [65, 35], "tolerance": 0 } },
2268
  "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2269
  }
2270
  ]
2271
  }
 
1040
  "name": "percol_b_zero_point_no_azp_below_dp4a_floor",
1041
  "provenance": {
1042
  "source": "onnxruntime/test/providers/cpu/math/matmul_integer_test.cc",
1043
+ "notes": "Per-column B zero points ([1, -2, 2]) with no A zero point (defaults to 0) check a compact M=4, K=8, N=3 integer matrix product."
1044
  },
1045
  "inputs": {
1046
  "a": {
 
1083
  "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
1084
  "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1085
  },
1086
+ {
1087
+ "name": "dp4a_percol_no_azp_narrow_m_tile_variable_subgroup",
1088
+ "provenance": {
1089
+ "source": "onnxruntime/test/providers/cpu/math/matmul_integer_test.cc",
1090
+ "notes": "Per-column B zero points without an A zero point, with M=64 rows, K=256, and N=128 columns, check exact integer output at a narrow row count."
1091
+ },
1092
+ "inputs": {
1093
+ "a": {
1094
+ "dtype": "uint8",
1095
+ "shape": [64, 256],
1096
+ "data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/dp4a_u8_pattern" } }
1097
+ },
1098
+ "b": {
1099
+ "dtype": "int8",
1100
+ "shape": [256, 128],
1101
+ "data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/dp4a_s8_pattern" } }
1102
+ },
1103
+ "b_zero_point": {
1104
+ "dtype": "int8",
1105
+ "shape": [128],
1106
+ "data": { "kind": "cycle", "values": [1, -2, 2, -1, 3, -3, 0, -4, 4, -5, 5] }
1107
+ }
1108
+ },
1109
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
1110
+ "tunables": {
1111
+ "EXACT_MATRIX_MIN_INVOCATIONS": 0,
1112
+ "DP4A_LARGE_MIN_M": 64,
1113
+ "DP4A_LARGE_MIN_N": 128,
1114
+ "DP4A_LARGE_MIN_K": 256
1115
+ }
1116
+ },
1117
  {
1118
  "name": "k258_unaligned_k_scalar_zp_u8u8",
1119
  "provenance": {
1120
+ "notes": "K=258 is not divisible by four; scalar zero points (a=128, b=127) on uint8 by uint8 operands check that the unaligned reduction tail is included exactly."
1121
  },
1122
  "inputs": {
1123
  "a": {
 
1139
  {
1140
  "name": "large_accumulator_dp4a_k1024_u8u8_maxmag",
1141
  "provenance": {
1142
+ "notes": "M=64, K=1024, and N=128 with uint8 operands at magnitude 255 produce large but int32-representable sums; nonzero zero points (3 and 7) verify the exact quantized result."
1143
  },
1144
  "inputs": {
1145
  "a": {
 
1335
  {
1336
  "name": "dp4a_tail_k130_rank2_u8u8_scalar_zp_exact",
1337
  "provenance": {
1338
+ "notes": "Reduction length 130 leaves two elements after complete four-element groups; scalar zero points must produce the exact integer result."
1339
  },
1340
  "inputs": {
1341
  "a": {
 
1363
  {
1364
  "name": "dp4a_tail_k131_rank2_s8s8_scalar_zp_exact",
1365
  "provenance": {
1366
+ "notes": "Reduction length 131 leaves three elements after complete four-element groups; signed operands and scalar zero points must produce the exact integer result."
1367
  },
1368
  "inputs": {
1369
  "a": {
 
1387
  },
1388
  {
1389
  "name": "dp4a_tail_k129_batched3_by_rank2_exact",
1390
+ "provenance": { "notes": "Compact integer matrix product with a one-element reduction tail and exact output." },
 
 
1391
  "inputs": {
1392
  "a": {
1393
  "dtype": "uint8",
 
1541
  {
1542
  "name": "dp4a_gemv_no_zero_s8s8_m1_k64_n512",
1543
  "provenance": {
1544
+ "notes": "A signed single-row matrix product with K=64 and N=512 omits both zero points; its result must match direct integer accumulation."
1545
  },
1546
  "inputs": {
1547
  "a": {
 
1721
  {
1722
  "name": "exact_precast_padding_m65_k33_n33_a0_bnone",
1723
  "provenance": {
1724
+ "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. Integer partials and requantization follow the exact integer contract."
1725
  },
1726
  "inputs": {
1727
  "a": {
 
1741
  {
1742
  "name": "exact_precast_padding_m65_k33_n33_a0_bscalar",
1743
  "provenance": {
1744
+ "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. Integer partials and requantization follow the exact integer contract."
1745
  },
1746
  "inputs": {
1747
  "a": {
 
1762
  {
1763
  "name": "exact_precast_padding_m65_k33_n33_a0_bcolumn",
1764
  "provenance": {
1765
+ "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. Integer partials and requantization follow the exact integer contract."
1766
  },
1767
  "inputs": {
1768
  "a": {
 
1783
  {
1784
  "name": "exact_precast_padding_m65_k33_n33_a1_bnone",
1785
  "provenance": {
1786
+ "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. Integer partials and requantization follow the exact integer contract."
1787
  },
1788
  "inputs": {
1789
  "a": {
 
1804
  {
1805
  "name": "exact_precast_padding_m65_k33_n33_a1_bscalar",
1806
  "provenance": {
1807
+ "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. Integer partials and requantization follow the exact integer contract."
1808
  },
1809
  "inputs": {
1810
  "a": {
 
1826
  {
1827
  "name": "exact_precast_padding_m65_k33_n33_a1_bcolumn",
1828
  "provenance": {
1829
+ "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. Integer partials and requantization follow the exact integer contract."
1830
  },
1831
  "inputs": {
1832
  "a": {
 
1848
  {
1849
  "name": "exact_precast_padding_m129_k65_n63_a0_bnone",
1850
  "provenance": {
1851
+ "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. Integer partials and requantization follow the exact integer contract."
1852
  },
1853
  "inputs": {
1854
  "a": {
 
1868
  {
1869
  "name": "exact_precast_padding_m129_k65_n63_a0_bscalar",
1870
  "provenance": {
1871
+ "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. Integer partials and requantization follow the exact integer contract."
1872
  },
1873
  "inputs": {
1874
  "a": {
 
1889
  {
1890
  "name": "exact_precast_padding_m129_k65_n63_a0_bcolumn",
1891
  "provenance": {
1892
+ "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. Integer partials and requantization follow the exact integer contract."
1893
  },
1894
  "inputs": {
1895
  "a": {
 
1910
  {
1911
  "name": "exact_precast_padding_m129_k65_n63_a1_bnone",
1912
  "provenance": {
1913
+ "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. Integer partials and requantization follow the exact integer contract."
1914
  },
1915
  "inputs": {
1916
  "a": {
 
1931
  {
1932
  "name": "exact_precast_padding_m129_k65_n63_a1_bscalar",
1933
  "provenance": {
1934
+ "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. Integer partials and requantization follow the exact integer contract."
1935
  },
1936
  "inputs": {
1937
  "a": {
 
1953
  {
1954
  "name": "exact_precast_padding_m129_k65_n63_a1_bcolumn",
1955
  "provenance": {
1956
+ "notes": "Exact operand conversion with simultaneous M/K/N padding; per-column zero points and scales vary independently. Integer partials and requantization follow the exact integer contract."
1957
  },
1958
  "inputs": {
1959
  "a": {
 
2295
  },
2296
  "outputs": { "y": { "dtype": "int32", "shape": [65, 35], "tolerance": 0 } },
2297
  "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2298
+ },
2299
+ {
2300
+ "name": "variable_subgroup_packed_crossover_no_zero_points",
2301
+ "provenance": {
2302
+ "notes": "A compact wide integer projection with M=64, K=128, N=128 and no zero points on either operand checks exact int8 output at a tile-aligned shape."
2303
+ },
2304
+ "inputs": {
2305
+ "a": {
2306
+ "dtype": "int8",
2307
+ "shape": [64, 128],
2308
+ "data": { "kind": "cycle", "values": [-128, 127, -37, 0, 19, 101] }
2309
+ },
2310
+ "b": {
2311
+ "dtype": "int8",
2312
+ "shape": [128, 128],
2313
+ "data": { "kind": "cycle", "values": [127, -128, 25, -63, 0, 47] }
2314
+ }
2315
+ },
2316
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
2317
+ "tunables": {
2318
+ "EXACT_MATRIX_MIN_INVOCATIONS": 0,
2319
+ "DP4A_LARGE_MIN_M": 32,
2320
+ "DP4A_LARGE_MIN_N": 64,
2321
+ "DP4A_MEDIUM_K_MAX": 64
2322
+ }
2323
+ },
2324
+ {
2325
+ "name": "variable_subgroup_packed_crossover_scalar_zero_points",
2326
+ "provenance": { "notes": "Checks exact integer output with both activation and weight zero points." },
2327
+ "inputs": {
2328
+ "a": { "dtype": "uint8", "shape": [64, 128], "data": { "kind": "cycle", "values": [0, 255, 17, 239, 128, 1] } },
2329
+ "b": {
2330
+ "dtype": "int8",
2331
+ "shape": [128, 128],
2332
+ "data": { "kind": "cycle", "values": [-128, 127, -23, 51, 0, 91] }
2333
+ },
2334
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [127] } },
2335
+ "b_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "values", "values": [-7] } }
2336
+ },
2337
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
2338
+ "tunables": {
2339
+ "EXACT_MATRIX_MIN_INVOCATIONS": 0,
2340
+ "DP4A_LARGE_MIN_M": 32,
2341
+ "DP4A_LARGE_MIN_N": 64,
2342
+ "DP4A_MEDIUM_K_MAX": 64
2343
+ }
2344
  }
2345
  ]
2346
  }