{ "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" } } ] } ] }