Xenova HF Staff commited on
Commit
2294432
·
verified ·
1 Parent(s): 053d171

sync 91d990483a17

Browse files
README.md CHANGED
@@ -12,24 +12,24 @@ tags:
12
 
13
  ## Description
14
 
15
- Computes an integer matrix product with 8-bit inputs, `int32` accumulation, and independently optional zero points that default to 0. The package implements rank-1 dot products, rank-2 products, rank-2/rank-3 broadcasting, rank-3 products, and rank-4-by-rank-4 products. Scalar zero points are supported throughout; `b_zero_point` additionally supports `[N]` for rank-2 B and `[batch, 1, N]` for non-broadcast rank-3 B. Other standard ONNX matmul rank combinations and N-D per-row/per-column zero-point layouts are not yet implemented.
16
 
17
  See the [ONNX `MatMulInteger` spec](https://onnx.ai/onnx/operators/onnx__MatMulInteger.html) for the reference semantics.
18
 
19
  ## Inputs
20
 
21
- | Name | Bind key | Logical dtype | Rank | Shape | Description | Presence |
22
  | --- | --- | --- | --- | --- | --- | --- |
23
- | `A` | `a` | `TA` | — | — | N-dimensional integer matrix A (int8 or uint8). | required |
24
- | `B` | `b` | `TB` | — | — | N-dimensional integer matrix B (int8 or uint8). | required |
25
- | `a_zero_point` | `a_zero_point` | `TA` | — | — | Optional scalar zero point for A; defaults to 0. Standard N-D per-row layouts are not yet implemented. | optional |
26
- | `b_zero_point` | `b_zero_point` | `TB` | — | — | Optional zero point for B; defaults to 0. Supports a scalar, `[N]` for rank-2 B, or `[batch, 1, N]` for non-broadcast rank-3 B; other standard N-D per-column layouts are not yet implemented. | optional |
27
 
28
  ## Outputs
29
 
30
- | Name | Bind key | Logical dtype | Rank | Shape | Description | Presence |
31
  | --- | --- | --- | --- | --- | --- | --- |
32
- | `Y` | `y` | `TY` | derived | ONNX MatMul result of `A` and `B` | int32 matrix product result of A * B. | required |
33
 
34
  ## Type constraints
35
 
@@ -39,23 +39,69 @@ See the [ONNX `MatMulInteger` spec](https://onnx.ai/onnx/operators/onnx__MatMulI
39
  | `TB` | `uint8`, `int8` |
40
  | `TY` | `int32` |
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  ## Files
43
 
44
- - [`metadata.json`](build/webgpu/metadata.json) — kernel metadata (id, digests, provenance)
45
  - [`manifest.json`](build/webgpu/manifest.json) — the op contract (source of truth)
46
  - [`test.json`](build/webgpu/test.json) — correctness cases
47
  - [`bench.json`](build/webgpu/bench.json) — benchmark + tuning cases
48
  - [`matmul-integer-batched.wgsl.jinja`](build/webgpu/matmul-integer-batched.wgsl.jinja)
49
  - [`quant-dp4a-matmul.wgsl.jinja`](build/webgpu/quant-dp4a-matmul.wgsl.jinja)
 
 
 
50
  - [`quant-matmul-accumulate-rank2.wgsl.jinja`](build/webgpu/quant-matmul-accumulate-rank2.wgsl.jinja)
51
  - [`quant-matmul-accumulate-rank4.wgsl.jinja`](build/webgpu/quant-matmul-accumulate-rank4.wgsl.jinja)
52
 
53
  ## Use with `@huggingface/kernels`
54
 
55
- The loader derives every required output's shape and logical dtype from the manifest contract and this call.
56
- It then allocates the result tensors automatically.
 
 
 
57
 
58
  The `version: 1` option selects the published kernel contract; it is independent of any operator opset, contrib `since_version`, or model version.
 
59
 
60
  Replace each `*Data` placeholder with a typed array containing the corresponding input data.
61
 
 
12
 
13
  ## Description
14
 
15
+ Computes an integer matrix product with 8-bit inputs, `int32` accumulation, and independently optional zero points that default to 0. The package implements rank-1 dot products, rank-2 products, rank-2/rank-3 broadcasting, rank-3 products, and rank-4-by-rank-4 products. Scalar zero points are supported throughout; `b_zero_point` additionally supports `[N]` for rank-2 B and `[batch, 1, N]` for non-broadcast rank-3 B. Other standard ONNX matmul rank combinations and N-D per-row/per-column zero-point layouts are unsupported.
16
 
17
  See the [ONNX `MatMulInteger` spec](https://onnx.ai/onnx/operators/onnx__MatMulInteger.html) for the reference semantics.
18
 
19
  ## Inputs
20
 
21
+ | Name | Upstream name | Logical dtype | Rank | Shape | Description | Presence |
22
  | --- | --- | --- | --- | --- | --- | --- |
23
+ | `a` | `A` | `TA` | — | — | N-dimensional integer matrix A (int8 or uint8). | required |
24
+ | `b` | `B` | `TB` | — | — | N-dimensional integer matrix B (int8 or uint8). | required |
25
+ | `a_zero_point` | — | `TA` | — | — | Optional scalar zero point for A; defaults to 0. Standard N-D per-row layouts are unsupported. | optional |
26
+ | `b_zero_point` | — | `TB` | — | — | Optional zero point for B; defaults to 0. Supports a scalar, `[N]` for rank-2 B, or `[batch, 1, N]` for non-broadcast rank-3 B; other standard N-D per-column layouts are unsupported. | optional |
27
 
28
  ## Outputs
29
 
30
+ | Name | Upstream name | Logical dtype | Rank | Shape | Description | Presence |
31
  | --- | --- | --- | --- | --- | --- | --- |
32
+ | `y` | `Y` | `TY` | derived | ONNX MatMul result of `a` and `b` | int32 matrix product result of A * B. | required |
33
 
34
  ## Type constraints
35
 
 
39
  | `TB` | `uint8`, `int8` |
40
  | `TY` | `int32` |
41
 
42
+ ## Implementation variants
43
+
44
+ One implementation is selected per call from the device capabilities, the request shapes and the dtypes; these notes say what each one covers.
45
+
46
+ - `sgmat_precast_a0_bnone_f16` — Prepare exact f16 representations of adjusted byte integers once, then load them directly into f32-accumulating subgroup matrices. Row groups follow matrix geometry, output rows, invocation limits and workgroup storage; bounded partial sums retain exact modular int32 arithmetic.
47
+ - `portable_precast_a0_bnone_f16` — Prepare lossless f16 representations of adjusted byte integers, then use vector workgroup GEMM with exact bounded f32 partials and modular int32 totals. Geometry follows output rows, invocation and storage limits; f32 storage requires enough row reuse to amortize preparation.
48
+ - `sgmat_precast_a0_bnone` — Prepare exact f32 representations of adjusted byte integers once, then load them directly into f32-accumulating subgroup matrices. Row groups follow matrix geometry, output rows, invocation limits and workgroup storage; bounded partial sums retain exact modular int32 arithmetic.
49
+ - `portable_precast_a0_bnone` — Prepare lossless f32 representations of adjusted byte integers, then use vector workgroup GEMM with exact bounded f32 partials and modular int32 totals. Geometry follows output rows, invocation and storage limits; f32 storage requires enough row reuse to amortize preparation.
50
+ - `sgmat_precast_a0_bscalar_f16` — Prepare exact f16 representations of adjusted byte integers once, then load them directly into f32-accumulating subgroup matrices. Row groups follow matrix geometry, output rows, invocation limits and workgroup storage; bounded partial sums retain exact modular int32 arithmetic.
51
+ - `portable_precast_a0_bscalar_f16` — Prepare lossless f16 representations of adjusted byte integers, then use vector workgroup GEMM with exact bounded f32 partials and modular int32 totals. Geometry follows output rows, invocation and storage limits; f32 storage requires enough row reuse to amortize preparation.
52
+ - `sgmat_precast_a0_bscalar` — Prepare exact f32 representations of adjusted byte integers once, then load them directly into f32-accumulating subgroup matrices. Row groups follow matrix geometry, output rows, invocation limits and workgroup storage; bounded partial sums retain exact modular int32 arithmetic.
53
+ - `portable_precast_a0_bscalar` — Prepare lossless f32 representations of adjusted byte integers, then use vector workgroup GEMM with exact bounded f32 partials and modular int32 totals. Geometry follows output rows, invocation and storage limits; f32 storage requires enough row reuse to amortize preparation.
54
+ - `sgmat_precast_a0_bcolumn_f16` — Prepare exact f16 representations of adjusted byte integers once, then load them directly into f32-accumulating subgroup matrices. Row groups follow matrix geometry, output rows, invocation limits and workgroup storage; bounded partial sums retain exact modular int32 arithmetic.
55
+ - `portable_precast_a0_bcolumn_f16` — Prepare lossless f16 representations of adjusted byte integers, then use vector workgroup GEMM with exact bounded f32 partials and modular int32 totals. Geometry follows output rows, invocation and storage limits; f32 storage requires enough row reuse to amortize preparation.
56
+ - `sgmat_precast_a0_bcolumn` — Prepare exact f32 representations of adjusted byte integers once, then load them directly into f32-accumulating subgroup matrices. Row groups follow matrix geometry, output rows, invocation limits and workgroup storage; bounded partial sums retain exact modular int32 arithmetic.
57
+ - `portable_precast_a0_bcolumn` — Prepare lossless f32 representations of adjusted byte integers, then use vector workgroup GEMM with exact bounded f32 partials and modular int32 totals. Geometry follows output rows, invocation and storage limits; f32 storage requires enough row reuse to amortize preparation.
58
+ - `sgmat_precast_a1_bnone_f16` — Prepare exact f16 representations of adjusted byte integers once, then load them directly into f32-accumulating subgroup matrices. Row groups follow matrix geometry, output rows, invocation limits and workgroup storage; bounded partial sums retain exact modular int32 arithmetic.
59
+ - `portable_precast_a1_bnone_f16` — Prepare lossless f16 representations of adjusted byte integers, then use vector workgroup GEMM with exact bounded f32 partials and modular int32 totals. Geometry follows output rows, invocation and storage limits; f32 storage requires enough row reuse to amortize preparation.
60
+ - `sgmat_precast_a1_bnone` — Prepare exact f32 representations of adjusted byte integers once, then load them directly into f32-accumulating subgroup matrices. Row groups follow matrix geometry, output rows, invocation limits and workgroup storage; bounded partial sums retain exact modular int32 arithmetic.
61
+ - `portable_precast_a1_bnone` — Prepare lossless f32 representations of adjusted byte integers, then use vector workgroup GEMM with exact bounded f32 partials and modular int32 totals. Geometry follows output rows, invocation and storage limits; f32 storage requires enough row reuse to amortize preparation.
62
+ - `sgmat_precast_a1_bscalar_f16` — Prepare exact f16 representations of adjusted byte integers once, then load them directly into f32-accumulating subgroup matrices. Row groups follow matrix geometry, output rows, invocation limits and workgroup storage; bounded partial sums retain exact modular int32 arithmetic.
63
+ - `portable_precast_a1_bscalar_f16` — Prepare lossless f16 representations of adjusted byte integers, then use vector workgroup GEMM with exact bounded f32 partials and modular int32 totals. Geometry follows output rows, invocation and storage limits; f32 storage requires enough row reuse to amortize preparation.
64
+ - `sgmat_precast_a1_bscalar` — Prepare exact f32 representations of adjusted byte integers once, then load them directly into f32-accumulating subgroup matrices. Row groups follow matrix geometry, output rows, invocation limits and workgroup storage; bounded partial sums retain exact modular int32 arithmetic.
65
+ - `portable_precast_a1_bscalar` — Prepare lossless f32 representations of adjusted byte integers, then use vector workgroup GEMM with exact bounded f32 partials and modular int32 totals. Geometry follows output rows, invocation and storage limits; f32 storage requires enough row reuse to amortize preparation.
66
+ - `sgmat_precast_a1_bcolumn_f16` — Prepare exact f16 representations of adjusted byte integers once, then load them directly into f32-accumulating subgroup matrices. Row groups follow matrix geometry, output rows, invocation limits and workgroup storage; bounded partial sums retain exact modular int32 arithmetic.
67
+ - `portable_precast_a1_bcolumn_f16` — Prepare lossless f16 representations of adjusted byte integers, then use vector workgroup GEMM with exact bounded f32 partials and modular int32 totals. Geometry follows output rows, invocation and storage limits; f32 storage requires enough row reuse to amortize preparation.
68
+ - `sgmat_precast_a1_bcolumn` — Prepare exact f32 representations of adjusted byte integers once, then load them directly into f32-accumulating subgroup matrices. Row groups follow matrix geometry, output rows, invocation limits and workgroup storage; bounded partial sums retain exact modular int32 arithmetic.
69
+ - `portable_precast_a1_bcolumn` — Prepare lossless f32 representations of adjusted byte integers, then use vector workgroup GEMM with exact bounded f32 partials and modular int32 totals. Geometry follows output rows, invocation and storage limits; f32 storage requires enough row reuse to amortize preparation.
70
+ - `sgmat_exact_a0_bnone` — Exact integer products through bounded f32 subgroup-matrix partials accumulated with modular int32 additions. Tile height follows workgroup memory and invocation limits.
71
+ - `sgmat_exact_a0_bscalar` — Exact integer products through bounded f32 subgroup-matrix partials accumulated with modular int32 additions. Tile height follows workgroup memory and invocation limits.
72
+ - `sgmat_exact_a0_bcolumn` — Exact integer products through bounded f32 subgroup-matrix partials accumulated with modular int32 additions. Tile height follows workgroup memory and invocation limits.
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
+
79
+ Some implementation variants require `subgroup-matrix`, `shader-f16`, and `subgroups`. These are route-specific capabilities, not package-wide requirements; availability also depends on the request shape and dtype.
80
+
81
  ## Files
82
 
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)
90
+ - [`quant-exact-portable.wgsl.jinja`](build/webgpu/quant-exact-portable.wgsl.jinja)
91
+ - [`quant-exact-prepare.wgsl.jinja`](build/webgpu/quant-exact-prepare.wgsl.jinja)
92
  - [`quant-matmul-accumulate-rank2.wgsl.jinja`](build/webgpu/quant-matmul-accumulate-rank2.wgsl.jinja)
93
  - [`quant-matmul-accumulate-rank4.wgsl.jinja`](build/webgpu/quant-matmul-accumulate-rank4.wgsl.jinja)
94
 
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.
102
 
103
  The `version: 1` option selects the published kernel contract; it is independent of any operator opset, contrib `since_version`, or model version.
104
+ It follows the `v1` branch as fixes land. To pin exact artifact bytes, pass a 40-character commit `revision` instead of `version`.
105
 
106
  Replace each `*Data` placeholder with a typed array containing the corresponding input data.
107
 
build/webgpu/bench.json CHANGED
@@ -1,5 +1,4 @@
1
  {
2
- "op": "ai.onnx.MatMulInteger",
3
  "cases": [
4
  {
5
  "name": "u8_128x128",
@@ -302,7 +301,7 @@
302
  "name": "manifest-gap-rank2-u8s8-k63-dp4a-floor-m512n4096",
303
  "preset": "stress",
304
  "provenance": {
305
- "source": "authored for boundary coverage",
306
  "notes": "Realistic narrow projection immediately below the rank-2 DP4A K >= 64 guard; the paired K64 case isolates the selector boundary."
307
  },
308
  "vars": { "M": 512, "K": 63, "N": 4096 },
@@ -314,6 +313,117 @@
314
  },
315
  "outputs": { "y": { "dtype": "int32", "shape": [512, 4096], "dist": "empty" } },
316
  "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  }
318
  ]
319
  }
 
1
  {
 
2
  "cases": [
3
  {
4
  "name": "u8_128x128",
 
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 },
 
313
  },
314
  "outputs": { "y": { "dtype": "int32", "shape": [512, 4096], "dist": "empty" } },
315
  "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] }
316
+ },
317
+ {
318
+ "name": "matrix_storage_m32_k128_n8192",
319
+ "preset": "stress",
320
+ "inputs": {
321
+ "a": { "dtype": "uint8", "shape": [32, 128], "dist": "randint", "seed": 1303, "min": 0, "max": 255 },
322
+ "b": { "dtype": "int8", "shape": [128, 8192], "dist": "randint", "seed": 1304, "min": -127, "max": 127 },
323
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [128] } },
324
+ "b_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "values", "values": [-3] } }
325
+ },
326
+ "outputs": { "y": { "dtype": "int32", "shape": [32, 8192] } },
327
+ "tunableSpace": {
328
+ "DP4A_LARGE_TILE_M": [16, 32],
329
+ "DP4A_LARGE_TILE_N": [64, 128],
330
+ "DP4A_LARGE_K_TILE_WORDS": [16, 32, 64]
331
+ },
332
+ "bench": { "metrics": [{ "type": "gflops", "value": 67108864 }] }
333
+ },
334
+ {
335
+ "name": "matrix_storage_m32_k1024_n8192",
336
+ "preset": "stress",
337
+ "inputs": {
338
+ "a": { "dtype": "uint8", "shape": [32, 1024], "dist": "randint", "seed": 1303, "min": 0, "max": 255 },
339
+ "b": { "dtype": "int8", "shape": [1024, 8192], "dist": "randint", "seed": 1304, "min": -127, "max": 127 },
340
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [128] } },
341
+ "b_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "values", "values": [-3] } }
342
+ },
343
+ "outputs": { "y": { "dtype": "int32", "shape": [32, 8192] } },
344
+ "tunableSpace": {
345
+ "DP4A_LARGE_TILE_M": [16, 32],
346
+ "DP4A_LARGE_TILE_N": [64, 128],
347
+ "DP4A_LARGE_K_TILE_WORDS": [16, 32, 64]
348
+ },
349
+ "bench": { "metrics": [{ "type": "gflops", "value": 536870912 }] }
350
+ },
351
+ {
352
+ "name": "matrix_storage_m48_k1024_n8192",
353
+ "preset": "stress",
354
+ "inputs": {
355
+ "a": { "dtype": "uint8", "shape": [48, 1024], "dist": "randint", "seed": 1303, "min": 0, "max": 255 },
356
+ "b": { "dtype": "int8", "shape": [1024, 8192], "dist": "randint", "seed": 1304, "min": -127, "max": 127 },
357
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [128] } },
358
+ "b_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "values", "values": [-3] } }
359
+ },
360
+ "outputs": { "y": { "dtype": "int32", "shape": [48, 8192] } },
361
+ "tunableSpace": {
362
+ "DP4A_LARGE_TILE_M": [16, 32],
363
+ "DP4A_LARGE_TILE_N": [64, 128],
364
+ "DP4A_LARGE_K_TILE_WORDS": [16, 32, 64]
365
+ },
366
+ "bench": { "metrics": [{ "type": "gflops", "value": 805306368 }] }
367
+ },
368
+ {
369
+ "name": "exact-precast-padded-m127-k257-n4097-column-zp",
370
+ "inputs": {
371
+ "a": { "dtype": "uint8", "shape": [127, 257], "dist": "randint", "min": 0, "max": 255, "seed": 1307 },
372
+ "b": { "dtype": "int8", "shape": [257, 4097], "dist": "randint", "min": -128, "max": 127, "seed": 1308 },
373
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "dist": "constant", "value": 127 },
374
+ "b_zero_point": { "dtype": "int8", "shape": [4097], "dist": "randint", "min": -8, "max": 8, "seed": 1309 }
375
+ },
376
+ "outputs": { "y": { "dtype": "int32", "shape": [127, 4097] } },
377
+ "vars": { "M": 127, "K": 257, "N": 4097 },
378
+ "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] }
379
+ },
380
+ {
381
+ "name": "exact-precast-padded-m129-k1025-n2049-column-zp",
382
+ "inputs": {
383
+ "a": { "dtype": "uint8", "shape": [129, 1025], "dist": "randint", "min": 0, "max": 255, "seed": 1307 },
384
+ "b": { "dtype": "int8", "shape": [1025, 2049], "dist": "randint", "min": -128, "max": 127, "seed": 1308 },
385
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "dist": "constant", "value": 127 },
386
+ "b_zero_point": { "dtype": "int8", "shape": [2049], "dist": "randint", "min": -8, "max": 8, "seed": 1309 }
387
+ },
388
+ "outputs": { "y": { "dtype": "int32", "shape": [129, 2049] } },
389
+ "vars": { "M": 129, "K": 1025, "N": 2049 },
390
+ "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] }
391
+ },
392
+ {
393
+ "name": "exact-portable-row-reuse-m63-k1025-n8193",
394
+ "inputs": {
395
+ "a": { "dtype": "uint8", "shape": [63, 1025], "dist": "randint", "min": 0, "max": 255, "seed": 1307 },
396
+ "b": { "dtype": "int8", "shape": [1025, 8193], "dist": "randint", "min": -128, "max": 127, "seed": 1308 },
397
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "dist": "constant", "value": 127 },
398
+ "b_zero_point": { "dtype": "int8", "shape": [8193], "dist": "randint", "min": -8, "max": 8, "seed": 1309 }
399
+ },
400
+ "outputs": { "y": { "dtype": "int32", "shape": [63, 8193] } },
401
+ "vars": { "M": 63, "K": 1025, "N": 8193 },
402
+ "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] }
403
+ },
404
+ {
405
+ "name": "exact-portable-row-reuse-m64-k1025-n8193",
406
+ "inputs": {
407
+ "a": { "dtype": "uint8", "shape": [64, 1025], "dist": "randint", "min": 0, "max": 255, "seed": 1307 },
408
+ "b": { "dtype": "int8", "shape": [1025, 8193], "dist": "randint", "min": -128, "max": 127, "seed": 1308 },
409
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "dist": "constant", "value": 127 },
410
+ "b_zero_point": { "dtype": "int8", "shape": [8193], "dist": "randint", "min": -8, "max": 8, "seed": 1309 }
411
+ },
412
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 8193] } },
413
+ "vars": { "M": 64, "K": 1025, "N": 8193 },
414
+ "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] }
415
+ },
416
+ {
417
+ "name": "exact-portable-row-reuse-m65-k1025-n8193",
418
+ "inputs": {
419
+ "a": { "dtype": "uint8", "shape": [65, 1025], "dist": "randint", "min": 0, "max": 255, "seed": 1307 },
420
+ "b": { "dtype": "int8", "shape": [1025, 8193], "dist": "randint", "min": -128, "max": 127, "seed": 1308 },
421
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "dist": "constant", "value": 127 },
422
+ "b_zero_point": { "dtype": "int8", "shape": [8193], "dist": "randint", "min": -8, "max": 8, "seed": 1309 }
423
+ },
424
+ "outputs": { "y": { "dtype": "int32", "shape": [65, 8193] } },
425
+ "vars": { "M": 65, "K": 1025, "N": 8193 },
426
+ "bench": { "metrics": [{ "type": "gflops", "value": "2 * args.M * args.K * args.N" }] }
427
  }
428
  ]
429
  }
build/webgpu/manifest.json CHANGED
The diff for this file is too large to render. See raw diff
 
build/webgpu/metadata.json CHANGED
@@ -1,21 +1,92 @@
1
  {
2
  "name": "ai.onnx.MatMulInteger",
3
- "id": "_ai_onnx_matmulinteger_webgpu_49a7f67",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "backend": { "type": "webgpu" },
7
  "digest": {
8
  "algorithm": "sha256",
9
  "files": {
10
- "bench.json": "FnGzHstTdNzZUAKkS4uTFK6rlFK9ZlpPlI3CowZMTYo=",
11
- "manifest.json": "4Z43Up2znCaOeLQGxVbSRZ8lMck5cRA9Dh9wYJoEyhY=",
12
  "matmul-integer-batched.wgsl.jinja": "pKWtzKeL62KPieYc+I4FzUkq7JlCuZg3n7/JNjoWTHo=",
13
- "quant-dp4a-matmul.wgsl.jinja": "Cn4P+iAsCchDRKrfqRJCz7fwjxB9dUBMeA5O+SaZcS0=",
 
 
 
14
  "quant-matmul-accumulate-rank2.wgsl.jinja": "S7SS4pG+oB2O1EmKrPiNg9VHkqQwJ8mrA5M68wciLE0=",
15
- "quant-matmul-accumulate-rank4.wgsl.jinja": "8nSBI898d9CXoR7teRTn37WPRfYQNpHKBiB/1XD2LBo=",
16
- "test.json": "ne4X/jrV8sQ610RNxaGWFTWppPB64cOp7y4KHoMljKk="
17
  }
18
  },
19
- "provenance": { "kernel": { "sha": "2e7068faf55e7f43df740015f6d1ee49391a41c5", "dirty": false } },
20
- "webgpu": { "manifestSpec": "1.0", "specialized": true, "opPath": "ops/ai.onnx.MatMulInteger" }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  }
 
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"],
28
+ "sgmat_precast_a0_bnone": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
29
+ "portable_precast_a0_bnone": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
30
+ "sgmat_precast_a0_bscalar_f16": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
31
+ "portable_precast_a0_bscalar_f16": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
32
+ "sgmat_precast_a0_bscalar": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
33
+ "portable_precast_a0_bscalar": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
34
+ "sgmat_precast_a0_bcolumn_f16": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
35
+ "portable_precast_a0_bcolumn_f16": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
36
+ "sgmat_precast_a0_bcolumn": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
37
+ "portable_precast_a0_bcolumn": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
38
+ "sgmat_precast_a1_bnone_f16": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
39
+ "portable_precast_a1_bnone_f16": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
40
+ "sgmat_precast_a1_bnone": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
41
+ "portable_precast_a1_bnone": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
42
+ "sgmat_precast_a1_bscalar_f16": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
43
+ "portable_precast_a1_bscalar_f16": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
44
+ "sgmat_precast_a1_bscalar": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
45
+ "portable_precast_a1_bscalar": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
46
+ "sgmat_precast_a1_bcolumn_f16": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
47
+ "portable_precast_a1_bcolumn_f16": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
48
+ "sgmat_precast_a1_bcolumn": ["quant-exact-matrix.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
49
+ "portable_precast_a1_bcolumn": ["quant-exact-portable.wgsl.jinja", "quant-exact-prepare.wgsl.jinja"],
50
+ "sgmat_exact_a0_bnone": ["quant-exact-matrix.wgsl.jinja"],
51
+ "sgmat_exact_a0_bscalar": ["quant-exact-matrix.wgsl.jinja"],
52
+ "sgmat_exact_a0_bcolumn": ["quant-exact-matrix.wgsl.jinja"],
53
+ "sgmat_exact_a1_bnone": ["quant-exact-matrix.wgsl.jinja"],
54
+ "sgmat_exact_a1_bscalar": ["quant-exact-matrix.wgsl.jinja"],
55
+ "sgmat_exact_a1_bcolumn": ["quant-exact-matrix.wgsl.jinja"],
56
+ "dp4a_rank2_scalar_zero_points_tail": ["quant-dp4a-matmul.wgsl.jinja"],
57
+ "dp4a_rank2_no_zero_points_tail": ["quant-dp4a-matmul.wgsl.jinja"],
58
+ "dp4a_rank3_by_rank2_scalar_zero_points_tail": ["quant-dp4a-matmul.wgsl.jinja"],
59
+ "dp4a_rank2_scalar_zero_points": ["quant-dp4a-matmul.wgsl.jinja"],
60
+ "dp4a_rank2_a_zero_point_only": ["quant-dp4a-matmul.wgsl.jinja"],
61
+ "dp4a_rank2_b_zero_point_only": ["quant-dp4a-matmul.wgsl.jinja"],
62
+ "dp4a_rank2_no_zero_points": ["quant-dp4a-matmul.wgsl.jinja"],
63
+ "dp4a_rank2_b_zero_point_per_column": ["quant-dp4a-matmul.wgsl.jinja"],
64
+ "dp4a_rank2_a_zero_point_b_per_column": ["quant-dp4a-matmul.wgsl.jinja"],
65
+ "rank2_scalar_zero_points": ["quant-matmul-accumulate-rank2.wgsl.jinja"],
66
+ "rank2_a_zero_point_only": ["quant-matmul-accumulate-rank2.wgsl.jinja"],
67
+ "rank2_b_zero_point_only": ["quant-matmul-accumulate-rank2.wgsl.jinja"],
68
+ "rank1_dot_b_zero_point_only": ["quant-matmul-accumulate-rank2.wgsl.jinja"],
69
+ "rank1_dot_no_zero_points": ["quant-matmul-accumulate-rank2.wgsl.jinja"],
70
+ "rank2_no_zero_points": ["quant-matmul-accumulate-rank2.wgsl.jinja"],
71
+ "rank2_b_zero_point_per_column": ["quant-matmul-accumulate-rank2.wgsl.jinja"],
72
+ "rank2_b_zero_point_per_column_no_azp": ["quant-matmul-accumulate-rank2.wgsl.jinja"],
73
+ "rank3_by_rank3_scalar_zero_points": ["matmul-integer-batched.wgsl.jinja"],
74
+ "rank3_by_rank3_no_zero_points": ["matmul-integer-batched.wgsl.jinja"],
75
+ "rank3_by_rank3_a_zero_point_only": ["matmul-integer-batched.wgsl.jinja"],
76
+ "rank3_by_rank3_b_zero_point_only": ["matmul-integer-batched.wgsl.jinja"],
77
+ "rank3_by_rank3_b_zero_point_per_column_batched": ["matmul-integer-batched.wgsl.jinja"],
78
+ "rank3_by_rank3_b_zero_point_per_column_batched_no_azp": ["matmul-integer-batched.wgsl.jinja"],
79
+ "rank2_by_rank3_scalar_zero_points": ["matmul-integer-batched.wgsl.jinja"],
80
+ "rank2_by_rank3_a_zero_point_only": ["matmul-integer-batched.wgsl.jinja"],
81
+ "rank2_by_rank3_b_zero_point_only": ["matmul-integer-batched.wgsl.jinja"],
82
+ "rank2_by_rank3_no_zero_points": ["matmul-integer-batched.wgsl.jinja"],
83
+ "rank4_scalar_zero_points": ["quant-matmul-accumulate-rank4.wgsl.jinja"],
84
+ "rank4_a_zero_point_only": ["quant-matmul-accumulate-rank4.wgsl.jinja"],
85
+ "rank4_b_zero_point_only": ["quant-matmul-accumulate-rank4.wgsl.jinja"],
86
+ "rank4_no_zero_points": ["quant-matmul-accumulate-rank4.wgsl.jinja"],
87
+ "dp4a_rank3_by_rank3_scalar_zero_points": ["quant-dp4a-matmul.wgsl.jinja"],
88
+ "dp4a_rank4_scalar_zero_points": ["quant-dp4a-matmul.wgsl.jinja"],
89
+ "dp4a_rank4_no_zero_points": ["quant-dp4a-matmul.wgsl.jinja"]
90
+ }
91
+ }
92
  }
build/webgpu/quant-dp4a-matmul.wgsl.jinja CHANGED
@@ -1,8 +1,25 @@
1
- {% if requant != "none" and scaleScalar == "f16" %}
2
- enable f16;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  {% endif %}
4
  {{ env.wgsl.resourceDeclarations }}
5
 
 
6
  const TILE_M: u32 = {{ tileM }}u;
7
  const TILE_N: u32 = {{ tileN }}u;
8
  const KT_WORDS: u32 = {{ ktWords }}u;
@@ -92,12 +109,6 @@ fn read_b_zero({% if bZeroPerColumn %}col: u32{% endif %}) -> i32 {
92
  {% endif %}
93
  }
94
 
95
- {% endif %}
96
- {% if requant != "none" %}
97
- fn read_y_zero() -> i32 {
98
- return y_zero_point[0];
99
- }
100
-
101
  {% endif %}
102
  @compute @workgroup_size(TILE_N, 1, 1)
103
  fn main(@builtin(workgroup_id) wg: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>) {
@@ -303,16 +314,7 @@ fn main(@builtin(workgroup_id) wg: vec3<u32>, @builtin(local_invocation_id) lid:
303
  acc = acc + ca * {% if tileM == 1 %}sum_b_total{% else %}sum_b{% endif %};
304
  {% endif %}
305
  acc = acc + kcc;
306
- {% if requant == "none" %}
307
  y[y_base + mr * params.N + col] = acc;
308
- {% else %}
309
- let scaled = f32(acc) * f32(a_scale[0]) * f32(b_scale[{% if requant == "per_column" %}col{% elif requant == "per_row" %}mr{% else %}0u{% endif %}]) / f32(y_scale[0]);
310
- // Clamp the rounded float into an i32-representable range before the cast
311
- // so a huge-finite / Inf requantized value saturates (the final clamp pins
312
- // it to [qMin,qMax]) instead of invoking undefined i32(huge_float).
313
- let q = clamp(i32(clamp(round(scaled), -2.0e9, 2.0e9)) + read_y_zero(), {{ qMin }}, {{ qMax }});
314
- y[y_base + mr * params.N + col] = q;
315
- {% endif %}
316
  }
317
  }
318
  {% endfor %}
 
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
4
+ // language feature is present. The user functions retain the built-ins'
5
+ // @must_use contract, but cannot be @const; every call is runtime.
6
+ // Inputs are function parameters, so replacing a built-in call with one of
7
+ // these same-name functions preserves WGSL's single evaluation of each
8
+ // argument. Byte extraction is unsigned. Signed lanes use the exact
9
+ // i32(byte ^ 0x80u) - 128i sign extension, avoiding signed-left-shift overflow
10
+ // while preserving every 8-bit two's-complement value.
11
+ @must_use fn dot4I8Packed(e1: u32, e2: u32) -> i32 {
12
+ let shifts = vec4<u32>(0u, 8u, 16u, 24u);
13
+ let a_bytes = (vec4<u32>(e1) >> shifts) & vec4<u32>(0xffu);
14
+ let b_bytes = (vec4<u32>(e2) >> shifts) & vec4<u32>(0xffu);
15
+ let a = vec4<i32>(a_bytes ^ vec4<u32>(0x80u)) - vec4<i32>(128i);
16
+ let b = vec4<i32>(b_bytes ^ vec4<u32>(0x80u)) - vec4<i32>(128i);
17
+ return dot(a, b);
18
+ }
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;
 
109
  {% endif %}
110
  }
111
 
 
 
 
 
 
 
112
  {% endif %}
113
  @compute @workgroup_size(TILE_N, 1, 1)
114
  fn main(@builtin(workgroup_id) wg: vec3<u32>, @builtin(local_invocation_id) lid: vec3<u32>) {
 
314
  acc = acc + ca * {% if tileM == 1 %}sum_b_total{% else %}sum_b{% endif %};
315
  {% endif %}
316
  acc = acc + kcc;
 
317
  y[y_base + mr * params.N + col] = acc;
 
 
 
 
 
 
 
 
318
  }
319
  }
320
  {% endfor %}
build/webgpu/quant-exact-matrix.wgsl.jinja ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
14
+ // has absolute magnitude at most 2^24; int32 adds then preserve wraparound.
15
+ const TILE_M: u32 = {{ sgmatTileM }}u;
16
+ const TILE_N: u32 = {{ sgmatTileN }}u;
17
+ const TILE_K: u32 = {{ sgmatTileK }}u;
18
+
19
+ {% if precastOperands %}
20
+ const PADDED_K: u32 = {{ preparedK }}u;
21
+ const PADDED_N: u32 = {{ preparedN }}u;
22
+ var<workgroup> matrix_out: array<f32, {{ sgmatSubgroups * 8 * 64 }}>;
23
+ {% else %}
24
+ var<workgroup> tile_A: array<f32, {{ sgmatTileM * sgmatTileK }}>;
25
+ var<workgroup> tile_B: array<f32, {{ sgmatTileK * sgmatTileN }}>;
26
+ {% if not sgmatReuseStaging %}
27
+ var<workgroup> scratch: array<array<array<f32, 64>, 4>, {{ sgmatSubgroups }}>;
28
+ {% endif %}
29
+ {% endif %}
30
+
31
+ @compute @workgroup_size({{ sgmatWorkgroup }}){{ " @subgroup_size(32)" if pinSubgroupSize32 else "" }}
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;
39
+ let row = lane / 4u;
40
+ let col = (lane % 4u) * 2u;
41
+ // Bound adjusted byte magnitudes from scalar zero points. A column-wise
42
+ // B zero point keeps the full byte-difference bound for the whole tile.
43
+ let max_a = {% if hasAZero %}u32(max(abs({{ 0 if aUnsigned else (0 - 128) }} - i32(a_zero_point[0])), abs({{ 255 if aUnsigned else 127 }} - i32(a_zero_point[0])))){% else %}{{ 255 if aUnsigned else 128 }}u{% endif %};
44
+ let max_b = {% if hasBZero and not bZeroPerColumn %}u32(max(abs({{ 0 if bUnsigned else (0 - 128) }} - i32(b_zero_point[0])), abs({{ 255 if bUnsigned else 127 }} - i32(b_zero_point[0])))){% else %}{{ 255 if hasBZero or bUnsigned else 128 }}u{% endif %};
45
+ let partial_k = (16777216u / (max_a * max_b) / TILE_K) * TILE_K;
46
+ var totals: array<i32, 16>;
47
+ for (var partial = 0u; partial < params.K; partial += partial_k) {
48
+ {% for r in range(2) %}{% for c in range(4) %}
49
+ var matC{{ r }}{{ c }}: subgroup_matrix_result<f32, 8, 8>;
50
+ {% endfor %}{% endfor %}
51
+ let partial_end = min(params.K, partial + partial_k);
52
+ for (var kb = partial; kb < partial_end; kb += TILE_K) {
53
+ {% if not precastOperands %}
54
+ for (var index = tid; index < TILE_M * TILE_K; index += {{ sgmatWorkgroup }}u) {
55
+ let m = wid.y * TILE_M + index / TILE_K;
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
+ }
63
+ for (var index = tid; index < TILE_K * TILE_N; index += {{ sgmatWorkgroup }}u) {
64
+ let k = kb + index / TILE_N;
65
+ let n = wid.x * TILE_N + index % TILE_N;
66
+ var value = f32(0.0);
67
+ if (k < params.K && n < params.N) {
68
+ value = f32(i32(b[k * params.N + n]){% if hasBZero %} - i32(b_zero_point[{{ "n" if bZeroPerColumn else "0" }}]){% endif %});
69
+ }
70
+ tile_B[index] = value;
71
+ }
72
+ workgroupBarrier();
73
+ {% endif %}
74
+ for (var step = 0u; step < TILE_K; step += 8u) {
75
+ {% for r in range(2) %}
76
+ let matA{{ r }} = subgroupMatrixLoad<subgroup_matrix_left<{{ precastScalar if precastOperands else "f32" }}, 8, 8>, row_major>(&{{ "a" if precastOperands else "tile_A" }}, {% if precastOperands %}(wid.y * TILE_M + base_A + {{ r * 8 }}u) * PADDED_K + kb + step{% else %}(base_A + {{ r * 8 }}u) * TILE_K + step{% endif %}, {{ "PADDED_K" if precastOperands else "TILE_K" }});
77
+ {% endfor %}
78
+ {% for c in range(4) %}
79
+ let matB{{ c }} = subgroupMatrixLoad<subgroup_matrix_right<{{ precastScalar if precastOperands else "f32" }}, 8, 8>, row_major>(&{{ "b" if precastOperands else "tile_B" }}, {% if precastOperands %}(kb + step) * PADDED_N + wid.x * TILE_N + base_B + {{ c * 8 }}u{% else %}step * TILE_N + base_B + {{ c * 8 }}u{% endif %}, {{ "PADDED_N" if precastOperands else "TILE_N" }});
80
+ {% endfor %}
81
+ {% for r in range(2) %}{% for c in range(4) %}
82
+ matC{{ r }}{{ c }} = subgroupMatrixMultiplyAccumulate(matA{{ r }}, matB{{ c }}, matC{{ r }}{{ c }});
83
+ {% endfor %}{% endfor %}
84
+ }
85
+ {% if not precastOperands %}
86
+ workgroupBarrier();
87
+ {% endif %}
88
+ }
89
+ {% if precastOperands %}
90
+ // The prepared operands need no staging barriers. Publish all eight
91
+ // matrices together before converting the bounded partial to int32.
92
+ {% for r in range(2) %}{% for c in range(4) %}
93
+ subgroupMatrixStore<row_major>(&matrix_out, subgroup * 512u + {{ r * 256 + c * 64 }}u, matC{{ r }}{{ c }}, 8u);
94
+ {% endfor %}{% endfor %}
95
+ workgroupBarrier();
96
+ {% for r in range(2) %}{% for c in range(4) %}{% for h in range(2) %}
97
+ totals[{{ r * 8 + c * 2 + h }}] += i32(matrix_out[subgroup * 512u + {{ r * 256 + c * 64 }}u + row * 8u + col + {{ h }}u]);
98
+ {% endfor %}{% endfor %}{% endfor %}
99
+ workgroupBarrier();
100
+ {% else %}
101
+ {% if sgmatReuseStaging %}
102
+ // All staged A reads have completed. Reuse its storage for one result band
103
+ // at a time: each subgroup needs 4 * 64 floats, exactly its A-tile share.
104
+ {% endif %}
105
+ {% for r in range(2) %}
106
+ {% for c in range(4) %}
107
+ subgroupMatrixStore<row_major>({% if sgmatReuseStaging %}&tile_A{% else %}&scratch[subgroup][{{ c }}]{% endif %}, {% if sgmatReuseStaging %}subgroup * 256u + {{ c * 64 }}u{% else %}0u{% endif %}, matC{{ r }}{{ c }}, 8u);
108
+ {% endfor %}
109
+ workgroupBarrier();
110
+ {% for c in range(4) %}{% for h in range(2) %}
111
+ totals[{{ r * 8 + c * 2 + h }}] += i32({% if sgmatReuseStaging %}tile_A[subgroup * 256u + {{ c * 64 }}u + row * 8u + col + {{ h }}u]{% else %}scratch[subgroup][{{ c }}][row * 8u + col + {{ h }}u]{% endif %});
112
+ {% endfor %}{% endfor %}
113
+ workgroupBarrier();
114
+ {% endfor %}
115
+ {% endif %}
116
+ }
117
+ {% for r in range(2) %}{% for c in range(4) %}{% for h in range(2) %}
118
+ {
119
+ let m = wid.y * TILE_M + base_A + {{ r * 8 }}u + row;
120
+ let n = wid.x * TILE_N + base_B + {{ c * 8 + h }}u + col;
121
+ if (m < params.M && n < params.N) {
122
+ y[m * params.N + n] = totals[{{ r * 8 + c * 2 + h }}];
123
+ }
124
+ }
125
+ {% endfor %}{% endfor %}{% endfor %}
126
+ }
build/webgpu/quant-exact-portable.wgsl.jinja ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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.
6
+ 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 %}
21
+ {% set threadRows = (blockRowsValue / workgroupRowsValue)|int %}
22
+ {% set threadColVectors = (blockColsValue / (workgroupColsValue * 4))|int %}
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].
30
+ // B may alternatively be stored physically as [N,K]; that mode retains vec4
31
+ // K loads and transposes only while staging the tile in workgroup memory.
32
+ //
33
+ // Both inputs and the output are four-wide along their contiguous dimension.
34
+ // The output-tile geometry and BK are selected from the shape and device's
35
+ // workgroup-storage limit. f16 operands stay packed in global and workgroup
36
+ // memory, then widen at the FMA so accumulation remains f32.
37
+ const M: u32 = {{ M }}u;
38
+ const K: u32 = {{ K }}u;
39
+ const N: u32 = {{ N }}u;
40
+ const K_V4: u32 = K / 4u;
41
+ const B_N_V4: u32 = {{ preparedNValue }}u / 4u;
42
+ const BK: u32 = {{ kTileValue }}u;
43
+ const BM: u32 = {{ blockRowsValue }}u;
44
+ const BN: u32 = {{ blockColsValue }}u;
45
+ const TM: u32 = {{ threadRows }}u;
46
+ const TN: u32 = {{ threadCols }}u;
47
+
48
+ // A is loaded and consumed four K values at a time. Keeping that packing in
49
+ // workgroup memory reduces A-side shared-memory instructions and inner-loop
50
+ // control without changing the four scalar FMA operations or their order.
51
+ var<workgroup> tileA: array<array<vec4<{{ scalar }}>, BK / 4u>, BM>;
52
+ var<workgroup> tileB: array<vec4<{{ scalar }}>, BK * (BN / 4u)>;
53
+
54
+ @compute @workgroup_size({{ workgroupColsValue }}, {{ workgroupRowsValue }}, 1)
55
+ fn main(
56
+ @builtin(workgroup_id) wg: vec3<u32>,
57
+ @builtin(local_invocation_id) lid: vec3<u32>
58
+ ) {
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) %}
67
+ var acc{{ i }}_{{ j }} = vec4<{{ accumulatorScalarValue }}>(0.0);
68
+ var total{{ i }}_{{ j }} = vec4<i32>(0);
69
+ {% endfor %}
70
+ {% endfor %}
71
+
72
+ for (var kBase: u32 = 0u; kBase < K; kBase = kBase + BK) {
73
+ {% for av in range(aVectorCount) %}
74
+ let aVector{{ av }} = li + {{ av * laneCount }}u;
75
+ let aRow{{ av }} = aVector{{ av }} / (BK / 4u);
76
+ let aColV4_{{ av }} = aVector{{ av }} % (BK / 4u);
77
+ let am{{ av }} = mBase + aRow{{ av }};
78
+ var av4_{{ av }} = vec4<{{ scalar }}>({{ scalar }}(0));
79
+ if (am{{ av }} < M) {
80
+ av4_{{ av }} = a[{{ aOff }}am{{ av }} * K_V4 + kBase / 4u + aColV4_{{ av }}];
81
+ }
82
+ tileA[aRow{{ av }}][aColV4_{{ av }}] = av4_{{ av }};
83
+ {% endfor %}
84
+ {% for bv in range(bVectorCount) %}
85
+ let bVector{{ bv }} = li + {{ bv * laneCount }}u;
86
+ let bRow{{ bv }} = bVector{{ bv }} / (BN / 4u);
87
+ let bColV4_{{ bv }} = bVector{{ bv }} % (BN / 4u);
88
+ let bn{{ bv }} = nBase + bColV4_{{ bv }} * 4u;
89
+ var bv4_{{ bv }} = vec4<{{ scalar }}>({{ scalar }}(0));
90
+ if (bn{{ bv }} < N) {
91
+ bv4_{{ bv }} = b[{{ bOff }}(kBase + bRow{{ bv }}) * {{ "B_N_V4" if exactIntegerPartialsValue else "N_V4" }} + bn{{ bv }} / 4u];
92
+ }
93
+ tileB[bRow{{ bv }} * (BN / 4u) + bColV4_{{ bv }}] = bv4_{{ bv }};
94
+ {% endfor %}
95
+ workgroupBarrier();
96
+
97
+ let aRow = lid.y * TM;
98
+ let bCol4 = lid.x * {{ threadColVectors }}u;
99
+ for (var kv: u32 = 0u; kv < BK / 4u; kv = kv + 1u) {
100
+ let kk = kv * 4u;
101
+ {% for j in range(threadColVectors) %}
102
+ let bv0_{{ j }} = vec4<{{ accumulatorScalarValue }}>(tileB[(kk + 0u) * (BN / 4u) + bCol4 + {{ j }}u]);
103
+ let bv1_{{ j }} = vec4<{{ accumulatorScalarValue }}>(tileB[(kk + 1u) * (BN / 4u) + bCol4 + {{ j }}u]);
104
+ let bv2_{{ j }} = vec4<{{ accumulatorScalarValue }}>(tileB[(kk + 2u) * (BN / 4u) + bCol4 + {{ j }}u]);
105
+ let bv3_{{ j }} = vec4<{{ accumulatorScalarValue }}>(tileB[(kk + 3u) * (BN / 4u) + bCol4 + {{ j }}u]);
106
+ {% endfor %}
107
+ {% for i in range(threadRows) %}
108
+ let av{{ i }} = tileA[aRow + {{ i }}u][kv];
109
+ {% for j in range(threadColVectors) %}
110
+ acc{{ i }}_{{ j }} = acc{{ i }}_{{ j }} + vec4<{{ accumulatorScalarValue }}>({{ accumulatorScalarValue }}(av{{ i }}.x)) * bv0_{{ j }};
111
+ acc{{ i }}_{{ j }} = acc{{ i }}_{{ j }} + vec4<{{ accumulatorScalarValue }}>({{ accumulatorScalarValue }}(av{{ i }}.y)) * bv1_{{ j }};
112
+ acc{{ i }}_{{ j }} = acc{{ i }}_{{ j }} + vec4<{{ accumulatorScalarValue }}>({{ accumulatorScalarValue }}(av{{ i }}.z)) * bv2_{{ j }};
113
+ acc{{ i }}_{{ j }} = acc{{ i }}_{{ j }} + vec4<{{ accumulatorScalarValue }}>({{ accumulatorScalarValue }}(av{{ i }}.w)) * bv3_{{ j }};
114
+ {% endfor %}
115
+ {% endfor %}
116
+ }
117
+ workgroupBarrier();
118
+ // Adjusted byte integers and each bounded partial are exact in f32.
119
+ // Convert before exceeding that bound; int32 additions retain wraparound.
120
+ if ((kBase + BK) % {{ integerPartialKValue }}u == 0u || kBase + BK == K) {
121
+ {% for i in range(threadRows) %}{% for j in range(threadColVectors) %}
122
+ total{{ i }}_{{ j }} += vec4<i32>(acc{{ i }}_{{ j }});
123
+ acc{{ i }}_{{ j }} = vec4<f32>(0.0);
124
+ {% endfor %}{% endfor %}
125
+ }
126
+ }
127
+
128
+ let m0 = mBase + lid.y * TM;
129
+ {% for j in range(threadColVectors) %}
130
+ let n{{ j }} = nBase + lid.x * TN + {{ j * 4 }}u;
131
+ {% endfor %}
132
+ {% for i in range(threadRows) %}
133
+ {% for j in range(threadColVectors) %}
134
+ if (m0 + {{ i }}u < M && n{{ j }} < N) {
135
+ {% for h in range(4) %}
136
+ if (n{{ j }} + {{ h }}u < N) {
137
+ store_integer_result(total{{ i }}_{{ j }}[{{ h }}], (m0 + {{ i }}u) * N + n{{ j }} + {{ h }}u);
138
+ }
139
+ {% endfor %}
140
+ }
141
+ {% endfor %}
142
+ {% endfor %}
143
+ }
build/webgpu/quant-exact-prepare.wgsl.jinja ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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) {
5
+ let offset = ((wid.y * params.groupsX + wid.x) * {{ prepareWorkgroup }}u + tid) * 4u;
6
+ if (offset >= params.count) { return; }
7
+ if (offset < params.aCount) {
8
+ let m = offset / params.paddedK;
9
+ let k = offset % params.paddedK;
10
+ {% for h in range(4) %}
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;
26
+ if (k < params.K && n + {{ h }}u < params.N) {
27
+ value = f32(i32(b[k * params.N + n + {{ h }}u]){% if hasBZero %} - i32(b_zero_point[{% if bZeroPerColumn %}n + {{ h }}u{% else %}0{% endif %}]){% endif %});
28
+ }
29
+ bFloat[bOffset + {{ h }}u] = {% if precastScalar == "f16" %}f16(value){% else %}value{% endif %};
30
+ }
31
+ {% endfor %}
32
+ }
33
+ }
build/webgpu/quant-matmul-accumulate-rank4.wgsl.jinja CHANGED
@@ -30,7 +30,7 @@ fn {{ fn_name }}() -> i32 {
30
  {%- endmacro %}
31
 
32
 
33
- {{ quant_read_scalar_zero("read_a_zero", "a_zero_point", aUnsigned, true if source.outputToScratch else hasAZero) }}
34
  {{ quant_read_scalar_zero("read_b_zero", "b_zero_point", bUnsigned, hasBZero) }}
35
 
36
  @compute @workgroup_size({{ tunables.WORKGROUP_SIZE_X }}, {{ tunables.WORKGROUP_SIZE_Y }})
 
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) }}
35
 
36
  @compute @workgroup_size({{ tunables.WORKGROUP_SIZE_X }}, {{ tunables.WORKGROUP_SIZE_Y }})
build/webgpu/test.json CHANGED
@@ -1,5 +1,4 @@
1
  {
2
- "op": "ai.onnx.MatMulInteger",
3
  "fixtureArrays": {
4
  "dp4a_s8_pattern": [-128, 127, 0, -1, 56, -77, 3, 100, -100, 42, -5, 19, -64, 88, -33, 7, 125, -90],
5
  "dp4a_u8_pattern": [0, 255, 128, 7, 200, 31, 129, 64, 99, 3, 254, 127, 1, 88, 173, 240, 16, 5],
@@ -642,7 +641,7 @@
642
  }
643
  },
644
  "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
645
- "tunables": { "DP4A_SHORT_K_MIN_MN": 64 }
646
  },
647
  {
648
  "name": "dp4a_s8s8_medium_k_m64_k96_n128",
@@ -662,7 +661,12 @@
662
  }
663
  },
664
  "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
665
- "tunables": { "DP4A_SHORT_K_MAX": 64, "DP4A_MEDIUM_K_MAX": 128, "DP4A_MEDIUM_K_MIN_MN": 64 }
 
 
 
 
 
666
  },
667
  {
668
  "name": "dp4a_u8s8_k256_a_zero_point_only_large",
@@ -679,7 +683,8 @@
679
  },
680
  "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [131] } }
681
  },
682
- "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } }
 
683
  },
684
  {
685
  "name": "dp4a_s8u8_k256_b_zero_point_only_large",
@@ -696,7 +701,8 @@
696
  },
697
  "b_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [200] } }
698
  },
699
- "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } }
 
700
  },
701
  {
702
  "name": "dp4a_s8s8_k260_both_zero_points_large",
@@ -718,7 +724,12 @@
718
  "b_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "values", "values": [-7] } }
719
  },
720
  "outputs": { "y": { "dtype": "int32", "shape": [65, 129], "tolerance": 0 } },
721
- "tunables": { "DP4A_LARGE_MIN_M": 64, "DP4A_LARGE_MIN_N": 128, "DP4A_LARGE_MIN_K": 256 }
 
 
 
 
 
722
  },
723
  {
724
  "name": "dp4a_rank3_by_rank3_u8s8_k256_large",
@@ -932,7 +943,7 @@
932
  "provenance": {
933
  "source": "onnxruntime/test/providers/cpu/math/matmul_integer_test.cc",
934
  "test": "MatmulIntegerOpTest.MatMulInteger_int8_uint8_A_ND_B_ND",
935
- "notes": "Compact 4D MatMul broadcast extension of ORT's ND MatMulInteger coverage."
936
  },
937
  "inputs": {
938
  "a": {
@@ -988,7 +999,7 @@
988
  {
989
  "name": "dispatch_cliff_mtile_rows_524296",
990
  "provenance": {
991
- "notes": "M=524296 rows -> M-tiles=ceil(524296/8)=65537 > 65535. dp4a_rank2 is capped (ceil(M/8)<=65535) so this falls through to the folded matmul-integer rank2 (gid.y + gid.z*nwg.y*WORKGROUP_SIZE_Y at nwg.z=2). Validates both the fold and the dp4a cap-fallthrough; before the fold the plan guard throws."
992
  },
993
  "inputs": {
994
  "a": { "dtype": "uint8", "shape": [524296, 4], "data": { "kind": "cycle", "values": [1, 2, 3, 4, 5, 6, 7] } },
@@ -1022,7 +1033,8 @@
1022
  "data": { "kind": "cycle", "values": [1, -2, 2, -1, 3, -3, 0, -4, 4, -5, 5] }
1023
  }
1024
  },
1025
- "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } }
 
1026
  },
1027
  {
1028
  "name": "percol_b_zero_point_no_azp_below_dp4a_floor",
@@ -1068,7 +1080,8 @@
1068
  "data": { "kind": "cycle", "values": [1, -2, 2, -1, 3, -3, 0, -4, 4, -5, 5] }
1069
  }
1070
  },
1071
- "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } }
 
1072
  },
1073
  {
1074
  "name": "k258_unaligned_k_scalar_zp_u8u8",
@@ -1089,12 +1102,13 @@
1089
  "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [128] } },
1090
  "b_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [127] } }
1091
  },
1092
- "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } }
 
1093
  },
1094
  {
1095
  "name": "large_accumulator_dp4a_k1024_u8u8_maxmag",
1096
  "provenance": {
1097
- "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. ORT/CPU validates."
1098
  },
1099
  "inputs": {
1100
  "a": {
@@ -1110,7 +1124,8 @@
1110
  "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [3] } },
1111
  "b_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [7] } }
1112
  },
1113
- "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } }
 
1114
  },
1115
  {
1116
  "name": "dp4a_rank4_scalar_s8s8_2x2x64x128",
@@ -1149,7 +1164,7 @@
1149
  {
1150
  "name": "dp4a_gemv_m1_u8s8_k257_n512_scalar_zp_tail",
1151
  "provenance": {
1152
- "notes": "M=1 int8 decode GEMV with a one-lane K tail routes to the tileM=1 ILP DP4A config; validates its unrolled full-word loop and scalar tail against the reference."
1153
  },
1154
  "inputs": {
1155
  "a": {
@@ -1224,7 +1239,8 @@
1224
  "data": { "kind": "cycle", "values": [1, -2, 2, -1, 3, -3, 0, -4, 4, -5, 5] }
1225
  }
1226
  },
1227
- "outputs": { "y": { "dtype": "int32", "shape": [64, 130], "tolerance": 0 } }
 
1228
  },
1229
  {
1230
  "name": "dp4a_partial_m63_n130_tile_edge_s8s8_k256",
@@ -1282,7 +1298,8 @@
1282
  "data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/dp4a_s8_pattern" } }
1283
  }
1284
  },
1285
- "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } }
 
1286
  },
1287
  {
1288
  "name": "dp4a_tail_k130_rank2_u8u8_scalar_zp_exact",
@@ -1309,7 +1326,8 @@
1309
  "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [121] } },
1310
  "b_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [117] } }
1311
  },
1312
- "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } }
 
1313
  },
1314
  {
1315
  "name": "dp4a_tail_k131_rank2_s8s8_scalar_zp_exact",
@@ -1333,7 +1351,8 @@
1333
  "a_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "values", "values": [5] } },
1334
  "b_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "values", "values": [-7] } }
1335
  },
1336
- "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } }
 
1337
  },
1338
  {
1339
  "name": "dp4a_tail_k129_batched3_by_rank2_exact",
@@ -1361,9 +1380,7 @@
1361
  },
1362
  {
1363
  "name": "dp4a_tail_k63_rank2_u8s8_scalar_zp_exact",
1364
- "provenance": {
1365
- "notes": "Exactness and direct-route lock for the 32<=K<128 packed-tail range opened by the K63 projection pathology fix."
1366
- },
1367
  "inputs": {
1368
  "a": { "dtype": "uint8", "shape": [16, 63], "data": { "kind": "cycle", "values": [0, 255, 121, 7, 200, 31] } },
1369
  "b": { "dtype": "int8", "shape": [63, 512], "data": { "kind": "cycle", "values": [-128, 127, 0, -1, 56, -77] } },
@@ -1495,7 +1512,7 @@
1495
  {
1496
  "name": "dp4a_gemv_no_zero_s8s8_m1_k64_n512",
1497
  "provenance": {
1498
- "notes": "M=1 selects the dp4a GEMV tile (tileM 1) and signed inputs with both zero points omitted make the B-sum correction unnecessary, which is the only combination that renders the GEMV loop without its running row sum. N=512 and K=64 clear the route's minimum-work guards."
1499
  },
1500
  "inputs": {
1501
  "a": {
@@ -1517,7 +1534,7 @@
1517
  {
1518
  "name": "dp4a_gemv_b_per_column_zero_u8u8_m1_k64_n512",
1519
  "provenance": {
1520
- "notes": "A per-column B zero point on an unsigned B, which is the only combination that renders the widening read in the per-column accessor; every other per-column case had a signed B. The zero point varies per column on a period coprime with N so a column-index error changes the result."
1521
  },
1522
  "inputs": {
1523
  "a": {
@@ -1541,7 +1558,7 @@
1541
  {
1542
  "name": "dp4a_tail_no_zero_s8s8_m1_k66_n512",
1543
  "provenance": {
1544
- "notes": "K=66 leaves a two-lane K tail, and signed inputs with both zero points omitted drop both running sums, which is the only combination that renders the tail block without them. The tail route previously existed only with both zero points present."
1545
  },
1546
  "inputs": {
1547
  "a": {
@@ -1559,6 +1576,696 @@
1559
  }
1560
  },
1561
  "outputs": { "y": { "dtype": "int32", "shape": [1, 512], "tolerance": 0 } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1562
  }
1563
  ]
1564
  }
 
1
  {
 
2
  "fixtureArrays": {
3
  "dp4a_s8_pattern": [-128, 127, 0, -1, 56, -77, 3, 100, -100, 42, -5, 19, -64, 88, -33, 7, 125, -90],
4
  "dp4a_u8_pattern": [0, 255, 128, 7, 200, 31, 129, 64, 99, 3, 254, 127, 1, 88, 173, 240, 16, 5],
 
641
  }
642
  },
643
  "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
644
+ "tunables": { "DP4A_SHORT_K_MIN_MN": 64, "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
645
  },
646
  {
647
  "name": "dp4a_s8s8_medium_k_m64_k96_n128",
 
661
  }
662
  },
663
  "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
664
+ "tunables": {
665
+ "DP4A_SHORT_K_MAX": 64,
666
+ "DP4A_MEDIUM_K_MAX": 128,
667
+ "DP4A_MEDIUM_K_MIN_MN": 64,
668
+ "EXACT_MATRIX_MIN_INVOCATIONS": 0
669
+ }
670
  },
671
  {
672
  "name": "dp4a_u8s8_k256_a_zero_point_only_large",
 
683
  },
684
  "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [131] } }
685
  },
686
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
687
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
688
  },
689
  {
690
  "name": "dp4a_s8u8_k256_b_zero_point_only_large",
 
701
  },
702
  "b_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [200] } }
703
  },
704
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
705
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
706
  },
707
  {
708
  "name": "dp4a_s8s8_k260_both_zero_points_large",
 
724
  "b_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "values", "values": [-7] } }
725
  },
726
  "outputs": { "y": { "dtype": "int32", "shape": [65, 129], "tolerance": 0 } },
727
+ "tunables": {
728
+ "DP4A_LARGE_MIN_M": 64,
729
+ "DP4A_LARGE_MIN_N": 128,
730
+ "DP4A_LARGE_MIN_K": 256,
731
+ "EXACT_MATRIX_MIN_INVOCATIONS": 0
732
+ }
733
  },
734
  {
735
  "name": "dp4a_rank3_by_rank3_u8s8_k256_large",
 
943
  "provenance": {
944
  "source": "onnxruntime/test/providers/cpu/math/matmul_integer_test.cc",
945
  "test": "MatmulIntegerOpTest.MatMulInteger_int8_uint8_A_ND_B_ND",
946
+ "notes": "A compact four-dimensional uint8 MatMulInteger exercises multidimensional batch broadcasting."
947
  },
948
  "inputs": {
949
  "a": {
 
999
  {
1000
  "name": "dispatch_cliff_mtile_rows_524296",
1001
  "provenance": {
1002
+ "notes": "M=524,296 produces 65,537 eight-row tiles, exceeding the dp4a rank-2 dispatch cap and selecting a folded y=65,535, z=2 integer MatMul. Distinct rows make incorrect y/z reconstruction observable."
1003
  },
1004
  "inputs": {
1005
  "a": { "dtype": "uint8", "shape": [524296, 4], "data": { "kind": "cycle", "values": [1, 2, 3, 4, 5, 6, 7] } },
 
1033
  "data": { "kind": "cycle", "values": [1, -2, 2, -1, 3, -3, 0, -4, 4, -5, 5] }
1034
  }
1035
  },
1036
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
1037
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1038
  },
1039
  {
1040
  "name": "percol_b_zero_point_no_azp_below_dp4a_floor",
 
1080
  "data": { "kind": "cycle", "values": [1, -2, 2, -1, 3, -3, 0, -4, 4, -5, 5] }
1081
  }
1082
  },
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",
 
1102
  "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [128] } },
1103
  "b_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [127] } }
1104
  },
1105
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
1106
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1107
  },
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": {
 
1124
  "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [3] } },
1125
  "b_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [7] } }
1126
  },
1127
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
1128
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1129
  },
1130
  {
1131
  "name": "dp4a_rank4_scalar_s8s8_2x2x64x128",
 
1164
  {
1165
  "name": "dp4a_gemv_m1_u8s8_k257_n512_scalar_zp_tail",
1166
  "provenance": {
1167
+ "notes": "An M=1 int8 GEMV with K=257 exercises the tileM=1 DP4A full-word loop and its one-lane scalar tail."
1168
  },
1169
  "inputs": {
1170
  "a": {
 
1239
  "data": { "kind": "cycle", "values": [1, -2, 2, -1, 3, -3, 0, -4, 4, -5, 5] }
1240
  }
1241
  },
1242
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 130], "tolerance": 0 } },
1243
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1244
  },
1245
  {
1246
  "name": "dp4a_partial_m63_n130_tile_edge_s8s8_k256",
 
1298
  "data": { "kind": "cycle", "values": { "$ref": "#/fixtureArrays/dp4a_s8_pattern" } }
1299
  }
1300
  },
1301
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
1302
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1303
  },
1304
  {
1305
  "name": "dp4a_tail_k130_rank2_u8u8_scalar_zp_exact",
 
1326
  "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [121] } },
1327
  "b_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "values", "values": [117] } }
1328
  },
1329
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
1330
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1331
  },
1332
  {
1333
  "name": "dp4a_tail_k131_rank2_s8s8_scalar_zp_exact",
 
1351
  "a_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "values", "values": [5] } },
1352
  "b_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "values", "values": [-7] } }
1353
  },
1354
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 128], "tolerance": 0 } },
1355
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1356
  },
1357
  {
1358
  "name": "dp4a_tail_k129_batched3_by_rank2_exact",
 
1380
  },
1381
  {
1382
  "name": "dp4a_tail_k63_rank2_u8s8_scalar_zp_exact",
1383
+ "provenance": { "notes": "K=63 exercises exact packed-tail handling in the 32<=K<128 DP4A range." },
 
 
1384
  "inputs": {
1385
  "a": { "dtype": "uint8", "shape": [16, 63], "data": { "kind": "cycle", "values": [0, 255, 121, 7, 200, 31] } },
1386
  "b": { "dtype": "int8", "shape": [63, 512], "data": { "kind": "cycle", "values": [-128, 127, 0, -1, 56, -77] } },
 
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": {
 
1534
  {
1535
  "name": "dp4a_gemv_b_per_column_zero_u8u8_m1_k64_n512",
1536
  "provenance": {
1537
+ "notes": "An unsigned B tensor uses per-column zero points that vary on a period coprime with N=512. Each zero point must be widened and indexed by its output column."
1538
  },
1539
  "inputs": {
1540
  "a": {
 
1558
  {
1559
  "name": "dp4a_tail_no_zero_s8s8_m1_k66_n512",
1560
  "provenance": {
1561
+ "notes": "K=66 leaves a two-lane reduction tail. Signed inputs with both zero points omitted exercise that tail without either running-sum correction."
1562
  },
1563
  "inputs": {
1564
  "a": {
 
1576
  }
1577
  },
1578
  "outputs": { "y": { "dtype": "int32", "shape": [1, 512], "tolerance": 0 } }
1579
+ },
1580
+ {
1581
+ "name": "exact_integer_partial_k255_uint8_maxmag",
1582
+ "provenance": {
1583
+ "notes": "Maximum adjusted-byte products across exact-f32 partial-sum boundaries. K=33027 also crosses signed-int32 overflow; the integer result must wrap exactly."
1584
+ },
1585
+ "inputs": {
1586
+ "a": { "dtype": "uint8", "shape": [64, 255], "data": { "kind": "cycle", "values": [255] } },
1587
+ "b": { "dtype": "uint8", "shape": [255, 32], "data": { "kind": "cycle", "values": [255] } }
1588
+ },
1589
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 32], "tolerance": 0 } },
1590
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1591
+ },
1592
+ {
1593
+ "name": "exact_integer_partial_k256_uint8_maxmag",
1594
+ "provenance": {
1595
+ "notes": "Maximum adjusted-byte products across exact-f32 partial-sum boundaries. K=33027 also crosses signed-int32 overflow; the integer result must wrap exactly."
1596
+ },
1597
+ "inputs": {
1598
+ "a": { "dtype": "uint8", "shape": [64, 256], "data": { "kind": "cycle", "values": [255] } },
1599
+ "b": { "dtype": "uint8", "shape": [256, 32], "data": { "kind": "cycle", "values": [255] } }
1600
+ },
1601
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 32], "tolerance": 0 } },
1602
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1603
+ },
1604
+ {
1605
+ "name": "exact_integer_partial_k259_uint8_maxmag",
1606
+ "provenance": {
1607
+ "notes": "Maximum adjusted-byte products across exact-f32 partial-sum boundaries. K=33027 also crosses signed-int32 overflow; the integer result must wrap exactly."
1608
+ },
1609
+ "inputs": {
1610
+ "a": { "dtype": "uint8", "shape": [64, 259], "data": { "kind": "cycle", "values": [255] } },
1611
+ "b": { "dtype": "uint8", "shape": [259, 32], "data": { "kind": "cycle", "values": [255] } }
1612
+ },
1613
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 32], "tolerance": 0 } },
1614
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1615
+ },
1616
+ {
1617
+ "name": "exact_integer_partial_k1025_int8_maxmag",
1618
+ "provenance": {
1619
+ "notes": "Maximum adjusted-byte products across exact-f32 partial-sum boundaries. K=33027 also crosses signed-int32 overflow; the integer result must wrap exactly."
1620
+ },
1621
+ "inputs": {
1622
+ "a": { "dtype": "int8", "shape": [64, 1025], "data": { "kind": "cycle", "values": [127] } },
1623
+ "b": { "dtype": "int8", "shape": [1025, 32], "data": { "kind": "cycle", "values": [127] } },
1624
+ "a_zero_point": { "dtype": "int8", "shape": [], "data": { "kind": "values", "values": [-128] } },
1625
+ "b_zero_point": { "dtype": "int8", "shape": [], "data": { "kind": "values", "values": [-128] } }
1626
+ },
1627
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 32], "tolerance": 0 } },
1628
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1629
+ },
1630
+ {
1631
+ "name": "exact_integer_partial_k33027_uint8_maxmag",
1632
+ "provenance": {
1633
+ "notes": "Maximum adjusted-byte products across exact-f32 partial-sum boundaries. K=33027 also crosses signed-int32 overflow; the integer result must wrap exactly."
1634
+ },
1635
+ "inputs": {
1636
+ "a": { "dtype": "uint8", "shape": [64, 33027], "data": { "kind": "cycle", "values": [255] } },
1637
+ "b": { "dtype": "uint8", "shape": [33027, 32], "data": { "kind": "cycle", "values": [255] } }
1638
+ },
1639
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 32], "tolerance": 0 } },
1640
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1641
+ },
1642
+ {
1643
+ "name": "exact_integer_partial_k513_m65_n65_column_zero_points",
1644
+ "provenance": {
1645
+ "notes": "Mixed signedness, per-column zero points and partial M/N/K tiles must retain exact integer arithmetic."
1646
+ },
1647
+ "inputs": {
1648
+ "a": { "dtype": "uint8", "shape": [65, 513], "data": { "kind": "cycle", "values": [0, 255, 128, 1, 254] } },
1649
+ "b": { "dtype": "int8", "shape": [513, 65], "data": { "kind": "cycle", "values": [-128, 127, 0, -1, 1] } },
1650
+ "a_zero_point": { "dtype": "uint8", "shape": [], "data": { "kind": "values", "values": [17] } },
1651
+ "b_zero_point": { "dtype": "int8", "shape": [65], "data": { "kind": "cycle", "values": [-128, 127, 3] } }
1652
+ },
1653
+ "outputs": { "y": { "dtype": "int32", "shape": [65, 65], "tolerance": 0 } },
1654
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1655
+ },
1656
+ {
1657
+ "name": "exact_integer_partial_k1041_int8_no_zp_signed_outputs",
1658
+ "provenance": {
1659
+ "notes": "Without zero points, signed-byte bounds permit 1024-term exact f32 partials. The odd final sums +/-16790289 are not representable in f32; converting each partial before the int32 addition preserves both signs exactly."
1660
+ },
1661
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 },
1662
+ "inputs": {
1663
+ "a": { "dtype": "int8", "shape": [64, 1041], "data": { "kind": "constant", "value": 127 } },
1664
+ "b": { "dtype": "int8", "shape": [1041, 64], "data": { "kind": "cycle", "values": [127, -127] } }
1665
+ },
1666
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 64], "tolerance": 0 } }
1667
+ },
1668
+ {
1669
+ "name": "exact_integer_storage_growth_m32_k128_n65",
1670
+ "provenance": {
1671
+ "notes": "Maximum adjusted-byte products across exact-f32 partial-sum boundaries. K=33027 also crosses signed-int32 overflow; the integer result must wrap exactly."
1672
+ },
1673
+ "inputs": {
1674
+ "a": { "dtype": "uint8", "shape": [32, 128], "data": { "kind": "cycle", "values": [255] } },
1675
+ "b": { "dtype": "uint8", "shape": [128, 65], "data": { "kind": "cycle", "values": [255] } }
1676
+ },
1677
+ "outputs": { "y": { "dtype": "int32", "shape": [32, 65], "tolerance": 0 } },
1678
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1679
+ },
1680
+ {
1681
+ "name": "exact_integer_storage_growth_m48_k259_n65",
1682
+ "provenance": {
1683
+ "notes": "Maximum adjusted-byte products across exact-f32 partial-sum boundaries. K=33027 also crosses signed-int32 overflow; the integer result must wrap exactly."
1684
+ },
1685
+ "inputs": {
1686
+ "a": { "dtype": "uint8", "shape": [48, 259], "data": { "kind": "cycle", "values": [255] } },
1687
+ "b": { "dtype": "uint8", "shape": [259, 65], "data": { "kind": "cycle", "values": [255] } }
1688
+ },
1689
+ "outputs": { "y": { "dtype": "int32", "shape": [48, 65], "tolerance": 0 } },
1690
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1691
+ },
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": {
1699
+ "dtype": "uint8",
1700
+ "shape": [65, 33],
1701
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1702
+ },
1703
+ "b": {
1704
+ "dtype": "int8",
1705
+ "shape": [33, 33],
1706
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1707
+ }
1708
+ },
1709
+ "outputs": { "y": { "dtype": "int32", "shape": [65, 33], "tolerance": 0 } },
1710
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1711
+ },
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": {
1719
+ "dtype": "uint8",
1720
+ "shape": [65, 33],
1721
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1722
+ },
1723
+ "b": {
1724
+ "dtype": "int8",
1725
+ "shape": [33, 33],
1726
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1727
+ },
1728
+ "b_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "cycle", "values": [3] } }
1729
+ },
1730
+ "outputs": { "y": { "dtype": "int32", "shape": [65, 33], "tolerance": 0 } },
1731
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1732
+ },
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": {
1740
+ "dtype": "uint8",
1741
+ "shape": [65, 33],
1742
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1743
+ },
1744
+ "b": {
1745
+ "dtype": "int8",
1746
+ "shape": [33, 33],
1747
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1748
+ },
1749
+ "b_zero_point": { "dtype": "int8", "shape": [33], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
1750
+ },
1751
+ "outputs": { "y": { "dtype": "int32", "shape": [65, 33], "tolerance": 0 } },
1752
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1753
+ },
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": {
1761
+ "dtype": "uint8",
1762
+ "shape": [65, 33],
1763
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1764
+ },
1765
+ "b": {
1766
+ "dtype": "int8",
1767
+ "shape": [33, 33],
1768
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1769
+ },
1770
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } }
1771
+ },
1772
+ "outputs": { "y": { "dtype": "int32", "shape": [65, 33], "tolerance": 0 } },
1773
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1774
+ },
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": {
1782
+ "dtype": "uint8",
1783
+ "shape": [65, 33],
1784
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1785
+ },
1786
+ "b": {
1787
+ "dtype": "int8",
1788
+ "shape": [33, 33],
1789
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1790
+ },
1791
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
1792
+ "b_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "cycle", "values": [3] } }
1793
+ },
1794
+ "outputs": { "y": { "dtype": "int32", "shape": [65, 33], "tolerance": 0 } },
1795
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1796
+ },
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": {
1804
+ "dtype": "uint8",
1805
+ "shape": [65, 33],
1806
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1807
+ },
1808
+ "b": {
1809
+ "dtype": "int8",
1810
+ "shape": [33, 33],
1811
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1812
+ },
1813
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
1814
+ "b_zero_point": { "dtype": "int8", "shape": [33], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
1815
+ },
1816
+ "outputs": { "y": { "dtype": "int32", "shape": [65, 33], "tolerance": 0 } },
1817
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1818
+ },
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": {
1826
+ "dtype": "uint8",
1827
+ "shape": [129, 65],
1828
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1829
+ },
1830
+ "b": {
1831
+ "dtype": "int8",
1832
+ "shape": [65, 63],
1833
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1834
+ }
1835
+ },
1836
+ "outputs": { "y": { "dtype": "int32", "shape": [129, 63], "tolerance": 0 } },
1837
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1838
+ },
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": {
1846
+ "dtype": "uint8",
1847
+ "shape": [129, 65],
1848
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1849
+ },
1850
+ "b": {
1851
+ "dtype": "int8",
1852
+ "shape": [65, 63],
1853
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1854
+ },
1855
+ "b_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "cycle", "values": [3] } }
1856
+ },
1857
+ "outputs": { "y": { "dtype": "int32", "shape": [129, 63], "tolerance": 0 } },
1858
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1859
+ },
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": {
1867
+ "dtype": "uint8",
1868
+ "shape": [129, 65],
1869
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1870
+ },
1871
+ "b": {
1872
+ "dtype": "int8",
1873
+ "shape": [65, 63],
1874
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1875
+ },
1876
+ "b_zero_point": { "dtype": "int8", "shape": [63], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
1877
+ },
1878
+ "outputs": { "y": { "dtype": "int32", "shape": [129, 63], "tolerance": 0 } },
1879
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1880
+ },
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": {
1888
+ "dtype": "uint8",
1889
+ "shape": [129, 65],
1890
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1891
+ },
1892
+ "b": {
1893
+ "dtype": "int8",
1894
+ "shape": [65, 63],
1895
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1896
+ },
1897
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } }
1898
+ },
1899
+ "outputs": { "y": { "dtype": "int32", "shape": [129, 63], "tolerance": 0 } },
1900
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1901
+ },
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": {
1909
+ "dtype": "uint8",
1910
+ "shape": [129, 65],
1911
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1912
+ },
1913
+ "b": {
1914
+ "dtype": "int8",
1915
+ "shape": [65, 63],
1916
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1917
+ },
1918
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
1919
+ "b_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "cycle", "values": [3] } }
1920
+ },
1921
+ "outputs": { "y": { "dtype": "int32", "shape": [129, 63], "tolerance": 0 } },
1922
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1923
+ },
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": {
1931
+ "dtype": "uint8",
1932
+ "shape": [129, 65],
1933
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1934
+ },
1935
+ "b": {
1936
+ "dtype": "int8",
1937
+ "shape": [65, 63],
1938
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1939
+ },
1940
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
1941
+ "b_zero_point": { "dtype": "int8", "shape": [63], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
1942
+ },
1943
+ "outputs": { "y": { "dtype": "int32", "shape": [129, 63], "tolerance": 0 } },
1944
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1945
+ },
1946
+ {
1947
+ "name": "exact_precast_row_band_m15_k33_n33",
1948
+ "provenance": {
1949
+ "notes": "Matrix row-band boundaries with all three padded axes and varying column zero points. M15 retains the integer fallback; subsequent bands use one to four effective 32-wide subgroups."
1950
+ },
1951
+ "inputs": {
1952
+ "a": {
1953
+ "dtype": "uint8",
1954
+ "shape": [15, 33],
1955
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1956
+ },
1957
+ "b": {
1958
+ "dtype": "int8",
1959
+ "shape": [33, 33],
1960
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1961
+ },
1962
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
1963
+ "b_zero_point": { "dtype": "int8", "shape": [33], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
1964
+ },
1965
+ "outputs": { "y": { "dtype": "int32", "shape": [15, 33], "tolerance": 0 } },
1966
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1967
+ },
1968
+ {
1969
+ "name": "exact_precast_row_band_m16_k33_n33",
1970
+ "provenance": {
1971
+ "notes": "Matrix row-band boundaries with all three padded axes and varying column zero points. M15 retains the integer fallback; subsequent bands use one to four effective 32-wide subgroups."
1972
+ },
1973
+ "inputs": {
1974
+ "a": {
1975
+ "dtype": "uint8",
1976
+ "shape": [16, 33],
1977
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
1978
+ },
1979
+ "b": {
1980
+ "dtype": "int8",
1981
+ "shape": [33, 33],
1982
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
1983
+ },
1984
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
1985
+ "b_zero_point": { "dtype": "int8", "shape": [33], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
1986
+ },
1987
+ "outputs": { "y": { "dtype": "int32", "shape": [16, 33], "tolerance": 0 } },
1988
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
1989
+ },
1990
+ {
1991
+ "name": "exact_precast_row_band_m17_k33_n33",
1992
+ "provenance": {
1993
+ "notes": "Matrix row-band boundaries with all three padded axes and varying column zero points. M15 retains the integer fallback; subsequent bands use one to four effective 32-wide subgroups."
1994
+ },
1995
+ "inputs": {
1996
+ "a": {
1997
+ "dtype": "uint8",
1998
+ "shape": [17, 33],
1999
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
2000
+ },
2001
+ "b": {
2002
+ "dtype": "int8",
2003
+ "shape": [33, 33],
2004
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
2005
+ },
2006
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
2007
+ "b_zero_point": { "dtype": "int8", "shape": [33], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
2008
+ },
2009
+ "outputs": { "y": { "dtype": "int32", "shape": [17, 33], "tolerance": 0 } },
2010
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2011
+ },
2012
+ {
2013
+ "name": "exact_precast_row_band_m31_k33_n33",
2014
+ "provenance": {
2015
+ "notes": "Matrix row-band boundaries with all three padded axes and varying column zero points. M15 retains the integer fallback; subsequent bands use one to four effective 32-wide subgroups."
2016
+ },
2017
+ "inputs": {
2018
+ "a": {
2019
+ "dtype": "uint8",
2020
+ "shape": [31, 33],
2021
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
2022
+ },
2023
+ "b": {
2024
+ "dtype": "int8",
2025
+ "shape": [33, 33],
2026
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
2027
+ },
2028
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
2029
+ "b_zero_point": { "dtype": "int8", "shape": [33], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
2030
+ },
2031
+ "outputs": { "y": { "dtype": "int32", "shape": [31, 33], "tolerance": 0 } },
2032
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2033
+ },
2034
+ {
2035
+ "name": "exact_precast_row_band_m32_k33_n33",
2036
+ "provenance": {
2037
+ "notes": "Matrix row-band boundaries with all three padded axes and varying column zero points. M15 retains the integer fallback; subsequent bands use one to four effective 32-wide subgroups."
2038
+ },
2039
+ "inputs": {
2040
+ "a": {
2041
+ "dtype": "uint8",
2042
+ "shape": [32, 33],
2043
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
2044
+ },
2045
+ "b": {
2046
+ "dtype": "int8",
2047
+ "shape": [33, 33],
2048
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
2049
+ },
2050
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
2051
+ "b_zero_point": { "dtype": "int8", "shape": [33], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
2052
+ },
2053
+ "outputs": { "y": { "dtype": "int32", "shape": [32, 33], "tolerance": 0 } },
2054
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2055
+ },
2056
+ {
2057
+ "name": "exact_precast_row_band_m33_k33_n33",
2058
+ "provenance": {
2059
+ "notes": "Matrix row-band boundaries with all three padded axes and varying column zero points. M15 retains the integer fallback; subsequent bands use one to four effective 32-wide subgroups."
2060
+ },
2061
+ "inputs": {
2062
+ "a": {
2063
+ "dtype": "uint8",
2064
+ "shape": [33, 33],
2065
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
2066
+ },
2067
+ "b": {
2068
+ "dtype": "int8",
2069
+ "shape": [33, 33],
2070
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
2071
+ },
2072
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
2073
+ "b_zero_point": { "dtype": "int8", "shape": [33], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
2074
+ },
2075
+ "outputs": { "y": { "dtype": "int32", "shape": [33, 33], "tolerance": 0 } },
2076
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2077
+ },
2078
+ {
2079
+ "name": "exact_precast_row_band_m47_k33_n33",
2080
+ "provenance": {
2081
+ "notes": "Matrix row-band boundaries with all three padded axes and varying column zero points. M15 retains the integer fallback; subsequent bands use one to four effective 32-wide subgroups."
2082
+ },
2083
+ "inputs": {
2084
+ "a": {
2085
+ "dtype": "uint8",
2086
+ "shape": [47, 33],
2087
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
2088
+ },
2089
+ "b": {
2090
+ "dtype": "int8",
2091
+ "shape": [33, 33],
2092
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
2093
+ },
2094
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
2095
+ "b_zero_point": { "dtype": "int8", "shape": [33], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
2096
+ },
2097
+ "outputs": { "y": { "dtype": "int32", "shape": [47, 33], "tolerance": 0 } },
2098
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2099
+ },
2100
+ {
2101
+ "name": "exact_precast_row_band_m48_k33_n33",
2102
+ "provenance": {
2103
+ "notes": "Matrix row-band boundaries with all three padded axes and varying column zero points. M15 retains the integer fallback; subsequent bands use one to four effective 32-wide subgroups."
2104
+ },
2105
+ "inputs": {
2106
+ "a": {
2107
+ "dtype": "uint8",
2108
+ "shape": [48, 33],
2109
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
2110
+ },
2111
+ "b": {
2112
+ "dtype": "int8",
2113
+ "shape": [33, 33],
2114
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
2115
+ },
2116
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
2117
+ "b_zero_point": { "dtype": "int8", "shape": [33], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
2118
+ },
2119
+ "outputs": { "y": { "dtype": "int32", "shape": [48, 33], "tolerance": 0 } },
2120
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2121
+ },
2122
+ {
2123
+ "name": "exact_precast_row_band_m49_k33_n33",
2124
+ "provenance": {
2125
+ "notes": "Matrix row-band boundaries with all three padded axes and varying column zero points. M15 retains the integer fallback; subsequent bands use one to four effective 32-wide subgroups."
2126
+ },
2127
+ "inputs": {
2128
+ "a": {
2129
+ "dtype": "uint8",
2130
+ "shape": [49, 33],
2131
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
2132
+ },
2133
+ "b": {
2134
+ "dtype": "int8",
2135
+ "shape": [33, 33],
2136
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
2137
+ },
2138
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
2139
+ "b_zero_point": { "dtype": "int8", "shape": [33], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
2140
+ },
2141
+ "outputs": { "y": { "dtype": "int32", "shape": [49, 33], "tolerance": 0 } },
2142
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2143
+ },
2144
+ {
2145
+ "name": "exact_precast_row_band_m63_k33_n33",
2146
+ "provenance": {
2147
+ "notes": "Matrix row-band boundaries with all three padded axes and varying column zero points. M15 retains the integer fallback; subsequent bands use one to four effective 32-wide subgroups."
2148
+ },
2149
+ "inputs": {
2150
+ "a": {
2151
+ "dtype": "uint8",
2152
+ "shape": [63, 33],
2153
+ "data": { "kind": "cycle", "values": [109, 151, 128, 137, 102, 165, 124] }
2154
+ },
2155
+ "b": {
2156
+ "dtype": "int8",
2157
+ "shape": [33, 33],
2158
+ "data": { "kind": "cycle", "values": [-9, 7, -3, 12, 5, -11, 2, 1, -6, 4, 8] }
2159
+ },
2160
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
2161
+ "b_zero_point": { "dtype": "int8", "shape": [33], "data": { "kind": "cycle", "values": [-3, 2, 7, -5, 1] } }
2162
+ },
2163
+ "outputs": { "y": { "dtype": "int32", "shape": [63, 33], "tolerance": 0 } },
2164
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2165
+ },
2166
+ {
2167
+ "name": "exact_portable_m63_k255_n35",
2168
+ "provenance": {
2169
+ "notes": "Exact partial-sum and row-reuse boundaries, signed and unsigned extremes, column zero points, and simultaneous padded axes."
2170
+ },
2171
+ "inputs": {
2172
+ "a": {
2173
+ "dtype": "uint8",
2174
+ "shape": [63, 255],
2175
+ "data": { "kind": "cycle", "values": [0, 255, 17, 239, 128, 1, 254] }
2176
+ },
2177
+ "b": {
2178
+ "dtype": "int8",
2179
+ "shape": [255, 35],
2180
+ "data": { "kind": "cycle", "values": [-128, 127, -127, 63, -64, 0, 126] }
2181
+ },
2182
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [255] } },
2183
+ "b_zero_point": {
2184
+ "dtype": "int8",
2185
+ "shape": [35],
2186
+ "data": { "kind": "cycle", "values": [-128, 127, 0, -111, 111] }
2187
+ }
2188
+ },
2189
+ "outputs": { "y": { "dtype": "int32", "shape": [63, 35], "tolerance": 0 } },
2190
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2191
+ },
2192
+ {
2193
+ "name": "exact_portable_m64_k256_n35",
2194
+ "provenance": {
2195
+ "notes": "Exact partial-sum and row-reuse boundaries, signed and unsigned extremes, column zero points, and simultaneous padded axes."
2196
+ },
2197
+ "inputs": {
2198
+ "a": {
2199
+ "dtype": "uint8",
2200
+ "shape": [64, 256],
2201
+ "data": { "kind": "cycle", "values": [0, 255, 17, 239, 128, 1, 254] }
2202
+ },
2203
+ "b": {
2204
+ "dtype": "uint8",
2205
+ "shape": [256, 35],
2206
+ "data": { "kind": "cycle", "values": [0, 255, 1, 191, 64, 128, 254] }
2207
+ },
2208
+ "a_zero_point": { "dtype": "uint8", "shape": [1], "data": { "kind": "cycle", "values": [255] } },
2209
+ "b_zero_point": {
2210
+ "dtype": "uint8",
2211
+ "shape": [35],
2212
+ "data": { "kind": "cycle", "values": [0, 255, 128, 17, 239] }
2213
+ }
2214
+ },
2215
+ "outputs": { "y": { "dtype": "int32", "shape": [64, 35], "tolerance": 0 } },
2216
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2217
+ },
2218
+ {
2219
+ "name": "exact_portable_m65_k257_n67",
2220
+ "provenance": {
2221
+ "notes": "Exact partial-sum and row-reuse boundaries, signed and unsigned extremes, column zero points, and simultaneous padded axes."
2222
+ },
2223
+ "inputs": {
2224
+ "a": {
2225
+ "dtype": "int8",
2226
+ "shape": [65, 257],
2227
+ "data": { "kind": "cycle", "values": [-128, 127, -111, 111, 0, -127, 126] }
2228
+ },
2229
+ "b": {
2230
+ "dtype": "int8",
2231
+ "shape": [257, 67],
2232
+ "data": { "kind": "cycle", "values": [-128, 127, -127, 63, -64, 0, 126] }
2233
+ },
2234
+ "a_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
2235
+ "b_zero_point": {
2236
+ "dtype": "int8",
2237
+ "shape": [67],
2238
+ "data": { "kind": "cycle", "values": [-128, 127, 0, -111, 111] }
2239
+ }
2240
+ },
2241
+ "outputs": { "y": { "dtype": "int32", "shape": [65, 67], "tolerance": 0 } },
2242
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2243
+ },
2244
+ {
2245
+ "name": "exact_portable_m65_k1025_n35",
2246
+ "provenance": {
2247
+ "notes": "Exact partial-sum and row-reuse boundaries, signed and unsigned extremes, column zero points, and simultaneous padded axes."
2248
+ },
2249
+ "inputs": {
2250
+ "a": {
2251
+ "dtype": "int8",
2252
+ "shape": [65, 1025],
2253
+ "data": { "kind": "cycle", "values": [-128, 127, -111, 111, 0, -127, 126] }
2254
+ },
2255
+ "b": {
2256
+ "dtype": "uint8",
2257
+ "shape": [1025, 35],
2258
+ "data": { "kind": "cycle", "values": [0, 255, 1, 191, 64, 128, 254] }
2259
+ },
2260
+ "a_zero_point": { "dtype": "int8", "shape": [1], "data": { "kind": "cycle", "values": [127] } },
2261
+ "b_zero_point": {
2262
+ "dtype": "uint8",
2263
+ "shape": [35],
2264
+ "data": { "kind": "cycle", "values": [0, 255, 128, 17, 239] }
2265
+ }
2266
+ },
2267
+ "outputs": { "y": { "dtype": "int32", "shape": [65, 35], "tolerance": 0 } },
2268
+ "tunables": { "EXACT_MATRIX_MIN_INVOCATIONS": 0 }
2269
  }
2270
  ]
2271
  }