std::rt::Float8
The OCP FP8 formats F8E4M3 and F8E5M2 as library structs.
Contents
| Name | Summary |
|---|---|
f32_bits | Returns the IEEE binary32 bit pattern of x. |
bits_f32 | Returns the f32 whose IEEE binary32 bit pattern is b. |
F8E4M3 | OCP E4M3, finite-only. |
extend F8E4M3 | |
F8E5M2 | OCP E5M2. 1 sign / 5 exponent / 2 mantissa, bias 15. IEEE-shaped: infinities AND NaN both present, unlike E4M3FN. |
extend F8E5M2 | |
extend F8E4M3 | |
extend F8E5M2 | |
verify_e4m3_roundtrip | Every one of the 256 E4M3FN bit patterns survives bits -> f32 -> bits unchanged. |
verify_e5m2_roundtrip | Checks that every non-NaN E5M2 bit pattern survives bits -> f32 -> bits unchanged. |
verify_e4m3_known | Spot-check the values the OCP spec names explicitly. |
verify_e5m2_known | Spot-checks the E5M2 encodings the OCP spec names: 0, 1, 2, max finite (57344), overflow to infinity, and -1. |
f32_bits
fn f32_bits(x: f32) -> u32
Returns the IEEE binary32 bit pattern of x.
Parameters
x: the value
Notes
Currently a numeric as conversion, not a bit cast (see the TODO in the source), so
it does not yet reinterpret the bits.
bits_f32
fn bits_f32(b: u32) -> f32
Returns the f32 whose IEEE binary32 bit pattern is b.
Parameters
b: the bit pattern
Notes
Currently a numeric as conversion, not a bit cast (see the TODO in the source).
F8E4M3
struct F8E4M3
OCP E4M3, finite-only. 1 sign / 4 exponent / 3 mantissa, bias 7.
Layout: S EEEE MMM
Max finite: 448.0 (S.1111.110)
Min normal: 2^-6 (S.0001.000)
Min subnormal: 2^-9 (S.0000.001)
NaN: S.1111.111 -- the ONLY NaN encoding
Infinity: none. Overflow saturates to +/-448.
Precision, not range. This is the weights-and-activations format.
F8E4M3.BIAS
static BIAS: i32
Exponent bias.
F8E4M3.MANT
static MANT: u32
Number of mantissa bits.
F8E4M3.MAX_FIN
static MAX_FIN: f32
Largest finite magnitude, 448.0.
F8E4M3.NAN_BITS
static NAN_BITS: u8
Encoding of NaN.
F8E4M3.bits
var bits: u8
The raw 8-bit encoding: sign, 4 exponent bits, 3 mantissa bits.
extend F8E4M3
extend F8E4M3
F8E4M3.F8E4M3
fn F8E4M3(self)
Constructs a zero (all bits clear).
F8E4M3.F8E4M3
fn F8E4M3(self, v: f32)
Constructs the nearest E4M3 value to v, rounding to nearest even; overflow saturates to
+/-448.
Parameters
v: the value to encode
F8E4M3.from_f32_bits
fn from_f32_bits(v: f32) -> u8
f32 -> E4M3FN, round-to-nearest-even, saturating.
Saturation rather than infinity is the whole point of the FN form: there is no inf encoding, so a value past 448 becomes 448, and only a NaN input produces a NaN output.
F8E4M3.to_f32
fn to_f32(self) -> f32
E4M3FN -> f32. Always exact: every E4M3 value is representable in binary32, so no rounding occurs and no mode is needed.
F8E4M3.is_nan
fn is_nan(self) -> bool
Returns whether the value is NaN: exponent and mantissa all ones, the only NaN encoding.
F8E4M3.is_zero
fn is_zero(self) -> bool
Returns whether the value is zero (positive or negative).
F8E4M3.op as
fn op as (self) -> f32
Converts to f32 with as; same as to_f32.
F8E5M2
struct F8E5M2
OCP E5M2. 1 sign / 5 exponent / 2 mantissa, bias 15. IEEE-shaped: infinities AND NaN both present, unlike E4M3FN.
Layout: S EEEEE MM
Max finite: 57344.0 (S.11110.11)
Min normal: 2^-14
Min subnormal: 2^-16
Inf: S.11111.00
NaN: S.11111.xx with xx != 00
Range, not precision. The exponent field is IDENTICAL to f16's,
which is why f16 <-> e5m2 is a shift rather than a
renormalization. This is the gradients format.
F8E5M2.BIAS
static BIAS: i32
Exponent bias.
F8E5M2.MANT
static MANT: u32
Number of mantissa bits.
F8E5M2.MAX_FIN
static MAX_FIN: f32
Largest finite magnitude, 57344.0.
F8E5M2.INF_BITS
static INF_BITS: u8
Encoding of positive infinity.
F8E5M2.bits
var bits: u8
The raw 8-bit encoding: sign, 5 exponent bits, 2 mantissa bits.
extend F8E5M2
extend F8E5M2
F8E5M2.F8E5M2
fn F8E5M2(self)
Constructs a zero (all bits clear).
F8E5M2.F8E5M2
fn F8E5M2(self, v: f32)
Constructs the nearest E5M2 value to v, rounding to nearest even; overflow gives an
infinity.
Parameters
v: the value to encode
F8E5M2.from_f32_bits
fn from_f32_bits(v: f32) -> u8
f32 -> E5M2, round-to-nearest-even. Overflow produces INFINITY here, not saturation -- E5M2 has inf encodings and IEEE semantics.
F8E5M2.to_f32
fn to_f32(self) -> f32
E5M2 -> f32. Always exact.
F8E5M2.is_nan
fn is_nan(self) -> bool
Returns whether the value is a NaN: exponent all ones and a nonzero mantissa.
F8E5M2.is_inf
fn is_inf(self) -> bool
Returns whether the value is an infinity (either sign).
F8E5M2.is_zero
fn is_zero(self) -> bool
Returns whether the value is zero (positive or negative).
F8E5M2.op as
fn op as (self) -> f32
Converts to f32 with as; same as to_f32.
extend F8E4M3
extend F8E4M3
F8E4M3.op +
fn op + (self, const rhs: F8E4M3) -> f32
Adds after promoting both operands to f32; the result is an f32, not an F8E4M3.
Arithmetic returns f32 on purpose: narrowing back to fp8 after every operation would
round at each step. Narrow once, at the final assignment.
F8E4M3.op -
fn op - (self, const rhs: F8E4M3) -> f32
Subtracts after promoting both operands to f32; the result is an f32, not an F8E4M3.
F8E4M3.op *
fn op * (self, const rhs: F8E4M3) -> f32
Multiplies after promoting both operands to f32; the result is an f32, not an F8E4M3.
F8E4M3.op /
fn op / (self, const rhs: F8E4M3) -> f32
Divides after promoting both operands to f32; the result is an f32, not an F8E4M3.
F8E4M3.op ==
fn op == (self, const rhs: F8E4M3) -> bool
Bitwise equality, NOT numeric. Two encodings of the same value do not exist in E4M3FN, so this differs from numeric equality only at NaN (which compares unequal to itself numerically) and signed zero (-0.0 == +0.0 numerically, different bits here). Compare through to_f32() when IEEE comparison semantics are what you want.
extend F8E5M2
extend F8E5M2
F8E5M2.op +
fn op + (self, const rhs: F8E5M2) -> f32
Adds after promoting both operands to f32; the result is an f32, not an F8E5M2.
Arithmetic returns f32 on purpose: narrowing back to fp8 after every operation would
round at each step. Narrow once, at the final assignment.
F8E5M2.op -
fn op - (self, const rhs: F8E5M2) -> f32
Subtracts after promoting both operands to f32; the result is an f32, not an F8E5M2.
F8E5M2.op *
fn op * (self, const rhs: F8E5M2) -> f32
Multiplies after promoting both operands to f32; the result is an f32, not an F8E5M2.
F8E5M2.op /
fn op / (self, const rhs: F8E5M2) -> f32
Divides after promoting both operands to f32; the result is an f32, not an F8E5M2.
F8E5M2.op ==
fn op == (self, const rhs: F8E5M2) -> bool
Bitwise equality of the encodings, not IEEE numeric equality: a NaN equals an identical NaN
here, and -0.0 differs from +0.0. Convert with to_f32 for numeric comparison.
verify_e4m3_roundtrip
fn verify_e4m3_roundtrip() -> bool
Every one of the 256 E4M3FN bit patterns survives bits -> f32 -> bits unchanged.
This is the half of the exhaustive test you can run WITHOUT
APFloat. It proves the two conversions are mutual inverses; it
does NOT prove either matches the OCP spec. For that, run the
same 256 patterns through APFloat's semFloat8E4M3FN in the
compiler and diff. Both halves are needed: mutually-inverse
conversions can still both be wrong in the same direction.
verify_e5m2_roundtrip
fn verify_e5m2_roundtrip() -> bool
Checks that every non-NaN E5M2 bit pattern survives bits -> f32 -> bits unchanged.
NaN payloads are skipped because they are not preserved.
Returns
true when every non-NaN encoding round-trips.
verify_e4m3_known
fn verify_e4m3_known() -> bool
Spot-check the values the OCP spec names explicitly. Cheap, and it catches a bias or shift that is off by one -- which round-trip testing alone cannot, since a consistent off-by-one is still self-inverse.
verify_e5m2_known
fn verify_e5m2_known() -> bool
Spot-checks the E5M2 encodings the OCP spec names: 0, 1, 2, max finite (57344), overflow to infinity, and -1.
Returns
true when every spot-check encodes to the expected bit pattern.
Generated from Kairo source, Apache-2.0 WITH AdditionRef-Kairo-Runtime-exception.