| { |
| "domain": "ai.onnx", |
| "name": "LayerNormalization", |
| "sinceVersion": 17, |
| "description": "Normalizes a tensor along a suffix of axes starting at `axis` by subtracting the mean and dividing by the square root of the variance plus `epsilon`, then scales and optionally shifts the result with learnable `Scale` and `B` tensors. The output `Y` has the same shape as `X`; optional outputs `Mean` and `InvStdDev` expose the per-normalization-group statistics computed during normalization.", |
| "inputs": [ |
| { "role": "X", "dtype": "T", "description": "Tensor to be normalized." }, |
| { "role": "Scale", "dtype": "T", "description": "Scale tensor applied after normalization." }, |
| { "role": "B", "dtype": "T", "optional": true, "description": "Optional bias tensor added after scaling." } |
| ], |
| "outputs": [ |
| { |
| "role": "Y", |
| "dtype": "T", |
| "rank": "ranks.X", |
| "description": "Normalized and scaled output tensor; same shape as X.", |
| "shape": "shapes.X" |
| }, |
| { |
| "role": "Mean", |
| "dtype": "float32", |
| "optional": true, |
| "description": "Per-normalization-group mean in the ONNX broadcastable keepdims shape: dimensions before `axis` are preserved and dimensions from `axis` onward are 1.", |
| "rank": "ranks.X" |
| }, |
| { |
| "role": "InvStdDev", |
| "dtype": "float32", |
| "optional": true, |
| "description": "Per-normalization-group reciprocal standard deviation `1 / sqrt(variance + epsilon)`, returned in the same ONNX broadcastable keepdims shape as `Mean`.", |
| "rank": "ranks.X" |
| } |
| ], |
| "attributes": { "axis": -1, "epsilon": 0.00001, "stash_type": 1 }, |
| "attributeDescriptions": { |
| "axis": "The first axis of the normalization range; all axes from `axis` to the last are normalized together. Negative values count from the end; the default `-1` normalizes only the last dimension.", |
| "epsilon": "Small constant added to the variance before taking the square root to avoid division by zero.", |
| "stash_type": "TensorProto element type used for the normalization stage and optional statistics; the implemented ONNX route supports the standard float32 value (`1`)." |
| }, |
| "attributeConstraints": { "stash_type": { "values": [1] } }, |
| "typeConstraints": { "T": ["float32", "float16"] }, |
| "args": { |
| "x": { "kind": "tensor", "semantic": "X", "role": "input" }, |
| "scale": { "kind": "tensor", "semantic": "Scale", "role": "input" }, |
| "b": { "kind": "tensor", "semantic": "B", "role": "input", "required": false }, |
| "y": { "kind": "tensor", "semantic": "Y", "role": "output" }, |
| "mean": { "kind": "tensor", "semantic": "Mean", "role": "output", "required": false }, |
| "invStdDev": { "kind": "tensor", "semantic": "InvStdDev", "role": "output", "required": false } |
| }, |
| "tunables": { "MAX_WORKGROUP_SIZE": 256, "SCALAR_FAST_MAX_HIDDEN": 1024 }, |
| "derive": { |
| "deviceWorkgroupCap": "min(device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX)", |
| "normWorkgroupCap": "min(tunables.MAX_WORKGROUP_SIZE, deviceWorkgroupCap)", |
| "hasSubgroupId": "device.features.has(\"subgroups\") and device.wgslLanguageFeatures.has(\"subgroup_id\")", |
| "lastAxisWg": "min(normWorkgroupCap, pow2ceil(dim(shapes.X, -1)))", |
| "lastAxisWgVec4": "min(normWorkgroupCap, pow2ceil(dim(shapes.X, -1) / 4))", |
| "lastAxisContractOk": "ranks.X >= 1 and ranks.Y == ranks.X and numel(shapes.X) == numel(shapes.Y) and (attrs.axis == -1 or attrs.axis == ranks.X - 1)", |
| "suffixAxisContractOk": "ranks.X >= 2 and ranks.Y == ranks.X and numel(shapes.X) == numel(shapes.Y) and attrs.axis + ranks.X >= 0 and attrs.axis < ranks.X and not (attrs.axis == -1 or attrs.axis == ranks.X - 1)", |
| "axisNorm": "attrs.axis if attrs.axis >= 0 else attrs.axis + ranks.X", |
| "normRows": "numel(shapes.X) / max(1, dim(shapes.X, -1)) if lastAxisContractOk else outer(shapes.X, axisNorm)", |
| "normRowStride": "max(1, min(normRows, device.limits.maxComputeWorkgroupsPerDimension))", |
| "suffixAxisSize": "numel(shapes.X) / max(1, outer(shapes.X, axisNorm))", |
| "suffixAxisWg": "min(normWorkgroupCap, pow2ceil(suffixAxisSize))", |
| "suffixAxisWgVec4": "min(normWorkgroupCap, pow2ceil(suffixAxisSize / 4))", |
| "genericHiddenSize": "dim(shapes.X, -1) if lastAxisContractOk else suffixAxisSize", |
| "genericWorkgroupSize": "lastAxisWg if lastAxisContractOk else suffixAxisWg", |
| "scaleExactOk": "ranks.X >= 1 and ranks.Scale >= 1 and numel(shapes.Scale) == dim(shapes.X, -1) and dim(shapes.Scale, -1) == dim(shapes.X, -1)", |
| "scaleBroadcastOk": "ranks.Scale >= 0 and ranks.Scale <= ranks.X and broadcastable(shapes.Scale, shapes.X)", |
| "biasExactOk": "present.b and ranks.X >= 1 and ranks.B >= 1 and numel(shapes.B) == dim(shapes.X, -1) and dim(shapes.B, -1) == dim(shapes.X, -1)", |
| "biasBroadcastOk": "present.b and ranks.B >= 0 and ranks.B <= ranks.X and broadcastable(shapes.B, shapes.X)", |
| "suffixScaleExactOk": "suffixAxisContractOk and scaleBroadcastOk and numel(shapes.Scale) == suffixAxisSize", |
| "suffixBiasExactOk": "present.b and suffixAxisContractOk and biasBroadcastOk and numel(shapes.B) == suffixAxisSize", |
| "lastAxisExactScaleOk": "lastAxisContractOk and scaleExactOk", |
| "lastAxisBroadcastScaleOk": "lastAxisContractOk and scaleBroadcastOk", |
| "suffixAxisBroadcastScaleOk": "suffixAxisContractOk and scaleBroadcastOk", |
| "suffixAxisExactAffineOk": "suffixAxisContractOk and suffixScaleExactOk and suffixBiasExactOk", |
| "lastAxisScalarFastOk": "dtypes.T == \"f16\" or dim(shapes.X, -1) <= tunables.SCALAR_FAST_MAX_HIDDEN", |
| "noStatsOutputs": "not present.mean and not present.invStdDev", |
| "meanOnlyOutputs": "present.mean and not present.invStdDev", |
| "invStdOnlyOutputs": "not present.mean and present.invStdDev", |
| "fullStatsOutputs": "present.mean and present.invStdDev", |
| "statsRowsOk": "fullStatsOutputs and ranks.X >= 1 and numel(shapes.Mean) == normRows and numel(shapes.InvStdDev) == normRows", |
| "meanRowsOk": "present.mean and ranks.X >= 1 and numel(shapes.Mean) == normRows", |
| "invStdRowsOk": "present.invStdDev and ranks.X >= 1 and numel(shapes.InvStdDev) == normRows", |
| "statsOuterOk": "fullStatsOutputs and ranks.X >= 2 and numel(shapes.Mean) == normRows and numel(shapes.InvStdDev) == normRows" |
| }, |
| "bindingSets": { |
| "vec4Affine": [ |
| { |
| "name": "x", |
| "arg": "x", |
| "semantic": "X", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "scale", |
| "arg": "scale", |
| "semantic": "Scale", |
| "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": "rows", "type": "u32", "value": "normRows" }, |
| { "name": "rowStride", "type": "u32", "value": "normRowStride" } |
| ] |
| } |
| } |
| ], |
| "vec4AffineBias": [ |
| { |
| "name": "x", |
| "arg": "x", |
| "semantic": "X", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "scale", |
| "arg": "scale", |
| "semantic": "Scale", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "bias", |
| "arg": "b", |
| "semantic": "B", |
| "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": "rows", "type": "u32", "value": "normRows" }, |
| { "name": "rowStride", "type": "u32", "value": "normRowStride" } |
| ] |
| } |
| } |
| ], |
| "vec4AffineStats": [ |
| { |
| "name": "x", |
| "arg": "x", |
| "semantic": "X", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "scale", |
| "arg": "scale", |
| "semantic": "Scale", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { "name": "y", "arg": "y", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$vectorScalar" }, |
| { "name": "mean_out", "arg": "mean", "semantic": "Mean", "buffer": { "type": "storage" }, "elementType": "f32" }, |
| { |
| "name": "inv_std_out", |
| "arg": "invStdDev", |
| "semantic": "InvStdDev", |
| "buffer": { "type": "storage" }, |
| "elementType": "f32" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "normRows" }, |
| { "name": "rowStride", "type": "u32", "value": "normRowStride" } |
| ] |
| } |
| } |
| ], |
| "vec4AffineBiasStats": [ |
| { |
| "name": "x", |
| "arg": "x", |
| "semantic": "X", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "scale", |
| "arg": "scale", |
| "semantic": "Scale", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "bias", |
| "arg": "b", |
| "semantic": "B", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { "name": "y", "arg": "y", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$vectorScalar" }, |
| { "name": "mean_out", "arg": "mean", "semantic": "Mean", "buffer": { "type": "storage" }, "elementType": "f32" }, |
| { |
| "name": "inv_std_out", |
| "arg": "invStdDev", |
| "semantic": "InvStdDev", |
| "buffer": { "type": "storage" }, |
| "elementType": "f32" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "normRows" }, |
| { "name": "rowStride", "type": "u32", "value": "normRowStride" } |
| ] |
| } |
| } |
| ], |
| "scalarAffineMean": [ |
| { "name": "x", "arg": "x", "semantic": "X", "buffer": { "type": "read-only-storage" }, "elementType": "$scalar" }, |
| { |
| "name": "scale", |
| "arg": "scale", |
| "semantic": "Scale", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { "name": "y", "arg": "y", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$scalar" }, |
| { "name": "mean_out", "arg": "mean", "semantic": "Mean", "buffer": { "type": "storage" }, "elementType": "f32" }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "normRows" }, |
| { "name": "rowStride", "type": "u32", "value": "normRowStride" } |
| ] |
| } |
| } |
| ], |
| "scalarAffineInvStd": [ |
| { "name": "x", "arg": "x", "semantic": "X", "buffer": { "type": "read-only-storage" }, "elementType": "$scalar" }, |
| { |
| "name": "scale", |
| "arg": "scale", |
| "semantic": "Scale", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { "name": "y", "arg": "y", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$scalar" }, |
| { |
| "name": "inv_std_out", |
| "arg": "invStdDev", |
| "semantic": "InvStdDev", |
| "buffer": { "type": "storage" }, |
| "elementType": "f32" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "normRows" }, |
| { "name": "rowStride", "type": "u32", "value": "normRowStride" } |
| ] |
| } |
| } |
| ], |
| "scalarAffineBiasMean": [ |
| { "name": "x", "arg": "x", "semantic": "X", "buffer": { "type": "read-only-storage" }, "elementType": "$scalar" }, |
| { |
| "name": "scale", |
| "arg": "scale", |
| "semantic": "Scale", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "bias", |
| "arg": "b", |
| "semantic": "B", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { "name": "y", "arg": "y", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$scalar" }, |
| { "name": "mean_out", "arg": "mean", "semantic": "Mean", "buffer": { "type": "storage" }, "elementType": "f32" }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "normRows" }, |
| { "name": "rowStride", "type": "u32", "value": "normRowStride" } |
| ] |
| } |
| } |
| ], |
| "scalarAffineBiasInvStd": [ |
| { "name": "x", "arg": "x", "semantic": "X", "buffer": { "type": "read-only-storage" }, "elementType": "$scalar" }, |
| { |
| "name": "scale", |
| "arg": "scale", |
| "semantic": "Scale", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "bias", |
| "arg": "b", |
| "semantic": "B", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { "name": "y", "arg": "y", "semantic": "Y", "buffer": { "type": "storage" }, "elementType": "$scalar" }, |
| { |
| "name": "inv_std_out", |
| "arg": "invStdDev", |
| "semantic": "InvStdDev", |
| "buffer": { "type": "storage" }, |
| "elementType": "f32" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "normRows" }, |
| { "name": "rowStride", "type": "u32", "value": "normRowStride" } |
| ] |
| } |
| } |
| ] |
| }, |
| "variants": [ |
| { |
| "id": "last_axis_row_vec4", |
| "priority": 110, |
| "when": ["f16Ok(dtypes.T)", "not present.b and noStatsOutputs", "lastAxisExactScaleOk", "dim(shapes.X, -1) % 4 == 0"], |
| "constants": { "scalar": "dtypes.T", "vectorScalar": "\"vec4<\" ~ dtypes.T ~ \">\"" }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.LastAxisRowVec4", |
| "source": { |
| "shader": "norm-row-stats.wgsl.jinja", |
| "inputs": { |
| "mode": "\"layer\"", |
| "vec4": true, |
| "hasBias": false, |
| "writeStats": false, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hidden": "dim(shapes.X, -1)", |
| "wg": "lastAxisWgVec4", |
| "epsilon": "attrs.epsilon", |
| "hiddenVec": "dim(shapes.X, -1) / 4", |
| "vecType": "\"vec4<\" ~ dtypes.T ~ \">\"", |
| "combineSubgroups": "hasSubgroupId" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4Affine", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "last_axis_row", |
| "priority": 100, |
| "when": ["not present.b and noStatsOutputs", "lastAxisExactScaleOk", "f16Ok(dtypes.T)"], |
| "demoteWhen": ["not lastAxisScalarFastOk"], |
| "constants": { "scalar": "dtypes.T", "vectorScalar": "dtypes.T" }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.LastAxisRow", |
| "source": { |
| "shader": "norm-row-stats.wgsl.jinja", |
| "inputs": { |
| "mode": "\"layer\"", |
| "vec4": false, |
| "hasBias": false, |
| "writeStats": false, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hidden": "dim(shapes.X, -1)", |
| "wg": "lastAxisWg", |
| "epsilon": "attrs.epsilon", |
| "combineSubgroups": "hasSubgroupId" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4Affine", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "last_axis_bias_row_vec4", |
| "priority": 111, |
| "when": ["f16Ok(dtypes.T)", "present.b and noStatsOutputs and biasExactOk", "lastAxisExactScaleOk", "dim(shapes.X, -1) % 4 == 0"], |
| "constants": { "scalar": "dtypes.T", "vectorScalar": "\"vec4<\" ~ dtypes.T ~ \">\"" }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.LastAxisRowVec4", |
| "source": { |
| "shader": "norm-row-stats.wgsl.jinja", |
| "inputs": { |
| "mode": "\"layer\"", |
| "vec4": true, |
| "hasBias": true, |
| "writeStats": false, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hidden": "dim(shapes.X, -1)", |
| "wg": "lastAxisWgVec4", |
| "epsilon": "attrs.epsilon", |
| "hiddenVec": "dim(shapes.X, -1) / 4", |
| "vecType": "\"vec4<\" ~ dtypes.T ~ \">\"", |
| "combineSubgroups": "hasSubgroupId" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4AffineBias", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "last_axis_bias_row", |
| "priority": 101, |
| "when": ["present.b and noStatsOutputs and biasExactOk", "lastAxisExactScaleOk", "f16Ok(dtypes.T)"], |
| "demoteWhen": ["not lastAxisScalarFastOk"], |
| "constants": { "scalar": "dtypes.T", "vectorScalar": "dtypes.T" }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.LastAxisRow", |
| "source": { |
| "shader": "norm-row-stats.wgsl.jinja", |
| "inputs": { |
| "mode": "\"layer\"", |
| "vec4": false, |
| "hasBias": true, |
| "writeStats": false, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hidden": "dim(shapes.X, -1)", |
| "wg": "lastAxisWg", |
| "epsilon": "attrs.epsilon", |
| "combineSubgroups": "hasSubgroupId" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4AffineBias", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "last_axis_stats_row_vec4", |
| "priority": 112, |
| "when": ["f16Ok(dtypes.T)", "not present.b and fullStatsOutputs and statsRowsOk", "lastAxisExactScaleOk", "dim(shapes.X, -1) % 4 == 0"], |
| "constants": { "scalar": "dtypes.T", "vectorScalar": "\"vec4<\" ~ dtypes.T ~ \">\"" }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.LastAxisRowVec4", |
| "source": { |
| "shader": "norm-row-stats.wgsl.jinja", |
| "inputs": { |
| "mode": "\"layer\"", |
| "vec4": true, |
| "hasBias": false, |
| "writeStats": true, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hidden": "dim(shapes.X, -1)", |
| "wg": "lastAxisWgVec4", |
| "epsilon": "attrs.epsilon", |
| "hiddenVec": "dim(shapes.X, -1) / 4", |
| "vecType": "\"vec4<\" ~ dtypes.T ~ \">\"", |
| "combineSubgroups": "hasSubgroupId" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4AffineStats", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "last_axis_stats_row", |
| "priority": 102, |
| "when": ["not present.b and fullStatsOutputs and statsRowsOk", "lastAxisExactScaleOk", "f16Ok(dtypes.T)"], |
| "demoteWhen": ["not lastAxisScalarFastOk"], |
| "constants": { "scalar": "dtypes.T", "vectorScalar": "dtypes.T" }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.LastAxisRow", |
| "source": { |
| "shader": "norm-row-stats.wgsl.jinja", |
| "inputs": { |
| "mode": "\"layer\"", |
| "vec4": false, |
| "hasBias": false, |
| "writeStats": true, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hidden": "dim(shapes.X, -1)", |
| "wg": "lastAxisWg", |
| "epsilon": "attrs.epsilon", |
| "combineSubgroups": "hasSubgroupId" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4AffineStats", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "last_axis_bias_stats_row_vec4", |
| "priority": 113, |
| "when": ["f16Ok(dtypes.T)", "present.b and fullStatsOutputs and biasExactOk and statsRowsOk", "lastAxisExactScaleOk", "dim(shapes.X, -1) % 4 == 0"], |
| "constants": { "scalar": "dtypes.T", "vectorScalar": "\"vec4<\" ~ dtypes.T ~ \">\"" }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.LastAxisRowVec4", |
| "source": { |
| "shader": "norm-row-stats.wgsl.jinja", |
| "inputs": { |
| "mode": "\"layer\"", |
| "vec4": true, |
| "hasBias": true, |
| "writeStats": true, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hidden": "dim(shapes.X, -1)", |
| "wg": "lastAxisWgVec4", |
| "epsilon": "attrs.epsilon", |
| "hiddenVec": "dim(shapes.X, -1) / 4", |
| "vecType": "\"vec4<\" ~ dtypes.T ~ \">\"", |
| "combineSubgroups": "hasSubgroupId" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4AffineBiasStats", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "last_axis_bias_stats_row", |
| "priority": 103, |
| "when": ["present.b and fullStatsOutputs and biasExactOk and statsRowsOk", "lastAxisExactScaleOk", "f16Ok(dtypes.T)"], |
| "demoteWhen": ["not lastAxisScalarFastOk"], |
| "constants": { "scalar": "dtypes.T", "vectorScalar": "dtypes.T" }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.LastAxisRow", |
| "source": { |
| "shader": "norm-row-stats.wgsl.jinja", |
| "inputs": { |
| "mode": "\"layer\"", |
| "vec4": false, |
| "hasBias": true, |
| "writeStats": true, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hidden": "dim(shapes.X, -1)", |
| "wg": "lastAxisWg", |
| "epsilon": "attrs.epsilon", |
| "combineSubgroups": "hasSubgroupId" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4AffineBiasStats", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "suffix_axis_bias_exact_row_vec4", |
| "priority": 121, |
| "when": ["f16Ok(dtypes.T)", "present.b", "noStatsOutputs", "suffixAxisExactAffineOk", "suffixAxisSize % 4 == 0"], |
| "constants": { "scalar": "dtypes.T", "vectorScalar": "\"vec4<\" ~ dtypes.T ~ \">\"" }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.SuffixAxisRowVec4", |
| "source": { |
| "shader": "norm-row-stats.wgsl.jinja", |
| "inputs": { |
| "mode": "\"layer\"", |
| "vec4": true, |
| "hasBias": true, |
| "writeStats": false, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hidden": "suffixAxisSize", |
| "wg": "suffixAxisWgVec4", |
| "epsilon": "attrs.epsilon", |
| "hiddenVec": "suffixAxisSize / 4", |
| "vecType": "\"vec4<\" ~ dtypes.T ~ \">\"", |
| "combineSubgroups": "hasSubgroupId" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4AffineBias", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "last_axis", |
| "priority": 0, |
| "when": ["not present.b", "noStatsOutputs", "lastAxisBroadcastScaleOk", "f16Ok(dtypes.T)"], |
| "constants": { |
| "hasBias": false, |
| "writeMean": false, |
| "writeInvStdDev": false, |
| "scalar": "dtypes.T", |
| "vectorScalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hiddenSize": "dim(shapes.X, -1)", |
| "workgroupSize": "lastAxisWg", |
| "epsilon": "attrs.epsilon" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization", |
| "source": { |
| "shader": "layer-normalization.wgsl.jinja", |
| "inputs": { "xShape": "shapes.X", "scaleShape": "shapes.Scale" } |
| }, |
| "bindings": "vec4Affine", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "last_axis_bias", |
| "priority": 10, |
| "when": ["present.b", "noStatsOutputs", "lastAxisBroadcastScaleOk", "biasBroadcastOk", "f16Ok(dtypes.T)"], |
| "constants": { |
| "hasBias": true, |
| "writeMean": false, |
| "writeInvStdDev": false, |
| "scalar": "dtypes.T", |
| "vectorScalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hiddenSize": "dim(shapes.X, -1)", |
| "workgroupSize": "lastAxisWg", |
| "epsilon": "attrs.epsilon" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization", |
| "source": { |
| "shader": "layer-normalization.wgsl.jinja", |
| "inputs": { "xShape": "shapes.X", "scaleShape": "shapes.Scale", "biasShape": "shapes.B" } |
| }, |
| "bindings": "vec4AffineBias", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "last_axis_stats", |
| "priority": 20, |
| "when": ["not present.b", "fullStatsOutputs", "lastAxisBroadcastScaleOk", "statsRowsOk", "f16Ok(dtypes.T)"], |
| "constants": { |
| "hasBias": false, |
| "writeMean": true, |
| "writeInvStdDev": true, |
| "scalar": "dtypes.T", |
| "vectorScalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hiddenSize": "dim(shapes.X, -1)", |
| "workgroupSize": "lastAxisWg", |
| "epsilon": "attrs.epsilon" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization", |
| "source": { |
| "shader": "layer-normalization.wgsl.jinja", |
| "inputs": { "xShape": "shapes.X", "scaleShape": "shapes.Scale" } |
| }, |
| "bindings": "vec4AffineStats", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "last_axis_bias_stats", |
| "priority": 30, |
| "when": ["present.b", "fullStatsOutputs", "lastAxisBroadcastScaleOk", "biasBroadcastOk", "statsRowsOk", "f16Ok(dtypes.T)"], |
| "constants": { |
| "hasBias": true, |
| "writeMean": true, |
| "writeInvStdDev": true, |
| "scalar": "dtypes.T", |
| "vectorScalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hiddenSize": "dim(shapes.X, -1)", |
| "workgroupSize": "lastAxisWg", |
| "epsilon": "attrs.epsilon" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization", |
| "source": { |
| "shader": "layer-normalization.wgsl.jinja", |
| "inputs": { "xShape": "shapes.X", "scaleShape": "shapes.Scale", "biasShape": "shapes.B" } |
| }, |
| "bindings": "vec4AffineBiasStats", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "suffix_axis", |
| "priority": 40, |
| "when": ["not present.b", "noStatsOutputs", "suffixAxisBroadcastScaleOk", "f16Ok(dtypes.T)"], |
| "constants": { |
| "hasBias": false, |
| "writeMean": false, |
| "writeInvStdDev": false, |
| "scalar": "dtypes.T", |
| "vectorScalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hiddenSize": "suffixAxisSize", |
| "workgroupSize": "suffixAxisWg", |
| "epsilon": "attrs.epsilon" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.SuffixAxis", |
| "source": { |
| "shader": "layer-normalization.wgsl.jinja", |
| "inputs": { "xShape": "shapes.X", "scaleShape": "shapes.Scale" } |
| }, |
| "bindings": "vec4Affine", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "suffix_axis_bias", |
| "priority": 50, |
| "when": ["present.b", "noStatsOutputs", "suffixAxisBroadcastScaleOk", "biasBroadcastOk", "f16Ok(dtypes.T)"], |
| "constants": { |
| "hasBias": true, |
| "writeMean": false, |
| "writeInvStdDev": false, |
| "scalar": "dtypes.T", |
| "vectorScalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hiddenSize": "suffixAxisSize", |
| "workgroupSize": "suffixAxisWg", |
| "epsilon": "attrs.epsilon" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.SuffixAxisBias", |
| "source": { |
| "shader": "layer-normalization.wgsl.jinja", |
| "inputs": { "xShape": "shapes.X", "scaleShape": "shapes.Scale", "biasShape": "shapes.B" } |
| }, |
| "bindings": "vec4AffineBias", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "suffix_axis_stats", |
| "priority": 45, |
| "when": ["not present.b", "fullStatsOutputs", "suffixAxisBroadcastScaleOk", "statsOuterOk", "f16Ok(dtypes.T)"], |
| "constants": { |
| "hasBias": false, |
| "writeMean": true, |
| "writeInvStdDev": true, |
| "scalar": "dtypes.T", |
| "vectorScalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hiddenSize": "suffixAxisSize", |
| "workgroupSize": "suffixAxisWg", |
| "epsilon": "attrs.epsilon" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.SuffixAxisStats", |
| "source": { |
| "shader": "layer-normalization.wgsl.jinja", |
| "inputs": { "xShape": "shapes.X", "scaleShape": "shapes.Scale" } |
| }, |
| "bindings": "vec4AffineStats", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "suffix_axis_bias_stats", |
| "priority": 55, |
| "when": ["present.b", "fullStatsOutputs", "suffixAxisBroadcastScaleOk", "biasBroadcastOk", "statsOuterOk", "f16Ok(dtypes.T)"], |
| "constants": { |
| "hasBias": true, |
| "writeMean": true, |
| "writeInvStdDev": true, |
| "scalar": "dtypes.T", |
| "vectorScalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hiddenSize": "suffixAxisSize", |
| "workgroupSize": "suffixAxisWg", |
| "epsilon": "attrs.epsilon" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.SuffixAxisBiasStats", |
| "source": { |
| "shader": "layer-normalization.wgsl.jinja", |
| "inputs": { "xShape": "shapes.X", "scaleShape": "shapes.Scale", "biasShape": "shapes.B" } |
| }, |
| "bindings": "vec4AffineBiasStats", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "mean_only", |
| "priority": 31, |
| "when": ["not present.b and meanOnlyOutputs and meanRowsOk", "lastAxisBroadcastScaleOk or suffixAxisBroadcastScaleOk", "f16Ok(dtypes.T)"], |
| "constants": { |
| "hasBias": false, |
| "writeMean": true, |
| "writeInvStdDev": false, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hiddenSize": "genericHiddenSize", |
| "workgroupSize": "genericWorkgroupSize", |
| "epsilon": "attrs.epsilon" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.MeanOnly", |
| "source": { |
| "shader": "layer-normalization.wgsl.jinja", |
| "inputs": { "xShape": "shapes.X", "scaleShape": "shapes.Scale" } |
| }, |
| "bindings": "scalarAffineMean", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "bias_mean_only", |
| "priority": 32, |
| "when": ["present.b and meanOnlyOutputs and biasBroadcastOk and meanRowsOk", "lastAxisBroadcastScaleOk or suffixAxisBroadcastScaleOk", "f16Ok(dtypes.T)"], |
| "constants": { |
| "hasBias": true, |
| "writeMean": true, |
| "writeInvStdDev": false, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hiddenSize": "genericHiddenSize", |
| "workgroupSize": "genericWorkgroupSize", |
| "epsilon": "attrs.epsilon" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.BiasMeanOnly", |
| "source": { |
| "shader": "layer-normalization.wgsl.jinja", |
| "inputs": { "xShape": "shapes.X", "scaleShape": "shapes.Scale", "biasShape": "shapes.B" } |
| }, |
| "bindings": "scalarAffineBiasMean", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "inv_std_dev_only", |
| "priority": 33, |
| "when": ["not present.b and invStdOnlyOutputs and invStdRowsOk", "lastAxisBroadcastScaleOk or suffixAxisBroadcastScaleOk", "f16Ok(dtypes.T)"], |
| "constants": { |
| "hasBias": false, |
| "writeMean": false, |
| "writeInvStdDev": true, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hiddenSize": "genericHiddenSize", |
| "workgroupSize": "genericWorkgroupSize", |
| "epsilon": "attrs.epsilon" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.InvStdDevOnly", |
| "source": { |
| "shader": "layer-normalization.wgsl.jinja", |
| "inputs": { "xShape": "shapes.X", "scaleShape": "shapes.Scale" } |
| }, |
| "bindings": "scalarAffineInvStd", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| }, |
| { |
| "id": "bias_inv_std_dev_only", |
| "priority": 34, |
| "when": ["present.b and invStdOnlyOutputs and biasBroadcastOk and invStdRowsOk", "lastAxisBroadcastScaleOk or suffixAxisBroadcastScaleOk", "f16Ok(dtypes.T)"], |
| "constants": { |
| "hasBias": true, |
| "writeMean": false, |
| "writeInvStdDev": true, |
| "scalar": "dtypes.T", |
| "usesF16": "dtypes.T == \"f16\"", |
| "hiddenSize": "genericHiddenSize", |
| "workgroupSize": "genericWorkgroupSize", |
| "epsilon": "attrs.epsilon" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "LayerNormalization.BiasInvStdDevOnly", |
| "source": { |
| "shader": "layer-normalization.wgsl.jinja", |
| "inputs": { "xShape": "shapes.X", "scaleShape": "shapes.Scale", "biasShape": "shapes.B" } |
| }, |
| "bindings": "scalarAffineBiasInvStd", |
| "dispatch": { "workgroups": "normRows" } |
| } |
| ] |
| } |
| ] |
| } |
|
|