File size: 6,241 Bytes
a0b9936
 
 
 
fca5e7d
 
 
 
 
a0b9936
 
 
fca5e7d
 
a0b9936
 
fca5e7d
 
a0b9936
 
 
 
 
fca5e7d
 
 
b08ac42
 
 
 
a0b9936
 
 
 
 
fca5e7d
 
a0b9936
 
 
 
 
 
 
fca5e7d
 
 
 
 
 
a0b9936
fca5e7d
 
 
 
a0b9936
fca5e7d
 
 
a0b9936
 
 
 
 
 
fca5e7d
 
 
 
 
 
 
 
a0b9936
fca5e7d
 
 
 
 
 
a0b9936
 
 
 
 
 
fca5e7d
 
a0b9936
 
 
 
 
 
 
fca5e7d
 
 
 
 
 
a0b9936
fca5e7d
 
 
 
a0b9936
fca5e7d
 
 
a0b9936
 
 
 
 
 
fca5e7d
 
 
 
 
 
 
 
a0b9936
fca5e7d
 
 
 
 
 
a0b9936
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
{
  "domain": "ai.onnx",
  "name": "TensorScatter",
  "sinceVersion": 24,
  "inputs": {
    "past": { "onnx": "past_cache", "dtype": "T" },
    "update": { "dtype": "T" },
    "writeIndices": {
      "onnx": "write_indices",
      "dtype": "I",
      "rank": 1,
      "optional": true,
      "storage": "uint32",
      "narrowing": "checked"
    }
  },
  "outputs": { "present": { "onnx": "present_cache", "dtype": "T", "rank": "ranks.past", "shape": "shapes.past" } },
  "attributes": { "axis": { "default": -2 }, "mode": { "default": "linear" } },
  "attributeConstraints": { "mode": { "values": ["linear", "circular"] } },
  "typeConstraints": {
    "T": ["float32", "float16", "int32", "int16", "int8", "uint32", "uint8", "bool"],
    "I": ["int64"]
  },
  "tunables": { "WORKGROUP_SIZE": { "default": 256 } },
  "when": ["(attrs.axis if attrs.axis >= 0 else attrs.axis + ranks.past) < ranks.past", "(attrs.axis if attrs.axis >= 0 else attrs.axis + ranks.past) >= 1", "f16Ok(dtypes.T)", "numel(shapes.past) == numel(shapes.present)", "ranks.past == ranks.present", "ranks.past == ranks.update", "ranks.past >= 2"],
  "bindings": {
    "update": { "elementType": "$scalar" },
    "present": { "elementType": "$scalar" },
    "params": { "struct": [{ "name": "count", "type": "u32", "value": "numel(shapes.update)" }] },
    "writeIndices": { "elementType": "u32" }
  },
  "variants": [
    {
      "id": "no_write_indices",
      "priority": 0,
      "when": ["not present.writeIndices"],
      "derive": {
        "scalar": "dtypes.T",
        "copyElementType": "(\"vec4<\" ~ dtypes.T ~ \">\") if numel(shapes.present) % 4 == 0 else dtypes.T"
      },
      "passes": [
        {
          "id": "copy",
          "name": "TensorScatter.Copy",
          "shader": "scatter-flat-copy.wgsl.jinja",
          "derive": {
            "count": "ceilDiv(numel(shapes.present), 16 if dtypes.T == \"f16\" and numel(shapes.present) % 4 != 0 else (8 if numel(shapes.present) % 4 != 0 else 4))",
            "copyWidth": "16 if dtypes.T == \"f16\" and numel(shapes.present) % 4 != 0 else (8 if numel(shapes.present) % 4 != 0 else 4)",
            "elementCount": "numel(shapes.present)",
            "scalarTailSafe": "numel(shapes.present) % 4 != 0"
          },
          "bindings": [
            { "arg": "past", "name": "src", "elementType": "$copyElementType" },
            { "arg": "present", "name": "dst", "elementType": "$copyElementType" }
          ],
          "dispatch": {
            "x": "min(ceilDiv((ceilDiv(numel(shapes.present), 16 if dtypes.T == \"f16\" and numel(shapes.present) % 4 != 0 else (8 if numel(shapes.present) % 4 != 0 else 4))), (tunables.WORKGROUP_SIZE)), 65535)",
            "y": "ceilDiv(ceilDiv((ceilDiv(numel(shapes.present), 16 if dtypes.T == \"f16\" and numel(shapes.present) % 4 != 0 else (8 if numel(shapes.present) % 4 != 0 else 4))), (tunables.WORKGROUP_SIZE)), 65535)",
            "z": 1
          },
          "viewAlias": [{ "input": "src", "output": "dst" }]
        },
        {
          "id": "scatter",
          "name": "TensorScatter.Scatter",
          "shader": "tensor-scatter.wgsl.jinja",
          "derive": {
            "pastShape": "shapes.past",
            "updateShape": "shapes.update",
            "rank": "ranks.past",
            "axisSpec": "attrs.axis if attrs.axis >= 0 else attrs.axis + ranks.past",
            "circular": "attrs.mode == \"circular\"",
            "hasIndices": "false"
          },
          "bindings": ["update", "present", "params"],
          "dispatch": {
            "x": "min(ceilDiv((numel(shapes.update)), (tunables.WORKGROUP_SIZE)), 65535)",
            "y": "ceilDiv(ceilDiv((numel(shapes.update)), (tunables.WORKGROUP_SIZE)), 65535)",
            "z": 1
          }
        }
      ]
    },
    {
      "id": "with_write_indices",
      "priority": 20,
      "when": ["present.writeIndices", "dtypes.I == \"u32\""],
      "derive": {
        "scalar": "dtypes.T",
        "copyElementType": "(\"vec4<\" ~ dtypes.T ~ \">\") if numel(shapes.present) % 4 == 0 else dtypes.T"
      },
      "passes": [
        {
          "id": "copy",
          "name": "TensorScatter.Copy",
          "shader": "scatter-flat-copy.wgsl.jinja",
          "derive": {
            "count": "ceilDiv(numel(shapes.present), 16 if dtypes.T == \"f16\" and numel(shapes.present) % 4 != 0 else (8 if numel(shapes.present) % 4 != 0 else 4))",
            "copyWidth": "16 if dtypes.T == \"f16\" and numel(shapes.present) % 4 != 0 else (8 if numel(shapes.present) % 4 != 0 else 4)",
            "elementCount": "numel(shapes.present)",
            "scalarTailSafe": "numel(shapes.present) % 4 != 0"
          },
          "bindings": [
            { "arg": "past", "name": "src", "elementType": "$copyElementType" },
            { "arg": "present", "name": "dst", "elementType": "$copyElementType" }
          ],
          "dispatch": {
            "x": "min(ceilDiv((ceilDiv(numel(shapes.present), 16 if dtypes.T == \"f16\" and numel(shapes.present) % 4 != 0 else (8 if numel(shapes.present) % 4 != 0 else 4))), (tunables.WORKGROUP_SIZE)), 65535)",
            "y": "ceilDiv(ceilDiv((ceilDiv(numel(shapes.present), 16 if dtypes.T == \"f16\" and numel(shapes.present) % 4 != 0 else (8 if numel(shapes.present) % 4 != 0 else 4))), (tunables.WORKGROUP_SIZE)), 65535)",
            "z": 1
          },
          "viewAlias": [{ "input": "src", "output": "dst" }]
        },
        {
          "id": "scatter",
          "name": "TensorScatter.Scatter",
          "shader": "tensor-scatter.wgsl.jinja",
          "derive": {
            "pastShape": "shapes.past",
            "updateShape": "shapes.update",
            "rank": "ranks.past",
            "axisSpec": "attrs.axis if attrs.axis >= 0 else attrs.axis + ranks.past",
            "circular": "attrs.mode == \"circular\"",
            "hasIndices": "true"
          },
          "bindings": ["update", "writeIndices", "present", "params"],
          "dispatch": {
            "x": "min(ceilDiv((numel(shapes.update)), (tunables.WORKGROUP_SIZE)), 65535)",
            "y": "ceilDiv(ceilDiv((numel(shapes.update)), (tunables.WORKGROUP_SIZE)), 65535)",
            "z": 1
          }
        }
      ]
    }
  ]
}