Xenova's picture
Xenova HF Staff
sync 2e7068faf55e
fe90e05 verified
Raw
History Blame
11.3 kB
{
"domain": "com.microsoft",
"name": "GemmFastGelu",
"sinceVersion": 1,
"description": "Fuses MatMul, an optional bias, and FastGelu: `Y = FastGelu(X @ W + bias)`. `X` has rank at least 2 with shape `(..., K)`, `W` has shape `(K, N)`, and `bias` has shape `(N)`. The activation runs in the float32 accumulator before the output is narrowed, avoiding an intermediate `(..., N)` tensor. Bfloat16 is not implemented.",
"inputs": [
{
"role": "X",
"dtype": "T",
"description": "Left operand of rank 2 or greater with shape `(..., K)`; every leading-axis coordinate identifies a row of the product."
},
{ "role": "W", "dtype": "T", "rank": 2, "description": "Right operand with shape `(K, N)`." },
{
"role": "bias",
"dtype": "T",
"rank": 1,
"optional": true,
"description": "Optional bias with shape `(N)`, added before the activation."
}
],
"outputs": [
{
"role": "Y",
"dtype": "T",
"rank": "ranks.X",
"shape": "matmulShape(shapes.X, shapes.W)",
"description": "`FastGelu(X @ W + bias)`, with the same rank and leading dimensions as `X` and a trailing `N`."
}
],
"typeConstraints": { "T": ["float32", "float16"] },
"args": {
"X": { "kind": "tensor", "semantic": "X", "role": "input" },
"W": { "kind": "tensor", "semantic": "W", "role": "weights" },
"bias": { "kind": "tensor", "semantic": "bias", "role": "weights", "required": false },
"Y": { "kind": "tensor", "semantic": "Y", "role": "output" }
},
"derive": {
"deviceWorkgroupCap": "min(device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX)",
"wave32Adapter": "has(device.adapterInfo, \"subgroupMinSize\") and has(device.adapterInfo, \"subgroupMaxSize\") and device.adapterInfo.subgroupMinSize == 32 and device.adapterInfo.subgroupMaxSize == 32",
"canPinSubgroupSize32": "device.features.has(\"subgroups\") and device.features.has(\"subgroup-size-control\") and has(device.adapterInfo, \"subgroupMinSize\") and has(device.adapterInfo, \"subgroupMaxSize\") and device.adapterInfo.subgroupMinSize <= 32 and device.adapterInfo.subgroupMaxSize >= 32",
"pinSubgroupSize32": "canPinSubgroupSize32 and not wave32Adapter",
"wave32Effective": "wave32Adapter or pinSubgroupSize32",
"kDim": "dim(shapes.W, 0)",
"nDim": "dim(shapes.W, 1)",
"gfgRows": "numel(shapes.X) / kDim if kDim > 0 else 0",
"shapeOk": "ranks.W == 2 and ranks.X >= 2 and kDim > 0 and nDim > 0 and dim(shapes.X, ranks.X - 1) == kDim and ranks.Y == ranks.X and dim(shapes.Y, ranks.Y - 1) == nDim and numel(shapes.Y) == gfgRows * nDim",
"dtypeOk": "(tensorDtypes.X == \"float32\" or tensorDtypes.X == \"float16\") and tensorDtypes.W == tensorDtypes.X and tensorDtypes.Y == tensorDtypes.X and f16Ok(dtypes.T)",
"biasOk": "ranks.bias == 1 and dim(shapes.bias, 0) == nDim and tensorDtypes.bias == tensorDtypes.X",
"baseContract": "shapeOk and dtypeOk",
"noBiasContract": "baseContract and not present.bias",
"biasContract": "baseContract and present.bias and biasOk",
"sgmatOperandBytes": "2 if tensorDtypes.X == \"float16\" and tensorDtypes.W == \"float16\" else 4",
"sgmatStorageBytes": "(32 * 32 + 64 * 32) * sgmatOperandBytes + 32 * 64 * 4",
"sgmatResourcesFit": "128 <= deviceWorkgroupCap and sgmatStorageBytes <= device.limits.maxComputeWorkgroupStorageSize",
"sgmatLayoutOk": "gfgRows > 0 and kDim % 32 == 0 and nDim % 64 == 0 and ((tensorDtypes.X == \"float16\" and device.features.has(\"shader-f16\") and gfgRows >= 2) or (tensorDtypes.X == \"float32\" and gfgRows >= 32)) and ceilDiv(gfgRows, 32) <= device.limits.maxComputeWorkgroupsPerDimension and ceilDiv(nDim, 64) <= device.limits.maxComputeWorkgroupsPerDimension",
"sgmatContract": "wave32Effective and sgmatLayoutOk and sgmatResourcesFit"
},
"constants": {
"usesF16": "tensorDtypes.X == \"float16\"",
"transA": false,
"transB": false,
"gemmEpilogue": "\"fastgelu\""
},
"bindingSets": {
"noBias": [
{ "name": "a", "arg": "X", "semantic": "X", "buffer": { "type": "read-only-storage" }, "elementType": "$T" },
{ "name": "b", "arg": "W", "semantic": "W", "buffer": { "type": "read-only-storage" }, "elementType": "$T" },
{ "name": "y", "arg": "Y", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$T" },
{
"name": "params",
"semantic": "kernel.params",
"buffer": { "type": "uniform" },
"struct": {
"name": "Params",
"fields": [
{ "name": "M", "type": "u32", "value": "gfgRows" },
{ "name": "N", "type": "u32", "value": "nDim" },
{ "name": "K", "type": "u32", "value": "kDim" },
{ "name": "alpha", "type": "f32", "value": 1 }
]
}
}
],
"withBias": [
{ "name": "a", "arg": "X", "semantic": "X", "buffer": { "type": "read-only-storage" }, "elementType": "$T" },
{ "name": "b", "arg": "W", "semantic": "W", "buffer": { "type": "read-only-storage" }, "elementType": "$T" },
{
"name": "bias",
"arg": "bias",
"semantic": "bias",
"buffer": { "type": "read-only-storage" },
"elementType": "$T"
},
{ "name": "y", "arg": "Y", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$T" },
{
"name": "params",
"semantic": "kernel.params",
"buffer": { "type": "uniform" },
"struct": {
"name": "Params",
"fields": [
{ "name": "M", "type": "u32", "value": "gfgRows" },
{ "name": "N", "type": "u32", "value": "nDim" },
{ "name": "K", "type": "u32", "value": "kDim" },
{ "name": "alpha", "type": "f32", "value": 1 },
{ "name": "beta", "type": "f32", "value": 1 }
]
}
}
],
"sgmatNoBias": [
{ "name": "x", "arg": "X", "semantic": "a", "buffer": { "type": "read-only-storage" }, "elementType": "$xScalar" },
{ "name": "w", "arg": "W", "semantic": "b", "buffer": { "type": "read-only-storage" }, "elementType": "$wScalar" },
{ "name": "y", "arg": "Y", "semantic": "y", "buffer": { "type": "storage" }, "elementType": "$yScalar" },
{
"name": "params",
"semantic": "kernel.params",
"buffer": { "type": "uniform" },
"struct": { "name": "Params", "fields": [{ "name": "M", "type": "u32", "value": "gfgRows" }] }
}
],
"sgmatBias": [
{ "name": "x", "arg": "X", "semantic": "a", "buffer": { "type": "read-only-storage" }, "elementType": "$xScalar" },
{ "name": "w", "arg": "W", "semantic": "b", "buffer": { "type": "read-only-storage" }, "elementType": "$wScalar" },
{
"name": "bias",
"arg": "bias",
"semantic": "bias",
"buffer": { "type": "read-only-storage" },
"elementType": "$bScalar"
},
{ "name": "y", "arg": "Y", "semantic": "y", "buffer": { "type": "storage" }, "elementType": "$yScalar" },
{
"name": "params",
"semantic": "kernel.params",
"buffer": { "type": "uniform" },
"struct": { "name": "Params", "fields": [{ "name": "M", "type": "u32", "value": "gfgRows" }] }
}
]
},
"variants": [
{
"id": "sgmat_bias",
"priority": 100,
"requires": {
"features": ["subgroups", "chromium-experimental-subgroup-matrix"],
"subgroupMatrixConfigs": [
{ "componentType": "f16", "M": 8, "N": 8, "K": 8 },
{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }
]
},
"when": ["biasContract", "sgmatContract"],
"constants": {
"hasBias": true,
"gemmEpilogue": "\"fastgelu\"",
"bTransposedStorage": true,
"xScalar": "\"f16\" if tensorDtypes.X == \"float16\" else \"f32\"",
"wScalar": "\"f16\" if tensorDtypes.W == \"float16\" else \"f32\"",
"bScalar": "\"f16\" if tensorDtypes.bias == \"float16\" else \"f32\"",
"yScalar": "\"f16\" if tensorDtypes.Y == \"float16\" else \"f32\"",
"mmaScalar": "\"f16\" if tensorDtypes.X == \"float16\" and tensorDtypes.W == \"float16\" else \"f32\"",
"usesF16": "tensorDtypes.X == \"float16\" or tensorDtypes.W == \"float16\" or tensorDtypes.Y == \"float16\"",
"inFeatures": "kDim",
"outFeatures": "nDim"
},
"passes": [
{
"id": "main",
"name": "GemmFastGelu.SubgroupMatrixBias",
"shader": "gemm-subgroup-matrix.wgsl.jinja",
"bindings": "sgmatBias",
"dispatch": { "workgroups": "ceilDiv(gfgRows, 32)", "x": "ceilDiv(nDim, 64)" }
}
]
},
{
"id": "sgmat",
"priority": 100,
"requires": {
"features": ["subgroups", "chromium-experimental-subgroup-matrix"],
"subgroupMatrixConfigs": [
{ "componentType": "f16", "M": 8, "N": 8, "K": 8 },
{ "componentType": "f32", "resultComponentType": "f32", "M": 8, "N": 8, "K": 8 }
]
},
"when": ["noBiasContract", "sgmatContract"],
"constants": {
"hasBias": false,
"gemmEpilogue": "\"fastgelu\"",
"bTransposedStorage": true,
"xScalar": "\"f16\" if tensorDtypes.X == \"float16\" else \"f32\"",
"wScalar": "\"f16\" if tensorDtypes.W == \"float16\" else \"f32\"",
"yScalar": "\"f16\" if tensorDtypes.Y == \"float16\" else \"f32\"",
"mmaScalar": "\"f16\" if tensorDtypes.X == \"float16\" and tensorDtypes.W == \"float16\" else \"f32\"",
"usesF16": "tensorDtypes.X == \"float16\" or tensorDtypes.W == \"float16\" or tensorDtypes.Y == \"float16\"",
"inFeatures": "kDim",
"outFeatures": "nDim"
},
"passes": [
{
"id": "main",
"name": "GemmFastGelu.SubgroupMatrix",
"shader": "gemm-subgroup-matrix.wgsl.jinja",
"bindings": "sgmatNoBias",
"dispatch": { "workgroups": "ceilDiv(gfgRows, 32)", "x": "ceilDiv(nDim, 64)" }
}
]
},
{
"id": "tiled_bias",
"priority": 0,
"when": ["biasContract"],
"constants": { "hasBias": true, "rowBias": true, "scalarBias": false, "columnBias": false },
"passes": [
{
"id": "main",
"name": "GemmFastGelu.Bias",
"shader": "gemm-fast-gelu.wgsl.jinja",
"bindings": "withBias",
"dispatch": {
"x": "min(ceilDiv(nDim, 64), device.limits.maxComputeWorkgroupsPerDimension)",
"y": "min(ceilDiv(gfgRows, 64), device.limits.maxComputeWorkgroupsPerDimension)"
}
}
]
},
{
"id": "tiled",
"priority": 0,
"when": ["noBiasContract"],
"constants": { "hasBias": false },
"passes": [
{
"id": "main",
"name": "GemmFastGelu",
"shader": "gemm-fast-gelu.wgsl.jinja",
"bindings": "noBias",
"dispatch": {
"x": "min(ceilDiv(nDim, 64), device.limits.maxComputeWorkgroupsPerDimension)",
"y": "min(ceilDiv(gfgRows, 64), device.limits.maxComputeWorkgroupsPerDimension)"
}
}
]
}
]
}