| { |
| "domain": "com.microsoft", |
| "name": "SkipLayerNormalization", |
| "sinceVersion": 1, |
| "description": "Fuses skip addition with layer normalization. The rank-3 standard surface currently supports float32, required `beta`, no `bias` or residual output, hidden sizes divisible by four, and exact or documented broadcast skip shapes. The provider's rank-2 extension supports float32 output-only with optional `beta`, or `beta` with optional `bias` when emitting the residual; its float16 path requires `beta`, `bias`, a residual output, and four-wide hidden size. Other combinations, bfloat16, and training statistics are not implemented.", |
| "inputs": [ |
| { |
| "role": "input", |
| "dtype": "T", |
| "description": "Primary input normalized over the final hidden-size axis. Rank 3 is the public shape; rank 2 is an ONNX Runtime provider extension supported by this package." |
| }, |
| { |
| "role": "skip", |
| "dtype": "T", |
| "description": "Residual tensor. For rank-3 input it is exact shape, `(1, sequence_length, hidden_size)`, or `(sequence_length, hidden_size)`; rank-2 input requires exact shape." |
| }, |
| { "role": "gamma", "dtype": "T", "rank": 1, "description": "Layer-norm scale weights of shape `(hidden_size)`." }, |
| { |
| "role": "beta", |
| "dtype": "T", |
| "rank": 1, |
| "optional": true, |
| "description": "Layer-norm bias weights of shape `(hidden_size)`." |
| }, |
| { |
| "role": "bias", |
| "dtype": "T", |
| "rank": 1, |
| "optional": true, |
| "description": "Optional additive bias of shape `(hidden_size)` added to `input + skip` before normalization." |
| } |
| ], |
| "outputs": [ |
| { |
| "role": "output", |
| "dtype": "T", |
| "rank": "ranks.inputT", |
| "shape": "shapes.inputT", |
| "description": "Normalized output tensor with the same shape as `input`." |
| }, |
| { |
| "role": "input_skip_bias_sum", |
| "dtype": "T", |
| "rank": "ranks.inputT", |
| "optional": true, |
| "shape": "shapes.inputT", |
| "description": "Sum of `input`, `skip`, and `bias` (when present) before normalization, with the same shape as `input`." |
| } |
| ], |
| "attributes": { "epsilon": 9.999999960041972e-13 }, |
| "attributeDescriptions": { "epsilon": "Non-negative epsilon added to the variance before taking the square root." }, |
| "args": { |
| "inputT": { "kind": "tensor", "semantic": "input", "role": "input" }, |
| "skipT": { "kind": "tensor", "semantic": "skip", "role": "input" }, |
| "gammaT": { "kind": "tensor", "semantic": "gamma", "role": "input" }, |
| "betaT": { "kind": "tensor", "semantic": "beta", "role": "input", "required": false }, |
| "biasT": { "kind": "tensor", "semantic": "bias", "role": "input", "required": false }, |
| "outputT": { "kind": "tensor", "semantic": "output", "role": "output" }, |
| "residualT": { "kind": "tensor", "semantic": "input_skip_bias_sum", "role": "output", "required": false } |
| }, |
| "typeConstraints": { "T": ["float32", "float16"] }, |
| "derive": { |
| "rowCount": "dim(shapes.inputT, 0)", |
| "hiddenSize": "dim(shapes.inputT, 1)", |
| "skipWg": "max(1, min(tunables.MAX_WORKGROUP_SIZE, device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX, pow2ceil(hiddenSize)))", |
| "skipWgVec4": "max(1, min(tunables.MAX_WORKGROUP_SIZE, device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX, pow2ceil(ceilDiv(hiddenSize, 4))))", |
| "portableWideExecution": "not has(device.adapterInfo, \"subgroupMinSize\") or device.adapterInfo.subgroupMinSize >= 32", |
| "broadcastRows": "dim(shapes.inputT, 0) * dim(shapes.inputT, 1)", |
| "broadcastHiddenSize": "dim(shapes.inputT, 2)", |
| "broadcastSkipWgVec4": "max(1, min(tunables.MAX_WORKGROUP_SIZE, device.limits.maxComputeInvocationsPerWorkgroup, device.limits.maxComputeWorkgroupSizeX, pow2ceil(ceilDiv(broadcastHiddenSize, 4))))", |
| "rowDispatchFits": "rowCount <= device.limits.maxComputeWorkgroupsPerDimension * device.limits.maxComputeWorkgroupsPerDimension", |
| "broadcastDispatchFits": "broadcastRows <= device.limits.maxComputeWorkgroupsPerDimension * device.limits.maxComputeWorkgroupsPerDimension", |
| "normResourcesFit": "skipWg * 8 <= device.limits.maxComputeWorkgroupStorageSize and skipWgVec4 * 8 <= device.limits.maxComputeWorkgroupStorageSize", |
| "broadcastResourcesFit": "broadcastSkipWgVec4 * 8 <= device.limits.maxComputeWorkgroupStorageSize", |
| "epsilonOk": "attrs.epsilon >= 0", |
| "rank2CoreContract": "epsilonOk and ranks.inputT == 2 and ranks.skipT == 2 and ranks.gammaT == 1 and ranks.outputT == 2 and dim(shapes.inputT, 0) == dim(shapes.skipT, 0) and dim(shapes.inputT, 1) == dim(shapes.skipT, 1) and dim(shapes.inputT, 1) > 0 and dim(shapes.gammaT, 0) == dim(shapes.inputT, 1) and dim(shapes.outputT, 0) == dim(shapes.inputT, 0) and dim(shapes.outputT, 1) == dim(shapes.inputT, 1)", |
| "residualOutputContract": "present.residualT and ranks.residualT == 2 and dim(shapes.residualT, 0) == dim(shapes.inputT, 0) and dim(shapes.residualT, 1) == dim(shapes.inputT, 1)", |
| "outputOnlyContract": "not present.residualT", |
| "betaContract": "false if not present.betaT else (ranks.betaT == 1 and dim(shapes.betaT, 0) == dim(shapes.inputT, 1))", |
| "noBetaContract": "not present.betaT", |
| "f32MainDtypes": "tensorDtypes.inputT == \"float32\" and tensorDtypes.skipT == \"float32\" and tensorDtypes.gammaT == \"float32\" and tensorDtypes.outputT == \"float32\"", |
| "f16MainDtypes": "tensorDtypes.inputT == \"float16\" and tensorDtypes.skipT == \"float16\" and tensorDtypes.gammaT == \"float16\" and tensorDtypes.outputT == \"float16\"", |
| "f32ResidualDtypes": "f32MainDtypes and tensorDtypes.residualT == \"float32\" if present.residualT else false", |
| "f16ResidualDtypes": "f16MainDtypes and tensorDtypes.residualT == \"float16\" if present.residualT else false", |
| "vec4Aligned": "dim(shapes.inputT, 1) % 4 == 0", |
| "broadcastSkipShapeOk": "(ranks.skipT == 2 and dim(shapes.skipT, 0) == dim(shapes.inputT, 1) and dim(shapes.skipT, 1) == dim(shapes.inputT, 2)) or (ranks.skipT == 3 and ((dim(shapes.skipT, 0) == 1 and dim(shapes.skipT, 1) == dim(shapes.inputT, 1) and dim(shapes.skipT, 2) == dim(shapes.inputT, 2)) or sameShape(shapes.skipT, shapes.inputT)))", |
| "broadcastOutputOnlyContract": "false if ranks.inputT != 3 or not present.betaT else (epsilonOk and not present.biasT and not present.residualT and dim(shapes.inputT, 2) % 4 == 0 and broadcastSkipShapeOk and ranks.gammaT == 1 and ranks.betaT == 1 and ranks.outputT == 3 and tensorDtypes.inputT == \"float32\" and tensorDtypes.skipT == \"float32\" and tensorDtypes.gammaT == \"float32\" and tensorDtypes.betaT == \"float32\" and tensorDtypes.outputT == \"float32\" and dim(shapes.inputT, 2) > 0 and dim(shapes.gammaT, 0) == dim(shapes.inputT, 2) and dim(shapes.betaT, 0) == dim(shapes.inputT, 2) and sameShape(shapes.outputT, shapes.inputT))", |
| "hasSubgroups": "device.features.has(\"subgroups\") and device.wgslLanguageFeatures.has(\"subgroup_id\")", |
| "hasF16": "device.features.has(\"shader-f16\")", |
| "f32_beta_no_bias_residual_contract": "rank2CoreContract and residualOutputContract and betaContract and f32ResidualDtypes and not present.biasT and tensorDtypes.betaT == \"float32\"", |
| "f32_beta_bias_residual_contract": "false if not present.biasT else (rank2CoreContract and residualOutputContract and betaContract and f32ResidualDtypes and ranks.biasT == 1 and tensorDtypes.betaT == \"float32\" and tensorDtypes.biasT == \"float32\" and dim(shapes.biasT, 0) == hiddenSize)", |
| "f16_beta_bias_residual_contract": "false if not present.biasT else (hasF16 and rank2CoreContract and residualOutputContract and betaContract and f16ResidualDtypes and ranks.biasT == 1 and tensorDtypes.betaT == \"float16\" and tensorDtypes.biasT == \"float16\" and dim(shapes.biasT, 0) == hiddenSize)", |
| "f32_no_beta_output_contract": "rank2CoreContract and outputOnlyContract and noBetaContract and f32MainDtypes and not present.biasT", |
| "f32_beta_no_bias_output_only_contract": "rank2CoreContract and outputOnlyContract and betaContract and f32MainDtypes and not present.biasT and tensorDtypes.betaT == \"float32\"", |
| "f32_beta_bias_output_only_contract": "false if not present.biasT else (rank2CoreContract and outputOnlyContract and betaContract and f32MainDtypes and ranks.biasT == 1 and tensorDtypes.betaT == \"float32\" and tensorDtypes.biasT == \"float32\" and dim(shapes.biasT, 0) == hiddenSize)" |
| }, |
| "bindingSets": { |
| "scalar_no_bias_residual": [ |
| { |
| "name": "input", |
| "arg": "inputT", |
| "semantic": "input", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "skip", |
| "arg": "skipT", |
| "semantic": "skip", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "gamma", |
| "arg": "gammaT", |
| "semantic": "gamma", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "beta", |
| "arg": "betaT", |
| "semantic": "beta", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "output", |
| "arg": "outputT", |
| "semantic": "output", |
| "buffer": { "type": "storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "input_skip_bias_sum", |
| "arg": "residualT", |
| "semantic": "input_skip_bias_sum", |
| "buffer": { "type": "storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "rowCount" }, |
| { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" } |
| ] |
| } |
| } |
| ], |
| "scalar_bias_output_residual": [ |
| { |
| "name": "input", |
| "arg": "inputT", |
| "semantic": "input", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "skip", |
| "arg": "skipT", |
| "semantic": "skip", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "bias", |
| "arg": "biasT", |
| "semantic": "bias", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "gamma", |
| "arg": "gammaT", |
| "semantic": "gamma", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "beta", |
| "arg": "betaT", |
| "semantic": "beta", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "output", |
| "arg": "outputT", |
| "semantic": "output", |
| "buffer": { "type": "storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "input_skip_bias_sum", |
| "arg": "residualT", |
| "semantic": "input_skip_bias_sum", |
| "buffer": { "type": "storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "rowCount" }, |
| { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" } |
| ] |
| } |
| } |
| ], |
| "vec4_bias_output_residual": [ |
| { |
| "name": "input", |
| "arg": "inputT", |
| "semantic": "input", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "skip", |
| "arg": "skipT", |
| "semantic": "skip", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "bias", |
| "arg": "biasT", |
| "semantic": "bias", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "gamma", |
| "arg": "gammaT", |
| "semantic": "gamma", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "beta", |
| "arg": "betaT", |
| "semantic": "beta", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "output", |
| "arg": "outputT", |
| "semantic": "output", |
| "buffer": { "type": "storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "input_skip_bias_sum", |
| "arg": "residualT", |
| "semantic": "input_skip_bias_sum", |
| "buffer": { "type": "storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "rowCount" }, |
| { |
| "name": "rowStride", |
| "type": "u32", |
| "value": "max(1, min(rowCount, device.limits.maxComputeWorkgroupsPerDimension))" |
| }, |
| { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" } |
| ] |
| } |
| } |
| ], |
| "scalar_no_bias_output_only": [ |
| { |
| "name": "input", |
| "arg": "inputT", |
| "semantic": "input", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "skip", |
| "arg": "skipT", |
| "semantic": "skip", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "gamma", |
| "arg": "gammaT", |
| "semantic": "gamma", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "beta", |
| "arg": "betaT", |
| "semantic": "beta", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "output", |
| "arg": "outputT", |
| "semantic": "output", |
| "buffer": { "type": "storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "rowCount" }, |
| { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" } |
| ] |
| } |
| } |
| ], |
| "scalar_bias_output_only": [ |
| { |
| "name": "input", |
| "arg": "inputT", |
| "semantic": "input", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "skip", |
| "arg": "skipT", |
| "semantic": "skip", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "bias", |
| "arg": "biasT", |
| "semantic": "bias", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "gamma", |
| "arg": "gammaT", |
| "semantic": "gamma", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "beta", |
| "arg": "betaT", |
| "semantic": "beta", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "output", |
| "arg": "outputT", |
| "semantic": "output", |
| "buffer": { "type": "storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "rowCount" }, |
| { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" } |
| ] |
| } |
| } |
| ], |
| "scalar_no_beta_output_only": [ |
| { |
| "name": "input", |
| "arg": "inputT", |
| "semantic": "input", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "skip", |
| "arg": "skipT", |
| "semantic": "skip", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "gamma", |
| "arg": "gammaT", |
| "semantic": "gamma", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$scalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "output", |
| "arg": "outputT", |
| "semantic": "output", |
| "buffer": { "type": "storage" }, |
| "elementType": "$scalar" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "rowCount" }, |
| { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" } |
| ] |
| } |
| } |
| ], |
| "vec4_no_bias_residual": [ |
| { |
| "name": "input", |
| "arg": "inputT", |
| "semantic": "input", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "skip", |
| "arg": "skipT", |
| "semantic": "skip", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "gamma", |
| "arg": "gammaT", |
| "semantic": "gamma", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "beta", |
| "arg": "betaT", |
| "semantic": "beta", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "output", |
| "arg": "outputT", |
| "semantic": "output", |
| "buffer": { "type": "storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "input_skip_bias_sum", |
| "arg": "residualT", |
| "semantic": "input_skip_bias_sum", |
| "buffer": { "type": "storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "rowCount" }, |
| { |
| "name": "rowStride", |
| "type": "u32", |
| "value": "max(1, min(rowCount, device.limits.maxComputeWorkgroupsPerDimension))" |
| }, |
| { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" } |
| ] |
| } |
| } |
| ], |
| "vec4_no_bias_output_only": [ |
| { |
| "name": "input", |
| "arg": "inputT", |
| "semantic": "input", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "skip", |
| "arg": "skipT", |
| "semantic": "skip", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "gamma", |
| "arg": "gammaT", |
| "semantic": "gamma", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "beta", |
| "arg": "betaT", |
| "semantic": "beta", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "output", |
| "arg": "outputT", |
| "semantic": "output", |
| "buffer": { "type": "storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "rowCount" }, |
| { |
| "name": "rowStride", |
| "type": "u32", |
| "value": "max(1, min(rowCount, device.limits.maxComputeWorkgroupsPerDimension))" |
| }, |
| { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" } |
| ] |
| } |
| } |
| ], |
| "vec4_bias_output_only": [ |
| { |
| "name": "input", |
| "arg": "inputT", |
| "semantic": "input", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "skip", |
| "arg": "skipT", |
| "semantic": "skip", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "gamma", |
| "arg": "gammaT", |
| "semantic": "gamma", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "beta", |
| "arg": "betaT", |
| "semantic": "beta", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "bias", |
| "arg": "biasT", |
| "semantic": "bias", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "output", |
| "arg": "outputT", |
| "semantic": "output", |
| "buffer": { "type": "storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "rowCount" }, |
| { |
| "name": "rowStride", |
| "type": "u32", |
| "value": "max(1, min(rowCount, device.limits.maxComputeWorkgroupsPerDimension))" |
| }, |
| { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" } |
| ] |
| } |
| } |
| ], |
| "vec4_no_beta_output_only": [ |
| { |
| "name": "input", |
| "arg": "inputT", |
| "semantic": "input", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "skip", |
| "arg": "skipT", |
| "semantic": "skip", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "gamma", |
| "arg": "gammaT", |
| "semantic": "gamma", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "output", |
| "arg": "outputT", |
| "semantic": "output", |
| "buffer": { "type": "storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "rowCount" }, |
| { |
| "name": "rowStride", |
| "type": "u32", |
| "value": "max(1, min(rowCount, device.limits.maxComputeWorkgroupsPerDimension))" |
| }, |
| { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" } |
| ] |
| } |
| } |
| ], |
| "vec4_beta_broadcast_output_only": [ |
| { |
| "name": "input", |
| "arg": "inputT", |
| "semantic": "input", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "skip", |
| "arg": "skipT", |
| "semantic": "skip", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "gamma", |
| "arg": "gammaT", |
| "semantic": "gamma", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "beta", |
| "arg": "betaT", |
| "semantic": "beta", |
| "buffer": { "type": "read-only-storage" }, |
| "elementType": "$vectorScalar", |
| "length": "$HIDDEN_LEN" |
| }, |
| { |
| "name": "output", |
| "arg": "outputT", |
| "semantic": "output", |
| "buffer": { "type": "storage" }, |
| "elementType": "$vectorScalar" |
| }, |
| { |
| "name": "params", |
| "semantic": "kernel.params", |
| "buffer": { "type": "uniform" }, |
| "struct": { |
| "name": "Params", |
| "fields": [ |
| { "name": "rows", "type": "u32", "value": "dim(shapes.inputT, 0) * dim(shapes.inputT, 1)" }, |
| { |
| "name": "rowStride", |
| "type": "u32", |
| "value": "max(1, min(broadcastRows, device.limits.maxComputeWorkgroupsPerDimension))" |
| }, |
| { "name": "epsilon", "type": "f32", "value": "attrs.epsilon" }, |
| { "name": "skipRows", "type": "u32", "value": "numel(shapes.skipT) / broadcastHiddenSize" } |
| ] |
| } |
| } |
| ] |
| }, |
| "variants": [ |
| { |
| "id": "beta_output_only_vec4_broadcast", |
| "priority": 19, |
| "when": ["broadcastOutputOnlyContract", "broadcastResourcesFit", "broadcastDispatchFits"], |
| "constants": { "scalar": "\"f32\"", "vectorScalar": "\"vec4<f32>\"", "HIDDEN_LEN": "broadcastHiddenSize / 4" }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "SkipLayerNormalization.BroadcastSkip", |
| "source": { |
| "shader": "norm-skip-row-vec4.wgsl.jinja", |
| "inputs": { |
| "simplified": false, |
| "hasBias": false, |
| "hasBeta": true, |
| "writeResidualSum": false, |
| "usesF16": false, |
| "broadcastSkip": true, |
| "hidden": "broadcastHiddenSize", |
| "hiddenVec": "broadcastHiddenSize / 4", |
| "wg": "broadcastSkipWgVec4", |
| "vecType": "\"vec4<f32>\"", |
| "useSubgroups": "hasSubgroups" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4_beta_broadcast_output_only", |
| "dispatch": { "workgroups": "broadcastRows" } |
| } |
| ] |
| }, |
| { |
| "id": "beta_bias_vec4", |
| "priority": 15, |
| "when": ["f32_beta_bias_residual_contract", "vec4Aligned", "hasSubgroups or \"bias\" == \"bias\" or portableWideExecution", "normResourcesFit", "rowDispatchFits"], |
| "constants": { |
| "scalar": "\"f32\"", |
| "vectorScalar": "\"vec4<f32>\"", |
| "hasBias": "\"bias\" == \"bias\"", |
| "hiddenSize": "hiddenSize", |
| "workgroupSize": "skipWg", |
| "HIDDEN_LEN": "hiddenSize / 4" |
| }, |
| "passes": [ |
| { |
| "id": "normalize", |
| "name": "SkipLayerNormalization.Vec4.Normalize", |
| "source": { |
| "shader": "norm-skip-row-vec4.wgsl.jinja", |
| "inputs": { |
| "simplified": false, |
| "hasBias": "\"bias\" == \"bias\"", |
| "hasBeta": true, |
| "writeResidualSum": true, |
| "usesF16": false, |
| "hidden": "hiddenSize", |
| "hiddenVec": "hiddenSize / 4", |
| "wg": "skipWgVec4", |
| "vecType": "\"vec4<f32>\"", |
| "useSubgroups": "hasSubgroups" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4_bias_output_residual", |
| "dispatch": { "workgroups": "rowCount" } |
| } |
| ] |
| }, |
| { |
| "id": "beta_bias_row", |
| "priority": 5, |
| "when": ["f32_beta_bias_residual_contract", "normResourcesFit", "rowDispatchFits"], |
| "constants": { |
| "simplified": false, |
| "useSubgroups": "hasSubgroups", |
| "hasBeta": true, |
| "writeResidualSum": true, |
| "hasBias": "\"bias\" == \"bias\"", |
| "scalar": "\"f32\"", |
| "hiddenSize": "hiddenSize", |
| "workgroupSize": "skipWg", |
| "HIDDEN_LEN": "hiddenSize" |
| }, |
| "passes": [ |
| { |
| "id": "normalize", |
| "name": "SkipLayerNormalization.Row.Normalize", |
| "shader": "norm-skip-row.wgsl.jinja", |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "scalar_bias_output_residual", |
| "dispatch": { "workgroups": "rowCount" }, |
| "constants": { "writeResidualSum": true } |
| } |
| ] |
| }, |
| { |
| "id": "beta_bias_vec4_f16", |
| "priority": 21, |
| "when": ["f16_beta_bias_residual_contract", "vec4Aligned", "normResourcesFit", "rowDispatchFits"], |
| "constants": { "scalar": "\"f16\"", "vectorScalar": "\"vec4<f16>\"", "HIDDEN_LEN": "hiddenSize / 4" }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "SkipLayerNormalization.Vec4", |
| "source": { |
| "shader": "norm-skip-row-vec4.wgsl.jinja", |
| "inputs": { |
| "simplified": false, |
| "hasBias": true, |
| "hasBeta": true, |
| "writeResidualSum": true, |
| "usesF16": true, |
| "hidden": "hiddenSize", |
| "hiddenVec": "hiddenSize / 4", |
| "wg": "skipWgVec4", |
| "vecType": "\"vec4<f16>\"", |
| "useSubgroups": "hasSubgroups" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4_bias_output_residual", |
| "dispatch": { "workgroups": "rowCount" } |
| } |
| ] |
| }, |
| { |
| "id": "no_beta_output_only_vec4", |
| "priority": 20, |
| "when": ["f32_no_beta_output_contract", "vec4Aligned", "normResourcesFit", "rowDispatchFits"], |
| "constants": { "scalar": "\"f32\"", "vectorScalar": "\"vec4<f32>\"", "HIDDEN_LEN": "hiddenSize / 4" }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "SkipLayerNormalization.NoBetaOutputOnly.Vec4", |
| "source": { |
| "shader": "norm-skip-row-vec4.wgsl.jinja", |
| "inputs": { |
| "simplified": false, |
| "hasBias": false, |
| "hasBeta": false, |
| "writeResidualSum": false, |
| "usesF16": false, |
| "hidden": "hiddenSize", |
| "hiddenVec": "hiddenSize / 4", |
| "wg": "skipWgVec4", |
| "vecType": "\"vec4<f32>\"", |
| "useSubgroups": "hasSubgroups" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4_no_beta_output_only", |
| "dispatch": { "workgroups": "rowCount" } |
| } |
| ] |
| }, |
| { |
| "id": "no_beta_output_only_row", |
| "priority": 10, |
| "when": ["f32_no_beta_output_contract", "normResourcesFit", "rowDispatchFits"], |
| "constants": { |
| "simplified": false, |
| "hasBias": false, |
| "hasBeta": false, |
| "writeResidualSum": false, |
| "useSubgroups": "hasSubgroups", |
| "scalar": "\"f32\"", |
| "hiddenSize": "hiddenSize", |
| "workgroupSize": "skipWg", |
| "HIDDEN_LEN": "hiddenSize" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "SkipLayerNormalization.NoBetaOutputOnly.Row", |
| "shader": "norm-skip-row.wgsl.jinja", |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "scalar_no_beta_output_only", |
| "dispatch": { "workgroups": "rowCount" } |
| } |
| ] |
| }, |
| { |
| "id": "beta_no_bias_vec4", |
| "priority": 20, |
| "when": ["f32_beta_no_bias_residual_contract", "vec4Aligned", "hasSubgroups or portableWideExecution", "normResourcesFit", "rowDispatchFits"], |
| "constants": { |
| "scalar": "\"f32\"", |
| "vectorScalar": "\"vec4<f32>\"", |
| "hasBias": "\"no_bias\" == \"bias\"", |
| "hiddenSize": "hiddenSize", |
| "workgroupSize": "skipWg", |
| "HIDDEN_LEN": "hiddenSize / 4" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "SkipLayerNormalization.Vec4", |
| "source": { |
| "shader": "norm-skip-row-vec4.wgsl.jinja", |
| "inputs": { |
| "simplified": false, |
| "hasBias": "\"no_bias\" == \"bias\"", |
| "hasBeta": true, |
| "writeResidualSum": true, |
| "usesF16": false, |
| "hidden": "hiddenSize", |
| "hiddenVec": "hiddenSize / 4", |
| "wg": "skipWgVec4", |
| "vecType": "\"vec4<f32>\"", |
| "useSubgroups": "hasSubgroups" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4_no_bias_residual", |
| "dispatch": { "workgroups": "rowCount" } |
| } |
| ] |
| }, |
| { |
| "id": "beta_no_bias_row", |
| "priority": 10, |
| "when": ["f32_beta_no_bias_residual_contract", "normResourcesFit", "rowDispatchFits"], |
| "constants": { |
| "simplified": false, |
| "useSubgroups": "hasSubgroups", |
| "hasBeta": true, |
| "writeResidualSum": true, |
| "hasBias": "\"no_bias\" == \"bias\"", |
| "scalar": "\"f32\"", |
| "hiddenSize": "hiddenSize", |
| "workgroupSize": "skipWg", |
| "HIDDEN_LEN": "hiddenSize" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "SkipLayerNormalization.Row", |
| "shader": "norm-skip-row.wgsl.jinja", |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "scalar_no_bias_residual", |
| "dispatch": { "workgroups": "rowCount" } |
| } |
| ] |
| }, |
| { |
| "id": "beta_no_bias_output_only_vec4", |
| "priority": 20, |
| "when": ["f32_beta_no_bias_output_only_contract", "vec4Aligned", "hasSubgroups or \"no_bias\" == \"bias\" or portableWideExecution", "normResourcesFit", "rowDispatchFits"], |
| "constants": { |
| "scalar": "\"f32\"", |
| "vectorScalar": "\"vec4<f32>\"", |
| "hasBias": "\"no_bias\" == \"bias\"", |
| "hiddenSize": "hiddenSize", |
| "workgroupSize": "skipWg", |
| "HIDDEN_LEN": "hiddenSize / 4" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "SkipLayerNormalization.Vec4", |
| "source": { |
| "shader": "norm-skip-row-vec4.wgsl.jinja", |
| "inputs": { |
| "simplified": false, |
| "hasBias": "\"no_bias\" == \"bias\"", |
| "hasBeta": true, |
| "writeResidualSum": false, |
| "usesF16": false, |
| "hidden": "hiddenSize", |
| "hiddenVec": "hiddenSize / 4", |
| "wg": "skipWgVec4", |
| "vecType": "\"vec4<f32>\"", |
| "useSubgroups": "hasSubgroups" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4_no_bias_output_only", |
| "dispatch": { "workgroups": "rowCount" } |
| } |
| ] |
| }, |
| { |
| "id": "beta_no_bias_output_only_row", |
| "priority": 10, |
| "when": ["f32_beta_no_bias_output_only_contract", "normResourcesFit", "rowDispatchFits"], |
| "constants": { |
| "simplified": false, |
| "useSubgroups": "hasSubgroups", |
| "hasBeta": true, |
| "writeResidualSum": false, |
| "hasBias": "\"no_bias\" == \"bias\"", |
| "scalar": "\"f32\"", |
| "hiddenSize": "hiddenSize", |
| "workgroupSize": "skipWg", |
| "HIDDEN_LEN": "hiddenSize" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "SkipLayerNormalization.Row", |
| "shader": "norm-skip-row.wgsl.jinja", |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "scalar_no_bias_output_only", |
| "dispatch": { "workgroups": "rowCount" } |
| } |
| ] |
| }, |
| { |
| "id": "beta_bias_output_only_vec4", |
| "priority": 20, |
| "when": ["f32_beta_bias_output_only_contract", "vec4Aligned", "hasSubgroups or \"bias\" == \"bias\" or portableWideExecution", "normResourcesFit", "rowDispatchFits"], |
| "constants": { |
| "scalar": "\"f32\"", |
| "vectorScalar": "\"vec4<f32>\"", |
| "hasBias": "\"bias\" == \"bias\"", |
| "hiddenSize": "hiddenSize", |
| "workgroupSize": "skipWg", |
| "HIDDEN_LEN": "hiddenSize / 4" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "SkipLayerNormalization.Vec4", |
| "source": { |
| "shader": "norm-skip-row-vec4.wgsl.jinja", |
| "inputs": { |
| "simplified": false, |
| "hasBias": "\"bias\" == \"bias\"", |
| "hasBeta": true, |
| "writeResidualSum": false, |
| "usesF16": false, |
| "hidden": "hiddenSize", |
| "hiddenVec": "hiddenSize / 4", |
| "wg": "skipWgVec4", |
| "vecType": "\"vec4<f32>\"", |
| "useSubgroups": "hasSubgroups" |
| } |
| }, |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "vec4_bias_output_only", |
| "dispatch": { "workgroups": "rowCount" } |
| } |
| ] |
| }, |
| { |
| "id": "beta_bias_output_only_row", |
| "priority": 10, |
| "when": ["f32_beta_bias_output_only_contract", "normResourcesFit", "rowDispatchFits"], |
| "constants": { |
| "simplified": false, |
| "useSubgroups": "hasSubgroups", |
| "hasBeta": true, |
| "writeResidualSum": false, |
| "hasBias": "\"bias\" == \"bias\"", |
| "scalar": "\"f32\"", |
| "hiddenSize": "hiddenSize", |
| "workgroupSize": "skipWg", |
| "HIDDEN_LEN": "hiddenSize" |
| }, |
| "passes": [ |
| { |
| "id": "main", |
| "name": "SkipLayerNormalization.Row", |
| "shader": "norm-skip-row.wgsl.jinja", |
| "subgroupCollectivesWidth": "portable", |
| "bindings": "scalar_bias_output_only", |
| "dispatch": { "workgroups": "rowCount" } |
| } |
| ] |
| } |
| ], |
| "tunables": { "MAX_WORKGROUP_SIZE": 256 } |
| } |
|
|