Xenova's picture
Xenova HF Staff
sync 2e7068faf55e
3aadfb1 verified
Raw
History Blame
8.37 kB
{
"domain": "com.microsoft",
"name": "FastGelu",
"sinceVersion": 1,
"description": "Applies the GELU (Gaussian Error Linear Unit) activation using a tanh approximation: `Y = 0.5 * X * (1 + tanh(0.797885 * X + 0.035677 * X^3))`. An optional `bias` is added to `X` before the activation is computed. This WebGPU package implements float16 and float32; the schema-allowed double and bfloat16 types are not supported.",
"inputs": [
{ "role": "X", "dtype": "T", "description": "Values transformed by FastGelu after adding the optional `bias`." },
{
"role": "bias",
"dtype": "T",
"rank": 1,
"optional": true,
"description": "Optional 1-D bias added to `X` along the last dimension before the GELU activation."
}
],
"outputs": [
{
"role": "Y",
"dtype": "T",
"rank": "ranks.X",
"shape": "shapes.X",
"description": "Output tensor after applying the GELU activation; same shape as `X`."
}
],
"typeConstraints": { "T": ["float32", "float16"] },
"args": {
"X": { "kind": "tensor", "semantic": "X", "role": "input" },
"bias": { "kind": "tensor", "semantic": "bias", "role": "input", "required": false },
"Y": { "kind": "tensor", "semantic": "Y", "role": "output" }
},
"tunables": { "WORKGROUP_SIZE": 256 },
"derive": {
"deviceWorkgroupCap": "min(device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX)",
"storageBufferLimit": "min(device.limits.maxStorageBufferBindingSize, device.limits.maxBufferSize)",
"workgroupSize": "min(tunables.WORKGROUP_SIZE, deviceWorkgroupCap)",
"buffersFit": "numel(shapes.X) * dtypeBytes(dtypes.T) <= storageBufferLimit and numel(shapes.Y) * dtypeBytes(dtypes.T) <= storageBufferLimit and (not present.bias or numel(shapes.bias) * dtypeBytes(dtypes.T) <= storageBufferLimit)",
"dispatchFits": "numel(shapes.X) <= device.limits.maxComputeWorkgroupsPerDimension * device.limits.maxComputeWorkgroupsPerDimension * workgroupSize * 4",
"baseOk": "workgroupSize > 0 and ranks.X >= 1 and numel(shapes.X) == numel(shapes.Y) and f16Ok(dtypes.T) and buffersFit and dispatchFits",
"biasOk": "present.bias and ranks.bias == 1 and dim(shapes.bias, 0) == dim(shapes.X, ranks.X - 1)",
"noBiasOk": "not present.bias",
"vec4Ok": "numel(shapes.X) > 0 and numel(shapes.X) % 4 == 0 and dim(shapes.X, ranks.X - 1) % 4 == 0"
},
"constants": { "scalar": "dtypes.T", "usesF16": "dtypes.T == \"f16\"", "approximate": "\"tanh\"" },
"bindingSets": {
"vec4Bias": [
{
"name": "x",
"arg": "X",
"semantic": "X",
"buffer": { "type": "read-only-storage" },
"elementType": "$vectorScalar"
},
{
"name": "bias",
"arg": "bias",
"semantic": "bias",
"buffer": { "type": "read-only-storage" },
"elementType": "$scalar",
"length": "$hidden"
},
{ "name": "y", "arg": "Y", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$vectorScalar" },
{
"name": "params",
"semantic": "kernel.params",
"buffer": { "type": "uniform" },
"struct": { "name": "Params", "fields": [{ "name": "count", "type": "u32", "value": "numel(shapes.X) / 4" }] }
}
],
"vec4": [
{
"name": "x",
"arg": "X",
"semantic": "X",
"buffer": { "type": "read-only-storage" },
"elementType": "$vectorScalar"
},
{ "name": "y", "arg": "Y", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$vectorScalar" },
{
"name": "params",
"semantic": "kernel.params",
"buffer": { "type": "uniform" },
"struct": { "name": "Params", "fields": [{ "name": "count", "type": "u32", "value": "numel(shapes.X) / 4" }] }
}
],
"scalarBias": [
{ "name": "x", "arg": "X", "semantic": "X", "buffer": { "type": "read-only-storage" }, "elementType": "$scalar" },
{
"name": "bias",
"arg": "bias",
"semantic": "bias",
"buffer": { "type": "read-only-storage" },
"elementType": "$scalar"
},
{ "name": "y", "arg": "Y", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$scalar" },
{
"name": "params",
"semantic": "kernel.params",
"buffer": { "type": "uniform" },
"struct": { "name": "Params", "fields": [{ "name": "count", "type": "u32", "value": "numel(shapes.X)" }] }
}
],
"scalar": [
{ "name": "x", "arg": "X", "semantic": "X", "buffer": { "type": "read-only-storage" }, "elementType": "$scalar" },
{ "name": "y", "arg": "Y", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$scalar" },
{
"name": "params",
"semantic": "kernel.params",
"buffer": { "type": "uniform" },
"struct": { "name": "Params", "fields": [{ "name": "count", "type": "u32", "value": "numel(shapes.X)" }] }
}
]
},
"variants": [
{
"id": "vec4_bias",
"priority": 30,
"when": ["baseOk", "biasOk", "vec4Ok"],
"constants": {
"vec4": true,
"vec4Tail": false,
"hasBias": true,
"vectorScalar": "\"vec4<\" ~ dtypes.T ~ \">\"",
"hidden": "dim(shapes.X, ranks.X - 1) if dim(shapes.X, ranks.X - 1) > 0 else 1"
},
"passes": [
{
"id": "main",
"name": "FastGelu.vec4Bias",
"shader": "elementwise-bias-gelu.wgsl.jinja",
"bindings": "vec4Bias",
"dispatch": { "threads": "numel(shapes.X) / 4", "workgroupSize": "workgroupSize" }
}
]
},
{
"id": "vec4_no_bias",
"priority": 25,
"when": ["baseOk", "noBiasOk", "vec4Ok"],
"constants": { "vec4": true, "vec4Tail": false, "hasBias": false, "vectorScalar": "\"vec4<\" ~ dtypes.T ~ \">\"" },
"passes": [
{
"id": "main",
"name": "FastGelu.vec4",
"shader": "elementwise-bias-gelu.wgsl.jinja",
"bindings": "vec4",
"dispatch": { "threads": "numel(shapes.X) / 4", "workgroupSize": "workgroupSize" }
}
]
},
{
"id": "vec4_tail_bias",
"priority": 20,
"when": ["baseOk", "biasOk", "numel(shapes.X) > 0"],
"constants": {
"vec4": false,
"vec4Tail": true,
"hasBias": true,
"hidden": "dim(shapes.X, ranks.X - 1) if dim(shapes.X, ranks.X - 1) > 0 else 1"
},
"passes": [
{
"id": "main",
"name": "FastGelu.vec4TailBias",
"shader": "elementwise-bias-gelu.wgsl.jinja",
"bindings": "scalarBias",
"dispatch": { "threads": "ceilDiv(numel(shapes.X), 4)", "workgroupSize": "workgroupSize" }
}
]
},
{
"id": "vec4_tail_no_bias",
"priority": 15,
"when": ["baseOk", "noBiasOk", "numel(shapes.X) > 0"],
"constants": { "vec4": false, "vec4Tail": true, "hasBias": false },
"passes": [
{
"id": "main",
"name": "FastGelu.vec4Tail",
"shader": "elementwise-bias-gelu.wgsl.jinja",
"bindings": "scalar",
"dispatch": { "threads": "ceilDiv(numel(shapes.X), 4)", "workgroupSize": "workgroupSize" }
}
]
},
{
"id": "scalar_bias",
"priority": 10,
"when": ["baseOk", "biasOk", "true"],
"constants": {
"vec4": false,
"vec4Tail": false,
"hasBias": true,
"hidden": "dim(shapes.X, ranks.X - 1) if dim(shapes.X, ranks.X - 1) > 0 else 1"
},
"passes": [
{
"id": "main",
"name": "FastGelu.scalarBias",
"shader": "elementwise-bias-gelu.wgsl.jinja",
"bindings": "scalarBias",
"dispatch": { "threads": "numel(shapes.X)", "workgroupSize": "workgroupSize" }
}
]
},
{
"id": "scalar_no_bias",
"priority": 0,
"when": ["baseOk", "noBiasOk", "true"],
"constants": { "vec4": false, "vec4Tail": false, "hasBias": false },
"passes": [
{
"id": "main",
"name": "FastGelu.scalar",
"shader": "elementwise-bias-gelu.wgsl.jinja",
"bindings": "scalar",
"dispatch": { "threads": "numel(shapes.X)", "workgroupSize": "workgroupSize" }
}
]
}
]
}