@@ -29,24 +29,20 @@ struct fp8_e4m3 {
2929 bits |= static_cast <uint8_t >(sign >> 24 );
3030 }
3131
32- operator float () {
33- // From PyTorch:
34- // https://github.com/pytorch/pytorch/blob/e3643e1e0e923f0fc063dfab6f45c956d568919d/c10/util/Float8_e4m3fn.h#L46
35- uint32_t w = static_cast <uint32_t >(bits) << 24 ;
36- uint32_t sign = w & 0x80000000 ;
37- uint32_t nonsign = w & 0x7FFFFFFF ;
32+ operator float16_t () {
33+ uint16_t v = (bits & 127 ) << 7 ;
34+ half converted = as_type<half>(v);
35+ converted *= 256.0 ;
36+ auto sign = bits & 128 ;
37+ return (sign ? -converted : converted);
38+ }
3839
39- uint32_t renorm_shift = metal::clz (nonsign);
40- renorm_shift = renorm_shift > 4 ? renorm_shift - 4 : 0 ;
40+ operator bfloat16_t () {
41+ return static_cast <bfloat16_t >(this ->operator float16_t ());
42+ }
4143
42- int32_t inf_nan_mask =
43- (static_cast <int32_t >(nonsign + 0x01000000 ) >> 8 ) & 0x7F800000 ;
44- int32_t zero_mask = static_cast <int32_t >(nonsign - 1 ) >> 31 ;
45- uint32_t result = sign |
46- ((((nonsign << renorm_shift >> 4 ) + ((0x78 - renorm_shift) << 23 )) |
47- inf_nan_mask) &
48- ~zero_mask);
49- return as_type<float >(result);
44+ operator float () {
45+ return static_cast <float >(this ->operator float16_t ());
5046 }
5147
5248 uint8_t bits;
@@ -74,8 +70,10 @@ struct fp8_e8m0 {
7470 uint16_t out = (bits == 0 ? 0x40 : (static_cast <uint16_t >(bits) << 7 ));
7571 return as_type<bfloat16_t >(out);
7672 }
73+
7774 operator float () {
78- return static_cast <float >(this ->operator bfloat16_t ());
75+ uint32_t out = (bits == 0 ? 0x400000 : (static_cast <uint16_t >(bits) << 23 ));
76+ return as_type<float >(out);
7977 }
8078
8179 uint8_t bits;
0 commit comments