Purpose and scope
This unit implements bit-exact matrix accumulator post-processing for B.FPATR. It coordinates C-scale multiplication, pre-quantization, activation, destination encoding, auxiliary reductions, and accumulated numeric flags.
PTO-ARCH-PROFILE-MATRIX-POSTPROCESSThe complete ASL owner is shown directly below.
// PTO-UNIT: {"id":"PTO-ARCH-PROFILE-MATRIX-POSTPROCESS","surface":"arch","classification":["profile","matrix-postprocess"],"depends_on":["PTO-ARCH-PROFILE-MATRIX-QUANTIZATION","PTO-ARCH-PROFILE-REFERENCE-PROFILE","PTO-TILE-MODEL-EXECUTION-MATRIX-SCALE"]}// Bit-exact B.FPATR conversion, activation, auxiliary reduction, and flags.// NDF-BEGIN: PTO-MATRIX-POSTPROCESS-BITEXACT-001// ndf: kind=contract level=L1 layer=architecture status=accepted// Matrix post-processing MUST reduce the raw accumulator before conversion,// select an activation-dependent multiplier before destination conversion,// canonicalize special results, and publish D, enabled auxiliary outputs, and// sticky flags as one non-faulting commit.// NDF-END: PTO-MATRIX-POSTPROCESS-BITEXACT-001
implementation func TileProfileMatrixCScale( value: Word, exponent: bits(8)) => Wordbegin let value_class = ClassifyFP32(value[31:0]); if NumericValueClassIsNaN(value_class) || value_class == NumericValue_PositiveInfinity || value_class == NumericValue_NegativeInfinity || value_class == NumericValue_PositiveZero || value_class == NumericValue_NegativeZero then return value; end; var scaled = ReferenceFP32FiniteValue(value[31:0]); for step = 1 to UInt(exponent) looplimit 255 do scaled = scaled / 2.0; end; let (encoded, flags) = ReferenceFP32FiniteEncoding( scaled, NumericRound_RNE); RecordNumericStatusFlags(flags); return encoded;end;
pure func MatrixFloatingSignedZero( data_type: TileDataType, negative: boolean) => Wordbegin if !negative then return Zeros{PTO_XLEN}; end; case data_type of when TileDataType_FP32 => return Zeros{PTO_XLEN} + 0x80000000; when TileDataType_FP16, TileDataType_BF16 => return Zeros{PTO_XLEN} + 0x8000; when TileDataType_E4M3 => return Zeros{PTO_XLEN} + 0x80; when TileDataType_HiF8 => return Zeros{PTO_XLEN}; otherwise => return Zeros{PTO_XLEN}; end;end;
pure func MatrixFloatingInfinity( data_type: TileDataType, negative: boolean) => Wordbegin case data_type of when TileDataType_FP32 => return Zeros{PTO_XLEN} + (if negative then 0xff800000 else 0x7f800000); when TileDataType_FP16 => return Zeros{PTO_XLEN} + (if negative then 0xfc00 else 0x7c00); when TileDataType_BF16 => return Zeros{PTO_XLEN} + (if negative then 0xff80 else 0x7f80); when TileDataType_HiF8 => return Zeros{PTO_XLEN} + (if negative then 0xef else 0x6f); otherwise => let (available, quiet_nan) = HardwareNumericCanonicalNaNResult(data_type); assert available; return quiet_nan; end;end;
pure func MatrixFloatingLargestFinite( data_type: TileDataType, negative: boolean) => Wordbegin case data_type of when TileDataType_FP32 => return Zeros{PTO_XLEN} + (if negative then 0xff7fffff else 0x7f7fffff); when TileDataType_FP16 => return Zeros{PTO_XLEN} + (if negative then 0xfbff else 0x7bff); when TileDataType_BF16 => return Zeros{PTO_XLEN} + (if negative then 0xff7f else 0x7f7f); when TileDataType_E4M3 => return Zeros{PTO_XLEN} + (if negative then 0xfe else 0x7e); when TileDataType_HiF8 => return Zeros{PTO_XLEN} + (if negative then 0xee else 0x6e); otherwise => unreachable; end;end;
func MatrixEncodeReal( value: real, data_type: TileDataType, control: NumericExecutionControl) => (Word, bits(5))begin if TileDataTypeIsInteger(data_type) then return ReferenceMatrixIntegerEncoding(value, data_type, control); end; return ReferenceMatrixFloatingEncoding(value, data_type, control);end;
func MatrixPostQuantSpecialValue( value: Word, source_type: TileDataType, destination_type: TileDataType, control: NumericExecutionControl) => (boolean, Word, bits(5))begin if !TileDataTypeIsFloating(source_type) then return (FALSE, Zeros{PTO_XLEN}, Zeros{5}); end; let value_class = TileNumericValueClass(source_type, value); if NumericValueClassIsNaN(value_class) then if TileDataTypeIsInteger(destination_type) then return (TRUE, if control.saturating then Zeros{PTO_XLEN} else TileIntegerMinimum(destination_type), Zeros{5} + 1); end; if control.saturating then return (TRUE, Zeros{PTO_XLEN}, if value_class == NumericValue_SignalingNaN then Zeros{5} + 1 else Zeros{5}); end; let (available, quiet_nan) = HardwareNumericCanonicalNaNResult(destination_type); assert available; return (TRUE, quiet_nan, if value_class == NumericValue_SignalingNaN then Zeros{5} + 1 else Zeros{5}); elsif NumericValueClassIsInfinity(value_class) then let negative = value_class == NumericValue_NegativeInfinity; if TileDataTypeIsInteger(destination_type) then let endpoint = if !control.saturating then TileIntegerMinimum(destination_type) else if negative then TileIntegerMinimum(destination_type) else TileIntegerMaximum(destination_type); return (TRUE, endpoint, if control.saturating then Zeros{5} + 0x14 else Zeros{5} + 1); elsif control.saturating then return (TRUE, MatrixFloatingLargestFinite(destination_type, negative), Zeros{5} + 0x14); else return (TRUE, MatrixFloatingInfinity(destination_type, negative), if destination_type == TileDataType_E4M3 then Zeros{5} + 0x14 else Zeros{5}); end; end; return (FALSE, Zeros{PTO_XLEN}, Zeros{5});end;
pure func MatrixValueClassNegative( value_class: NumericValueClass) => booleanbegin return value_class == NumericValue_NegativeNormal || value_class == NumericValue_NegativeSubnormal || value_class == NumericValue_NegativeInfinity || value_class == NumericValue_NegativeZero;end;
pure func MatrixSelectedMultiplier( source_negative: boolean, relu_mode: bits(3), quant_scale: real, relu_param: Word) => realbegin if !source_negative || UInt(relu_mode) == 0 then return quant_scale; elsif UInt(relu_mode) == 1 then return 0.0; end; return FP19FiniteValue(relu_param[18:0]);end;
func MatrixActivationWithFlags( value: real, source_negative: boolean, relu_mode: bits(3), quant_scale: real, relu_param: Word) => (real, bits(5))begin let multiplier = MatrixSelectedMultiplier( source_negative, relu_mode, quant_scale, relu_param); return (value * multiplier, Zeros{5});end;
pure func MatrixFPATREffectiveControl( pre_quant_mode: bits(6), control: NumericExecutionControl) => NumericExecutionControlbegin var result = control; let mode = UInt(pre_quant_mode); if mode == 25 || mode == 28 then result.rounding_mode = NumericRound_RHB; elsif BundleFPATRModeFixedRounding(pre_quant_mode) then result.rounding_mode = NumericRound_RNE; end; return result;end;
func MatrixPostQuantBaseWithFlags( value: Word, pre_quant_mode: bits(6), output_type: TileDataType, relu_mode: bits(3), quant_param: Word, relu_param: Word, control: NumericExecutionControl) => (Word, bits(5))begin if UInt(pre_quant_mode) == 0 && UInt(relu_mode) == 0 then return (value, Zeros{5}); end; if BundleFPATRModeIsShift(pre_quant_mode) then let shift = UInt(quant_param[35:32]) + 1; return MatrixShiftS32ToS16( value[31:0], shift as integer {1..16}); end;
let source_type = if UInt(pre_quant_mode) == 0 then output_type else if BundleFPATRModeUsesS32Accumulator( pre_quant_mode) then TileDataType_S32 else TileDataType_FP32; let source_class = if source_type == TileDataType_FP32 then TileNumericValueClass(source_type, value) else NumericValue_PositiveNormal; let source_negative = if source_type == TileDataType_S32 then SInt(value[31:0]) < 0 else MatrixValueClassNegative(source_class); let scale = if BundleFPATRModeUsesScalarParameter(pre_quant_mode) || BundleFPATRModeUsesVectorParameter(pre_quant_mode) then FP19FiniteValue(quant_param[31:13]) else 1.0; let multiplier = MatrixSelectedMultiplier( source_negative, relu_mode, scale, relu_param); let (special, special_result, special_flags) = MatrixPostQuantSpecialValue( value, source_type, output_type, control); if special && !(source_class == NumericValue_NegativeInfinity && multiplier == 0.0) then return (special_result, special_flags); end;
let source_value = if source_type == TileDataType_S32 then Real(SInt(value[31:0])) else if source_type == TileDataType_U32 then Real(UInt(value[31:0])) else if source_class == NumericValue_NegativeInfinity then 0.0 else ReferenceFP32FiniteValue(value[31:0]); let (activated, activation_flags) = MatrixActivationWithFlags( source_value, source_negative, relu_mode, scale, relu_param); let offset = MatrixQuantOffset( quant_param, BundleFPATRModeOffsetWidth(pre_quant_mode)); let intermediate_width = BundleFPATRModeOffsetWidth(pre_quant_mode); if source_class == NumericValue_NegativeZero && multiplier != 0.0 && offset == 0 && TileDataTypeIsFloating(output_type) then return ( MatrixFloatingSignedZero(output_type, TRUE), activation_flags); end; if intermediate_width != 0 then let (encoded, encoding_flags) = MatrixQuantizedAffine( activated, 1.0, offset, intermediate_width, output_type, control); return (encoded, activation_flags OR encoding_flags); end; let (encoded, encoding_flags) = MatrixEncodeReal( activated + Real(offset), output_type, control); return (encoded, activation_flags OR encoding_flags);end;
implementation func TileProfileMatrixPostProcessWithFlags( value: Word, pre_quant_mode: bits(6), relu_mode: bits(3), group_n_code: bits(4), output_type: TileDataType, quant_param: Word, relu_param: Word, control: NumericExecutionControl) => (Word, bits(5))begin let effective_control = MatrixFPATREffectiveControl( pre_quant_mode, control); return MatrixPostQuantBaseWithFlags( value, pre_quant_mode, output_type, relu_mode, quant_param, relu_param, effective_control);end;
implementation func TileProfileMatrixPostProcess( value: Word, pre_quant_mode: bits(6), relu_mode: bits(3), group_n_code: bits(4), output_type: TileDataType, quant_param: Word, relu_param: Word, control: NumericExecutionControl) => Wordbegin let (result, -) = TileProfileMatrixPostProcessWithFlags( value, pre_quant_mode, relu_mode, group_n_code, output_type, quant_param, relu_param, control); return result;end;
implementation func TileProfileMatrixReductionStep( current: Word, candidate: Word, max_abs: boolean, data_type: TileDataType) => Wordbegin let (result, -) = TileProfileMatrixReductionStepWithFlags( current, candidate, max_abs, data_type); return result;end;
pure func MatrixReductionAbsoluteWithFlags( value: Word, data_type: TileDataType) => (Word, bits(5))begin if data_type == TileDataType_U32 then return (ZeroExtend{PTO_XLEN}(value[31:0]), Zeros{5}); elsif data_type == TileDataType_S32 then if value[31] == '0' then return (SignExtend{PTO_XLEN}(value[31:0]), Zeros{5}); end; let magnitude = Zeros{32} - value[31:0]; if value[31:0] == '10000000000000000000000000000000' then return (Zeros{PTO_XLEN} + 0x7fffffff, Zeros{5} + 4); end; return ( SignExtend{PTO_XLEN}(magnitude), Zeros{5}); end; let (result, invalid) = TileFixedUnaryValue( TileUnary_ABS, data_type, value); return (result, if invalid then Zeros{5} + 1 else Zeros{5});end;
implementation func TileProfileMatrixReductionStepWithFlags( current: Word, candidate: Word, max_abs: boolean, data_type: TileDataType) => (Word, bits(5))begin let (lhs_abs, lhs_flags) = if max_abs then MatrixReductionAbsoluteWithFlags(current, data_type) else (current, Zeros{5}); let (rhs_abs, rhs_flags) = if max_abs then MatrixReductionAbsoluteWithFlags(candidate, data_type) else (candidate, Zeros{5}); let lhs = if max_abs then lhs_abs else current; let rhs = if max_abs then rhs_abs else candidate; let (selected, -, flags) = TileReductionStepWithFlags( TileReduction_MAX, data_type, lhs, rhs); return (selected, flags OR lhs_flags OR rhs_flags);end;
This unit implements bit-exact matrix accumulator post-processing for B.FPATR. It coordinates C-scale multiplication, pre-quantization, activation, destination encoding, auxiliary reductions, and accumulated numeric flags.
TileProfileMatrixCScale returns a scaled Word. When finite re-encoding produces flags, it records them through RecordNumericStatusFlags before returning the encoded value.MatrixFPATREffectiveControl applies the effective rounding and saturation controls used after bundle attributes are resolved.MatrixSelectedMultiplier, MatrixActivationWithFlags, and MatrixEncodeReal cover multiplier choice, activation, and final encoding stages.The raw accumulator is reduced before conversion, an activation-dependent multiplier is selected before destination conversion, special results are canonicalized, and D, enabled auxiliary outputs, and sticky flags are published as one non-faulting commit.
The implementation orders pre-quantization, activation, and destination encoding and accumulates flags from those internal stages. Its format helpers select the encoded signed-zero, infinity, or largest-finite representation used by the selected path.
The WithFlags entry points expose value and five-bit status together; wrapper entry points may return only the value. Auxiliary reduction uses separate step functions, including an absolute-value path that reports its own flags. Concrete bundle legality and publication remain with the matrix operation owners.
Use this example block only as a reading aid: apply the rules above, then confirm the result in the normative ASL owner. It does not add an architectural contract.
Bodies come from owning ASL. Dragging or buttons change only this page-session view order.
Matrix post-processing MUST reduce the raw accumulator before conversion, select an activation-dependent multiplier before destination conversion, canonicalize special results, and publish D, enabled auxiliary outputs, and sticky flags as one non-faulting commit.
PTO-MATRIX-POSTPROCESS-BITEXACT-001asl/arch/profile/matrix-postprocess.aslf69bbad94a6064490398c10817a50f8a7249d7a32b5ab95f807761e14363b30cd53b7b9242d9dece4a8dbdd5c3f050bc743992a428f2b62ae502dd3ca9690c3320 matching entries
PTO-AVS-ARCH-MATRIX-POST-001tests/asl/arch/profile/matrix-postprocess/arch-exec-matrix-postprocess-001.asl92669a95060a3b8714455a3f9963aeede37677257743c6098cf45a6af57758dePTO-AVS-ARCH-MATRIX-POSTPROCESS-PIPELINE-002tests/asl/arch/profile/matrix-postprocess/arch-exec-matrix-postprocess-pipeline-002.asl29d156198af9caef5156e22bb229ffab7286670561b6228df661121249708a90PTO-AVS-ARCH-PROFILE-MATRIX-POSTPROCESS-STATIC-001tests/asl/arch/profile/matrix-postprocess/arch-static-matrix-postprocess-contract-001.asl7f3949620ad409c9911878179425bdf2233a8d259ff2f765ff99f61aeea01392PTO-AVS-BLOCK-B-FPATR-ZERO-AFFINE-009tests/asl/block/attributes/B.FPATR/block-exec-b-fpatr-zero-affine-009.aslf2fbb807f80841402374fda9bf213be973ba03c06448e6f5b63100f72d868f17PTO-AVS-TILE-MATRIX-PARAMS-002tests/asl/tile/model/legality/matrix-postprocess/tile-bound-matrix-params-002.asl9103c56ebc98d0f221d43e774a367f91d6e5c7cd530cfaa2b88dc95daec57f49PTO-AVS-TILE-MODEL-EXECUTION-POSTPROCESS-AUX-EXECUTION-001tests/asl/tile/model/execution/postprocess/tile-exec-postprocess-aux-001.asl6ef6b64a850a6909c5a28c2eab0b4155dd555044ee0fc0d066441c64a5c3170aPTO-AVS-TILE-POST-MAXABS-SINGLE-002tests/asl/tile/model/execution/postprocess/tile-exec-postprocess-maxabs-single-002.asld986c36499a47c94a87f10e4854cc11a611fb33e4aa9f8f07baf619ea52f5bb0PTO-AVS-TILE-POSTPROCESS-GROUP-LARGE-004tests/asl/tile/model/execution/postprocess/tile-exec-postprocess-group-large-004.asld85357a8178860f0d81961453d6ba041aa3d9a81e7989d3bf5ab297c871ac511PTO-AVS-TILE-POSTPROCESS-ROLLBACK-003tests/asl/tile/model/execution/postprocess/tile-atomic-postprocess-rollback-003.asleb6bfb4b57227a8805ff5b5189112fc0d2e85e64efa2ec7dc18de907e4bbf51dPTO-EVIDENCE-RELEASE-TRACEABILITYPTO-EVIDENCE-RELEASE-TRACEABILITYspec/evidence/release-traceability-readiness.jsonc7327021d39dc67ac5564bc55073b3870a397d79ac8d9648284d56e33bc14a3ePTO-EVIDENCE-INSTRUCTION-CONTRACT-CLOSUREPTO-EVIDENCE-INSTRUCTION-CONTRACT-CLOSUREspec/evidence/instruction-contract-closure.json3ef2bb62421c79dff8fa77a1c7983923b523244b8090812883ef81286ca8106aPTO-EVIDENCE-ARCHITECTURE-READINESSPTO-EVIDENCE-ARCHITECTURE-READINESSspec/evidence/architecture-readiness.json4b0b85199101251bea744e0f3591cc31906909dc80d5ab651c417a936036a004PTO-EVIDENCE-RELEASE-GATE-READINESSPTO-EVIDENCE-RELEASE-GATE-READINESSspec/evidence/release-gate-readiness.jsona0f4d2b6920c08981ea55fd8ef820708a40d4feb5402c5150e8e9ab532d84ce0PTO-EVIDENCE-RELEASE-MANIFESTPTO-EVIDENCE-RELEASE-MANIFESTspec/release-manifest.json1a64c109ed7a90351c41e2a418b3c0ebaf8ad975838986d2101385186b85c0d8Loading ADR-0005…
ADR-0005docs/status/decisions/0005-pto-v0-concrete-reference-profile.mda83528c2fc744cc120c2a0a32c82410059638ea88936fa65ac0eb36a0274d87cLoading ADR-0037…
ADR-0037docs/status/decisions/0037-numeric-profile-identity-and-variation-framework.mdb09efd36ccfc7258d1743c974f42b875ead42137c503f576a12f471f65b52e30Loading ADR-0042…
ADR-0042docs/status/decisions/0042-numeric-variation-point-ownership.mdf25df23306837e4199f6b7c03f70de853a693fdc6435c65ead57b2a174076081Loading ADR-0050…
ADR-0050docs/status/decisions/0050-hardware-special-value-checkpoint.md08cfdeb16bf245980c9db849994e181e5079efc53475762cdad1df9f555993b5Loading ADR-0064…
ADR-0064docs/status/decisions/0064-b-fpatr-complete-bundle-postprocess.md853e7fe83cf78a1fbf1fe1668ce6dbf64e5da29ddb301865ed03e8af8f99cad1Loading ADR-0101…
ADR-0101docs/status/decisions/0101-matrix-scale-and-cscale.mda5c962437636c0d3f4f3585d3b529fcc9821d4b00c540243c2351978196e9be0{
"classification": [
"profile",
"matrix-postprocess"
],
"documentation": "docs/arch/profile/matrix-postprocess.md",
"id": "PTO-ARCH-PROFILE-MATRIX-POSTPROCESS",
"mnemonic": null,
"readiness_subjects": [
"ADR-0005",
"ADR-0037",
"ADR-0042",
"ADR-0050",
"ADR-0064",
"ADR-0101"
],
"semantic_tests": [
"PTO-AVS-ARCH-MATRIX-POST-001",
"PTO-AVS-ARCH-MATRIX-POSTPROCESS-PIPELINE-002"
],
"source": "asl/arch/profile/matrix-postprocess.asl",
"surface": "arch",
"tests": [
"PTO-AVS-ARCH-MATRIX-POST-001",
"PTO-AVS-ARCH-MATRIX-POSTPROCESS-PIPELINE-002",
"PTO-AVS-ARCH-PROFILE-MATRIX-POSTPROCESS-STATIC-001"
]
}0.58.5 · Release candidate7dc8b7e5b121d2b2499a2273bebff29e2cd86812f69bbad94a6064490398c10817a50f8a7249d7a32b5ab95f807761e14363b30c6c620e8f326fa991a2a35cf3d9aad4e1e9b9321ea63bc78e8fdabdfb17802378asl/arch/profile/matrix-postprocess.aslasl/arch/profile/matrix-postprocess.asl