Xenova HF Staff commited on
Commit
69e74ac
·
verified ·
1 Parent(s): 07147ca

sync 2e7068faf55e

Browse files
README.md CHANGED
@@ -1,3 +1,80 @@
1
  ---
 
2
  license: apache-2.0
 
 
 
 
3
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ library_name: kernels
3
  license: apache-2.0
4
+ tags:
5
+ - kernel
6
+ - webgpu
7
+ - wgsl
8
  ---
9
+ # com.microsoft.SkipSimplifiedLayerNormalization
10
+
11
+ `com.microsoft` · ONNX Runtime contrib operator · contrib since_version 1
12
+
13
+ ## Description
14
+
15
+ Adds `input` and `skip` (plus optional `bias`), then applies RMS normalization scaled by `gamma`. The optional second output exposes the pre-normalization sum. The schema's training-only mean and inverse-standard-deviation outputs are not implemented.
16
+
17
+ See the [ONNX Runtime `SkipSimplifiedLayerNormalization` contrib-operator spec](https://github.com/microsoft/onnxruntime/blob/main/docs/ContribOperators.md#com.microsoft.SkipSimplifiedLayerNormalization) for the reference semantics.
18
+
19
+ ## Inputs
20
+
21
+ | Name | Bind key | Logical dtype | Rank | Shape | Description | Presence |
22
+ | --- | --- | --- | --- | --- | --- | --- |
23
+ | `input` | `inputT` | `T` | — | — | Input tensor of shape `(token_count, hidden_size)` or `(batch, sequence, hidden_size)`, normalized over the last axis. | required |
24
+ | `skip` | `skipT` | `T` | — | — | Residual tensor of the same shape as `input`, added before normalization. | required |
25
+ | `gamma` | `gammaT` | `T` | `1` | — | 1-D scale tensor with shape `(hidden_size)` applied after normalization. | required |
26
+ | `bias` | `biasT` | `T` | `1` | — | Optional 1-D bias tensor with shape `(hidden_size)` added to the `input + skip` sum. | optional |
27
+
28
+ ## Outputs
29
+
30
+ | Name | Bind key | Logical dtype | Rank | Shape | Description | Presence |
31
+ | --- | --- | --- | --- | --- | --- | --- |
32
+ | `output` | `outputT` | `T` | same as `input` | same as `input` | Normalized output tensor with the same shape as `input`. | required |
33
+ | `input_skip_bias_sum` | `residualT` | `T` | same as `input` | same as `input` | Sum of `input`, `skip`, and optional `bias` before normalization, with the same shape as `input`. | optional |
34
+
35
+ ## Attributes
36
+
37
+ Default values (overridable per request):
38
+
39
+ | Attribute | Default | Description |
40
+ | --- | --- | --- |
41
+ | `epsilon` | `9.999999960041972e-13` | Non-negative epsilon added to the mean square before taking the square root. |
42
+
43
+ ## Type constraints
44
+
45
+ | Variable | Allowed dtypes |
46
+ | --- | --- |
47
+ | `T` | `float32`, `float16` |
48
+
49
+ ## Device requirements
50
+
51
+ Some implementation variants require `shader-f16`. These are route-specific capabilities, not package-wide requirements; availability also depends on the request shape and dtype.
52
+
53
+ ## Files
54
+
55
+ - [`metadata.json`](build/webgpu/metadata.json) — kernel metadata (id, digests, provenance)
56
+ - [`manifest.json`](build/webgpu/manifest.json) — the op contract (source of truth)
57
+ - [`test.json`](build/webgpu/test.json) — correctness cases
58
+ - [`bench.json`](build/webgpu/bench.json) — benchmark + tuning cases
59
+ - [`norm-skip-row-vec4.wgsl.jinja`](build/webgpu/norm-skip-row-vec4.wgsl.jinja)
60
+ - [`norm-skip-row.wgsl.jinja`](build/webgpu/norm-skip-row.wgsl.jinja)
61
+
62
+ ## Use with `@huggingface/kernels`
63
+
64
+ The loader derives every required output's shape and logical dtype from the manifest contract and this call.
65
+ It then allocates the result tensors automatically.
66
+
67
+ The `version: 1` option selects the published kernel contract; it is independent of any operator opset, contrib `since_version`, or model version.
68
+
69
+ Replace each `*Data` placeholder with a typed array containing the corresponding input data.
70
+
71
+ ```js
72
+ import { getKernel } from "@huggingface/kernels";
73
+
74
+ const kernel = await getKernel("webgpu-kernels/com.microsoft.SkipSimplifiedLayerNormalization", { version: 1 });
75
+ const { outputT } = await kernel({
76
+ inputT: { data: inputTData, shape: [2, 4] },
77
+ skipT: { data: skipTData, shape: [2, 4] },
78
+ gammaT: { data: gammaTData, shape: [4] },
79
+ });
80
+ ```
build/webgpu/bench.json ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "op": "com.microsoft.SkipSimplifiedLayerNormalization",
3
+ "cases": [
4
+ {
5
+ "name": "skip-rmsnorm-f32-256x128",
6
+ "preset": "smoke",
7
+ "vars": { "rows": 256, "hidden": 128 },
8
+ "attrs": { "epsilon": 0.00001 },
9
+ "inputs": {
10
+ "inputT": { "shape": [256, 128], "dtype": "float32", "dist": "normal", "seed": 215, "scale": 0.2 },
11
+ "skipT": { "shape": [256, 128], "dtype": "float32", "dist": "normal", "seed": 216, "scale": 0.2 },
12
+ "gammaT": { "shape": [128], "dtype": "float32", "dist": "uniform", "seed": 217, "scale": 0.1, "offset": 1 }
13
+ },
14
+ "outputs": {
15
+ "outputT": { "shape": [256, 128], "dtype": "float32" },
16
+ "residualT": { "shape": [256, 128], "dtype": "float32" }
17
+ },
18
+ "bench": {
19
+ "primary": true,
20
+ "metrics": [{ "type": "bandwidth", "value": "4 * (4 * args.rows * args.hidden + args.hidden)" }]
21
+ }
22
+ },
23
+ {
24
+ "name": "kimi-linear-decode-f32-1x2304",
25
+ "preset": "model",
26
+ "provenance": {
27
+ "notes": "Original Kimi Linear hidden_size=2304 decode residual-plus-RMSNorm shape; occurs twice per decoder layer."
28
+ },
29
+ "vars": { "rows": 1, "hidden": 2304 },
30
+ "attrs": { "epsilon": 0.00001 },
31
+ "inputs": {
32
+ "inputT": { "shape": [1, 2304], "dtype": "float32", "dist": "normal", "seed": 1201, "scale": 0.2 },
33
+ "skipT": { "shape": [1, 2304], "dtype": "float32", "dist": "normal", "seed": 1202, "scale": 0.2 },
34
+ "gammaT": { "shape": [2304], "dtype": "float32", "dist": "uniform", "seed": 1203, "scale": 0.1, "offset": 1 }
35
+ },
36
+ "outputs": {
37
+ "outputT": { "shape": [1, 2304], "dtype": "float32" },
38
+ "residualT": { "shape": [1, 2304], "dtype": "float32" }
39
+ },
40
+ "bench": {
41
+ "primary": true,
42
+ "metrics": [{ "type": "bandwidth", "value": "4 * (4 * args.rows * args.hidden + args.hidden)" }]
43
+ }
44
+ },
45
+ {
46
+ "name": "kimi-linear-prefill-f32-64x2304",
47
+ "preset": "model",
48
+ "provenance": {
49
+ "notes": "Original Kimi Linear hidden_size=2304 at the 64-token recurrent chunk boundary; this is a future vectorized-prefill target because the current graph replays T=1."
50
+ },
51
+ "vars": { "rows": 64, "hidden": 2304 },
52
+ "attrs": { "epsilon": 0.00001 },
53
+ "inputs": {
54
+ "inputT": { "shape": [64, 2304], "dtype": "float32", "dist": "normal", "seed": 1211, "scale": 0.2 },
55
+ "skipT": { "shape": [64, 2304], "dtype": "float32", "dist": "normal", "seed": 1212, "scale": 0.2 },
56
+ "gammaT": { "shape": [2304], "dtype": "float32", "dist": "uniform", "seed": 1213, "scale": 0.1, "offset": 1 }
57
+ },
58
+ "outputs": {
59
+ "outputT": { "shape": [64, 2304], "dtype": "float32" },
60
+ "residualT": { "shape": [64, 2304], "dtype": "float32" }
61
+ },
62
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "4 * (4 * args.rows * args.hidden + args.hidden)" }] }
63
+ },
64
+ {
65
+ "name": "kimi-linear-prefill-f32-512x2304",
66
+ "preset": "model",
67
+ "provenance": {
68
+ "notes": "Original Kimi Linear hidden_size=2304 representative future vectorized-prefill shape; the current graph replays T=1."
69
+ },
70
+ "vars": { "rows": 512, "hidden": 2304 },
71
+ "attrs": { "epsilon": 0.00001 },
72
+ "inputs": {
73
+ "inputT": { "shape": [512, 2304], "dtype": "float32", "dist": "normal", "seed": 1221, "scale": 0.2 },
74
+ "skipT": { "shape": [512, 2304], "dtype": "float32", "dist": "normal", "seed": 1222, "scale": 0.2 },
75
+ "gammaT": { "shape": [2304], "dtype": "float32", "dist": "uniform", "seed": 1223, "scale": 0.1, "offset": 1 }
76
+ },
77
+ "outputs": {
78
+ "outputT": { "shape": [512, 2304], "dtype": "float32" },
79
+ "residualT": { "shape": [512, 2304], "dtype": "float32" }
80
+ },
81
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "4 * (4 * args.rows * args.hidden + args.hidden)" }] }
82
+ },
83
+ {
84
+ "name": "kimi-linear-prefill-f32-1024x2304",
85
+ "preset": "model",
86
+ "provenance": {
87
+ "notes": "Original Kimi Linear hidden_size=2304 representative future vectorized-prefill shape; the current graph replays T=1."
88
+ },
89
+ "vars": { "rows": 1024, "hidden": 2304 },
90
+ "attrs": { "epsilon": 0.00001 },
91
+ "inputs": {
92
+ "inputT": { "shape": [1024, 2304], "dtype": "float32", "dist": "normal", "seed": 1231, "scale": 0.2 },
93
+ "skipT": { "shape": [1024, 2304], "dtype": "float32", "dist": "normal", "seed": 1232, "scale": 0.2 },
94
+ "gammaT": { "shape": [2304], "dtype": "float32", "dist": "uniform", "seed": 1233, "scale": 0.1, "offset": 1 }
95
+ },
96
+ "outputs": {
97
+ "outputT": { "shape": [1024, 2304], "dtype": "float32" },
98
+ "residualT": { "shape": [1024, 2304], "dtype": "float32" }
99
+ },
100
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "4 * (4 * args.rows * args.hidden + args.hidden)" }] }
101
+ },
102
+ {
103
+ "name": "skip-rmsnorm-f32-bias-256x128",
104
+ "preset": "smoke",
105
+ "vars": { "rows": 256, "hidden": 128 },
106
+ "attrs": { "epsilon": 0.00001 },
107
+ "inputs": {
108
+ "inputT": { "shape": [256, 128], "dtype": "float32", "dist": "normal", "seed": 216, "scale": 0.2 },
109
+ "skipT": { "shape": [256, 128], "dtype": "float32", "dist": "normal", "seed": 217, "scale": 0.2 },
110
+ "gammaT": { "shape": [128], "dtype": "float32", "dist": "uniform", "seed": 218, "scale": 0.1, "offset": 1 },
111
+ "biasT": { "shape": [128], "dtype": "float32", "dist": "normal", "seed": 219, "scale": 0.05 }
112
+ },
113
+ "outputs": {
114
+ "outputT": { "shape": [256, 128], "dtype": "float32" },
115
+ "residualT": { "shape": [256, 128], "dtype": "float32" }
116
+ },
117
+ "bench": {
118
+ "primary": true,
119
+ "metrics": [{ "type": "bandwidth", "value": "4 * (4 * args.rows * args.hidden + 2 * args.hidden)" }]
120
+ }
121
+ },
122
+ {
123
+ "name": "skip-rmsnorm-f32-output-256x128",
124
+ "preset": "smoke",
125
+ "vars": { "rows": 256, "hidden": 128 },
126
+ "attrs": { "epsilon": 0.00001 },
127
+ "inputs": {
128
+ "inputT": { "shape": [256, 128], "dtype": "float32", "dist": "normal", "seed": 224, "scale": 0.2 },
129
+ "skipT": { "shape": [256, 128], "dtype": "float32", "dist": "normal", "seed": 225, "scale": 0.2 },
130
+ "gammaT": { "shape": [128], "dtype": "float32", "dist": "uniform", "seed": 226, "scale": 0.1, "offset": 1 }
131
+ },
132
+ "outputs": { "outputT": { "shape": [256, 128], "dtype": "float32" } },
133
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "4 * (3 * args.rows * args.hidden + args.hidden)" }] }
134
+ },
135
+ {
136
+ "name": "skip-rmsnorm-f32-bias-output-256x128",
137
+ "preset": "smoke",
138
+ "vars": { "rows": 256, "hidden": 128 },
139
+ "attrs": { "epsilon": 0.00001 },
140
+ "inputs": {
141
+ "inputT": { "shape": [256, 128], "dtype": "float32", "dist": "normal", "seed": 227, "scale": 0.2 },
142
+ "skipT": { "shape": [256, 128], "dtype": "float32", "dist": "normal", "seed": 228, "scale": 0.2 },
143
+ "gammaT": { "shape": [128], "dtype": "float32", "dist": "uniform", "seed": 229, "scale": 0.1, "offset": 1 },
144
+ "biasT": { "shape": [128], "dtype": "float32", "dist": "normal", "seed": 230, "scale": 0.05 }
145
+ },
146
+ "outputs": { "outputT": { "shape": [256, 128], "dtype": "float32" } },
147
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "4 * (3 * args.rows * args.hidden + 2 * args.hidden)" }] }
148
+ },
149
+ {
150
+ "name": "skip-rmsnorm-f32-4096x768",
151
+ "preset": "model",
152
+ "vars": { "rows": 4096, "hidden": 768 },
153
+ "attrs": { "epsilon": 0.00001 },
154
+ "inputs": {
155
+ "inputT": { "shape": [4096, 768], "dtype": "float32", "dist": "normal", "seed": 319, "scale": 0.2 },
156
+ "skipT": { "shape": [4096, 768], "dtype": "float32", "dist": "normal", "seed": 320, "scale": 0.2 },
157
+ "gammaT": { "shape": [768], "dtype": "float32", "dist": "uniform", "seed": 321, "scale": 0.1, "offset": 1 }
158
+ },
159
+ "outputs": {
160
+ "outputT": { "shape": [4096, 768], "dtype": "float32" },
161
+ "residualT": { "shape": [4096, 768], "dtype": "float32" }
162
+ },
163
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "4 * (4 * args.rows * args.hidden + args.hidden)" }] }
164
+ },
165
+ {
166
+ "name": "skip-rmsnorm-f32-8192x4096",
167
+ "preset": "model",
168
+ "vars": { "rows": 8192, "hidden": 4096 },
169
+ "attrs": { "epsilon": 0.00001 },
170
+ "inputs": {
171
+ "inputT": { "shape": [8192, 4096], "dtype": "float32", "dist": "normal", "seed": 419, "scale": 0.2 },
172
+ "skipT": { "shape": [8192, 4096], "dtype": "float32", "dist": "normal", "seed": 420, "scale": 0.2 },
173
+ "gammaT": { "shape": [4096], "dtype": "float32", "dist": "uniform", "seed": 421, "scale": 0.1, "offset": 1 }
174
+ },
175
+ "outputs": {
176
+ "outputT": { "shape": [8192, 4096], "dtype": "float32" },
177
+ "residualT": { "shape": [8192, 4096], "dtype": "float32" }
178
+ },
179
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "4 * (4 * args.rows * args.hidden + args.hidden)" }] }
180
+ },
181
+ {
182
+ "name": "skip-rmsnorm-f32-output-4096x768",
183
+ "preset": "model",
184
+ "vars": { "rows": 4096, "hidden": 768 },
185
+ "attrs": { "epsilon": 0.00001 },
186
+ "inputs": {
187
+ "inputT": { "shape": [4096, 768], "dtype": "float32", "dist": "normal", "seed": 324, "scale": 0.2 },
188
+ "skipT": { "shape": [4096, 768], "dtype": "float32", "dist": "normal", "seed": 325, "scale": 0.2 },
189
+ "gammaT": { "shape": [768], "dtype": "float32", "dist": "uniform", "seed": 326, "scale": 0.1, "offset": 1 }
190
+ },
191
+ "outputs": { "outputT": { "shape": [4096, 768], "dtype": "float32" } },
192
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "4 * (3 * args.rows * args.hidden + args.hidden)" }] }
193
+ },
194
+ {
195
+ "name": "skip-rmsnorm-f32-bias-4096x768",
196
+ "preset": "model",
197
+ "vars": { "rows": 4096, "hidden": 768 },
198
+ "attrs": { "epsilon": 0.00001 },
199
+ "inputs": {
200
+ "inputT": { "shape": [4096, 768], "dtype": "float32", "dist": "normal", "seed": 320, "scale": 0.2 },
201
+ "skipT": { "shape": [4096, 768], "dtype": "float32", "dist": "normal", "seed": 321, "scale": 0.2 },
202
+ "gammaT": { "shape": [768], "dtype": "float32", "dist": "uniform", "seed": 322, "scale": 0.1, "offset": 1 },
203
+ "biasT": { "shape": [768], "dtype": "float32", "dist": "normal", "seed": 323, "scale": 0.05 }
204
+ },
205
+ "outputs": {
206
+ "outputT": { "shape": [4096, 768], "dtype": "float32" },
207
+ "residualT": { "shape": [4096, 768], "dtype": "float32" }
208
+ },
209
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "4 * (4 * args.rows * args.hidden + 2 * args.hidden)" }] }
210
+ },
211
+ {
212
+ "name": "skip-rmsnorm-f32-bias-output-4096x768",
213
+ "preset": "model",
214
+ "vars": { "rows": 4096, "hidden": 768 },
215
+ "attrs": { "epsilon": 0.00001 },
216
+ "inputs": {
217
+ "inputT": { "shape": [4096, 768], "dtype": "float32", "dist": "normal", "seed": 327, "scale": 0.2 },
218
+ "skipT": { "shape": [4096, 768], "dtype": "float32", "dist": "normal", "seed": 328, "scale": 0.2 },
219
+ "gammaT": { "shape": [768], "dtype": "float32", "dist": "uniform", "seed": 329, "scale": 0.1, "offset": 1 },
220
+ "biasT": { "shape": [768], "dtype": "float32", "dist": "normal", "seed": 330, "scale": 0.05 }
221
+ },
222
+ "outputs": { "outputT": { "shape": [4096, 768], "dtype": "float32" } },
223
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "4 * (3 * args.rows * args.hidden + 2 * args.hidden)" }] }
224
+ },
225
+ {
226
+ "name": "skip-rmsnorm-f32-scalar-fallback-8192x4095",
227
+ "preset": "stress",
228
+ "vars": { "rows": 8192, "hidden": 4095 },
229
+ "attrs": { "epsilon": 0.00001 },
230
+ "inputs": {
231
+ "inputT": { "shape": [8192, 4095], "dtype": "float32", "dist": "normal", "seed": 621, "scale": 0.2 },
232
+ "skipT": { "shape": [8192, 4095], "dtype": "float32", "dist": "normal", "seed": 622, "scale": 0.2 },
233
+ "gammaT": { "shape": [4095], "dtype": "float32", "dist": "uniform", "seed": 623, "scale": 0.1, "offset": 1 }
234
+ },
235
+ "outputs": {
236
+ "outputT": { "shape": [8192, 4095], "dtype": "float32", "dist": "empty" },
237
+ "residualT": { "shape": [8192, 4095], "dtype": "float32", "dist": "empty" }
238
+ },
239
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "4 * (4 * args.rows * args.hidden + args.hidden)" }] }
240
+ },
241
+ {
242
+ "name": "skip-rmsnorm-f32-bias-scalar-fallback-8192x2049",
243
+ "preset": "stress",
244
+ "vars": { "rows": 8192, "hidden": 2049 },
245
+ "attrs": { "epsilon": 0.00001 },
246
+ "inputs": {
247
+ "inputT": { "shape": [8192, 2049], "dtype": "float32", "dist": "normal", "seed": 631, "scale": 0.2 },
248
+ "skipT": { "shape": [8192, 2049], "dtype": "float32", "dist": "normal", "seed": 632, "scale": 0.2 },
249
+ "gammaT": { "shape": [2049], "dtype": "float32", "dist": "uniform", "seed": 633, "scale": 0.1, "offset": 1 },
250
+ "biasT": { "shape": [2049], "dtype": "float32", "dist": "normal", "seed": 634, "scale": 0.05 }
251
+ },
252
+ "outputs": {
253
+ "outputT": { "shape": [8192, 2049], "dtype": "float32", "dist": "empty" },
254
+ "residualT": { "shape": [8192, 2049], "dtype": "float32", "dist": "empty" }
255
+ },
256
+ "bench": { "metrics": [{ "type": "bandwidth", "value": "4 * (4 * args.rows * args.hidden + 2 * args.hidden)" }] }
257
+ }
258
+ ]
259
+ }
build/webgpu/manifest.json ADDED
@@ -0,0 +1,1006 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "domain": "com.microsoft",
3
+ "name": "SkipSimplifiedLayerNormalization",
4
+ "sinceVersion": 1,
5
+ "description": "Adds `input` and `skip` (plus optional `bias`), then applies RMS normalization scaled by `gamma`. The optional second output exposes the pre-normalization sum. The schema's training-only mean and inverse-standard-deviation outputs are not implemented.",
6
+ "inputs": [
7
+ {
8
+ "role": "input",
9
+ "dtype": "T",
10
+ "description": "Input tensor of shape `(token_count, hidden_size)` or `(batch, sequence, hidden_size)`, normalized over the last axis."
11
+ },
12
+ {
13
+ "role": "skip",
14
+ "dtype": "T",
15
+ "description": "Residual tensor of the same shape as `input`, added before normalization."
16
+ },
17
+ {
18
+ "role": "gamma",
19
+ "dtype": "T",
20
+ "rank": 1,
21
+ "description": "1-D scale tensor with shape `(hidden_size)` applied after normalization."
22
+ },
23
+ {
24
+ "role": "bias",
25
+ "dtype": "T",
26
+ "rank": 1,
27
+ "optional": true,
28
+ "description": "Optional 1-D bias tensor with shape `(hidden_size)` added to the `input + skip` sum."
29
+ }
30
+ ],
31
+ "outputs": [
32
+ {
33
+ "role": "output",
34
+ "dtype": "T",
35
+ "rank": "ranks.inputT",
36
+ "shape": "shapes.inputT",
37
+ "description": "Normalized output tensor with the same shape as `input`."
38
+ },
39
+ {
40
+ "role": "input_skip_bias_sum",
41
+ "dtype": "T",
42
+ "optional": true,
43
+ "rank": "ranks.inputT",
44
+ "shape": "shapes.inputT",
45
+ "description": "Sum of `input`, `skip`, and optional `bias` before normalization, with the same shape as `input`."
46
+ }
47
+ ],
48
+ "attributes": { "epsilon": 9.999999960041972e-13 },
49
+ "attributeDescriptions": { "epsilon": "Non-negative epsilon added to the mean square before taking the square root." },
50
+ "args": {
51
+ "inputT": { "kind": "tensor", "semantic": "input", "role": "input" },
52
+ "skipT": { "kind": "tensor", "semantic": "skip", "role": "input" },
53
+ "gammaT": { "kind": "tensor", "semantic": "gamma", "role": "input" },
54
+ "biasT": { "kind": "tensor", "semantic": "bias", "role": "input", "required": false },
55
+ "outputT": { "kind": "tensor", "semantic": "output", "role": "output" },
56
+ "residualT": { "kind": "tensor", "semantic": "input_skip_bias_sum", "role": "output", "required": false }
57
+ },
58
+ "typeConstraints": { "T": ["float32", "float16"] },
59
+ "derive": {
60
+ "rowCount": "numel(shapes.inputT) / max(1, dim(shapes.inputT, -1))",
61
+ "hiddenSize": "dim(shapes.inputT, -1)",
62
+ "skipWg": "max(1, min(tunables.MAX_WORKGROUP_SIZE, device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX, pow2ceil(hiddenSize)))",
63
+ "skipWgVec4": "max(1, min(tunables.MAX_WORKGROUP_SIZE, device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX, pow2ceil(ceilDiv(hiddenSize, 4))))",
64
+ "rowDispatchFits": "rowCount <= device.limits.maxComputeWorkgroupsPerDimension * device.limits.maxComputeWorkgroupsPerDimension",
65
+ "normResourcesFit": "skipWg * 8 <= device.limits.maxComputeWorkgroupStorageSize and skipWgVec4 * 8 <= device.limits.maxComputeWorkgroupStorageSize",
66
+ "epsilonOk": "attrs.epsilon >= 0",
67
+ "coreContract": "epsilonOk and (ranks.inputT == 2 or ranks.inputT == 3) and ranks.skipT == ranks.inputT and ranks.gammaT == 1 and ranks.outputT == ranks.inputT and sameShape(shapes.inputT, shapes.skipT) and sameShape(shapes.outputT, shapes.inputT) and dim(shapes.inputT, -1) > 0 and dim(shapes.gammaT, 0) == dim(shapes.inputT, -1)",
68
+ "residualOutputContract": "present.residualT and sameShape(shapes.residualT, shapes.inputT)",
69
+ "outputOnlyContract": "not present.residualT",
70
+ "f32MainDtypes": "tensorDtypes.inputT == \"float32\" and tensorDtypes.skipT == \"float32\" and tensorDtypes.gammaT == \"float32\" and tensorDtypes.outputT == \"float32\"",
71
+ "f16MainDtypes": "tensorDtypes.inputT == \"float16\" and tensorDtypes.skipT == \"float16\" and tensorDtypes.gammaT == \"float16\" and tensorDtypes.outputT == \"float16\"",
72
+ "f32ResidualDtypes": "f32MainDtypes and tensorDtypes.residualT == \"float32\" if present.residualT else false",
73
+ "f16ResidualDtypes": "f16MainDtypes and tensorDtypes.residualT == \"float16\" if present.residualT else false",
74
+ "vec4Aligned": "dim(shapes.inputT, -1) % 4 == 0",
75
+ "hasSubgroups": "device.features.has(\"subgroups\") and device.wgslLanguageFeatures.has(\"subgroup_id\")",
76
+ "hasF16": "device.features.has(\"shader-f16\")",
77
+ "no_bias_contract": "not present.biasT",
78
+ "f32_bias_contract": "false if not present.biasT else (ranks.biasT == 1 and tensorDtypes.biasT == \"float32\" and dim(shapes.biasT, 0) == hiddenSize)",
79
+ "f16_bias_contract": "false if not present.biasT else (ranks.biasT == 1 and tensorDtypes.biasT == \"float16\" and dim(shapes.biasT, 0) == hiddenSize)",
80
+ "f32_no_bias_residual_contract": "coreContract and residualOutputContract and f32ResidualDtypes and no_bias_contract",
81
+ "f32_bias_residual_contract": "coreContract and residualOutputContract and f32ResidualDtypes and f32_bias_contract",
82
+ "f16_no_bias_residual_contract": "hasF16 and coreContract and residualOutputContract and f16ResidualDtypes and no_bias_contract",
83
+ "f16_bias_residual_contract": "hasF16 and coreContract and residualOutputContract and f16ResidualDtypes and f16_bias_contract",
84
+ "f32_no_bias_output_contract": "coreContract and outputOnlyContract and f32MainDtypes and no_bias_contract",
85
+ "f32_bias_output_contract": "coreContract and outputOnlyContract and f32MainDtypes and f32_bias_contract",
86
+ "f16_no_bias_output_contract": "hasF16 and coreContract and outputOnlyContract and f16MainDtypes and no_bias_contract",
87
+ "f16_bias_output_contract": "hasF16 and coreContract and outputOnlyContract and f16MainDtypes and f16_bias_contract"
88
+ },
89
+ "bindingSets": {
90
+ "vec4_no_bias_residual": [
91
+ {
92
+ "name": "input",
93
+ "arg": "inputT",
94
+ "semantic": "input",
95
+ "buffer": { "type": "read-only-storage" },
96
+ "elementType": "$vectorScalar"
97
+ },
98
+ {
99
+ "name": "skip",
100
+ "arg": "skipT",
101
+ "semantic": "skip",
102
+ "buffer": { "type": "read-only-storage" },
103
+ "elementType": "$vectorScalar"
104
+ },
105
+ {
106
+ "name": "gamma",
107
+ "arg": "gammaT",
108
+ "semantic": "gamma",
109
+ "buffer": { "type": "read-only-storage" },
110
+ "elementType": "$vectorScalar",
111
+ "length": "$HIDDEN_LEN"
112
+ },
113
+ {
114
+ "name": "output",
115
+ "arg": "outputT",
116
+ "semantic": "output",
117
+ "buffer": { "type": "storage" },
118
+ "elementType": "$vectorScalar"
119
+ },
120
+ {
121
+ "name": "input_skip_bias_sum",
122
+ "arg": "residualT",
123
+ "semantic": "input_skip_bias_sum",
124
+ "buffer": { "type": "storage" },
125
+ "elementType": "$vectorScalar"
126
+ },
127
+ {
128
+ "name": "params",
129
+ "semantic": "kernel.params",
130
+ "buffer": { "type": "uniform" },
131
+ "struct": {
132
+ "name": "Params",
133
+ "fields": [
134
+ { "name": "rows", "type": "u32", "value": "rowCount" },
135
+ {
136
+ "name": "rowStride",
137
+ "type": "u32",
138
+ "value": "max(1, min(rowCount, device.limits.maxComputeWorkgroupsPerDimension))"
139
+ },
140
+ { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" }
141
+ ]
142
+ }
143
+ }
144
+ ],
145
+ "vec4_bias_residual": [
146
+ {
147
+ "name": "input",
148
+ "arg": "inputT",
149
+ "semantic": "input",
150
+ "buffer": { "type": "read-only-storage" },
151
+ "elementType": "$vectorScalar"
152
+ },
153
+ {
154
+ "name": "skip",
155
+ "arg": "skipT",
156
+ "semantic": "skip",
157
+ "buffer": { "type": "read-only-storage" },
158
+ "elementType": "$vectorScalar"
159
+ },
160
+ {
161
+ "name": "gamma",
162
+ "arg": "gammaT",
163
+ "semantic": "gamma",
164
+ "buffer": { "type": "read-only-storage" },
165
+ "elementType": "$vectorScalar",
166
+ "length": "$HIDDEN_LEN"
167
+ },
168
+ {
169
+ "name": "bias",
170
+ "arg": "biasT",
171
+ "semantic": "bias",
172
+ "buffer": { "type": "read-only-storage" },
173
+ "elementType": "$vectorScalar",
174
+ "length": "$HIDDEN_LEN"
175
+ },
176
+ {
177
+ "name": "output",
178
+ "arg": "outputT",
179
+ "semantic": "output",
180
+ "buffer": { "type": "storage" },
181
+ "elementType": "$vectorScalar"
182
+ },
183
+ {
184
+ "name": "input_skip_bias_sum",
185
+ "arg": "residualT",
186
+ "semantic": "input_skip_bias_sum",
187
+ "buffer": { "type": "storage" },
188
+ "elementType": "$vectorScalar"
189
+ },
190
+ {
191
+ "name": "params",
192
+ "semantic": "kernel.params",
193
+ "buffer": { "type": "uniform" },
194
+ "struct": {
195
+ "name": "Params",
196
+ "fields": [
197
+ { "name": "rows", "type": "u32", "value": "rowCount" },
198
+ {
199
+ "name": "rowStride",
200
+ "type": "u32",
201
+ "value": "max(1, min(rowCount, device.limits.maxComputeWorkgroupsPerDimension))"
202
+ },
203
+ { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" }
204
+ ]
205
+ }
206
+ }
207
+ ],
208
+ "vec4_no_bias_output_only": [
209
+ {
210
+ "name": "input",
211
+ "arg": "inputT",
212
+ "semantic": "input",
213
+ "buffer": { "type": "read-only-storage" },
214
+ "elementType": "$vectorScalar"
215
+ },
216
+ {
217
+ "name": "skip",
218
+ "arg": "skipT",
219
+ "semantic": "skip",
220
+ "buffer": { "type": "read-only-storage" },
221
+ "elementType": "$vectorScalar"
222
+ },
223
+ {
224
+ "name": "gamma",
225
+ "arg": "gammaT",
226
+ "semantic": "gamma",
227
+ "buffer": { "type": "read-only-storage" },
228
+ "elementType": "$vectorScalar",
229
+ "length": "$HIDDEN_LEN"
230
+ },
231
+ {
232
+ "name": "output",
233
+ "arg": "outputT",
234
+ "semantic": "output",
235
+ "buffer": { "type": "storage" },
236
+ "elementType": "$vectorScalar"
237
+ },
238
+ {
239
+ "name": "params",
240
+ "semantic": "kernel.params",
241
+ "buffer": { "type": "uniform" },
242
+ "struct": {
243
+ "name": "Params",
244
+ "fields": [
245
+ { "name": "rows", "type": "u32", "value": "rowCount" },
246
+ {
247
+ "name": "rowStride",
248
+ "type": "u32",
249
+ "value": "max(1, min(rowCount, device.limits.maxComputeWorkgroupsPerDimension))"
250
+ },
251
+ { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" }
252
+ ]
253
+ }
254
+ }
255
+ ],
256
+ "vec4_bias_output_only": [
257
+ {
258
+ "name": "input",
259
+ "arg": "inputT",
260
+ "semantic": "input",
261
+ "buffer": { "type": "read-only-storage" },
262
+ "elementType": "$vectorScalar"
263
+ },
264
+ {
265
+ "name": "skip",
266
+ "arg": "skipT",
267
+ "semantic": "skip",
268
+ "buffer": { "type": "read-only-storage" },
269
+ "elementType": "$vectorScalar"
270
+ },
271
+ {
272
+ "name": "gamma",
273
+ "arg": "gammaT",
274
+ "semantic": "gamma",
275
+ "buffer": { "type": "read-only-storage" },
276
+ "elementType": "$vectorScalar",
277
+ "length": "$HIDDEN_LEN"
278
+ },
279
+ {
280
+ "name": "bias",
281
+ "arg": "biasT",
282
+ "semantic": "bias",
283
+ "buffer": { "type": "read-only-storage" },
284
+ "elementType": "$vectorScalar",
285
+ "length": "$HIDDEN_LEN"
286
+ },
287
+ {
288
+ "name": "output",
289
+ "arg": "outputT",
290
+ "semantic": "output",
291
+ "buffer": { "type": "storage" },
292
+ "elementType": "$vectorScalar"
293
+ },
294
+ {
295
+ "name": "params",
296
+ "semantic": "kernel.params",
297
+ "buffer": { "type": "uniform" },
298
+ "struct": {
299
+ "name": "Params",
300
+ "fields": [
301
+ { "name": "rows", "type": "u32", "value": "rowCount" },
302
+ {
303
+ "name": "rowStride",
304
+ "type": "u32",
305
+ "value": "max(1, min(rowCount, device.limits.maxComputeWorkgroupsPerDimension))"
306
+ },
307
+ { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" }
308
+ ]
309
+ }
310
+ }
311
+ ],
312
+ "scalar_no_bias_residual": [
313
+ {
314
+ "name": "input",
315
+ "arg": "inputT",
316
+ "semantic": "input",
317
+ "buffer": { "type": "read-only-storage" },
318
+ "elementType": "$scalar"
319
+ },
320
+ {
321
+ "name": "skip",
322
+ "arg": "skipT",
323
+ "semantic": "skip",
324
+ "buffer": { "type": "read-only-storage" },
325
+ "elementType": "$scalar"
326
+ },
327
+ {
328
+ "name": "gamma",
329
+ "arg": "gammaT",
330
+ "semantic": "gamma",
331
+ "buffer": { "type": "read-only-storage" },
332
+ "elementType": "$scalar",
333
+ "length": "$HIDDEN_LEN"
334
+ },
335
+ {
336
+ "name": "output",
337
+ "arg": "outputT",
338
+ "semantic": "output",
339
+ "buffer": { "type": "storage" },
340
+ "elementType": "$scalar"
341
+ },
342
+ {
343
+ "name": "input_skip_bias_sum",
344
+ "arg": "residualT",
345
+ "semantic": "input_skip_bias_sum",
346
+ "buffer": { "type": "storage" },
347
+ "elementType": "$scalar"
348
+ },
349
+ {
350
+ "name": "params",
351
+ "semantic": "kernel.params",
352
+ "buffer": { "type": "uniform" },
353
+ "struct": {
354
+ "name": "Params",
355
+ "fields": [
356
+ { "name": "rows", "type": "u32", "value": "rowCount" },
357
+ { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" }
358
+ ]
359
+ }
360
+ }
361
+ ],
362
+ "scalar_bias_residual": [
363
+ {
364
+ "name": "input",
365
+ "arg": "inputT",
366
+ "semantic": "input",
367
+ "buffer": { "type": "read-only-storage" },
368
+ "elementType": "$scalar"
369
+ },
370
+ {
371
+ "name": "skip",
372
+ "arg": "skipT",
373
+ "semantic": "skip",
374
+ "buffer": { "type": "read-only-storage" },
375
+ "elementType": "$scalar"
376
+ },
377
+ {
378
+ "name": "gamma",
379
+ "arg": "gammaT",
380
+ "semantic": "gamma",
381
+ "buffer": { "type": "read-only-storage" },
382
+ "elementType": "$scalar",
383
+ "length": "$HIDDEN_LEN"
384
+ },
385
+ {
386
+ "name": "bias",
387
+ "arg": "biasT",
388
+ "semantic": "bias",
389
+ "buffer": { "type": "read-only-storage" },
390
+ "elementType": "$scalar",
391
+ "length": "$HIDDEN_LEN"
392
+ },
393
+ {
394
+ "name": "output",
395
+ "arg": "outputT",
396
+ "semantic": "output",
397
+ "buffer": { "type": "storage" },
398
+ "elementType": "$scalar"
399
+ },
400
+ {
401
+ "name": "input_skip_bias_sum",
402
+ "arg": "residualT",
403
+ "semantic": "input_skip_bias_sum",
404
+ "buffer": { "type": "storage" },
405
+ "elementType": "$scalar"
406
+ },
407
+ {
408
+ "name": "params",
409
+ "semantic": "kernel.params",
410
+ "buffer": { "type": "uniform" },
411
+ "struct": {
412
+ "name": "Params",
413
+ "fields": [
414
+ { "name": "rows", "type": "u32", "value": "rowCount" },
415
+ { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" }
416
+ ]
417
+ }
418
+ }
419
+ ],
420
+ "scalar_no_bias_output_only": [
421
+ {
422
+ "name": "input",
423
+ "arg": "inputT",
424
+ "semantic": "input",
425
+ "buffer": { "type": "read-only-storage" },
426
+ "elementType": "$scalar"
427
+ },
428
+ {
429
+ "name": "skip",
430
+ "arg": "skipT",
431
+ "semantic": "skip",
432
+ "buffer": { "type": "read-only-storage" },
433
+ "elementType": "$scalar"
434
+ },
435
+ {
436
+ "name": "gamma",
437
+ "arg": "gammaT",
438
+ "semantic": "gamma",
439
+ "buffer": { "type": "read-only-storage" },
440
+ "elementType": "$scalar",
441
+ "length": "$HIDDEN_LEN"
442
+ },
443
+ {
444
+ "name": "output",
445
+ "arg": "outputT",
446
+ "semantic": "output",
447
+ "buffer": { "type": "storage" },
448
+ "elementType": "$scalar"
449
+ },
450
+ {
451
+ "name": "params",
452
+ "semantic": "kernel.params",
453
+ "buffer": { "type": "uniform" },
454
+ "struct": {
455
+ "name": "Params",
456
+ "fields": [
457
+ { "name": "rows", "type": "u32", "value": "rowCount" },
458
+ { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" }
459
+ ]
460
+ }
461
+ }
462
+ ],
463
+ "scalar_bias_output_only": [
464
+ {
465
+ "name": "input",
466
+ "arg": "inputT",
467
+ "semantic": "input",
468
+ "buffer": { "type": "read-only-storage" },
469
+ "elementType": "$scalar"
470
+ },
471
+ {
472
+ "name": "skip",
473
+ "arg": "skipT",
474
+ "semantic": "skip",
475
+ "buffer": { "type": "read-only-storage" },
476
+ "elementType": "$scalar"
477
+ },
478
+ {
479
+ "name": "gamma",
480
+ "arg": "gammaT",
481
+ "semantic": "gamma",
482
+ "buffer": { "type": "read-only-storage" },
483
+ "elementType": "$scalar",
484
+ "length": "$HIDDEN_LEN"
485
+ },
486
+ {
487
+ "name": "bias",
488
+ "arg": "biasT",
489
+ "semantic": "bias",
490
+ "buffer": { "type": "read-only-storage" },
491
+ "elementType": "$scalar",
492
+ "length": "$HIDDEN_LEN"
493
+ },
494
+ {
495
+ "name": "output",
496
+ "arg": "outputT",
497
+ "semantic": "output",
498
+ "buffer": { "type": "storage" },
499
+ "elementType": "$scalar"
500
+ },
501
+ {
502
+ "name": "params",
503
+ "semantic": "kernel.params",
504
+ "buffer": { "type": "uniform" },
505
+ "struct": {
506
+ "name": "Params",
507
+ "fields": [
508
+ { "name": "rows", "type": "u32", "value": "rowCount" },
509
+ { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" }
510
+ ]
511
+ }
512
+ }
513
+ ]
514
+ },
515
+ "tunables": { "MAX_WORKGROUP_SIZE": 256 },
516
+ "variants": [
517
+ {
518
+ "id": "no_bias_vec4_f16",
519
+ "priority": 21,
520
+ "when": ["f16_no_bias_residual_contract", "vec4Aligned", "normResourcesFit", "rowDispatchFits"],
521
+ "constants": {
522
+ "scalar": "\"f16\"",
523
+ "vectorScalar": "\"vec4<f16>\"",
524
+ "hasBias": "\"no_bias\" == \"bias\"",
525
+ "HIDDEN_LEN": "hiddenSize / 4"
526
+ },
527
+ "passes": [
528
+ {
529
+ "id": "main",
530
+ "name": "SkipSimplifiedLayerNormalization.Vec4",
531
+ "source": {
532
+ "shader": "norm-skip-row-vec4.wgsl.jinja",
533
+ "inputs": {
534
+ "simplified": true,
535
+ "hasBias": "\"no_bias\" == \"bias\"",
536
+ "hasBeta": false,
537
+ "writeResidualSum": true,
538
+ "usesF16": true,
539
+ "hidden": "hiddenSize",
540
+ "hiddenVec": "hiddenSize / 4",
541
+ "wg": "skipWgVec4",
542
+ "vecType": "\"vec4<f16>\"",
543
+ "useSubgroups": "hasSubgroups"
544
+ }
545
+ },
546
+ "subgroupCollectivesWidth": "portable",
547
+ "bindings": "vec4_no_bias_residual",
548
+ "dispatch": { "workgroups": "rowCount" }
549
+ }
550
+ ]
551
+ },
552
+ {
553
+ "id": "no_bias_vec4",
554
+ "priority": 20,
555
+ "when": ["f32_no_bias_residual_contract", "vec4Aligned", "normResourcesFit", "rowDispatchFits"],
556
+ "constants": {
557
+ "scalar": "\"f32\"",
558
+ "vectorScalar": "\"vec4<f32>\"",
559
+ "hasBias": "\"no_bias\" == \"bias\"",
560
+ "HIDDEN_LEN": "hiddenSize / 4"
561
+ },
562
+ "passes": [
563
+ {
564
+ "id": "main",
565
+ "name": "SkipSimplifiedLayerNormalization.Vec4",
566
+ "source": {
567
+ "shader": "norm-skip-row-vec4.wgsl.jinja",
568
+ "inputs": {
569
+ "simplified": true,
570
+ "hasBias": "\"no_bias\" == \"bias\"",
571
+ "hasBeta": false,
572
+ "writeResidualSum": true,
573
+ "usesF16": false,
574
+ "hidden": "hiddenSize",
575
+ "hiddenVec": "hiddenSize / 4",
576
+ "wg": "skipWgVec4",
577
+ "vecType": "\"vec4<f32>\"",
578
+ "useSubgroups": "hasSubgroups"
579
+ }
580
+ },
581
+ "subgroupCollectivesWidth": "portable",
582
+ "bindings": "vec4_no_bias_residual",
583
+ "dispatch": { "workgroups": "rowCount" }
584
+ }
585
+ ]
586
+ },
587
+ {
588
+ "id": "no_bias_output_only_vec4",
589
+ "priority": 20,
590
+ "when": ["f32_no_bias_output_contract", "vec4Aligned", "normResourcesFit", "rowDispatchFits"],
591
+ "constants": {
592
+ "scalar": "\"f32\"",
593
+ "vectorScalar": "\"vec4<f32>\"",
594
+ "hasBias": "\"no_bias\" == \"bias\"",
595
+ "HIDDEN_LEN": "hiddenSize / 4"
596
+ },
597
+ "passes": [
598
+ {
599
+ "id": "main",
600
+ "name": "SkipSimplifiedLayerNormalization.Vec4OutputOnly",
601
+ "source": {
602
+ "shader": "norm-skip-row-vec4.wgsl.jinja",
603
+ "inputs": {
604
+ "simplified": true,
605
+ "hasBias": "\"no_bias\" == \"bias\"",
606
+ "hasBeta": false,
607
+ "writeResidualSum": false,
608
+ "usesF16": false,
609
+ "hidden": "hiddenSize",
610
+ "hiddenVec": "hiddenSize / 4",
611
+ "wg": "skipWgVec4",
612
+ "vecType": "\"vec4<f32>\"",
613
+ "useSubgroups": "hasSubgroups"
614
+ }
615
+ },
616
+ "subgroupCollectivesWidth": "portable",
617
+ "bindings": "vec4_no_bias_output_only",
618
+ "dispatch": { "workgroups": "rowCount" }
619
+ }
620
+ ]
621
+ },
622
+ {
623
+ "id": "no_bias_output_only_vec4_f16",
624
+ "priority": 21,
625
+ "when": ["f16_no_bias_output_contract", "vec4Aligned", "normResourcesFit", "rowDispatchFits"],
626
+ "constants": {
627
+ "scalar": "\"f16\"",
628
+ "vectorScalar": "\"vec4<f16>\"",
629
+ "hasBias": "\"no_bias\" == \"bias\"",
630
+ "HIDDEN_LEN": "hiddenSize / 4"
631
+ },
632
+ "passes": [
633
+ {
634
+ "id": "main",
635
+ "name": "SkipSimplifiedLayerNormalization.Vec4OutputOnly",
636
+ "source": {
637
+ "shader": "norm-skip-row-vec4.wgsl.jinja",
638
+ "inputs": {
639
+ "simplified": true,
640
+ "hasBias": "\"no_bias\" == \"bias\"",
641
+ "hasBeta": false,
642
+ "writeResidualSum": false,
643
+ "usesF16": true,
644
+ "hidden": "hiddenSize",
645
+ "hiddenVec": "hiddenSize / 4",
646
+ "wg": "skipWgVec4",
647
+ "vecType": "\"vec4<f16>\"",
648
+ "useSubgroups": "hasSubgroups"
649
+ }
650
+ },
651
+ "subgroupCollectivesWidth": "portable",
652
+ "bindings": "vec4_no_bias_output_only",
653
+ "dispatch": { "workgroups": "rowCount" }
654
+ }
655
+ ]
656
+ },
657
+ {
658
+ "id": "no_bias",
659
+ "priority": 0,
660
+ "when": ["f32_no_bias_residual_contract", "normResourcesFit", "rowDispatchFits"],
661
+ "constants": {
662
+ "simplified": true,
663
+ "useSubgroups": false,
664
+ "hasBeta": false,
665
+ "writeResidualSum": true,
666
+ "hasBias": "\"no_bias\" == \"bias\"",
667
+ "scalar": "\"f32\"",
668
+ "hiddenSize": "dim(shapes.inputT, -1)",
669
+ "workgroupSize": "skipWg",
670
+ "HIDDEN_LEN": "hiddenSize"
671
+ },
672
+ "passes": [
673
+ {
674
+ "id": "main",
675
+ "name": "SkipSimplifiedLayerNormalization",
676
+ "shader": "norm-skip-row.wgsl.jinja",
677
+ "bindings": "scalar_no_bias_residual",
678
+ "dispatch": { "workgroups": "rowCount" }
679
+ }
680
+ ]
681
+ },
682
+ {
683
+ "id": "no_bias_f16",
684
+ "requires": { "features": ["shader-f16"] },
685
+ "priority": 0,
686
+ "when": ["f16_no_bias_residual_contract", "normResourcesFit", "rowDispatchFits"],
687
+ "constants": {
688
+ "simplified": true,
689
+ "useSubgroups": false,
690
+ "hasBeta": false,
691
+ "writeResidualSum": true,
692
+ "hasBias": "\"no_bias\" == \"bias\"",
693
+ "scalar": "\"f16\"",
694
+ "usesF16": true,
695
+ "hiddenSize": "dim(shapes.inputT, -1)",
696
+ "workgroupSize": "skipWg",
697
+ "HIDDEN_LEN": "hiddenSize"
698
+ },
699
+ "passes": [
700
+ {
701
+ "id": "main",
702
+ "name": "SkipSimplifiedLayerNormalization",
703
+ "shader": "norm-skip-row.wgsl.jinja",
704
+ "bindings": "scalar_no_bias_residual",
705
+ "dispatch": { "workgroups": "rowCount" }
706
+ }
707
+ ]
708
+ },
709
+ {
710
+ "id": "no_bias_output_only_f16",
711
+ "requires": { "features": ["shader-f16"] },
712
+ "priority": 0,
713
+ "when": ["f16_no_bias_output_contract", "normResourcesFit", "rowDispatchFits"],
714
+ "constants": {
715
+ "simplified": true,
716
+ "useSubgroups": false,
717
+ "hasBeta": false,
718
+ "writeResidualSum": false,
719
+ "hasBias": "\"no_bias\" == \"bias\"",
720
+ "scalar": "\"f16\"",
721
+ "usesF16": true,
722
+ "hiddenSize": "dim(shapes.inputT, -1)",
723
+ "workgroupSize": "skipWg",
724
+ "HIDDEN_LEN": "hiddenSize"
725
+ },
726
+ "passes": [
727
+ {
728
+ "id": "main",
729
+ "name": "SkipSimplifiedLayerNormalization.OutputOnly",
730
+ "shader": "norm-skip-row.wgsl.jinja",
731
+ "bindings": "scalar_no_bias_output_only",
732
+ "dispatch": { "workgroups": "rowCount" }
733
+ }
734
+ ]
735
+ },
736
+ {
737
+ "id": "no_bias_output_only",
738
+ "priority": 0,
739
+ "when": ["f32_no_bias_output_contract", "normResourcesFit", "rowDispatchFits"],
740
+ "constants": {
741
+ "simplified": true,
742
+ "useSubgroups": false,
743
+ "hasBeta": false,
744
+ "writeResidualSum": false,
745
+ "hasBias": "\"no_bias\" == \"bias\"",
746
+ "scalar": "\"f32\"",
747
+ "hiddenSize": "dim(shapes.inputT, -1)",
748
+ "workgroupSize": "skipWg",
749
+ "HIDDEN_LEN": "hiddenSize"
750
+ },
751
+ "passes": [
752
+ {
753
+ "id": "main",
754
+ "name": "SkipSimplifiedLayerNormalization.OutputOnly",
755
+ "shader": "norm-skip-row.wgsl.jinja",
756
+ "bindings": "scalar_no_bias_output_only",
757
+ "dispatch": { "workgroups": "rowCount" }
758
+ }
759
+ ]
760
+ },
761
+ {
762
+ "id": "bias_vec4_f16",
763
+ "priority": 21,
764
+ "when": ["f16_bias_residual_contract", "vec4Aligned", "normResourcesFit", "rowDispatchFits"],
765
+ "constants": {
766
+ "scalar": "\"f16\"",
767
+ "vectorScalar": "\"vec4<f16>\"",
768
+ "hasBias": "\"bias\" == \"bias\"",
769
+ "HIDDEN_LEN": "hiddenSize / 4"
770
+ },
771
+ "passes": [
772
+ {
773
+ "id": "main",
774
+ "name": "SkipSimplifiedLayerNormalization.Vec4",
775
+ "source": {
776
+ "shader": "norm-skip-row-vec4.wgsl.jinja",
777
+ "inputs": {
778
+ "simplified": true,
779
+ "hasBias": "\"bias\" == \"bias\"",
780
+ "hasBeta": false,
781
+ "writeResidualSum": true,
782
+ "usesF16": true,
783
+ "hidden": "hiddenSize",
784
+ "hiddenVec": "hiddenSize / 4",
785
+ "wg": "skipWgVec4",
786
+ "vecType": "\"vec4<f16>\"",
787
+ "useSubgroups": "hasSubgroups"
788
+ }
789
+ },
790
+ "subgroupCollectivesWidth": "portable",
791
+ "bindings": "vec4_bias_residual",
792
+ "dispatch": { "workgroups": "rowCount" }
793
+ }
794
+ ]
795
+ },
796
+ {
797
+ "id": "bias_vec4",
798
+ "priority": 20,
799
+ "when": ["f32_bias_residual_contract", "vec4Aligned", "normResourcesFit", "rowDispatchFits"],
800
+ "constants": {
801
+ "scalar": "\"f32\"",
802
+ "vectorScalar": "\"vec4<f32>\"",
803
+ "hasBias": "\"bias\" == \"bias\"",
804
+ "HIDDEN_LEN": "hiddenSize / 4"
805
+ },
806
+ "passes": [
807
+ {
808
+ "id": "main",
809
+ "name": "SkipSimplifiedLayerNormalization.Vec4",
810
+ "source": {
811
+ "shader": "norm-skip-row-vec4.wgsl.jinja",
812
+ "inputs": {
813
+ "simplified": true,
814
+ "hasBias": "\"bias\" == \"bias\"",
815
+ "hasBeta": false,
816
+ "writeResidualSum": true,
817
+ "usesF16": false,
818
+ "hidden": "hiddenSize",
819
+ "hiddenVec": "hiddenSize / 4",
820
+ "wg": "skipWgVec4",
821
+ "vecType": "\"vec4<f32>\"",
822
+ "useSubgroups": "hasSubgroups"
823
+ }
824
+ },
825
+ "subgroupCollectivesWidth": "portable",
826
+ "bindings": "vec4_bias_residual",
827
+ "dispatch": { "workgroups": "rowCount" }
828
+ }
829
+ ]
830
+ },
831
+ {
832
+ "id": "bias_output_only_vec4",
833
+ "priority": 20,
834
+ "when": ["f32_bias_output_contract", "vec4Aligned", "normResourcesFit", "rowDispatchFits"],
835
+ "constants": {
836
+ "scalar": "\"f32\"",
837
+ "vectorScalar": "\"vec4<f32>\"",
838
+ "hasBias": "\"bias\" == \"bias\"",
839
+ "HIDDEN_LEN": "hiddenSize / 4"
840
+ },
841
+ "passes": [
842
+ {
843
+ "id": "main",
844
+ "name": "SkipSimplifiedLayerNormalization.Vec4OutputOnly",
845
+ "source": {
846
+ "shader": "norm-skip-row-vec4.wgsl.jinja",
847
+ "inputs": {
848
+ "simplified": true,
849
+ "hasBias": "\"bias\" == \"bias\"",
850
+ "hasBeta": false,
851
+ "writeResidualSum": false,
852
+ "usesF16": false,
853
+ "hidden": "hiddenSize",
854
+ "hiddenVec": "hiddenSize / 4",
855
+ "wg": "skipWgVec4",
856
+ "vecType": "\"vec4<f32>\"",
857
+ "useSubgroups": "hasSubgroups"
858
+ }
859
+ },
860
+ "subgroupCollectivesWidth": "portable",
861
+ "bindings": "vec4_bias_output_only",
862
+ "dispatch": { "workgroups": "rowCount" }
863
+ }
864
+ ]
865
+ },
866
+ {
867
+ "id": "bias_output_only_vec4_f16",
868
+ "priority": 21,
869
+ "when": ["f16_bias_output_contract", "vec4Aligned", "normResourcesFit", "rowDispatchFits"],
870
+ "constants": {
871
+ "scalar": "\"f16\"",
872
+ "vectorScalar": "\"vec4<f16>\"",
873
+ "hasBias": "\"bias\" == \"bias\"",
874
+ "HIDDEN_LEN": "hiddenSize / 4"
875
+ },
876
+ "passes": [
877
+ {
878
+ "id": "main",
879
+ "name": "SkipSimplifiedLayerNormalization.Vec4OutputOnly",
880
+ "source": {
881
+ "shader": "norm-skip-row-vec4.wgsl.jinja",
882
+ "inputs": {
883
+ "simplified": true,
884
+ "hasBias": "\"bias\" == \"bias\"",
885
+ "hasBeta": false,
886
+ "writeResidualSum": false,
887
+ "usesF16": true,
888
+ "hidden": "hiddenSize",
889
+ "hiddenVec": "hiddenSize / 4",
890
+ "wg": "skipWgVec4",
891
+ "vecType": "\"vec4<f16>\"",
892
+ "useSubgroups": "hasSubgroups"
893
+ }
894
+ },
895
+ "subgroupCollectivesWidth": "portable",
896
+ "bindings": "vec4_bias_output_only",
897
+ "dispatch": { "workgroups": "rowCount" }
898
+ }
899
+ ]
900
+ },
901
+ {
902
+ "id": "bias",
903
+ "priority": 0,
904
+ "when": ["f32_bias_residual_contract", "normResourcesFit", "rowDispatchFits"],
905
+ "constants": {
906
+ "simplified": true,
907
+ "useSubgroups": false,
908
+ "hasBeta": false,
909
+ "writeResidualSum": true,
910
+ "hasBias": "\"bias\" == \"bias\"",
911
+ "scalar": "\"f32\"",
912
+ "hiddenSize": "dim(shapes.inputT, -1)",
913
+ "workgroupSize": "skipWg",
914
+ "HIDDEN_LEN": "hiddenSize"
915
+ },
916
+ "passes": [
917
+ {
918
+ "id": "main",
919
+ "name": "SkipSimplifiedLayerNormalization",
920
+ "shader": "norm-skip-row.wgsl.jinja",
921
+ "bindings": "scalar_bias_residual",
922
+ "dispatch": { "workgroups": "rowCount" }
923
+ }
924
+ ]
925
+ },
926
+ {
927
+ "id": "bias_f16",
928
+ "requires": { "features": ["shader-f16"] },
929
+ "priority": 0,
930
+ "when": ["f16_bias_residual_contract", "normResourcesFit", "rowDispatchFits"],
931
+ "constants": {
932
+ "simplified": true,
933
+ "useSubgroups": false,
934
+ "hasBeta": false,
935
+ "writeResidualSum": true,
936
+ "hasBias": "\"bias\" == \"bias\"",
937
+ "scalar": "\"f16\"",
938
+ "usesF16": true,
939
+ "hiddenSize": "dim(shapes.inputT, -1)",
940
+ "workgroupSize": "skipWg",
941
+ "HIDDEN_LEN": "hiddenSize"
942
+ },
943
+ "passes": [
944
+ {
945
+ "id": "main",
946
+ "name": "SkipSimplifiedLayerNormalization",
947
+ "shader": "norm-skip-row.wgsl.jinja",
948
+ "bindings": "scalar_bias_residual",
949
+ "dispatch": { "workgroups": "rowCount" }
950
+ }
951
+ ]
952
+ },
953
+ {
954
+ "id": "bias_output_only_f16",
955
+ "requires": { "features": ["shader-f16"] },
956
+ "priority": 0,
957
+ "when": ["f16_bias_output_contract", "normResourcesFit", "rowDispatchFits"],
958
+ "constants": {
959
+ "simplified": true,
960
+ "useSubgroups": false,
961
+ "hasBeta": false,
962
+ "writeResidualSum": false,
963
+ "hasBias": "\"bias\" == \"bias\"",
964
+ "scalar": "\"f16\"",
965
+ "usesF16": true,
966
+ "hiddenSize": "dim(shapes.inputT, -1)",
967
+ "workgroupSize": "skipWg",
968
+ "HIDDEN_LEN": "hiddenSize"
969
+ },
970
+ "passes": [
971
+ {
972
+ "id": "main",
973
+ "name": "SkipSimplifiedLayerNormalization.OutputOnly",
974
+ "shader": "norm-skip-row.wgsl.jinja",
975
+ "bindings": "scalar_bias_output_only",
976
+ "dispatch": { "workgroups": "rowCount" }
977
+ }
978
+ ]
979
+ },
980
+ {
981
+ "id": "bias_output_only",
982
+ "priority": 0,
983
+ "when": ["f32_bias_output_contract", "normResourcesFit", "rowDispatchFits"],
984
+ "constants": {
985
+ "simplified": true,
986
+ "useSubgroups": false,
987
+ "hasBeta": false,
988
+ "writeResidualSum": false,
989
+ "hasBias": "\"bias\" == \"bias\"",
990
+ "scalar": "\"f32\"",
991
+ "hiddenSize": "dim(shapes.inputT, -1)",
992
+ "workgroupSize": "skipWg",
993
+ "HIDDEN_LEN": "hiddenSize"
994
+ },
995
+ "passes": [
996
+ {
997
+ "id": "main",
998
+ "name": "SkipSimplifiedLayerNormalization.OutputOnly",
999
+ "shader": "norm-skip-row.wgsl.jinja",
1000
+ "bindings": "scalar_bias_output_only",
1001
+ "dispatch": { "workgroups": "rowCount" }
1002
+ }
1003
+ ]
1004
+ }
1005
+ ]
1006
+ }
build/webgpu/metadata.json ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "com.microsoft.SkipSimplifiedLayerNormalization",
3
+ "id": "_com_microsoft_skipsimplifiedlayernormalization_webgpu_6026e4e",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "backend": { "type": "webgpu" },
7
+ "digest": {
8
+ "algorithm": "sha256",
9
+ "files": {
10
+ "bench.json": "Qjd8vGH/qoXU3rXEQhkz+xTQK2qSM5Kl4BHnWY/nzeQ=",
11
+ "manifest.json": "0QZ+D26SsY6uIHFcZV326mQMPoEYAClEUEifNI/9jms=",
12
+ "norm-skip-row-vec4.wgsl.jinja": "L7sH/FpRWVXbyaGm4QTjBAaLMacnNmwb0dbt2pKie5s=",
13
+ "norm-skip-row.wgsl.jinja": "bo/2mKHvO3Xkb7rbXnHkw/csvMsxID6bhdF8Wv7efKM=",
14
+ "test.json": "oQayex/aOYAhZXp9ESTPlwVGivSDeuEumSnU6kNNUR0="
15
+ }
16
+ },
17
+ "provenance": { "kernel": { "sha": "2e7068faf55e7f43df740015f6d1ee49391a41c5", "dirty": false } },
18
+ "webgpu": {
19
+ "manifestSpec": "1.0",
20
+ "specialized": true,
21
+ "opPath": "ops/com.microsoft.SkipSimplifiedLayerNormalization"
22
+ }
23
+ }
build/webgpu/norm-skip-row-vec4.wgsl.jinja ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% macro wgsl_tree_fold_stmt(a, op, idx, svar) %}
2
+ {% if op == "max" %}
3
+ {{ a }}[{{ idx }}] = max({{ a }}[{{ idx }}], {{ a }}[{{ idx }} + {{ svar }}]);
4
+ {%- else %}
5
+ {{ a }}[{{ idx }}] = {{ a }}[{{ idx }}] + {{ a }}[{{ idx }} + {{ svar }}];
6
+ {%- endif %}
7
+ {% endmacro %}
8
+ {% macro wgsl_tree_fold(arrays, op="add", idx="lid", wg="WORKGROUP_SIZE", svar="stride", typed=false, form="tail", breakInline=false, bodyInline=false, barrierFirst=false) %}
9
+ var {{ svar }}{{ ": u32 " if typed else " " }}= {{ wg }} / 2u;
10
+ loop {
11
+ {% if form == "head" %}
12
+ {% if breakInline %}
13
+ if ({{ svar }} == 0u) { break; }
14
+ {% else %}
15
+ if ({{ svar }} == 0u) {
16
+ break;
17
+ }
18
+ {% endif %}
19
+ {% endif %}
20
+ {% if bodyInline %}
21
+ if ({{ idx }} < {{ svar }}) { {{ wgsl_tree_fold_stmt(arrays[0], op, idx, svar) }} }
22
+ {% else %}
23
+ if ({{ idx }} < {{ svar }}) {
24
+ {% for a in arrays %}
25
+ {{ wgsl_tree_fold_stmt(a, op, idx, svar) }}
26
+ {% endfor %}
27
+ }
28
+ {% endif %}
29
+ {% if form == "head" %}
30
+ {% if barrierFirst %}
31
+ workgroupBarrier();
32
+ {{ svar }} = {{ svar }} / 2u;
33
+ {% else %}
34
+ {{ svar }} = {{ svar }} / 2u;
35
+ workgroupBarrier();
36
+ {% endif %}
37
+ {% else %}
38
+ workgroupBarrier();
39
+ if ({{ svar }} == 1u) {
40
+ break;
41
+ }
42
+ {{ svar }} = {{ svar }} / 2u;
43
+ {% endif %}
44
+ }
45
+ {%- endmacro %}{% set useSubgroups = source.useSubgroups %}
46
+ {% if source.usesF16 %}
47
+ enable f16;
48
+ {% endif %}
49
+ {% if useSubgroups %}
50
+ enable subgroups;
51
+ {% endif %}
52
+ {{ env.wgsl.resourceDeclarations }}
53
+
54
+ const HIDDEN: u32 = {{ source.hidden }}u;
55
+ const HIDDEN_V: u32 = {{ source.hiddenVec }}u;
56
+ const WG: u32 = {{ source.wg }}u;
57
+
58
+ var<workgroup> sg_partials: array<f32, WG>;
59
+
60
+ fn reduce_scalar(value: f32{% if useSubgroups %}, sg_lane: u32, sg_id: u32, num_sg: u32{% else %}, tid: u32{% endif %}) -> f32 {
61
+ {% if useSubgroups %}
62
+ let s = subgroupAdd(value);
63
+ if (num_sg == 1u) {
64
+ return s;
65
+ }
66
+ if (sg_lane == 0u) {
67
+ sg_partials[sg_id] = s;
68
+ }
69
+ workgroupBarrier();
70
+ var total = 0.0;
71
+ for (var i = 0u; i < num_sg; i = i + 1u) {
72
+ total = total + sg_partials[i];
73
+ }
74
+ return total;
75
+ {% else %}
76
+ // No-subgroup tier: workgroup barrier tree-reduction (WG is a power of two).
77
+ sg_partials[tid] = value;
78
+ workgroupBarrier();
79
+ {{ wgsl_tree_fold(["sg_partials"], idx="tid", wg="WG", form="head", breakInline=true) }}
80
+ return sg_partials[0];
81
+ {% endif %}
82
+ }
83
+
84
+ // 4 contiguous residual elements (input[idx] + skip[skip_idx] [+ bias]) at vec4
85
+ // index `vi`. skip_idx == idx for the normal (non-broadcast) path; for a skip
86
+ // that broadcasts across the leading/batch dim uses a folded index.
87
+ fn residual_value(idx: u32, skip_idx: u32{% if source.hasBias %}, vi: u32{% endif %}) -> vec4<f32> {
88
+ var value = vec4<f32>(input[idx]) + vec4<f32>(skip[skip_idx]);
89
+ {% if source.hasBias %}
90
+ value = value + vec4<f32>(bias[vi]);
91
+ {% endif %}
92
+ return value;
93
+ }
94
+
95
+ @compute @workgroup_size(WG, 1, 1)
96
+ fn main(
97
+ @builtin(workgroup_id) wg_id: vec3<u32>,
98
+ @builtin(local_invocation_id) lid: vec3<u32>{% if useSubgroups %},
99
+ @builtin(subgroup_invocation_id) sg_lane: u32,
100
+ @builtin(subgroup_id) sg_id: u32,
101
+ @builtin(num_subgroups) num_sg: u32{% endif %}
102
+ ) {
103
+ let row = wg_id.x + wg_id.y * params.rowStride;
104
+ if (row >= params.rows) {
105
+ return;
106
+ }
107
+ let tid = lid.x;
108
+ let base = row * HIDDEN_V;
109
+ let skip_base = base;
110
+
111
+
112
+ var acc = 0.0;
113
+ for (var i = tid; i < HIDDEN_V; i = i + WG) {
114
+ let v = residual_value(base + i, skip_base + i{% if source.hasBias %}, i{% endif %});
115
+ acc = acc + dot(v, v);
116
+ }
117
+
118
+ let total = reduce_scalar(acc{% if useSubgroups %}, sg_lane, sg_id, num_sg{% else %}, tid{% endif %});
119
+ let row_inv = inverseSqrt(total / f32(HIDDEN) + params.epsilon);
120
+
121
+ for (var i = tid; i < HIDDEN_V; i = i + WG) {
122
+ let idx = base + i;
123
+ let residual = residual_value(idx, skip_base + i{% if source.hasBias %}, i{% endif %});
124
+ {% if source.writeResidualSum %}
125
+ input_skip_bias_sum[idx] = {{ source.vecType }}(residual);
126
+ {% endif %}
127
+ output[idx] = {{ source.vecType }}(residual * row_inv * vec4<f32>(gamma[i]));
128
+ }
129
+ }
build/webgpu/norm-skip-row.wgsl.jinja ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {% macro wgsl_tree_fold_stmt(a, op, idx, svar) %}
2
+ {% if op == "max" %}
3
+ {{ a }}[{{ idx }}] = max({{ a }}[{{ idx }}], {{ a }}[{{ idx }} + {{ svar }}]);
4
+ {%- else %}
5
+ {{ a }}[{{ idx }}] = {{ a }}[{{ idx }}] + {{ a }}[{{ idx }} + {{ svar }}];
6
+ {%- endif %}
7
+ {% endmacro %}
8
+ {% macro wgsl_tree_fold(arrays, op="add", idx="lid", wg="WORKGROUP_SIZE", svar="stride", typed=false, form="tail", breakInline=false, bodyInline=false, barrierFirst=false) %}
9
+ var {{ svar }}{{ ": u32 " if typed else " " }}= {{ wg }} / 2u;
10
+ loop {
11
+ {% if form == "head" %}
12
+ {% if breakInline %}
13
+ if ({{ svar }} == 0u) { break; }
14
+ {% else %}
15
+ if ({{ svar }} == 0u) {
16
+ break;
17
+ }
18
+ {% endif %}
19
+ {% endif %}
20
+ {% if bodyInline %}
21
+ if ({{ idx }} < {{ svar }}) { {{ wgsl_tree_fold_stmt(arrays[0], op, idx, svar) }} }
22
+ {% else %}
23
+ if ({{ idx }} < {{ svar }}) {
24
+ {% for a in arrays %}
25
+ {{ wgsl_tree_fold_stmt(a, op, idx, svar) }}
26
+ {% endfor %}
27
+ }
28
+ {% endif %}
29
+ {% if form == "head" %}
30
+ {% if barrierFirst %}
31
+ workgroupBarrier();
32
+ {{ svar }} = {{ svar }} / 2u;
33
+ {% else %}
34
+ {{ svar }} = {{ svar }} / 2u;
35
+ workgroupBarrier();
36
+ {% endif %}
37
+ {% else %}
38
+ workgroupBarrier();
39
+ if ({{ svar }} == 1u) {
40
+ break;
41
+ }
42
+ {{ svar }} = {{ svar }} / 2u;
43
+ {% endif %}
44
+ }
45
+ {%- endmacro %}
46
+
47
+ /* One workgroup normalizes each row of residual = input + skip, with an
48
+ * optional bias. */
49
+ {% set degenerateRow = (not simplified) and hiddenSize == 1 %}
50
+ {% if usesF16 %}
51
+ enable f16;
52
+ {% endif %}
53
+ {% if useSubgroups and not degenerateRow %}
54
+ enable subgroups;
55
+ {% endif %}
56
+ {{ env.wgsl.resourceDeclarations }}
57
+
58
+ {% if not degenerateRow or writeResidualSum %}
59
+ const HIDDEN: u32 = {{ hiddenSize }}u;
60
+ {% endif %}
61
+ const WG: u32 = {{ workgroupSize }}u;
62
+ {% if simplified %}
63
+
64
+ var<workgroup> partial: array<f32, WG>;
65
+ {% macro wgsl_tree_reduce_f32(name, mode, buffer="partial", wg="WG", trailingBarrier=true) %}
66
+ fn {{ name }}(value: f32, tid: u32) -> f32 {
67
+ {{ buffer }}[tid] = value;
68
+ workgroupBarrier();
69
+ // Ceil-halving keeps every lane when the workgroup size is not a power of
70
+ // two. For even n this matches the power-of-two tree order; for odd n, lanes
71
+ // [0, n-half) fold the upper tail while the middle lane carries forward.
72
+ var n: u32 = {{ wg }};
73
+ loop {
74
+ let half = (n + 1u) / 2u;
75
+ if (tid < n - half) {
76
+ {% if mode == "max" %}
77
+ {{ buffer }}[tid] = max({{ buffer }}[tid], {{ buffer }}[tid + half]);
78
+ {% else %}
79
+ {{ buffer }}[tid] = {{ buffer }}[tid] + {{ buffer }}[tid + half];
80
+ {% endif %}
81
+ }
82
+ workgroupBarrier();
83
+ n = half;
84
+ if (n == 1u) {
85
+ break;
86
+ }
87
+ }
88
+ // The default trailing barrier makes this helper safe for back-to-back calls: every lane reads
89
+ // slot 0 here, so the next call's first store must not run until all lanes have read it.
90
+ // `trailingBarrier=false` is safe only when the buffer is never written again before kernel exit.
91
+ let reduced = {{ buffer }}[0];
92
+ {% if trailingBarrier %}
93
+ workgroupBarrier();
94
+ {% endif %}
95
+ return reduced;
96
+ }
97
+ {% endmacro %}
98
+
99
+ {{ wgsl_tree_reduce_f32("reduce_sum", "add", "partial", "WG") }}
100
+ var<workgroup> row_inv: f32;
101
+ {% else %}
102
+ {% if not degenerateRow %}
103
+
104
+ var<workgroup> pair_partial: array<vec2<f32>, WG>;
105
+
106
+ {% if useSubgroups %}
107
+ fn reduce_pair(value: vec2<f32>, sg_lane: u32, sg_id: u32, num_sg: u32) -> vec2<f32> {
108
+ let s = vec2<f32>(subgroupAdd(value.x), subgroupAdd(value.y));
109
+ if (num_sg == 1u) {
110
+ return s;
111
+ }
112
+ if (sg_lane == 0u) {
113
+ pair_partial[sg_id] = s;
114
+ }
115
+ workgroupBarrier();
116
+ var total = vec2<f32>(0.0, 0.0);
117
+ for (var i = 0u; i < num_sg; i = i + 1u) {
118
+ total = total + pair_partial[i];
119
+ }
120
+ return total;
121
+ }
122
+ {% else %}
123
+ fn reduce_pair(value: vec2<f32>, tid: u32) -> vec2<f32> {
124
+ pair_partial[tid] = value;
125
+ workgroupBarrier();
126
+ {{ wgsl_tree_fold(["pair_partial"], idx="tid", wg="WG", form="head") }}
127
+ return pair_partial[0];
128
+ }
129
+ {% endif %}
130
+ {% endif %}
131
+ {% endif %}
132
+
133
+ {% if not degenerateRow or writeResidualSum %}
134
+ fn residual_value(row: u32, d: u32) -> f32 {
135
+ let index = row * HIDDEN + d;
136
+ var value = f32(input[index]) + f32(skip[index]);
137
+ {% if hasBias %}
138
+ value = value + f32(bias[d]);
139
+ {% endif %}
140
+ return value;
141
+ }
142
+ {% endif %}
143
+
144
+ @compute @workgroup_size(WG, 1, 1)
145
+ fn main(
146
+ @builtin(workgroup_id) wg: vec3<u32>,
147
+ @builtin(num_workgroups) nwg: vec3<u32>{% if not degenerateRow %},
148
+ @builtin(local_invocation_id) lid: vec3<u32>{% endif %}{% if useSubgroups and not degenerateRow %},
149
+ @builtin(subgroup_invocation_id) sg_lane: u32,
150
+ @builtin(subgroup_id) sg_id: u32,
151
+ @builtin(num_subgroups) num_sg: u32{% endif %}
152
+ ) {
153
+ // 2D-folded row index: wg.y carries the high bits past the maxComputeWorkgroupsPerDimension
154
+ // workgroup-per-dimension dispatch limit. Reduces to wg.x when nwg.y == 1;
155
+ // the row >= params.rows guard drops the over-dispatched tail.
156
+ let row = wg.x + wg.y * nwg.x;
157
+ if (row >= params.rows) {
158
+ return;
159
+ }
160
+ {% if not degenerateRow %}
161
+ let tid = lid.x;
162
+ {% endif %}
163
+ {% if simplified %}
164
+
165
+ // RMS normalization uses one sum-of-squares sweep, without a mean or beta.
166
+
167
+ var local_sq = 0.0;
168
+ for (var d: u32 = tid; d < HIDDEN; d = d + WG) {
169
+ let value = residual_value(row, d);
170
+ local_sq = local_sq + value * value;
171
+ }
172
+ let sq = reduce_sum(local_sq, tid);
173
+ if (tid == 0u) {
174
+ row_inv = inverseSqrt(sq / f32(HIDDEN) + params.epsilon);
175
+ }
176
+ workgroupBarrier();
177
+
178
+ for (var d: u32 = tid; d < HIDDEN; d = d + WG) {
179
+ let index = row * HIDDEN + d;
180
+ let residual = residual_value(row, d);
181
+ {% if writeResidualSum %}
182
+ input_skip_bias_sum[index] = {{ scalar }}(residual);
183
+ {% endif %}
184
+ output[index] = {{ scalar }}(residual * row_inv * f32(gamma[d]));
185
+ }
186
+ {% elif degenerateRow %}
187
+
188
+ // HIDDEN == 1: the row's mean is its only element, so the centered value and
189
+ // the variance are exactly zero and the output reduces to beta. The closed
190
+ // form avoids computing that zero by subtracting two equal rounded values.
191
+ let row_inv = inverseSqrt(params.epsilon);
192
+ {% if writeResidualSum %}
193
+ let residual = residual_value(row, 0u);
194
+ input_skip_bias_sum[row] = {{ scalar }}(residual);
195
+ {% endif %}
196
+ // 0.0 * row_inv keeps the IEEE result when epsilon == 0 makes row_inv +Inf.
197
+ output[row] = {{ scalar }}(0.0 * row_inv * f32(gamma[0]){% if hasBeta %} + f32(beta[0]){% endif %});
198
+ {% else %}
199
+
200
+ // Shifted moments: accumulating (x - x[0], (x - x[0])^2) keeps the sums
201
+ // small for rows with a large common offset; every thread reconstructs the
202
+ // row mean and variance from the merged pair.
203
+ let shift = residual_value(row, 0u);
204
+ var acc = vec2<f32>(0.0, 0.0);
205
+ for (var d = tid; d < HIDDEN; d = d + WG) {
206
+ let centered = residual_value(row, d) - shift;
207
+ acc.x = acc.x + centered;
208
+ acc.y = acc.y + centered * centered;
209
+ }
210
+
211
+ {% if useSubgroups %}
212
+ let totals = reduce_pair(acc, sg_lane, sg_id, num_sg);
213
+ {% else %}
214
+ let totals = reduce_pair(acc, tid);
215
+ {% endif %}
216
+ let mean_delta = totals.x / f32(HIDDEN);
217
+ let row_mean = shift + mean_delta;
218
+ let variance = max(totals.y / f32(HIDDEN) - mean_delta * mean_delta, 0.0);
219
+ let row_inv = inverseSqrt(variance + params.epsilon);
220
+ for (var d = tid; d < HIDDEN; d = d + WG) {
221
+ let index = row * HIDDEN + d;
222
+ let residual = residual_value(row, d);
223
+ {% if writeResidualSum %}
224
+ input_skip_bias_sum[index] = {{ scalar }}(residual);
225
+ {% endif %}
226
+ output[index] = {{ scalar }}((residual - row_mean) * row_inv * f32(gamma[d]){% if hasBeta %} + f32(beta[d]){% endif %});
227
+ }
228
+ {% endif %}
229
+ }
build/webgpu/test.json ADDED
@@ -0,0 +1,837 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "op": "com.microsoft.SkipSimplifiedLayerNormalization",
3
+ "cases": [
4
+ {
5
+ "name": "no_bias",
6
+ "attrs": { "epsilon": 0.00001 },
7
+ "inputs": {
8
+ "inputT": {
9
+ "dtype": "float32",
10
+ "shape": [3, 8],
11
+ "data": { "kind": "fillFloat32", "sinStep": 0.17, "cosStep": 0.31 }
12
+ },
13
+ "skipT": {
14
+ "dtype": "float32",
15
+ "shape": [3, 8],
16
+ "data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23 }
17
+ },
18
+ "gammaT": {
19
+ "dtype": "float32",
20
+ "shape": [8],
21
+ "data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.2 }
22
+ }
23
+ },
24
+ "outputs": {
25
+ "outputT": { "dtype": "float32", "shape": [3, 8], "tolerance": 0.00002 },
26
+ "residualT": { "dtype": "float32", "shape": [3, 8], "tolerance": 0.000001 }
27
+ }
28
+ },
29
+ {
30
+ "name": "f32_epsilon_zero_explicit_tiny_variance",
31
+ "attrs": { "epsilon": 0 },
32
+ "provenance": {
33
+ "source": "onnxruntime/contrib_ops/webgpu/bert/skip_layer_norm.h",
34
+ "test": "GetAttrOrDefault epsilon semantics",
35
+ "notes": "An explicit epsilon=0.0 must be honored, not replaced by the 1e-12 schema default via a truthiness fallback. The 1e-7-scale rows make that difference numerically observable."
36
+ },
37
+ "inputs": {
38
+ "inputT": {
39
+ "dtype": "float32",
40
+ "shape": [3, 8],
41
+ "data": { "kind": "fillFloat32", "sinStep": 0.17, "cosStep": 0.31, "scale": 1e-7 }
42
+ },
43
+ "skipT": {
44
+ "dtype": "float32",
45
+ "shape": [3, 8],
46
+ "data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23, "scale": 1e-7 }
47
+ },
48
+ "gammaT": {
49
+ "dtype": "float32",
50
+ "shape": [8],
51
+ "data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.2 }
52
+ }
53
+ },
54
+ "outputs": {
55
+ "outputT": { "dtype": "float32", "shape": [3, 8], "tolerance": 0.0001 },
56
+ "residualT": { "dtype": "float32", "shape": [3, 8], "tolerance": 1e-9 }
57
+ }
58
+ },
59
+ {
60
+ "name": "bias",
61
+ "attrs": { "epsilon": 0.00001 },
62
+ "inputs": {
63
+ "inputT": {
64
+ "dtype": "float32",
65
+ "shape": [3, 8],
66
+ "data": { "kind": "fillFloat32", "sinStep": 0.17, "cosStep": 0.31 }
67
+ },
68
+ "skipT": {
69
+ "dtype": "float32",
70
+ "shape": [3, 8],
71
+ "data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23 }
72
+ },
73
+ "gammaT": {
74
+ "dtype": "float32",
75
+ "shape": [8],
76
+ "data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.2 }
77
+ },
78
+ "biasT": {
79
+ "dtype": "float32",
80
+ "shape": [8],
81
+ "data": { "kind": "fillFloat32", "sinStep": 0.29, "cosStep": 0.17, "scale": 0.08 }
82
+ }
83
+ },
84
+ "outputs": {
85
+ "outputT": { "dtype": "float32", "shape": [3, 8], "tolerance": 0.00002 },
86
+ "residualT": { "dtype": "float32", "shape": [3, 8], "tolerance": 0.000001 }
87
+ }
88
+ },
89
+ {
90
+ "name": "zero_residual_hidden_vector",
91
+ "attrs": { "epsilon": 0.00001 },
92
+ "inputs": {
93
+ "inputT": {
94
+ "dtype": "float32",
95
+ "shape": [2, 4],
96
+ "data": { "kind": "values", "values": [5.0, 5.0, 5.0, 5.0, -3.0, -3.0, -3.0, -3.0] }
97
+ },
98
+ "skipT": {
99
+ "dtype": "float32",
100
+ "shape": [2, 4],
101
+ "data": { "kind": "values", "values": [-5.0, -5.0, -5.0, -5.0, 3.0, 3.0, 3.0, 3.0] }
102
+ },
103
+ "gammaT": { "dtype": "float32", "shape": [4], "data": { "kind": "values", "values": [10.0, -2.0, 3.0, 4.0] } }
104
+ },
105
+ "outputs": {
106
+ "outputT": { "dtype": "float32", "shape": [2, 4], "tolerance": 0.000001 },
107
+ "residualT": { "dtype": "float32", "shape": [2, 4], "tolerance": 0.000001 }
108
+ }
109
+ },
110
+ {
111
+ "name": "hidden_size_one_bias_path",
112
+ "attrs": { "epsilon": 0.00001 },
113
+ "inputs": {
114
+ "inputT": { "dtype": "float32", "shape": [3, 1], "data": { "kind": "values", "values": [2.0, -4.0, 0.5] } },
115
+ "skipT": { "dtype": "float32", "shape": [3, 1], "data": { "kind": "values", "values": [3.0, 1.0, -0.5] } },
116
+ "gammaT": { "dtype": "float32", "shape": [1], "data": { "kind": "values", "values": [7.0] } },
117
+ "biasT": { "dtype": "float32", "shape": [1], "data": { "kind": "values", "values": [0.25] } }
118
+ },
119
+ "outputs": {
120
+ "outputT": { "dtype": "float32", "shape": [3, 1], "tolerance": 0.00001 },
121
+ "residualT": { "dtype": "float32", "shape": [3, 1], "tolerance": 0.000001 }
122
+ }
123
+ },
124
+ {
125
+ "name": "large_values_scaled_by_rms",
126
+ "attrs": { "epsilon": 0.00001 },
127
+ "inputs": {
128
+ "inputT": {
129
+ "dtype": "float32",
130
+ "shape": [1, 4],
131
+ "data": { "kind": "values", "values": [40000.0, 40001.0, 40002.0, 40003.0] }
132
+ },
133
+ "skipT": {
134
+ "dtype": "float32",
135
+ "shape": [1, 4],
136
+ "data": { "kind": "values", "values": [-39999.0, -40000.0, -40001.0, -40002.0] }
137
+ },
138
+ "gammaT": { "dtype": "float32", "shape": [4], "data": { "kind": "values", "values": [1.0, 2.0, -1.0, 0.5] } }
139
+ },
140
+ "outputs": {
141
+ "outputT": { "dtype": "float32", "shape": [1, 4], "tolerance": 0.000001 },
142
+ "residualT": { "dtype": "float32", "shape": [1, 4], "tolerance": 0.000001 }
143
+ }
144
+ },
145
+ {
146
+ "name": "zero_tokens_null_input",
147
+ "provenance": {
148
+ "source": "onnxruntime/test/contrib_ops/skiplayernorm_op_test.cc",
149
+ "test": "SkipLayerNormTest.SkipLayerNormNullInput",
150
+ "notes": "Same zero-token lowered shape as ORT's SkipLayerNormalization null-input case, applied to simplified RMS normalization."
151
+ },
152
+ "attrs": { "epsilon": 1e-12 },
153
+ "inputs": {
154
+ "inputT": { "dtype": "float32", "shape": [0, 4], "data": { "kind": "values", "values": [] } },
155
+ "skipT": { "dtype": "float32", "shape": [0, 4], "data": { "kind": "values", "values": [] } },
156
+ "gammaT": { "dtype": "float32", "shape": [4], "data": { "kind": "values", "values": [0.3, 0.2, 4.0, 2.2] } }
157
+ },
158
+ "outputs": {
159
+ "outputT": { "dtype": "float32", "shape": [0, 4], "tolerance": 0 },
160
+ "residualT": { "dtype": "float32", "shape": [0, 4], "tolerance": 0 }
161
+ }
162
+ },
163
+ {
164
+ "name": "large_hidden_320_no_bias",
165
+ "attrs": { "epsilon": 0.00001 },
166
+ "inputs": {
167
+ "inputT": {
168
+ "dtype": "float32",
169
+ "shape": [2, 320],
170
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.017, "cosStep": 0.031 }
171
+ },
172
+ "skipT": {
173
+ "dtype": "float32",
174
+ "shape": [2, 320],
175
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.011, "cosStep": 0.023 }
176
+ },
177
+ "gammaT": {
178
+ "dtype": "float32",
179
+ "shape": [320],
180
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.007, "cosStep": 0.041 }
181
+ }
182
+ },
183
+ "outputs": {
184
+ "outputT": { "dtype": "float32", "shape": [2, 320], "tolerance": 0.0002 },
185
+ "residualT": { "dtype": "float32", "shape": [2, 320], "tolerance": 0.000001 }
186
+ }
187
+ },
188
+ {
189
+ "name": "large_hidden_320_bias",
190
+ "attrs": { "epsilon": 0.00001 },
191
+ "inputs": {
192
+ "inputT": {
193
+ "dtype": "float32",
194
+ "shape": [2, 320],
195
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.013, "cosStep": 0.029 }
196
+ },
197
+ "skipT": {
198
+ "dtype": "float32",
199
+ "shape": [2, 320],
200
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.019, "cosStep": 0.037 }
201
+ },
202
+ "gammaT": {
203
+ "dtype": "float32",
204
+ "shape": [320],
205
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.029, "cosStep": 0.017 }
206
+ },
207
+ "biasT": {
208
+ "dtype": "float32",
209
+ "shape": [320],
210
+ "data": { "kind": "fillFloat32", "scale": 0.05, "sinStep": 0.031, "cosStep": 0.007 }
211
+ }
212
+ },
213
+ "outputs": {
214
+ "outputT": { "dtype": "float32", "shape": [2, 320], "tolerance": 0.0002 },
215
+ "residualT": { "dtype": "float32", "shape": [2, 320], "tolerance": 0.000001 }
216
+ }
217
+ },
218
+ {
219
+ "name": "large_hidden_768_no_bias",
220
+ "attrs": { "epsilon": 0.00001 },
221
+ "inputs": {
222
+ "inputT": {
223
+ "dtype": "float32",
224
+ "shape": [1, 768],
225
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.003, "cosStep": 0.005 }
226
+ },
227
+ "skipT": {
228
+ "dtype": "float32",
229
+ "shape": [1, 768],
230
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.007, "cosStep": 0.011 }
231
+ },
232
+ "gammaT": {
233
+ "dtype": "float32",
234
+ "shape": [768],
235
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.013, "cosStep": 0.017 }
236
+ }
237
+ },
238
+ "outputs": {
239
+ "outputT": { "dtype": "float32", "shape": [1, 768], "tolerance": 0.0002 },
240
+ "residualT": { "dtype": "float32", "shape": [1, 768], "tolerance": 0.000001 }
241
+ }
242
+ },
243
+ {
244
+ "name": "large_hidden_768_bias",
245
+ "attrs": { "epsilon": 0.00001 },
246
+ "inputs": {
247
+ "inputT": {
248
+ "dtype": "float32",
249
+ "shape": [1, 768],
250
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.005, "cosStep": 0.009 }
251
+ },
252
+ "skipT": {
253
+ "dtype": "float32",
254
+ "shape": [1, 768],
255
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.011, "cosStep": 0.015 }
256
+ },
257
+ "gammaT": {
258
+ "dtype": "float32",
259
+ "shape": [768],
260
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.017, "cosStep": 0.021 }
261
+ },
262
+ "biasT": {
263
+ "dtype": "float32",
264
+ "shape": [768],
265
+ "data": { "kind": "fillFloat32", "scale": 0.05, "sinStep": 0.023, "cosStep": 0.027 }
266
+ }
267
+ },
268
+ "outputs": {
269
+ "outputT": { "dtype": "float32", "shape": [1, 768], "tolerance": 0.0002 },
270
+ "residualT": { "dtype": "float32", "shape": [1, 768], "tolerance": 0.000001 }
271
+ }
272
+ },
273
+ {
274
+ "name": "ort_simplified_batch1_flattened_tokens",
275
+ "provenance": {
276
+ "source": "onnxruntime/test/contrib_ops/skiplayernorm_op_test.cc",
277
+ "test": "SkipLayerNormTest.SkipSimplifiedLayerNormBatch1_Float16",
278
+ "notes": "ORT fp16 shape [1, 2, 4] is represented as float32 [2, 4] tokens by this lowered kernel. Epsilon is omitted to exercise the schema default of 1e-12."
279
+ },
280
+ "inputs": {
281
+ "inputT": {
282
+ "dtype": "float32",
283
+ "shape": [2, 4],
284
+ "data": { "kind": "values", "values": [0.8, -0.5, 0.0, 1.0, 0.5, 0.2, 0.3, -0.6] }
285
+ },
286
+ "skipT": {
287
+ "dtype": "float32",
288
+ "shape": [2, 4],
289
+ "data": { "kind": "values", "values": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] }
290
+ },
291
+ "gammaT": { "dtype": "float32", "shape": [4], "data": { "kind": "values", "values": [0.3, 0.2, 4.0, 2.2] } }
292
+ },
293
+ "outputs": {
294
+ "outputT": { "dtype": "float32", "shape": [2, 4], "tolerance": 0.00002 },
295
+ "residualT": { "dtype": "float32", "shape": [2, 4], "tolerance": 0.000001 }
296
+ }
297
+ },
298
+ {
299
+ "name": "ort_simplified_batch1_bias_flattened_tokens",
300
+ "provenance": {
301
+ "source": "onnxruntime/test/contrib_ops/skiplayernorm_op_test.cc",
302
+ "test": "SkipLayerNormTest.SkipSimplifiedLayerNormBatch1_Bias_Float16",
303
+ "notes": "ORT fp16 shape [1, 1, 8] is represented as float32 [1, 8] tokens by this lowered kernel."
304
+ },
305
+ "attrs": { "epsilon": 0.00001 },
306
+ "inputs": {
307
+ "inputT": {
308
+ "dtype": "float32",
309
+ "shape": [1, 8],
310
+ "data": {
311
+ "kind": "values",
312
+ "values": [0.12573242, -0.13208008, 0.640625, 0.10491943, -0.53564453, 0.36157227, 1.3037109, 0.94726562]
313
+ }
314
+ },
315
+ "skipT": {
316
+ "dtype": "float32",
317
+ "shape": [1, 8],
318
+ "data": {
319
+ "kind": "values",
320
+ "values": [-0.70361328, -1.265625, -0.62304688, 0.041320801, -2.3242188, -0.21875, -1.2460938, -0.73242188]
321
+ }
322
+ },
323
+ "gammaT": {
324
+ "dtype": "float32",
325
+ "shape": [8],
326
+ "data": {
327
+ "kind": "values",
328
+ "values": [0.94580078, 0.96826172, 1.0410156, 1.1044922, 0.98730469, 1.1367188, 0.93359375, 1.0351562]
329
+ }
330
+ },
331
+ "biasT": {
332
+ "dtype": "float32",
333
+ "shape": [8],
334
+ "data": {
335
+ "kind": "values",
336
+ "values": [0.45166016, 0.04699707, -0.37182617, -0.4609375, -0.22888184, 0.11010742, -0.50488281, -0.10461426]
337
+ }
338
+ }
339
+ },
340
+ "outputs": {
341
+ "outputT": { "dtype": "float32", "shape": [1, 8], "tolerance": 0.00002 },
342
+ "residualT": { "dtype": "float32", "shape": [1, 8], "tolerance": 0.000001 }
343
+ }
344
+ },
345
+ {
346
+ "name": "output_only_no_bias",
347
+ "attrs": { "epsilon": 0.00001 },
348
+ "inputs": {
349
+ "inputT": {
350
+ "dtype": "float32",
351
+ "shape": [2, 4],
352
+ "data": { "kind": "values", "values": [1.0, 2.0, 3.0, 4.0, 2.0, -1.0, 0.5, -0.5] }
353
+ },
354
+ "skipT": {
355
+ "dtype": "float32",
356
+ "shape": [2, 4],
357
+ "data": { "kind": "values", "values": [0.5, -1.0, 1.0, 0.0, 0.0, 1.0, -0.5, 0.5] }
358
+ },
359
+ "gammaT": { "dtype": "float32", "shape": [4], "data": { "kind": "values", "values": [1.0, 2.0, -1.0, 0.5] } }
360
+ },
361
+ "outputs": {
362
+ "outputT": {
363
+ "dtype": "float32",
364
+ "shape": [2, 4],
365
+ "tolerance": 0.00002,
366
+ "data": {
367
+ "kind": "values",
368
+ "values": [0.5052908659501396, 0.6737211546001862, -1.3474423092003724, 0.6737211546001862, 1.9999900000749995, 0.0, 0.0, 0.0]
369
+ }
370
+ }
371
+ }
372
+ },
373
+ {
374
+ "name": "no_bias_hidden128_compact",
375
+ "provenance": {
376
+ "notes": "Compact hidden-size-128 companion for the output-only bench family; keeps the same row width under reference-computed full outputs."
377
+ },
378
+ "attrs": { "epsilon": 0.00001 },
379
+ "inputs": {
380
+ "inputT": {
381
+ "dtype": "float32",
382
+ "shape": [16, 128],
383
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.017, "cosStep": 0.031 }
384
+ },
385
+ "skipT": {
386
+ "dtype": "float32",
387
+ "shape": [16, 128],
388
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.011, "cosStep": 0.023 }
389
+ },
390
+ "gammaT": {
391
+ "dtype": "float32",
392
+ "shape": [128],
393
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.007, "cosStep": 0.041 }
394
+ }
395
+ },
396
+ "outputs": {
397
+ "outputT": { "dtype": "float32", "shape": [16, 128], "tolerance": 0.0002, "relTolerance": 0.0002 },
398
+ "residualT": { "dtype": "float32", "shape": [16, 128], "tolerance": 0.000001 }
399
+ }
400
+ },
401
+ {
402
+ "name": "output_only_bias",
403
+ "attrs": { "epsilon": 0.00001 },
404
+ "inputs": {
405
+ "inputT": {
406
+ "dtype": "float32",
407
+ "shape": [2, 4],
408
+ "data": { "kind": "values", "values": [0.25, -0.5, 1.0, 2.0, -1.0, 0.5, 1.5, -2.0] }
409
+ },
410
+ "skipT": {
411
+ "dtype": "float32",
412
+ "shape": [2, 4],
413
+ "data": { "kind": "values", "values": [0.75, 0.25, -0.5, 1.0, 1.0, -1.0, 0.5, 0.25] }
414
+ },
415
+ "gammaT": { "dtype": "float32", "shape": [4], "data": { "kind": "values", "values": [1.5, -1.0, 0.5, 2.0] } },
416
+ "biasT": { "dtype": "float32", "shape": [4], "data": { "kind": "values", "values": [0.1, -0.2, 0.3, 0.4] } }
417
+ },
418
+ "outputs": {
419
+ "outputT": {
420
+ "dtype": "float32",
421
+ "shape": [2, 4],
422
+ "tolerance": 0.00002,
423
+ "data": {
424
+ "kind": "values",
425
+ "values": [0.8944258768765443, 0.24393433005723933, 0.21683051560643496, 3.686118765309394, 0.10873177077789489, 0.5074149302968427, 0.8336102426305274, -1.957171874002108]
426
+ }
427
+ }
428
+ }
429
+ },
430
+ {
431
+ "name": "f16_no_bias_hidden768_decode",
432
+ "attrs": { "epsilon": 0.00001 },
433
+ "inputs": {
434
+ "inputT": {
435
+ "dtype": "float16",
436
+ "shape": [2, 768],
437
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.013, "cosStep": 0.029 }
438
+ },
439
+ "skipT": {
440
+ "dtype": "float16",
441
+ "shape": [2, 768],
442
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.019, "cosStep": 0.037 }
443
+ },
444
+ "gammaT": {
445
+ "dtype": "float16",
446
+ "shape": [768],
447
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.007, "cosStep": 0.041 }
448
+ }
449
+ },
450
+ "outputs": {
451
+ "outputT": { "dtype": "float16", "shape": [2, 768], "tolerance": 0.01 },
452
+ "residualT": { "dtype": "float16", "shape": [2, 768], "tolerance": 0.01 }
453
+ }
454
+ },
455
+ {
456
+ "name": "f16_bias_hidden2048",
457
+ "attrs": { "epsilon": 0.00001 },
458
+ "inputs": {
459
+ "inputT": {
460
+ "dtype": "float16",
461
+ "shape": [2, 2048],
462
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.005, "cosStep": 0.009 }
463
+ },
464
+ "skipT": {
465
+ "dtype": "float16",
466
+ "shape": [2, 2048],
467
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.011, "cosStep": 0.015 }
468
+ },
469
+ "gammaT": {
470
+ "dtype": "float16",
471
+ "shape": [2048],
472
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.017, "cosStep": 0.021 }
473
+ },
474
+ "biasT": {
475
+ "dtype": "float16",
476
+ "shape": [2048],
477
+ "data": { "kind": "fillFloat32", "scale": 0.05, "sinStep": 0.023, "cosStep": 0.027 }
478
+ }
479
+ },
480
+ "outputs": {
481
+ "outputT": { "dtype": "float16", "shape": [2, 2048], "tolerance": 0.01 },
482
+ "residualT": { "dtype": "float16", "shape": [2, 2048], "tolerance": 0.01 }
483
+ }
484
+ },
485
+ {
486
+ "name": "unaligned_hidden770_bias_scalar_fallback",
487
+ "attrs": { "epsilon": 0.00001 },
488
+ "inputs": {
489
+ "inputT": {
490
+ "dtype": "float32",
491
+ "shape": [2, 770],
492
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.017, "cosStep": 0.031 }
493
+ },
494
+ "skipT": {
495
+ "dtype": "float32",
496
+ "shape": [2, 770],
497
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.011, "cosStep": 0.023 }
498
+ },
499
+ "gammaT": {
500
+ "dtype": "float32",
501
+ "shape": [770],
502
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.013, "cosStep": 0.017 }
503
+ },
504
+ "biasT": {
505
+ "dtype": "float32",
506
+ "shape": [770],
507
+ "data": { "kind": "fillFloat32", "scale": 0.05, "sinStep": 0.029, "cosStep": 0.007 }
508
+ }
509
+ },
510
+ "outputs": {
511
+ "outputT": { "dtype": "float32", "shape": [2, 770], "tolerance": 0.0002 },
512
+ "residualT": { "dtype": "float32", "shape": [2, 770], "tolerance": 0.000001 }
513
+ }
514
+ },
515
+ {
516
+ "name": "scalar_fallback_odd_hidden_large_common_offset_residual",
517
+ "attrs": { "epsilon": 0.00001 },
518
+ "inputs": {
519
+ "inputT": {
520
+ "dtype": "float32",
521
+ "shape": [5, 771],
522
+ "data": { "kind": "fillFloat32", "scale": 0.2, "offset": 1000.0, "sinStep": 0.017, "cosStep": 0.031 }
523
+ },
524
+ "skipT": {
525
+ "dtype": "float32",
526
+ "shape": [5, 771],
527
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.011, "cosStep": 0.023 }
528
+ },
529
+ "gammaT": {
530
+ "dtype": "float32",
531
+ "shape": [771],
532
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.007, "cosStep": 0.041 }
533
+ }
534
+ },
535
+ "outputs": {
536
+ "outputT": { "dtype": "float32", "shape": [5, 771], "tolerance": 0.0005 },
537
+ "residualT": { "dtype": "float32", "shape": [5, 771], "tolerance": 0.001 }
538
+ }
539
+ },
540
+ {
541
+ "name": "empty_rows_vec4_hidden8",
542
+ "attrs": { "epsilon": 0.00001 },
543
+ "inputs": {
544
+ "inputT": { "dtype": "float32", "shape": [0, 8], "data": { "kind": "values", "values": [] } },
545
+ "skipT": { "dtype": "float32", "shape": [0, 8], "data": { "kind": "values", "values": [] } },
546
+ "gammaT": {
547
+ "dtype": "float32",
548
+ "shape": [8],
549
+ "data": { "kind": "values", "values": [0.3, 0.2, 4.0, 2.2, 1.0, -1.0, 0.5, 1.5] }
550
+ }
551
+ },
552
+ "outputs": {
553
+ "outputT": { "dtype": "float32", "shape": [0, 8], "tolerance": 0 },
554
+ "residualT": { "dtype": "float32", "shape": [0, 8], "tolerance": 0 }
555
+ }
556
+ },
557
+ {
558
+ "name": "rank3_no_bias_residual_2x3x8",
559
+ "attrs": { "epsilon": 0.00001 },
560
+ "inputs": {
561
+ "inputT": {
562
+ "dtype": "float32",
563
+ "shape": [2, 3, 8],
564
+ "data": { "kind": "fillFloat32", "sinStep": 0.17, "cosStep": 0.31 }
565
+ },
566
+ "skipT": {
567
+ "dtype": "float32",
568
+ "shape": [2, 3, 8],
569
+ "data": { "kind": "fillFloat32", "sinStep": 0.11, "cosStep": 0.23 }
570
+ },
571
+ "gammaT": {
572
+ "dtype": "float32",
573
+ "shape": [8],
574
+ "data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.41, "scale": 0.2 }
575
+ }
576
+ },
577
+ "outputs": {
578
+ "outputT": { "dtype": "float32", "shape": [2, 3, 8], "tolerance": 0.00002 },
579
+ "residualT": { "dtype": "float32", "shape": [2, 3, 8], "tolerance": 0.000001 }
580
+ }
581
+ },
582
+ {
583
+ "name": "rank3_output_only_bias_2x2x12",
584
+ "attrs": { "epsilon": 0.00001 },
585
+ "inputs": {
586
+ "inputT": {
587
+ "dtype": "float32",
588
+ "shape": [2, 2, 12],
589
+ "data": { "kind": "fillFloat32", "sinStep": 0.19, "cosStep": 0.27 }
590
+ },
591
+ "skipT": {
592
+ "dtype": "float32",
593
+ "shape": [2, 2, 12],
594
+ "data": { "kind": "fillFloat32", "sinStep": 0.13, "cosStep": 0.29 }
595
+ },
596
+ "gammaT": {
597
+ "dtype": "float32",
598
+ "shape": [12],
599
+ "data": { "kind": "fillFloat32", "sinStep": 0.07, "cosStep": 0.37, "scale": 0.2 }
600
+ },
601
+ "biasT": {
602
+ "dtype": "float32",
603
+ "shape": [12],
604
+ "data": { "kind": "fillFloat32", "sinStep": 0.23, "cosStep": 0.11, "scale": 0.1 }
605
+ }
606
+ },
607
+ "outputs": { "outputT": { "dtype": "float32", "shape": [2, 2, 12], "tolerance": 0.00002 } }
608
+ },
609
+ {
610
+ "name": "f16_rank3_residual_2x2x768",
611
+ "attrs": { "epsilon": 0.00001 },
612
+ "inputs": {
613
+ "inputT": {
614
+ "dtype": "float16",
615
+ "shape": [2, 2, 768],
616
+ "data": { "kind": "fillFloat32", "sinStep": 0.017, "cosStep": 0.031 }
617
+ },
618
+ "skipT": {
619
+ "dtype": "float16",
620
+ "shape": [2, 2, 768],
621
+ "data": { "kind": "fillFloat32", "sinStep": 0.011, "cosStep": 0.023 }
622
+ },
623
+ "gammaT": {
624
+ "dtype": "float16",
625
+ "shape": [768],
626
+ "data": { "kind": "fillFloat32", "sinStep": 0.007, "cosStep": 0.041, "scale": 0.2 }
627
+ }
628
+ },
629
+ "outputs": {
630
+ "outputT": { "dtype": "float16", "shape": [2, 2, 768], "tolerance": 0.01 },
631
+ "residualT": { "dtype": "float16", "shape": [2, 2, 768], "tolerance": 0.005 }
632
+ }
633
+ },
634
+ {
635
+ "name": "f16_no_bias_output_only_768",
636
+ "attrs": { "epsilon": 0.00001 },
637
+ "inputs": {
638
+ "inputT": {
639
+ "dtype": "float16",
640
+ "shape": [2, 768],
641
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.013, "cosStep": 0.029 }
642
+ },
643
+ "skipT": {
644
+ "dtype": "float16",
645
+ "shape": [2, 768],
646
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.019, "cosStep": 0.037 }
647
+ },
648
+ "gammaT": {
649
+ "dtype": "float16",
650
+ "shape": [768],
651
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.007, "cosStep": 0.041 }
652
+ }
653
+ },
654
+ "outputs": { "outputT": { "dtype": "float16", "shape": [2, 768], "tolerance": 0.01 } }
655
+ },
656
+ {
657
+ "name": "f16_bias_output_only_2048",
658
+ "attrs": { "epsilon": 0.00001 },
659
+ "inputs": {
660
+ "inputT": {
661
+ "dtype": "float16",
662
+ "shape": [2, 2048],
663
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.005, "cosStep": 0.009 }
664
+ },
665
+ "skipT": {
666
+ "dtype": "float16",
667
+ "shape": [2, 2048],
668
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.011, "cosStep": 0.015 }
669
+ },
670
+ "gammaT": {
671
+ "dtype": "float16",
672
+ "shape": [2048],
673
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.017, "cosStep": 0.021 }
674
+ },
675
+ "biasT": {
676
+ "dtype": "float16",
677
+ "shape": [2048],
678
+ "data": { "kind": "fillFloat32", "scale": 0.05, "sinStep": 0.023, "cosStep": 0.027 }
679
+ }
680
+ },
681
+ "outputs": { "outputT": { "dtype": "float16", "shape": [2, 2048], "tolerance": 0.01 } }
682
+ },
683
+ {
684
+ "name": "f16_rank3_output_only_unaligned_2x2x767",
685
+ "attrs": { "epsilon": 0.00001 },
686
+ "inputs": {
687
+ "inputT": {
688
+ "dtype": "float16",
689
+ "shape": [2, 2, 767],
690
+ "data": { "kind": "fillFloat32", "sinStep": 0.017, "cosStep": 0.031 }
691
+ },
692
+ "skipT": {
693
+ "dtype": "float16",
694
+ "shape": [2, 2, 767],
695
+ "data": { "kind": "fillFloat32", "sinStep": 0.011, "cosStep": 0.023 }
696
+ },
697
+ "gammaT": {
698
+ "dtype": "float16",
699
+ "shape": [767],
700
+ "data": { "kind": "fillFloat32", "sinStep": 0.007, "cosStep": 0.041, "scale": 0.2 }
701
+ }
702
+ },
703
+ "outputs": { "outputT": { "dtype": "float16", "shape": [2, 2, 767], "tolerance": 0.01 } }
704
+ },
705
+ {
706
+ "name": "output_only_no_bias_unaligned_hidden6_scalar_row",
707
+ "attrs": { "epsilon": 0.00001 },
708
+ "inputs": {
709
+ "inputT": {
710
+ "dtype": "float32",
711
+ "shape": [2, 6],
712
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.017, "cosStep": 0.031 }
713
+ },
714
+ "skipT": {
715
+ "dtype": "float32",
716
+ "shape": [2, 6],
717
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.011, "cosStep": 0.023 }
718
+ },
719
+ "gammaT": {
720
+ "dtype": "float32",
721
+ "shape": [6],
722
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.007, "cosStep": 0.041 }
723
+ }
724
+ },
725
+ "outputs": { "outputT": { "dtype": "float32", "shape": [2, 6], "tolerance": 0.000002 } }
726
+ },
727
+ {
728
+ "name": "output_only_bias_unaligned_hidden6_scalar_row",
729
+ "attrs": { "epsilon": 0.00001 },
730
+ "inputs": {
731
+ "inputT": {
732
+ "dtype": "float32",
733
+ "shape": [2, 6],
734
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.019, "cosStep": 0.037 }
735
+ },
736
+ "skipT": {
737
+ "dtype": "float32",
738
+ "shape": [2, 6],
739
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.013, "cosStep": 0.029 }
740
+ },
741
+ "gammaT": {
742
+ "dtype": "float32",
743
+ "shape": [6],
744
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.007, "cosStep": 0.041 }
745
+ },
746
+ "biasT": {
747
+ "dtype": "float32",
748
+ "shape": [6],
749
+ "data": { "kind": "fillFloat32", "scale": 0.05, "sinStep": 0.023, "cosStep": 0.027 }
750
+ }
751
+ },
752
+ "outputs": { "outputT": { "dtype": "float32", "shape": [2, 6], "tolerance": 0.000002 } }
753
+ },
754
+ {
755
+ "name": "f16_no_bias_unaligned_hidden6_scalar_row",
756
+ "attrs": { "epsilon": 0.00001 },
757
+ "inputs": {
758
+ "inputT": {
759
+ "dtype": "float16",
760
+ "shape": [2, 6],
761
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.017, "cosStep": 0.031 }
762
+ },
763
+ "skipT": {
764
+ "dtype": "float16",
765
+ "shape": [2, 6],
766
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.011, "cosStep": 0.023 }
767
+ },
768
+ "gammaT": {
769
+ "dtype": "float16",
770
+ "shape": [6],
771
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.007, "cosStep": 0.041 }
772
+ }
773
+ },
774
+ "outputs": {
775
+ "outputT": { "dtype": "float16", "shape": [2, 6], "tolerance": 0.01 },
776
+ "residualT": { "dtype": "float16", "shape": [2, 6], "tolerance": 0.005 }
777
+ }
778
+ },
779
+ {
780
+ "name": "f16_bias_unaligned_hidden6_scalar_row",
781
+ "attrs": { "epsilon": 0.00001 },
782
+ "inputs": {
783
+ "inputT": {
784
+ "dtype": "float16",
785
+ "shape": [2, 6],
786
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.019, "cosStep": 0.037 }
787
+ },
788
+ "skipT": {
789
+ "dtype": "float16",
790
+ "shape": [2, 6],
791
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.013, "cosStep": 0.029 }
792
+ },
793
+ "gammaT": {
794
+ "dtype": "float16",
795
+ "shape": [6],
796
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.007, "cosStep": 0.041 }
797
+ },
798
+ "biasT": {
799
+ "dtype": "float16",
800
+ "shape": [6],
801
+ "data": { "kind": "fillFloat32", "scale": 0.05, "sinStep": 0.023, "cosStep": 0.027 }
802
+ }
803
+ },
804
+ "outputs": {
805
+ "outputT": { "dtype": "float16", "shape": [2, 6], "tolerance": 0.01 },
806
+ "residualT": { "dtype": "float16", "shape": [2, 6], "tolerance": 0.005 }
807
+ }
808
+ },
809
+ {
810
+ "name": "f16_bias_output_only_unaligned_hidden6_scalar_row",
811
+ "attrs": { "epsilon": 0.00001 },
812
+ "inputs": {
813
+ "inputT": {
814
+ "dtype": "float16",
815
+ "shape": [2, 6],
816
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.005, "cosStep": 0.009 }
817
+ },
818
+ "skipT": {
819
+ "dtype": "float16",
820
+ "shape": [2, 6],
821
+ "data": { "kind": "fillFloat32", "scale": 0.2, "sinStep": 0.011, "cosStep": 0.015 }
822
+ },
823
+ "gammaT": {
824
+ "dtype": "float16",
825
+ "shape": [6],
826
+ "data": { "kind": "fillFloat32", "scale": 0.1, "offset": 1.0, "sinStep": 0.017, "cosStep": 0.021 }
827
+ },
828
+ "biasT": {
829
+ "dtype": "float16",
830
+ "shape": [6],
831
+ "data": { "kind": "fillFloat32", "scale": 0.05, "sinStep": 0.023, "cosStep": 0.027 }
832
+ }
833
+ },
834
+ "outputs": { "outputT": { "dtype": "float16", "shape": [2, 6], "tolerance": 0.01 } }
835
+ }
836
+ ]
837
+ }