Xenova HF Staff commited on
Commit
85afcec
·
verified ·
1 Parent(s): 6d3894e

sync c928d21e6cc1

Browse files
build/webgpu/conv-1x1-gemm-tiled-reg.wgsl.jinja CHANGED
@@ -32,7 +32,10 @@ fn fused_act(v: f32) -> f32 {
32
  {% elif activation == "Sigmoid" %}
33
  return 1.0 / (1.0 + exp(-v));
34
  {% elif activation == "Tanh" %}
35
- return tanh(v);
 
 
 
36
  {% elif activation == "HardSigmoid" %}
37
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
38
  {% else %}
 
32
  {% elif activation == "Sigmoid" %}
33
  return 1.0 / (1.0 + exp(-v));
34
  {% elif activation == "Tanh" %}
35
+ // Clamped for the reason given in the GEMM activation: an unbounded accumulator
36
+ // overflows the hardware tanh's internal e^2v to Inf/Inf = NaN, and tanh is
37
+ // already +/-1 to full f32 precision by |v| ~ 9.
38
+ return tanh(clamp(v, -10.0, 10.0));
39
  {% elif activation == "HardSigmoid" %}
40
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
41
  {% else %}
build/webgpu/conv-1x1-gemm-tiled.wgsl.jinja CHANGED
@@ -32,7 +32,10 @@ fn fused_act(v: f32) -> f32 {
32
  {% elif activation == "Sigmoid" %}
33
  return 1.0 / (1.0 + exp(-v));
34
  {% elif activation == "Tanh" %}
35
- return tanh(v);
 
 
 
36
  {% elif activation == "HardSigmoid" %}
37
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
38
  {% else %}
 
32
  {% elif activation == "Sigmoid" %}
33
  return 1.0 / (1.0 + exp(-v));
34
  {% elif activation == "Tanh" %}
35
+ // Clamped for the reason given in the GEMM activation: an unbounded accumulator
36
+ // overflows the hardware tanh's internal e^2v to Inf/Inf = NaN, and tanh is
37
+ // already +/-1 to full f32 precision by |v| ~ 9.
38
+ return tanh(clamp(v, -10.0, 10.0));
39
  {% elif activation == "HardSigmoid" %}
40
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
41
  {% else %}
build/webgpu/conv-1x1-subgroup-matrix.wgsl.jinja CHANGED
@@ -115,7 +115,10 @@ fn fused_act(v: f32) -> f32 {
115
  {% elif activation == "Sigmoid" %}
116
  return 1.0 / (1.0 + exp(-v));
117
  {% elif activation == "Tanh" %}
118
- return tanh(v);
 
 
 
119
  {% elif activation == "HardSigmoid" %}
120
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
121
  {% else %}
@@ -217,14 +220,14 @@ fn main(
217
 
218
  for (var step = 0u; step < TILE_K; step = step + 8u) {
219
  let matrix_a_offset = subtile_idy * SUB_ROWS * TILE_K + step;
220
- var matA0: subgroup_matrix_left<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_left<{{ operandScalar }}, 8, 8>>(&tile_A, matrix_a_offset, false, TILE_K);
221
- var matA1: subgroup_matrix_left<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_left<{{ operandScalar }}, 8, 8>>(&tile_A, matrix_a_offset + 8u * TILE_K, false, TILE_K);
222
 
223
  let matrix_b_offset = subtile_idx * SUB_COLS * TILE_K + step;
224
- var matB0: subgroup_matrix_right<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_right<{{ operandScalar }}, 8, 8>>(&tile_B, matrix_b_offset, true, TILE_K);
225
- var matB1: subgroup_matrix_right<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_right<{{ operandScalar }}, 8, 8>>(&tile_B, matrix_b_offset + 8u * TILE_K, true, TILE_K);
226
- var matB2: subgroup_matrix_right<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_right<{{ operandScalar }}, 8, 8>>(&tile_B, matrix_b_offset + 16u * TILE_K, true, TILE_K);
227
- var matB3: subgroup_matrix_right<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_right<{{ operandScalar }}, 8, 8>>(&tile_B, matrix_b_offset + 24u * TILE_K, true, TILE_K);
228
 
229
  matC00 = subgroupMatrixMultiplyAccumulate(matA0, matB0, matC00);
230
  matC01 = subgroupMatrixMultiplyAccumulate(matA0, matB1, matC01);
@@ -244,14 +247,14 @@ fn main(
244
  // cross-subgroup handoff into the narrow projection. All collective stores
245
  // remain subgroup-uniform, and every fragment has a disjoint destination.
246
  let fused_tile_offset = base_A * TILE_COLS + base_B;
247
- subgroupMatrixStore(&tile_B, fused_tile_offset + 0u * TILE_COLS + 0u, matC00, false, TILE_COLS);
248
- subgroupMatrixStore(&tile_B, fused_tile_offset + 0u * TILE_COLS + 8u, matC01, false, TILE_COLS);
249
- subgroupMatrixStore(&tile_B, fused_tile_offset + 0u * TILE_COLS + 16u, matC02, false, TILE_COLS);
250
- subgroupMatrixStore(&tile_B, fused_tile_offset + 0u * TILE_COLS + 24u, matC03, false, TILE_COLS);
251
- subgroupMatrixStore(&tile_B, fused_tile_offset + 8u * TILE_COLS + 0u, matC10, false, TILE_COLS);
252
- subgroupMatrixStore(&tile_B, fused_tile_offset + 8u * TILE_COLS + 8u, matC11, false, TILE_COLS);
253
- subgroupMatrixStore(&tile_B, fused_tile_offset + 8u * TILE_COLS + 16u, matC12, false, TILE_COLS);
254
- subgroupMatrixStore(&tile_B, fused_tile_offset + 8u * TILE_COLS + 24u, matC13, false, TILE_COLS);
255
  workgroupBarrier();
256
 
257
  // One invocation owns one spatial column and walks the producer channels in
@@ -290,14 +293,14 @@ fn main(
290
  // When an epilogue is present, publish the raw accumulators first, then apply
291
  // bias, residual Z, and activation cooperatively after one storage barrier.
292
  let matrix_c_offset = c_base + (a_global_base + base_A) * N + b_global_base + base_B;
293
- subgroupMatrixStore(&y, matrix_c_offset + 0u * N + 0u, matC00, false, N);
294
- subgroupMatrixStore(&y, matrix_c_offset + 0u * N + 8u, matC01, false, N);
295
- subgroupMatrixStore(&y, matrix_c_offset + 0u * N + 16u, matC02, false, N);
296
- subgroupMatrixStore(&y, matrix_c_offset + 0u * N + 24u, matC03, false, N);
297
- subgroupMatrixStore(&y, matrix_c_offset + 8u * N + 0u, matC10, false, N);
298
- subgroupMatrixStore(&y, matrix_c_offset + 8u * N + 8u, matC11, false, N);
299
- subgroupMatrixStore(&y, matrix_c_offset + 8u * N + 16u, matC12, false, N);
300
- subgroupMatrixStore(&y, matrix_c_offset + 8u * N + 24u, matC13, false, N);
301
  {% if hasBias or hasActivation or hasZ %}
302
  storageBarrier();
303
  for (var tile_idx = local_idx; tile_idx < TILE_ROWS * TILE_COLS; tile_idx += {{ workgroupThreadsValue }}u) {
@@ -328,10 +331,10 @@ fn main(
328
  // give the reads visibility of the store AND stop the second row-group's store from
329
  // clobbering the first's still-in-flight readback when a partial final M-tile
330
  // diverges storeOutput's guard. Without both barriers the last valid row can be corrupted.
331
- subgroupMatrixStore(&scratch[subtile_id][0], 0u, matC00, false, 8u);
332
- subgroupMatrixStore(&scratch[subtile_id][1], 0u, matC01, false, 8u);
333
- subgroupMatrixStore(&scratch[subtile_id][2], 0u, matC02, false, 8u);
334
- subgroupMatrixStore(&scratch[subtile_id][3], 0u, matC03, false, 8u);
335
  workgroupBarrier();
336
  let row = sg_id / 4u;
337
  let col = (sg_id % 4u) * 2u;
@@ -341,10 +344,10 @@ fn main(
341
  storeOutput(matrix_c_offset, {% if hasBias or polyphase %}row_base, {% endif %}row, col, subtile_id, row_limit{% if padded %}, b_global_base + base_B{% endif %});
342
  workgroupBarrier();
343
 
344
- subgroupMatrixStore(&scratch[subtile_id][0], 0u, matC10, false, 8u);
345
- subgroupMatrixStore(&scratch[subtile_id][1], 0u, matC11, false, 8u);
346
- subgroupMatrixStore(&scratch[subtile_id][2], 0u, matC12, false, 8u);
347
- subgroupMatrixStore(&scratch[subtile_id][3], 0u, matC13, false, 8u);
348
  workgroupBarrier();
349
  matrix_c_offset = matrix_c_offset + 8u * N;
350
  row_limit = i32(M) - i32(row_base + 8u);
 
115
  {% elif activation == "Sigmoid" %}
116
  return 1.0 / (1.0 + exp(-v));
117
  {% elif activation == "Tanh" %}
118
+ // Clamped for the reason given in the GEMM activation: an unbounded accumulator
119
+ // overflows the hardware tanh's internal e^2v to Inf/Inf = NaN, and tanh is
120
+ // already +/-1 to full f32 precision by |v| ~ 9.
121
+ return tanh(clamp(v, -10.0, 10.0));
122
  {% elif activation == "HardSigmoid" %}
123
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
124
  {% else %}
 
220
 
221
  for (var step = 0u; step < TILE_K; step = step + 8u) {
222
  let matrix_a_offset = subtile_idy * SUB_ROWS * TILE_K + step;
223
+ var matA0: subgroup_matrix_left<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_left<{{ operandScalar }}, 8, 8>, row_major>(&tile_A, matrix_a_offset, TILE_K);
224
+ var matA1: subgroup_matrix_left<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_left<{{ operandScalar }}, 8, 8>, row_major>(&tile_A, matrix_a_offset + 8u * TILE_K, TILE_K);
225
 
226
  let matrix_b_offset = subtile_idx * SUB_COLS * TILE_K + step;
227
+ var matB0: subgroup_matrix_right<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_right<{{ operandScalar }}, 8, 8>, col_major>(&tile_B, matrix_b_offset, TILE_K);
228
+ var matB1: subgroup_matrix_right<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_right<{{ operandScalar }}, 8, 8>, col_major>(&tile_B, matrix_b_offset + 8u * TILE_K, TILE_K);
229
+ var matB2: subgroup_matrix_right<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_right<{{ operandScalar }}, 8, 8>, col_major>(&tile_B, matrix_b_offset + 16u * TILE_K, TILE_K);
230
+ var matB3: subgroup_matrix_right<{{ operandScalar }}, 8, 8> = subgroupMatrixLoad<subgroup_matrix_right<{{ operandScalar }}, 8, 8>, col_major>(&tile_B, matrix_b_offset + 24u * TILE_K, TILE_K);
231
 
232
  matC00 = subgroupMatrixMultiplyAccumulate(matA0, matB0, matC00);
233
  matC01 = subgroupMatrixMultiplyAccumulate(matA0, matB1, matC01);
 
247
  // cross-subgroup handoff into the narrow projection. All collective stores
248
  // remain subgroup-uniform, and every fragment has a disjoint destination.
249
  let fused_tile_offset = base_A * TILE_COLS + base_B;
250
+ subgroupMatrixStore<row_major>(&tile_B, fused_tile_offset + 0u * TILE_COLS + 0u, matC00, TILE_COLS);
251
+ subgroupMatrixStore<row_major>(&tile_B, fused_tile_offset + 0u * TILE_COLS + 8u, matC01, TILE_COLS);
252
+ subgroupMatrixStore<row_major>(&tile_B, fused_tile_offset + 0u * TILE_COLS + 16u, matC02, TILE_COLS);
253
+ subgroupMatrixStore<row_major>(&tile_B, fused_tile_offset + 0u * TILE_COLS + 24u, matC03, TILE_COLS);
254
+ subgroupMatrixStore<row_major>(&tile_B, fused_tile_offset + 8u * TILE_COLS + 0u, matC10, TILE_COLS);
255
+ subgroupMatrixStore<row_major>(&tile_B, fused_tile_offset + 8u * TILE_COLS + 8u, matC11, TILE_COLS);
256
+ subgroupMatrixStore<row_major>(&tile_B, fused_tile_offset + 8u * TILE_COLS + 16u, matC12, TILE_COLS);
257
+ subgroupMatrixStore<row_major>(&tile_B, fused_tile_offset + 8u * TILE_COLS + 24u, matC13, TILE_COLS);
258
  workgroupBarrier();
259
 
260
  // One invocation owns one spatial column and walks the producer channels in
 
293
  // When an epilogue is present, publish the raw accumulators first, then apply
294
  // bias, residual Z, and activation cooperatively after one storage barrier.
295
  let matrix_c_offset = c_base + (a_global_base + base_A) * N + b_global_base + base_B;
296
+ subgroupMatrixStore<row_major>(&y, matrix_c_offset + 0u * N + 0u, matC00, N);
297
+ subgroupMatrixStore<row_major>(&y, matrix_c_offset + 0u * N + 8u, matC01, N);
298
+ subgroupMatrixStore<row_major>(&y, matrix_c_offset + 0u * N + 16u, matC02, N);
299
+ subgroupMatrixStore<row_major>(&y, matrix_c_offset + 0u * N + 24u, matC03, N);
300
+ subgroupMatrixStore<row_major>(&y, matrix_c_offset + 8u * N + 0u, matC10, N);
301
+ subgroupMatrixStore<row_major>(&y, matrix_c_offset + 8u * N + 8u, matC11, N);
302
+ subgroupMatrixStore<row_major>(&y, matrix_c_offset + 8u * N + 16u, matC12, N);
303
+ subgroupMatrixStore<row_major>(&y, matrix_c_offset + 8u * N + 24u, matC13, N);
304
  {% if hasBias or hasActivation or hasZ %}
305
  storageBarrier();
306
  for (var tile_idx = local_idx; tile_idx < TILE_ROWS * TILE_COLS; tile_idx += {{ workgroupThreadsValue }}u) {
 
331
  // give the reads visibility of the store AND stop the second row-group's store from
332
  // clobbering the first's still-in-flight readback when a partial final M-tile
333
  // diverges storeOutput's guard. Without both barriers the last valid row can be corrupted.
334
+ subgroupMatrixStore<row_major>(&scratch[subtile_id][0], 0u, matC00, 8u);
335
+ subgroupMatrixStore<row_major>(&scratch[subtile_id][1], 0u, matC01, 8u);
336
+ subgroupMatrixStore<row_major>(&scratch[subtile_id][2], 0u, matC02, 8u);
337
+ subgroupMatrixStore<row_major>(&scratch[subtile_id][3], 0u, matC03, 8u);
338
  workgroupBarrier();
339
  let row = sg_id / 4u;
340
  let col = (sg_id % 4u) * 2u;
 
344
  storeOutput(matrix_c_offset, {% if hasBias or polyphase %}row_base, {% endif %}row, col, subtile_id, row_limit{% if padded %}, b_global_base + base_B{% endif %});
345
  workgroupBarrier();
346
 
347
+ subgroupMatrixStore<row_major>(&scratch[subtile_id][0], 0u, matC10, 8u);
348
+ subgroupMatrixStore<row_major>(&scratch[subtile_id][1], 0u, matC11, 8u);
349
+ subgroupMatrixStore<row_major>(&scratch[subtile_id][2], 0u, matC12, 8u);
350
+ subgroupMatrixStore<row_major>(&scratch[subtile_id][3], 0u, matC13, 8u);
351
  workgroupBarrier();
352
  matrix_c_offset = matrix_c_offset + 8u * N;
353
  row_limit = i32(M) - i32(row_base + 8u);
build/webgpu/conv-direct-nd.wgsl.jinja CHANGED
@@ -19,7 +19,10 @@ fn fused_act(v: f32) -> f32 {
19
  {% elif activation == "Sigmoid" %}
20
  return 1.0 / (1.0 + exp(-v));
21
  {% elif activation == "Tanh" %}
22
- return tanh(v);
 
 
 
23
  {% elif activation == "HardSigmoid" %}
24
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
25
  {% else %}
 
19
  {% elif activation == "Sigmoid" %}
20
  return 1.0 / (1.0 + exp(-v));
21
  {% elif activation == "Tanh" %}
22
+ // Clamped for the reason given in the GEMM activation: an unbounded accumulator
23
+ // overflows the hardware tanh's internal e^2v to Inf/Inf = NaN, and tanh is
24
+ // already +/-1 to full f32 precision by |v| ~ 9.
25
+ return tanh(clamp(v, -10.0, 10.0));
26
  {% elif activation == "HardSigmoid" %}
27
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
28
  {% else %}
build/webgpu/conv-direct-unrolled.wgsl.jinja CHANGED
@@ -25,7 +25,10 @@ fn fused_act(v: f32) -> f32 {
25
  {% elif activation == "Sigmoid" %}
26
  return 1.0 / (1.0 + exp(-v));
27
  {% elif activation == "Tanh" %}
28
- return tanh(v);
 
 
 
29
  {% elif activation == "HardSigmoid" %}
30
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
31
  {% else %}
 
25
  {% elif activation == "Sigmoid" %}
26
  return 1.0 / (1.0 + exp(-v));
27
  {% elif activation == "Tanh" %}
28
+ // Clamped for the reason given in the GEMM activation: an unbounded accumulator
29
+ // overflows the hardware tanh's internal e^2v to Inf/Inf = NaN, and tanh is
30
+ // already +/-1 to full f32 precision by |v| ~ 9.
31
+ return tanh(clamp(v, -10.0, 10.0));
32
  {% elif activation == "HardSigmoid" %}
33
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
34
  {% else %}
build/webgpu/conv1d-tiled-reg.wgsl.jinja CHANGED
@@ -34,7 +34,10 @@ fn fused_act(v: f32) -> f32 {
34
  {% elif activation == "Sigmoid" %}
35
  return 1.0 / (1.0 + exp(-v));
36
  {% elif activation == "Tanh" %}
37
- return tanh(v);
 
 
 
38
  {% elif activation == "HardSigmoid" %}
39
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
40
  {% else %}
 
34
  {% elif activation == "Sigmoid" %}
35
  return 1.0 / (1.0 + exp(-v));
36
  {% elif activation == "Tanh" %}
37
+ // Clamped for the reason given in the GEMM activation: an unbounded accumulator
38
+ // overflows the hardware tanh's internal e^2v to Inf/Inf = NaN, and tanh is
39
+ // already +/-1 to full f32 precision by |v| ~ 9.
40
+ return tanh(clamp(v, -10.0, 10.0));
41
  {% elif activation == "HardSigmoid" %}
42
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
43
  {% else %}
build/webgpu/conv2d-grouped-large-w4.wgsl.jinja CHANGED
@@ -16,7 +16,10 @@ fn fused_act(v: f32) -> f32 {
16
  {% elif activation == "Sigmoid" %}
17
  return 1.0 / (1.0 + exp(-v));
18
  {% elif activation == "Tanh" %}
19
- return tanh(v);
 
 
 
20
  {% elif activation == "HardSigmoid" %}
21
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
22
  {% else %}
 
16
  {% elif activation == "Sigmoid" %}
17
  return 1.0 / (1.0 + exp(-v));
18
  {% elif activation == "Tanh" %}
19
+ // Clamped for the reason given in the GEMM activation: an unbounded accumulator
20
+ // overflows the hardware tanh's internal e^2v to Inf/Inf = NaN, and tanh is
21
+ // already +/-1 to full f32 precision by |v| ~ 9.
22
+ return tanh(clamp(v, -10.0, 10.0));
23
  {% elif activation == "HardSigmoid" %}
24
  return clamp(f32({{ actAlpha }}) * v + f32({{ actBeta }}), 0.0, 1.0);
25
  {% else %}
build/webgpu/metadata.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "name": "com.microsoft.FusedConv",
3
- "id": "_com_microsoft_fusedconv_webgpu_947df1c",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "backend": { "type": "webgpu" },
@@ -8,18 +8,18 @@
8
  "algorithm": "sha256",
9
  "files": {
10
  "bench.json": "0T4EaJworpji9PrXCF3znUUqiMBBbSgShzzAaM/dOWY=",
11
- "conv-1x1-gemm-tiled-reg.wgsl.jinja": "bDk/sW4LxlVlqVJ6L/hpKGjfky1UKWwYL3C0fdVWjFA=",
12
- "conv-1x1-gemm-tiled.wgsl.jinja": "eHdHLa3X2HriPxhMMSmzkVPelPg+sm4xDz9ZJ4qI0hA=",
13
- "conv-1x1-subgroup-matrix.wgsl.jinja": "FTHq1ftW5Zk7as0fc8T+b0dvbQFQFmcX0AWARnICV28=",
14
- "conv-direct-nd.wgsl.jinja": "yEas2jFgJNfM8NoHjv+4ZafMC1/nwl5MvgQeTFfOl4w=",
15
- "conv-direct-unrolled.wgsl.jinja": "84nok2Ie1Lc91UrXiUEl1GFk+cwa4Fu0vEkhRyOmsxs=",
16
  "conv-im2col-nchw.wgsl.jinja": "7IUuXo33elZx0pnR9M2vUXzXDjFuw2bJODkZViV/WQg=",
17
- "conv1d-tiled-reg.wgsl.jinja": "d9H8LBgSgsqxBbg85o5dCMuOEIW/hOICoEi5gysrvTg=",
18
- "conv2d-grouped-large-w4.wgsl.jinja": "jhLKpmvfkcFQPBXXznt3im++rtVwNNxUoRqqgHNpmDM=",
19
  "manifest.json": "jMjmEiSVgMOjNheSacCaHlppVU7uWplUp2lv3fvGH1A=",
20
  "test.json": "/KodhC9ZJ6IxO1wokLmeGH0zsOfDpds9+mjZLZRnPXw="
21
  }
22
  },
23
- "provenance": { "kernel": { "sha": "2e7068faf55e7f43df740015f6d1ee49391a41c5", "dirty": false } },
24
  "webgpu": { "manifestSpec": "1.0", "specialized": true, "opPath": "ops/com.microsoft.FusedConv" }
25
  }
 
1
  {
2
  "name": "com.microsoft.FusedConv",
3
+ "id": "_com_microsoft_fusedconv_webgpu_e37405a",
4
  "version": 1,
5
  "license": "Apache-2.0",
6
  "backend": { "type": "webgpu" },
 
8
  "algorithm": "sha256",
9
  "files": {
10
  "bench.json": "0T4EaJworpji9PrXCF3znUUqiMBBbSgShzzAaM/dOWY=",
11
+ "conv-1x1-gemm-tiled-reg.wgsl.jinja": "n0CRMXMLwCsmBCTq9ruaSshgRFN+QcWfYHmLLT/nYDg=",
12
+ "conv-1x1-gemm-tiled.wgsl.jinja": "tAifcSzQFhljZg7xs7W7xJ1t92ZjRlCCfET/7sxsrzI=",
13
+ "conv-1x1-subgroup-matrix.wgsl.jinja": "4M+d7l/v8cK31b+6c2QaD20PSrT3EcpMNT5LV14H+wg=",
14
+ "conv-direct-nd.wgsl.jinja": "+rZdtrCmC5XWDKzniyQgM8ZuEPelUn15Wy8XASMqRoI=",
15
+ "conv-direct-unrolled.wgsl.jinja": "Z8nzgvMffIyDdiORizHznKPUpi70ZcWPZvmwhnuE+PQ=",
16
  "conv-im2col-nchw.wgsl.jinja": "7IUuXo33elZx0pnR9M2vUXzXDjFuw2bJODkZViV/WQg=",
17
+ "conv1d-tiled-reg.wgsl.jinja": "f6XtRoLCTQvmBsoTWjymS9jK1ewlj9R2t+DWBa7vv/0=",
18
+ "conv2d-grouped-large-w4.wgsl.jinja": "HMab+h8mlTI14B1EdMAkYmwFRFkRipfdT2ZOx36X2dY=",
19
  "manifest.json": "jMjmEiSVgMOjNheSacCaHlppVU7uWplUp2lv3fvGH1A=",
20
  "test.json": "/KodhC9ZJ6IxO1wokLmeGH0zsOfDpds9+mjZLZRnPXw="
21
  }
22
  },
23
+ "provenance": { "kernel": { "sha": "c928d21e6cc1310861cba3bafb75f5f679ecf5f3", "dirty": false } },
24
  "webgpu": { "manifestSpec": "1.0", "specialized": true, "opPath": "ops/com.microsoft.FusedConv" }
25
  }