Download build/webgpu/manifest.json from webgpu-kernels/com.microsoft.SkipGroupNorm: direct link, hf CLI and curl.
- Browser
- Download file 29.5 kB
-
https://huggingface.co/kernels/webgpu-kernels/com.microsoft.SkipGroupNorm/resolve/v1/build/webgpu/manifest.json
- Command line
-
hf download hf://webgpu-kernels/com.microsoft.SkipGroupNorm@v1/build/webgpu/manifest.json
-
curl -L -o manifest.json https://huggingface.co/kernels/webgpu-kernels/com.microsoft.SkipGroupNorm/resolve/v1/build/webgpu/manifest.json
29.5 kB
| { | |
| "domain": "com.microsoft", | |
| "name": "SkipGroupNorm", | |
| "sinceVersion": 1, | |
| "inputs": { | |
| "X": { "dtype": "T", "rank": 4 }, | |
| "gamma": { "dtype": "M", "rank": 1 }, | |
| "beta": { "dtype": "M", "rank": 1 }, | |
| "skip": { "dtype": "T" }, | |
| "bias": { "dtype": "T", "rank": 1, "optional": true } | |
| }, | |
| "outputs": { | |
| "Y": { "dtype": "T", "rank": 4, "shape": "shapes.X" }, | |
| "S": { "dtype": "T", "rank": 4, "optional": true, "shape": "shapes.X" } | |
| }, | |
| "attributes": { "activation": {}, "groups": {}, "channels_last": { "default": 1 }, "epsilon": { "default": 0.00001 } }, | |
| "attributeConstraints": { "activation": { "required": true, "values": [0, 1] }, "groups": { "required": true } }, | |
| "typeConstraints": { "T": ["float32", "float16"], "M": ["float32", "float16"] }, | |
| "tunables": { | |
| "WORKGROUP_SIZE": { "default": 256 }, | |
| "MAX_SPLITS": { "default": 256 }, | |
| "VALUES_PER_SPLIT": { "default": 4096 }, | |
| "SPLIT_MIN_ELEMENTS": { "default": 262144 }, | |
| "APPLY_SLAB_ELEMENTS": { "default": 8192 }, | |
| "FUSED_MIN_ROWS": { "default": 64 }, | |
| "FUSED_MAX_GROUP_BYTES": { "default": 131072 } | |
| }, | |
| "derive": { | |
| "attrsPresent": "has(attrs, \"groups\") and has(attrs, \"activation\")", | |
| "numGroups": "attrs.groups if attrsPresent else 0", | |
| "activationKind": "attrs.activation if attrsPresent else 0", | |
| "channelsLast": "attrs.channels_last != 0", | |
| "rankOk": "ranks.X == 4 and ranks.Y == 4 and ranks.gamma == 1 and ranks.beta == 1", | |
| "dimN": "dim(shapes.X, 0) if rankOk else 0", | |
| "dimC": "(dim(shapes.X, 3) if channelsLast else dim(shapes.X, 1)) if rankOk else 0", | |
| "dimHW": "(dim(shapes.X, 1) * dim(shapes.X, 2) if channelsLast else dim(shapes.X, 2) * dim(shapes.X, 3)) if rankOk else 0", | |
| "groupsOk": "numGroups >= 1 and dimC >= 1 and dimC % numGroups == 0", | |
| "channelsPerGroup": "dimC / numGroups if groupsOk else 0", | |
| "planeCount": "dimN * dimC", | |
| "groupSize": "channelsPerGroup * dimHW", | |
| "normRows": "dimN * numGroups", | |
| "elementCount": "numel(shapes.X) if rankOk else 0", | |
| "shapeOk": "rankOk and groupsOk and dimN > 0 and dimHW > 0 and groupSize > 0 and sameShape(shapes.Y, shapes.X) and dim(shapes.gamma, 0) == dimC and dim(shapes.beta, 0) == dimC", | |
| "deviceWorkgroupCap": "min(device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX)", | |
| "storageBufferLimit": "min(device.limits.maxStorageBufferBindingSize, device.limits.maxBufferSize)", | |
| "foldedDispatchCapacity": "min(device.limits.maxComputeWorkgroupsPerDimension, 65535) * min(device.limits.maxComputeWorkgroupsPerDimension, 65535)", | |
| "statsVec4Ok": "(channelsPerGroup % 4 == 0 and dimC % 4 == 0) if channelsLast else (dimHW % 4 == 0)", | |
| "applyVec4Ok": "(dimC % 4 == 0) if channelsLast else (dimHW % 4 == 0)", | |
| "fusedVecWidth": "4 if statsVec4Ok else 1", | |
| "statsVecWidth": "4 if statsVec4Ok else (2 if channelsLast and channelsPerGroup % 2 == 0 else 1)", | |
| "applyVecWidth": "4 if applyVec4Ok else 1", | |
| "workgroupCap": "max(1, floor(pow2ceil(min(tunables.WORKGROUP_SIZE, deviceWorkgroupCap) + 1) / 2))", | |
| "statsChunks": "max(1, floor(dimC / statsVecWidth))", | |
| "fusedRowChunks": "max(1, floor(dimC / fusedVecWidth))", | |
| "statsSegment": "max(1, floor(channelsPerGroup / statsVecWidth))", | |
| "statsGroupsPerBlock": "max(1, min(numGroups, floor(workgroupCap / statsSegment))) if channelsLast and statsChunks > deviceWorkgroupCap and statsSegment <= workgroupCap else max(1, numGroups)", | |
| "statsGroupBlocks": "ceilDiv(max(1, numGroups), statsGroupsPerBlock)", | |
| "statsTileChunks": "statsGroupsPerBlock * statsSegment if statsGroupBlocks > 1 else statsChunks", | |
| "applyChunks": "max(1, floor(dimC / applyVecWidth))", | |
| "statsRowsPerStep": "max(1, floor(workgroupCap / statsTileChunks))", | |
| "applyRowsPerStep": "max(1, floor(workgroupCap / applyChunks))", | |
| "planeVecs": "max(1, floor(dimHW / statsVecWidth))", | |
| "slabCount": "ceilDiv(dimHW, ceilDiv(dimHW, max(1, min(tunables.MAX_SPLITS, dimHW, ceilDiv(dimHW * dimC, tunables.VALUES_PER_SPLIT)))))", | |
| "planeSplits": "max(1, min(tunables.MAX_SPLITS, planeVecs, ceilDiv(dimHW, tunables.VALUES_PER_SPLIT)))", | |
| "splitCount": "slabCount if channelsLast else planeSplits", | |
| "partialsPerRow": "slabCount if channelsLast else max(1, channelsPerGroup) * planeSplits", | |
| "partialElements": "max(1, normRows * partialsPerRow)", | |
| "statsElements": "max(1, normRows)", | |
| "statsWorkgroup": "(statsTileChunks * statsRowsPerStep) if channelsLast else min(workgroupCap, max(32, pow2ceil(ceilDiv(planeVecs, planeSplits))))", | |
| "applyWorkgroup": "(applyChunks * applyRowsPerStep) if channelsLast else statsWorkgroup", | |
| "applySlabCount": "ceilDiv(dimHW, ceilDiv(dimHW, max(1, min(dimHW, min(device.limits.maxComputeWorkgroupsPerDimension, 65535), ceilDiv(elementCount, tunables.APPLY_SLAB_ELEMENTS)))))", | |
| "applySplit": "applySlabCount if channelsLast else planeSplits", | |
| "applyUnits": "(dimN * applySlabCount) if channelsLast else (planeCount * planeSplits)", | |
| "workUnits": "(dimN * slabCount * statsGroupBlocks) if channelsLast else (planeCount * planeSplits)", | |
| "splitFits": "statsWorkgroup <= deviceWorkgroupCap and applyWorkgroup <= deviceWorkgroupCap and statsWorkgroup * 8 <= device.limits.maxComputeWorkgroupStorageSize and partialElements * 8 <= storageBufferLimit and workUnits > 0 and workUnits <= foldedDispatchCapacity and applyUnits <= foldedDispatchCapacity", | |
| "fusedChunks": "max(1, floor(channelsPerGroup / fusedVecWidth)) if channelsLast else 1", | |
| "fusedWorkgroup": "(fusedChunks * max(1, floor(workgroupCap / fusedChunks))) if channelsLast else min(workgroupCap, max(32, pow2ceil(max(1, floor(groupSize / fusedVecWidth)))))", | |
| "fusedLanes": "pow2ceil(fusedWorkgroup)", | |
| "fusedFits": "fusedWorkgroup <= deviceWorkgroupCap and fusedLanes * 8 <= device.limits.maxComputeWorkgroupStorageSize and normRows <= min(device.limits.maxComputeWorkgroupsPerDimension, 65535) * min(device.limits.maxComputeWorkgroupsPerDimension, 65535)", | |
| "combineWorkgroup": "min(workgroupCap, 64)", | |
| "statsElement": "(\"vec\" ~ statsVecWidth ~ \"<\" ~ dtypes.T ~ \">\") if statsVecWidth > 1 else dtypes.T", | |
| "fusedElement": "(\"vec4<\" ~ dtypes.T ~ \">\") if statsVec4Ok else dtypes.T", | |
| "applyElement": "(\"vec4<\" ~ dtypes.T ~ \">\") if applyVec4Ok else dtypes.T", | |
| "mScalar": "dtypes.M", | |
| "tScalar": "dtypes.T", | |
| "skipExact": "rankOk and ranks.skip == 4 and sameShape(shapes.skip, shapes.X)", | |
| "skipBroadcast2": "rankOk and ranks.skip == 2 and dim(shapes.skip, 0) == dimN and dim(shapes.skip, 1) == dimC", | |
| "skipBroadcast4": "rankOk and ranks.skip == 4 and dim(shapes.skip, 0) == dimN and dim(shapes.skip, 1) == 1 and dim(shapes.skip, 2) == 1 and dim(shapes.skip, 3) == dimC", | |
| "broadcastSkipSpec": "(not skipExact) and (skipBroadcast2 or skipBroadcast4)", | |
| "skipOk": "skipExact or broadcastSkipSpec", | |
| "biasOk": "(not present.bias) or (ranks.bias == 1 and dim(shapes.bias, 0) == dimC)", | |
| "sumOk": "(not present.S) or (ranks.S == 4 and sameShape(shapes.S, shapes.X))", | |
| "contractOk": "shapeOk and skipOk and biasOk and sumOk and f16Ok(dtypes.T) and f16Ok(dtypes.M)", | |
| "skipElement": "dtypes.T if broadcastSkipSpec else statsElement" | |
| }, | |
| "when": ["contractOk"], | |
| "bindings": { | |
| "xIn": { "arg": "X", "name": "X", "elementType": "$statsElement" }, | |
| "gamma": { "elementType": "$mScalar" }, | |
| "beta": { "elementType": "$mScalar" }, | |
| "yOut": { "arg": "Y", "name": "Y", "elementType": "$applyElement" }, | |
| "partialsW": { "name": "partials", "buffer": "storage", "elementType": "vec2<f32>" }, | |
| "partialsR": { "name": "partials", "buffer": "read-only-storage", "elementType": "vec2<f32>" }, | |
| "statsW": { "name": "stats", "buffer": "storage", "elementType": "vec2<f32>" }, | |
| "statsR": { "name": "stats", "buffer": "read-only-storage", "elementType": "vec2<f32>" }, | |
| "yFused": { "arg": "Y", "name": "Y", "elementType": "$statsElement" }, | |
| "skipIn": { "arg": "skip", "name": "skip", "elementType": "$skipElement" }, | |
| "biasIn": { "arg": "bias", "name": "bias", "elementType": "$tScalar" }, | |
| "sumDstS": { "arg": "S", "name": "sum_dst", "elementType": "$statsElement" }, | |
| "sumDstY": { "arg": "Y", "name": "sum_dst", "elementType": "$statsElement" }, | |
| "srcCombineS": { "arg": "S", "name": "src", "buffer": "read-only-storage", "elementType": "$statsElement" }, | |
| "srcCombineY": { "arg": "Y", "name": "src", "buffer": "read-only-storage", "elementType": "$statsElement" }, | |
| "srcApplyS": { "arg": "S", "name": "src", "buffer": "read-only-storage", "elementType": "$applyElement" } | |
| }, | |
| "variants": [ | |
| { | |
| "id": "split_bias_sum", | |
| "priority": 20, | |
| "when": ["splitFits", "present.bias", "present.S"], | |
| "demoteWhen": ["elementCount < tunables.SPLIT_MIN_ELEMENTS * statsGroupBlocks", "(not channelsLast) and normRows >= tunables.FUSED_MIN_ROWS and groupSize * dtypeBytes(tensorDtypes.X) <= tunables.FUSED_MAX_GROUP_BYTES"], | |
| "derive": { | |
| "phaseLayout": "channelsLast", | |
| "hasSkip": "true", | |
| "hasBias": "true", | |
| "broadcastSkip": "broadcastSkipSpec", | |
| "vecSpec": "statsVecWidth", | |
| "dimCSpec": "dimC", | |
| "dimHWSpec": "dimHW", | |
| "cpgSpec": "channelsPerGroup", | |
| "groupsSpec": "numGroups", | |
| "groupSizeSpec": "groupSize", | |
| "normRowsSpec": "normRows", | |
| "epsilonSpec": "attrs.epsilon", | |
| "activationSpec": "activationKind", | |
| "chunksSpec": "statsChunks", | |
| "rowsPerStepSpec": "statsRowsPerStep", | |
| "splitSpec": "splitCount", | |
| "rowsPerSlabSpec": "ceilDiv(dimHW, slabCount)", | |
| "planeVecsSpec": "planeVecs", | |
| "chunkVecsSpec": "ceilDiv(planeVecs, planeSplits)", | |
| "partialsPerRowSpec": "partialsPerRow", | |
| "wgSpec": "statsWorkgroup", | |
| "combineWgSpec": "combineWorkgroup", | |
| "vecF32": "(\"vec\" ~ statsVecWidth ~ \"<f32>\") if statsVecWidth > 1 else \"f32\"", | |
| "storeElement": "statsElement", | |
| "applySrc": "\"src\"", | |
| "groupUniform": "true" | |
| }, | |
| "intermediates": [ | |
| { "id": "partials", "dtype": "float32", "shape": "[partialElements, 2]" }, | |
| { "id": "stats", "dtype": "float32", "shape": "[statsElements, 2]" } | |
| ], | |
| "passes": [ | |
| { | |
| "id": "stats", | |
| "name": "GroupNorm.Partials", | |
| "shader": "group-norm-slab.wgsl.jinja", | |
| "derive": { | |
| "phase": "\"stats\"", | |
| "unitsSpec": "workUnits", | |
| "statsBlockedSpec": "channelsLast and statsGroupBlocks > 1", | |
| "statsGroupsPerBlockSpec": "statsGroupsPerBlock", | |
| "statsGroupBlocksSpec": "statsGroupBlocks", | |
| "statsTileChunksSpec": "statsTileChunks" | |
| }, | |
| "bindings": ["xIn", "skipIn", "biasIn", "sumDstS", "partialsW"], | |
| "dispatch": { "x": "min(workUnits, 65535)", "y": "ceilDiv(workUnits, 65535)", "z": 1 } | |
| }, | |
| { | |
| "id": "combine", | |
| "name": "GroupNorm.Combine", | |
| "shader": "group-norm-combine.wgsl.jinja", | |
| "bindings": ["srcCombineS", "partialsR", "statsW"], | |
| "dispatch": { | |
| "x": "min(ceilDiv((normRows), (combineWorkgroup)), 65535)", | |
| "y": "ceilDiv(ceilDiv((normRows), (combineWorkgroup)), 65535)", | |
| "z": 1 | |
| } | |
| }, | |
| { | |
| "id": "apply", | |
| "name": "GroupNorm.Apply", | |
| "shader": "group-norm-slab.wgsl.jinja", | |
| "derive": { | |
| "phase": "\"apply\"", | |
| "vecSpec": "applyVecWidth", | |
| "chunksSpec": "applyChunks", | |
| "rowsPerStepSpec": "applyRowsPerStep", | |
| "wgSpec": "applyWorkgroup", | |
| "splitSpec": "applySplit", | |
| "rowsPerSlabSpec": "ceilDiv(dimHW, applySlabCount)", | |
| "groupUniform": "(channelsPerGroup % applyVecWidth == 0) if channelsLast else true", | |
| "storeElement": "applyElement", | |
| "vecF32": "\"vec4<f32>\" if applyVec4Ok else \"f32\"", | |
| "unitsSpec": "applyUnits", | |
| "applySrc": "\"src\"" | |
| }, | |
| "bindings": ["srcApplyS", "gamma", "beta", "statsR", "yOut"], | |
| "dispatch": { "x": "min(applyUnits, 65535)", "y": "ceilDiv(applyUnits, 65535)", "z": 1 } | |
| } | |
| ] | |
| }, | |
| { | |
| "id": "fused_bias_sum", | |
| "priority": 10, | |
| "when": ["fusedFits", "present.bias", "present.S"], | |
| "derive": { | |
| "statsElement": "fusedElement", | |
| "phaseLayout": "channelsLast", | |
| "hasSkip": "true", | |
| "hasBias": "true", | |
| "broadcastSkip": "broadcastSkipSpec", | |
| "useVec4": "statsVec4Ok", | |
| "vecSpec": "fusedVecWidth", | |
| "dimCSpec": "dimC", | |
| "dimHWSpec": "dimHW", | |
| "cpgSpec": "channelsPerGroup", | |
| "groupsSpec": "numGroups", | |
| "groupSizeSpec": "groupSize", | |
| "normRowsSpec": "normRows", | |
| "epsilonSpec": "attrs.epsilon", | |
| "activationSpec": "activationKind", | |
| "chunksSpec": "fusedRowChunks", | |
| "fusedChunksSpec": "fusedChunks", | |
| "fusedRowsSpec": "max(1, floor(fusedWorkgroup / fusedChunks))", | |
| "spanVecsSpec": "max(1, floor(groupSize / fusedVecWidth))", | |
| "wgSpec": "fusedWorkgroup", | |
| "ldsSpec": "fusedLanes", | |
| "vecF32": "\"vec4<f32>\" if statsVec4Ok else \"f32\"", | |
| "storeElement": "fusedElement", | |
| "fusedSrc": "\"sum_dst\"", | |
| "planeVecsSpec": "planeVecs", | |
| "skipElement": "tScalar if broadcastSkipSpec else fusedElement" | |
| }, | |
| "passes": [ | |
| { | |
| "id": "main", | |
| "name": "GroupNorm.Fused", | |
| "shader": "group-norm-fused.wgsl.jinja", | |
| "bindings": ["xIn", "skipIn", "biasIn", "gamma", "beta", "sumDstS", "yFused"], | |
| "dispatch": { "x": "min(normRows, 65535)", "y": "ceilDiv(normRows, 65535)", "z": 1 } | |
| } | |
| ] | |
| }, | |
| { | |
| "id": "split_bias_plain", | |
| "priority": 20, | |
| "when": ["splitFits", "present.bias", "not present.S"], | |
| "demoteWhen": ["elementCount < tunables.SPLIT_MIN_ELEMENTS * statsGroupBlocks", "(not channelsLast) and normRows >= tunables.FUSED_MIN_ROWS and groupSize * dtypeBytes(tensorDtypes.X) <= tunables.FUSED_MAX_GROUP_BYTES"], | |
| "derive": { | |
| "phaseLayout": "channelsLast", | |
| "hasSkip": "true", | |
| "hasBias": "true", | |
| "broadcastSkip": "broadcastSkipSpec", | |
| "vecSpec": "statsVecWidth", | |
| "dimCSpec": "dimC", | |
| "dimHWSpec": "dimHW", | |
| "cpgSpec": "channelsPerGroup", | |
| "groupsSpec": "numGroups", | |
| "groupSizeSpec": "groupSize", | |
| "normRowsSpec": "normRows", | |
| "epsilonSpec": "attrs.epsilon", | |
| "activationSpec": "activationKind", | |
| "chunksSpec": "statsChunks", | |
| "rowsPerStepSpec": "statsRowsPerStep", | |
| "splitSpec": "splitCount", | |
| "rowsPerSlabSpec": "ceilDiv(dimHW, slabCount)", | |
| "planeVecsSpec": "planeVecs", | |
| "chunkVecsSpec": "ceilDiv(planeVecs, planeSplits)", | |
| "partialsPerRowSpec": "partialsPerRow", | |
| "wgSpec": "statsWorkgroup", | |
| "combineWgSpec": "combineWorkgroup", | |
| "vecF32": "(\"vec\" ~ statsVecWidth ~ \"<f32>\") if statsVecWidth > 1 else \"f32\"", | |
| "storeElement": "statsElement", | |
| "applySrc": "\"Y\"", | |
| "groupUniform": "true" | |
| }, | |
| "intermediates": [ | |
| { "id": "partials", "dtype": "float32", "shape": "[partialElements, 2]" }, | |
| { "id": "stats", "dtype": "float32", "shape": "[statsElements, 2]" } | |
| ], | |
| "passes": [ | |
| { | |
| "id": "stats", | |
| "name": "GroupNorm.Partials", | |
| "shader": "group-norm-slab.wgsl.jinja", | |
| "derive": { | |
| "phase": "\"stats\"", | |
| "unitsSpec": "workUnits", | |
| "statsBlockedSpec": "channelsLast and statsGroupBlocks > 1", | |
| "statsGroupsPerBlockSpec": "statsGroupsPerBlock", | |
| "statsGroupBlocksSpec": "statsGroupBlocks", | |
| "statsTileChunksSpec": "statsTileChunks" | |
| }, | |
| "bindings": ["xIn", "skipIn", "biasIn", "sumDstY", "partialsW"], | |
| "dispatch": { "x": "min(workUnits, 65535)", "y": "ceilDiv(workUnits, 65535)", "z": 1 } | |
| }, | |
| { | |
| "id": "combine", | |
| "name": "GroupNorm.Combine", | |
| "shader": "group-norm-combine.wgsl.jinja", | |
| "bindings": ["srcCombineY", "partialsR", "statsW"], | |
| "dispatch": { | |
| "x": "min(ceilDiv((normRows), (combineWorkgroup)), 65535)", | |
| "y": "ceilDiv(ceilDiv((normRows), (combineWorkgroup)), 65535)", | |
| "z": 1 | |
| } | |
| }, | |
| { | |
| "id": "apply", | |
| "name": "GroupNorm.Apply", | |
| "shader": "group-norm-slab.wgsl.jinja", | |
| "derive": { | |
| "phase": "\"apply\"", | |
| "vecSpec": "applyVecWidth", | |
| "chunksSpec": "applyChunks", | |
| "rowsPerStepSpec": "applyRowsPerStep", | |
| "wgSpec": "applyWorkgroup", | |
| "splitSpec": "applySplit", | |
| "rowsPerSlabSpec": "ceilDiv(dimHW, applySlabCount)", | |
| "groupUniform": "(channelsPerGroup % applyVecWidth == 0) if channelsLast else true", | |
| "storeElement": "applyElement", | |
| "vecF32": "\"vec4<f32>\" if applyVec4Ok else \"f32\"", | |
| "unitsSpec": "applyUnits", | |
| "applySrc": "\"Y\"" | |
| }, | |
| "bindings": ["gamma", "beta", "statsR", "yOut"], | |
| "dispatch": { "x": "min(applyUnits, 65535)", "y": "ceilDiv(applyUnits, 65535)", "z": 1 } | |
| } | |
| ] | |
| }, | |
| { | |
| "id": "fused_bias_plain", | |
| "priority": 10, | |
| "when": ["fusedFits", "present.bias", "not present.S"], | |
| "derive": { | |
| "statsElement": "fusedElement", | |
| "phaseLayout": "channelsLast", | |
| "hasSkip": "true", | |
| "hasBias": "true", | |
| "broadcastSkip": "broadcastSkipSpec", | |
| "useVec4": "statsVec4Ok", | |
| "vecSpec": "fusedVecWidth", | |
| "dimCSpec": "dimC", | |
| "dimHWSpec": "dimHW", | |
| "cpgSpec": "channelsPerGroup", | |
| "groupsSpec": "numGroups", | |
| "groupSizeSpec": "groupSize", | |
| "normRowsSpec": "normRows", | |
| "epsilonSpec": "attrs.epsilon", | |
| "activationSpec": "activationKind", | |
| "chunksSpec": "fusedRowChunks", | |
| "fusedChunksSpec": "fusedChunks", | |
| "fusedRowsSpec": "max(1, floor(fusedWorkgroup / fusedChunks))", | |
| "spanVecsSpec": "max(1, floor(groupSize / fusedVecWidth))", | |
| "wgSpec": "fusedWorkgroup", | |
| "ldsSpec": "fusedLanes", | |
| "vecF32": "\"vec4<f32>\" if statsVec4Ok else \"f32\"", | |
| "storeElement": "fusedElement", | |
| "fusedSrc": "\"Y\"", | |
| "planeVecsSpec": "planeVecs", | |
| "skipElement": "tScalar if broadcastSkipSpec else fusedElement" | |
| }, | |
| "passes": [ | |
| { | |
| "id": "main", | |
| "name": "GroupNorm.Fused", | |
| "shader": "group-norm-fused.wgsl.jinja", | |
| "bindings": ["xIn", "skipIn", "biasIn", "gamma", "beta", "yFused"], | |
| "dispatch": { "x": "min(normRows, 65535)", "y": "ceilDiv(normRows, 65535)", "z": 1 } | |
| } | |
| ] | |
| }, | |
| { | |
| "id": "split_sum", | |
| "priority": 20, | |
| "when": ["splitFits", "not present.bias", "present.S"], | |
| "demoteWhen": ["elementCount < tunables.SPLIT_MIN_ELEMENTS * statsGroupBlocks", "(not channelsLast) and normRows >= tunables.FUSED_MIN_ROWS and groupSize * dtypeBytes(tensorDtypes.X) <= tunables.FUSED_MAX_GROUP_BYTES"], | |
| "derive": { | |
| "phaseLayout": "channelsLast", | |
| "hasSkip": "true", | |
| "hasBias": "false", | |
| "broadcastSkip": "broadcastSkipSpec", | |
| "vecSpec": "statsVecWidth", | |
| "dimCSpec": "dimC", | |
| "dimHWSpec": "dimHW", | |
| "cpgSpec": "channelsPerGroup", | |
| "groupsSpec": "numGroups", | |
| "groupSizeSpec": "groupSize", | |
| "normRowsSpec": "normRows", | |
| "epsilonSpec": "attrs.epsilon", | |
| "activationSpec": "activationKind", | |
| "chunksSpec": "statsChunks", | |
| "rowsPerStepSpec": "statsRowsPerStep", | |
| "splitSpec": "splitCount", | |
| "rowsPerSlabSpec": "ceilDiv(dimHW, slabCount)", | |
| "planeVecsSpec": "planeVecs", | |
| "chunkVecsSpec": "ceilDiv(planeVecs, planeSplits)", | |
| "partialsPerRowSpec": "partialsPerRow", | |
| "wgSpec": "statsWorkgroup", | |
| "combineWgSpec": "combineWorkgroup", | |
| "vecF32": "(\"vec\" ~ statsVecWidth ~ \"<f32>\") if statsVecWidth > 1 else \"f32\"", | |
| "storeElement": "statsElement", | |
| "applySrc": "\"src\"", | |
| "groupUniform": "true" | |
| }, | |
| "intermediates": [ | |
| { "id": "partials", "dtype": "float32", "shape": "[partialElements, 2]" }, | |
| { "id": "stats", "dtype": "float32", "shape": "[statsElements, 2]" } | |
| ], | |
| "passes": [ | |
| { | |
| "id": "stats", | |
| "name": "GroupNorm.Partials", | |
| "shader": "group-norm-slab.wgsl.jinja", | |
| "derive": { | |
| "phase": "\"stats\"", | |
| "unitsSpec": "workUnits", | |
| "statsBlockedSpec": "channelsLast and statsGroupBlocks > 1", | |
| "statsGroupsPerBlockSpec": "statsGroupsPerBlock", | |
| "statsGroupBlocksSpec": "statsGroupBlocks", | |
| "statsTileChunksSpec": "statsTileChunks" | |
| }, | |
| "bindings": ["xIn", "skipIn", "sumDstS", "partialsW"], | |
| "dispatch": { "x": "min(workUnits, 65535)", "y": "ceilDiv(workUnits, 65535)", "z": 1 } | |
| }, | |
| { | |
| "id": "combine", | |
| "name": "GroupNorm.Combine", | |
| "shader": "group-norm-combine.wgsl.jinja", | |
| "bindings": ["srcCombineS", "partialsR", "statsW"], | |
| "dispatch": { | |
| "x": "min(ceilDiv((normRows), (combineWorkgroup)), 65535)", | |
| "y": "ceilDiv(ceilDiv((normRows), (combineWorkgroup)), 65535)", | |
| "z": 1 | |
| } | |
| }, | |
| { | |
| "id": "apply", | |
| "name": "GroupNorm.Apply", | |
| "shader": "group-norm-slab.wgsl.jinja", | |
| "derive": { | |
| "phase": "\"apply\"", | |
| "vecSpec": "applyVecWidth", | |
| "chunksSpec": "applyChunks", | |
| "rowsPerStepSpec": "applyRowsPerStep", | |
| "wgSpec": "applyWorkgroup", | |
| "splitSpec": "applySplit", | |
| "rowsPerSlabSpec": "ceilDiv(dimHW, applySlabCount)", | |
| "groupUniform": "(channelsPerGroup % applyVecWidth == 0) if channelsLast else true", | |
| "storeElement": "applyElement", | |
| "vecF32": "\"vec4<f32>\" if applyVec4Ok else \"f32\"", | |
| "unitsSpec": "applyUnits", | |
| "applySrc": "\"src\"" | |
| }, | |
| "bindings": ["srcApplyS", "gamma", "beta", "statsR", "yOut"], | |
| "dispatch": { "x": "min(applyUnits, 65535)", "y": "ceilDiv(applyUnits, 65535)", "z": 1 } | |
| } | |
| ] | |
| }, | |
| { | |
| "id": "fused_sum", | |
| "priority": 10, | |
| "when": ["fusedFits", "not present.bias", "present.S"], | |
| "derive": { | |
| "statsElement": "fusedElement", | |
| "phaseLayout": "channelsLast", | |
| "hasSkip": "true", | |
| "hasBias": "false", | |
| "broadcastSkip": "broadcastSkipSpec", | |
| "useVec4": "statsVec4Ok", | |
| "vecSpec": "fusedVecWidth", | |
| "dimCSpec": "dimC", | |
| "dimHWSpec": "dimHW", | |
| "cpgSpec": "channelsPerGroup", | |
| "groupsSpec": "numGroups", | |
| "groupSizeSpec": "groupSize", | |
| "normRowsSpec": "normRows", | |
| "epsilonSpec": "attrs.epsilon", | |
| "activationSpec": "activationKind", | |
| "chunksSpec": "fusedRowChunks", | |
| "fusedChunksSpec": "fusedChunks", | |
| "fusedRowsSpec": "max(1, floor(fusedWorkgroup / fusedChunks))", | |
| "spanVecsSpec": "max(1, floor(groupSize / fusedVecWidth))", | |
| "wgSpec": "fusedWorkgroup", | |
| "ldsSpec": "fusedLanes", | |
| "vecF32": "\"vec4<f32>\" if statsVec4Ok else \"f32\"", | |
| "storeElement": "fusedElement", | |
| "fusedSrc": "\"sum_dst\"", | |
| "planeVecsSpec": "planeVecs", | |
| "skipElement": "tScalar if broadcastSkipSpec else fusedElement" | |
| }, | |
| "passes": [ | |
| { | |
| "id": "main", | |
| "name": "GroupNorm.Fused", | |
| "shader": "group-norm-fused.wgsl.jinja", | |
| "bindings": ["xIn", "skipIn", "gamma", "beta", "sumDstS", "yFused"], | |
| "dispatch": { "x": "min(normRows, 65535)", "y": "ceilDiv(normRows, 65535)", "z": 1 } | |
| } | |
| ] | |
| }, | |
| { | |
| "id": "split_plain", | |
| "priority": 20, | |
| "when": ["splitFits", "not present.bias", "not present.S"], | |
| "demoteWhen": ["elementCount < tunables.SPLIT_MIN_ELEMENTS * statsGroupBlocks", "(not channelsLast) and normRows >= tunables.FUSED_MIN_ROWS and groupSize * dtypeBytes(tensorDtypes.X) <= tunables.FUSED_MAX_GROUP_BYTES"], | |
| "derive": { | |
| "phaseLayout": "channelsLast", | |
| "hasSkip": "true", | |
| "hasBias": "false", | |
| "broadcastSkip": "broadcastSkipSpec", | |
| "vecSpec": "statsVecWidth", | |
| "dimCSpec": "dimC", | |
| "dimHWSpec": "dimHW", | |
| "cpgSpec": "channelsPerGroup", | |
| "groupsSpec": "numGroups", | |
| "groupSizeSpec": "groupSize", | |
| "normRowsSpec": "normRows", | |
| "epsilonSpec": "attrs.epsilon", | |
| "activationSpec": "activationKind", | |
| "chunksSpec": "statsChunks", | |
| "rowsPerStepSpec": "statsRowsPerStep", | |
| "splitSpec": "splitCount", | |
| "rowsPerSlabSpec": "ceilDiv(dimHW, slabCount)", | |
| "planeVecsSpec": "planeVecs", | |
| "chunkVecsSpec": "ceilDiv(planeVecs, planeSplits)", | |
| "partialsPerRowSpec": "partialsPerRow", | |
| "wgSpec": "statsWorkgroup", | |
| "combineWgSpec": "combineWorkgroup", | |
| "vecF32": "(\"vec\" ~ statsVecWidth ~ \"<f32>\") if statsVecWidth > 1 else \"f32\"", | |
| "storeElement": "statsElement", | |
| "applySrc": "\"Y\"", | |
| "groupUniform": "true" | |
| }, | |
| "intermediates": [ | |
| { "id": "partials", "dtype": "float32", "shape": "[partialElements, 2]" }, | |
| { "id": "stats", "dtype": "float32", "shape": "[statsElements, 2]" } | |
| ], | |
| "passes": [ | |
| { | |
| "id": "stats", | |
| "name": "GroupNorm.Partials", | |
| "shader": "group-norm-slab.wgsl.jinja", | |
| "derive": { | |
| "phase": "\"stats\"", | |
| "unitsSpec": "workUnits", | |
| "statsBlockedSpec": "channelsLast and statsGroupBlocks > 1", | |
| "statsGroupsPerBlockSpec": "statsGroupsPerBlock", | |
| "statsGroupBlocksSpec": "statsGroupBlocks", | |
| "statsTileChunksSpec": "statsTileChunks" | |
| }, | |
| "bindings": ["xIn", "skipIn", "sumDstY", "partialsW"], | |
| "dispatch": { "x": "min(workUnits, 65535)", "y": "ceilDiv(workUnits, 65535)", "z": 1 } | |
| }, | |
| { | |
| "id": "combine", | |
| "name": "GroupNorm.Combine", | |
| "shader": "group-norm-combine.wgsl.jinja", | |
| "bindings": ["srcCombineY", "partialsR", "statsW"], | |
| "dispatch": { | |
| "x": "min(ceilDiv((normRows), (combineWorkgroup)), 65535)", | |
| "y": "ceilDiv(ceilDiv((normRows), (combineWorkgroup)), 65535)", | |
| "z": 1 | |
| } | |
| }, | |
| { | |
| "id": "apply", | |
| "name": "GroupNorm.Apply", | |
| "shader": "group-norm-slab.wgsl.jinja", | |
| "derive": { | |
| "phase": "\"apply\"", | |
| "vecSpec": "applyVecWidth", | |
| "chunksSpec": "applyChunks", | |
| "rowsPerStepSpec": "applyRowsPerStep", | |
| "wgSpec": "applyWorkgroup", | |
| "splitSpec": "applySplit", | |
| "rowsPerSlabSpec": "ceilDiv(dimHW, applySlabCount)", | |
| "groupUniform": "(channelsPerGroup % applyVecWidth == 0) if channelsLast else true", | |
| "storeElement": "applyElement", | |
| "vecF32": "\"vec4<f32>\" if applyVec4Ok else \"f32\"", | |
| "unitsSpec": "applyUnits", | |
| "applySrc": "\"Y\"" | |
| }, | |
| "bindings": ["gamma", "beta", "statsR", "yOut"], | |
| "dispatch": { "x": "min(applyUnits, 65535)", "y": "ceilDiv(applyUnits, 65535)", "z": 1 } | |
| } | |
| ] | |
| }, | |
| { | |
| "id": "fused_plain", | |
| "priority": 10, | |
| "when": ["fusedFits", "not present.bias", "not present.S"], | |
| "derive": { | |
| "statsElement": "fusedElement", | |
| "phaseLayout": "channelsLast", | |
| "hasSkip": "true", | |
| "hasBias": "false", | |
| "broadcastSkip": "broadcastSkipSpec", | |
| "useVec4": "statsVec4Ok", | |
| "vecSpec": "fusedVecWidth", | |
| "dimCSpec": "dimC", | |
| "dimHWSpec": "dimHW", | |
| "cpgSpec": "channelsPerGroup", | |
| "groupsSpec": "numGroups", | |
| "groupSizeSpec": "groupSize", | |
| "normRowsSpec": "normRows", | |
| "epsilonSpec": "attrs.epsilon", | |
| "activationSpec": "activationKind", | |
| "chunksSpec": "fusedRowChunks", | |
| "fusedChunksSpec": "fusedChunks", | |
| "fusedRowsSpec": "max(1, floor(fusedWorkgroup / fusedChunks))", | |
| "spanVecsSpec": "max(1, floor(groupSize / fusedVecWidth))", | |
| "wgSpec": "fusedWorkgroup", | |
| "ldsSpec": "fusedLanes", | |
| "vecF32": "\"vec4<f32>\" if statsVec4Ok else \"f32\"", | |
| "storeElement": "fusedElement", | |
| "fusedSrc": "\"Y\"", | |
| "planeVecsSpec": "planeVecs", | |
| "skipElement": "tScalar if broadcastSkipSpec else fusedElement" | |
| }, | |
| "passes": [ | |
| { | |
| "id": "main", | |
| "name": "GroupNorm.Fused", | |
| "shader": "group-norm-fused.wgsl.jinja", | |
| "bindings": ["xIn", "skipIn", "gamma", "beta", "yFused"], | |
| "dispatch": { "x": "min(normRows, 65535)", "y": "ceilDiv(normRows, 65535)", "z": 1 } | |
| } | |
| ] | |
| } | |
| ] | |
| } | |