File size: 11,536 Bytes
a0dbbbe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
{
  "domain": "com.microsoft",
  "name": "GatedRMSNorm",
  "sinceVersion": 1,
  "inputs": {
    "xT": { "onnx": "X", "dtype": "T" },
    "scaleT": { "onnx": "scale", "dtype": "T" },
    "gateT": { "onnx": "gate", "dtype": "T" }
  },
  "outputs": { "yT": { "onnx": "Y", "dtype": "T", "rank": "ranks.xT", "shape": "shapes.xT" } },
  "attributes": { "epsilon": { "default": 0.00001 } },
  "typeConstraints": { "T": ["float32", "float16"] },
  "tunables": { "WORKGROUP_SIZE": { "default": 256 }, "LANE_WORDS": { "default": 2 } },
  "derive": {
    "deviceWorkgroupCap": "min(device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX)",
    "foldedDispatchCapacity": "min(device.limits.maxComputeWorkgroupsPerDimension, 65535) * min(device.limits.maxComputeWorkgroupsPerDimension, 65535)",
    "normSize": "numel(shapes.scaleT)",
    "lastDim": "dim(shapes.xT, ranks.xT - 1)",
    "elementCount": "numel(shapes.xT)",
    "rowCount": "elementCount / max(1, normSize)",
    "dtypeOk": "tensorDtypes.xT == tensorDtypes.scaleT and tensorDtypes.xT == tensorDtypes.gateT and tensorDtypes.xT == tensorDtypes.yT and f16Ok(dtypes.T)",
    "shapeOk": "ranks.xT >= 1 and ranks.scaleT >= 1 and normSize > 0 and lastDim % normSize == 0 and sameShape(shapes.gateT, shapes.xT) and sameShape(shapes.yT, shapes.xT)",
    "contractOk": "dtypeOk and shapeOk",
    "workgroupOk": "tunables.WORKGROUP_SIZE > 0 and tunables.WORKGROUP_SIZE <= deviceWorkgroupCap and pow2ceil(tunables.WORKGROUP_SIZE) == tunables.WORKGROUP_SIZE and tunables.WORKGROUP_SIZE * 4 <= device.limits.maxComputeWorkgroupStorageSize and tunables.LANE_WORDS > 0",
    "vec4Ok": "normSize % 4 == 0",
    "vecWords": "normSize / 4",
    "vecPreferredLanes": "max(1, min(tunables.WORKGROUP_SIZE / 2, pow2ceil(max(1, ceilDiv(vecWords, max(1, tunables.LANE_WORDS))))))",
    "vecWideLanes": "max(1, min(tunables.WORKGROUP_SIZE, pow2ceil(max(1, ceilDiv(vecWords, max(1, tunables.LANE_WORDS))))))",
    "vecLanesPerRow": "pick([[ceilDiv(vecWords, vecPreferredLanes) <= 8, vecPreferredLanes]], vecWideLanes)",
    "vecRowsPerGroup": "tunables.WORKGROUP_SIZE / max(1, vecLanesPerRow)",
    "vecWordsPerLane": "ceilDiv(vecWords, max(1, vecLanesPerRow))",
    "vecRowGroups": "ceilDiv(rowCount, max(1, vecRowsPerGroup))",
    "scalarPreferredLanes": "1 if normSize <= 8 else (max(1, min(tunables.WORKGROUP_SIZE / 2, pow2ceil(max(1, ceilDiv(normSize, max(1, tunables.LANE_WORDS)))))))",
    "scalarWideLanes": "max(1, min(tunables.WORKGROUP_SIZE, pow2ceil(max(1, ceilDiv(normSize, max(1, tunables.LANE_WORDS))))))",
    "scalarLanesPerRow": "pick([[ceilDiv(normSize, scalarPreferredLanes) <= 8, scalarPreferredLanes]], scalarWideLanes)",
    "scalarRowsPerGroup": "tunables.WORKGROUP_SIZE / max(1, scalarLanesPerRow)",
    "scalarWordsPerLane": "ceilDiv(normSize, max(1, scalarLanesPerRow))",
    "scalarRowGroups": "ceilDiv(rowCount, max(1, scalarRowsPerGroup))",
    "subgroupShapeKnown": "device.features.has(\"subgroups\") and has(device.adapterInfo, \"subgroupMinSize\") and has(device.adapterInfo, \"subgroupMaxSize\") and device.adapterInfo.subgroupMinSize > 0 and device.adapterInfo.subgroupMinSize <= device.adapterInfo.subgroupMaxSize and device.adapterInfo.subgroupMaxSize <= tunables.WORKGROUP_SIZE and tunables.WORKGROUP_SIZE % device.adapterInfo.subgroupMaxSize == 0",
    "sgMin": "device.adapterInfo.subgroupMinSize if subgroupShapeKnown else 0",
    "sgFullWidth": "subgroupShapeKnown and device.adapterInfo.subgroupMinSize == device.adapterInfo.subgroupMaxSize",
    "sgVecLanesPerRow": "min(sgMin, vecLanesPerRow) if subgroupShapeKnown else 1",
    "sgVecRowsPerGroup": "tunables.WORKGROUP_SIZE / max(1, sgVecLanesPerRow)",
    "sgVecWordsPerLane": "ceilDiv(vecWords, max(1, sgVecLanesPerRow))",
    "sgVecRowGroups": "ceilDiv(rowCount, max(1, sgVecRowsPerGroup))",
    "sgScalarLanesPerRow": "min(sgMin, scalarLanesPerRow) if subgroupShapeKnown else 1",
    "sgScalarRowsPerGroup": "tunables.WORKGROUP_SIZE / max(1, sgScalarLanesPerRow)",
    "sgScalarWordsPerLane": "ceilDiv(normSize, max(1, sgScalarLanesPerRow))",
    "sgScalarRowGroups": "ceilDiv(rowCount, max(1, sgScalarRowsPerGroup))",
    "vectorElement": "\"vec4<\" ~ dtypes.T ~ \">\"",
    "workgroupSize": "tunables.WORKGROUP_SIZE",
    "epsilon": "attrs.epsilon",
    "scalar": "dtypes.T",
    "vectorScalar": "vectorElement"
  },
  "when": ["contractOk", "workgroupOk"],
  "bindings": {
    "x": { "arg": "xT", "elementType": "$vectorElement" },
    "scale": { "arg": "scaleT", "elementType": "$vectorElement" },
    "gate": { "arg": "gateT", "elementType": "$vectorElement" },
    "y": { "arg": "yT", "elementType": "$vectorElement" },
    "x_x_t": { "arg": "xT", "name": "x", "elementType": "$scalar" },
    "scale_main": { "arg": "scaleT", "name": "scale", "elementType": "$scalar" },
    "gate_main": { "arg": "gateT", "name": "gate", "elementType": "$scalar" },
    "y_y_t": { "arg": "yT", "name": "y", "elementType": "$scalar" },
    "params": { "struct": [{ "name": "rows", "type": "u32", "value": "rowCount" }] }
  },
  "variants": [
    {
      "id": "subgroup_rows_vec4",
      "priority": 30,
      "when": ["vec4Ok", "subgroupShapeKnown", "sgVecWordsPerLane >= 1", "sgVecWordsPerLane <= 8", "sgVecRowGroups <= foldedDispatchCapacity"],
      "requires": { "features": ["subgroups"] },
      "derive": {
        "foldKind": "\"none\" if sgVecLanesPerRow <= 1 else (\"subgroup_full\" if (sgFullWidth and sgVecLanesPerRow == sgMin) else \"subgroup_butterfly\")",
        "foldSteps": "log2ceil(sgVecLanesPerRow)",
        "useVec4": "true",
        "stageRow": "true",
        "rowWords": "vecWords",
        "wordsPerLane": "sgVecWordsPerLane",
        "lanesPerRow": "sgVecLanesPerRow",
        "rowsPerGroup": "sgVecRowsPerGroup"
      },
      "passes": [
        {
          "id": "main",
          "name": "GatedRMSNorm.SubgroupRowsVec4",
          "shader": "gated-rms-norm-rows.wgsl.jinja",
          "bindings": ["x", "scale", "gate", "y", "params"],
          "dispatch": {
            "x": "min(sgVecRowGroups, DISPATCH_FOLD_WIDTH)",
            "y": "ceilDiv(sgVecRowGroups, DISPATCH_FOLD_WIDTH)"
          }
        }
      ]
    },
    {
      "id": "packed_rows_vec4",
      "priority": 20,
      "when": ["vec4Ok", "vecRowGroups <= foldedDispatchCapacity"],
      "derive": {
        "foldKind": "\"none\" if vecLanesPerRow <= 1 else \"workgroup_tree\"",
        "foldSteps": "log2ceil(vecLanesPerRow)",
        "useVec4": "true",
        "stageRow": "vecWordsPerLane <= 8",
        "rowWords": "vecWords",
        "wordsPerLane": "vecWordsPerLane",
        "lanesPerRow": "vecLanesPerRow",
        "rowsPerGroup": "vecRowsPerGroup"
      },
      "passes": [
        {
          "id": "main",
          "name": "GatedRMSNorm.PackedRowsVec4",
          "shader": "gated-rms-norm-rows.wgsl.jinja",
          "bindings": ["x", "scale", "gate", "y", "params"],
          "dispatch": {
            "x": "min(vecRowGroups, DISPATCH_FOLD_WIDTH)",
            "y": "ceilDiv(vecRowGroups, DISPATCH_FOLD_WIDTH)"
          }
        }
      ]
    },
    {
      "id": "subgroup_rows_scalar",
      "priority": 10,
      "when": ["subgroupShapeKnown", "sgScalarWordsPerLane >= 1", "sgScalarWordsPerLane <= 8", "sgScalarRowGroups <= foldedDispatchCapacity"],
      "requires": { "features": ["subgroups"] },
      "derive": {
        "foldKind": "\"none\" if sgScalarLanesPerRow <= 1 else (\"subgroup_full\" if (sgFullWidth and sgScalarLanesPerRow == sgMin) else \"subgroup_butterfly\")",
        "foldSteps": "log2ceil(sgScalarLanesPerRow)",
        "useVec4": "false",
        "stageRow": "true",
        "rowWords": "normSize",
        "wordsPerLane": "sgScalarWordsPerLane",
        "lanesPerRow": "sgScalarLanesPerRow",
        "rowsPerGroup": "sgScalarRowsPerGroup"
      },
      "passes": [
        {
          "id": "main",
          "name": "GatedRMSNorm.SubgroupRowsScalar",
          "shader": "gated-rms-norm-rows.wgsl.jinja",
          "bindings": ["x_x_t", "scale_main", "gate_main", "y_y_t", "params"],
          "dispatch": {
            "x": "min(sgScalarRowGroups, DISPATCH_FOLD_WIDTH)",
            "y": "ceilDiv(sgScalarRowGroups, DISPATCH_FOLD_WIDTH)"
          }
        }
      ]
    },
    {
      "id": "packed_rows_scalar",
      "priority": 0,
      "when": ["scalarRowGroups <= foldedDispatchCapacity"],
      "derive": {
        "foldKind": "\"none\" if scalarLanesPerRow <= 1 else \"workgroup_tree\"",
        "foldSteps": "log2ceil(scalarLanesPerRow)",
        "useVec4": "false",
        "stageRow": "scalarWordsPerLane <= 8",
        "rowWords": "normSize",
        "wordsPerLane": "scalarWordsPerLane",
        "lanesPerRow": "scalarLanesPerRow",
        "rowsPerGroup": "scalarRowsPerGroup"
      },
      "passes": [
        {
          "id": "main",
          "name": "GatedRMSNorm.PackedRowsScalar",
          "shader": "gated-rms-norm-rows.wgsl.jinja",
          "bindings": ["x_x_t", "scale_main", "gate_main", "y_y_t", "params"],
          "dispatch": {
            "x": "min(scalarRowGroups, DISPATCH_FOLD_WIDTH)",
            "y": "ceilDiv(scalarRowGroups, DISPATCH_FOLD_WIDTH)"
          }
        }
      ]
    },
    {
      "id": "subgroup_wide_rows_vec4",
      "priority": 25,
      "when": ["vec4Ok", "vecRowGroups <= foldedDispatchCapacity", "dtypes.T == \"f32\"", "sgFullWidth", "device.wgslLanguageFeatures.has(\"subgroup_id\")", "vecLanesPerRow > sgMin", "vecLanesPerRow % max(1, sgMin) == 0"],
      "requires": { "features": ["subgroups"] },
      "derive": {
        "foldKind": "\"subgroup_tree\"",
        "useVec4": "true",
        "stageRow": "vecWordsPerLane <= 8",
        "rowWords": "vecWords",
        "wordsPerLane": "vecWordsPerLane",
        "lanesPerRow": "vecLanesPerRow",
        "rowsPerGroup": "vecRowsPerGroup",
        "subgroupWidth": "sgMin",
        "subgroupsPerRow": "vecLanesPerRow / max(1, sgMin)"
      },
      "passes": [
        {
          "id": "main",
          "name": "GatedRMSNorm.SubgroupWideRowsVec4",
          "shader": "gated-rms-norm-rows.wgsl.jinja",
          "bindings": ["x", "scale", "gate", "y", "params"],
          "dispatch": {
            "x": "min(vecRowGroups, DISPATCH_FOLD_WIDTH)",
            "y": "ceilDiv(vecRowGroups, DISPATCH_FOLD_WIDTH)"
          }
        }
      ]
    },
    {
      "id": "subgroup_wide_rows_scalar",
      "priority": 5,
      "when": ["scalarRowGroups <= foldedDispatchCapacity", "dtypes.T == \"f32\"", "sgFullWidth", "device.wgslLanguageFeatures.has(\"subgroup_id\")", "scalarLanesPerRow > sgMin", "scalarLanesPerRow % max(1, sgMin) == 0"],
      "requires": { "features": ["subgroups"] },
      "derive": {
        "foldKind": "\"subgroup_tree\"",
        "useVec4": "false",
        "stageRow": "scalarWordsPerLane <= 8",
        "rowWords": "normSize",
        "wordsPerLane": "scalarWordsPerLane",
        "lanesPerRow": "scalarLanesPerRow",
        "rowsPerGroup": "scalarRowsPerGroup",
        "subgroupWidth": "sgMin",
        "subgroupsPerRow": "scalarLanesPerRow / max(1, sgMin)"
      },
      "passes": [
        {
          "id": "main",
          "name": "GatedRMSNorm.SubgroupWideRowsScalar",
          "shader": "gated-rms-norm-rows.wgsl.jinja",
          "bindings": ["x_x_t", "scale_main", "gate_main", "y_y_t", "params"],
          "dispatch": {
            "x": "min(scalarRowGroups, DISPATCH_FOLD_WIDTH)",
            "y": "ceilDiv(scalarRowGroups, DISPATCH_FOLD_WIDTH)"
          }
        }
      ]
    }
  ]
}