Skip to content

Fix float 8 conversion #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ _doc/examples/data/*.optimized.onnx
_doc/examples/*.html
_doc/_static/require.js
_doc/_static/viz.js
_doc/LICENSE.txt
_doc/CHANGELOGS.rst
_unittests/ut__main/*.png
_unittests/ut__main/_cache/*
_unittests/ut__main/*.html
Expand Down
5 changes: 5 additions & 0 deletions _doc/api/f8.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Float 8
=======

.. automodule:: onnx_array_api.validation.f8
:members:
1 change: 1 addition & 0 deletions _doc/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ API
reference
tools
profiling
f8
4 changes: 1 addition & 3 deletions _doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,7 @@
"onnxruntime": "https://onnxruntime.ai/",
"numpy": "https://numpy.org/",
"numba": "https://numba.pydata.org/",
"onnx-array-api": (
"http://www.xavierdupre.fr/app/onnx-array-api/helpsphinx/index.html"
),
"onnx-array-api": ("https://sdpython.github.io/doc/onnx-array-api/dev/"),
"pyinstrument": "https://github.com/joerick/pyinstrument",
"python": "https://www.python.org/",
"scikit-learn": "https://scikit-learn.org/stable/",
Expand Down
11 changes: 10 additions & 1 deletion _unittests/ut_validation/test_f8.py
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,16 @@ def test_float8_e5m2fnuz_negative_nan(self):
back = fe4m3_to_float32(to, fn=True, uz=True)
self.assertTrue(numpy.isnan(back))

def test_fe4m3fn_to_float32_bug(self):
cases = [(1.8131605, 1.875)]
for val, expected in cases:
with self.subTest(value=val, expected=expected):
res = fe4m3_to_float32(search_float32_into_fe4m3(val))
self.assertEqual(expected, res)
res = fe4m3_to_float32(float32_to_fe4m3(val))
self.assertEqual(expected, res)


if __name__ == "__main__":
TestF8().test_search_float32_into_fe4m3fn_simple()
TestF8().test_fe4m3fn_to_float32_bug()
unittest.main(verbosity=2)
55 changes: 32 additions & 23 deletions onnx_array_api/validation/f8.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@ class UndefinedCastError(FloatingPointError):
pass


def display_float32(value, sign=1, exponent=8, mantissa=23):
def display_int(ival, sign=1, exponent=8, mantissa=23):
"""
Displays a float32 into b.
Displays an integer as bits.

:param value: value to display (float32)
:param ival: value to display (float32)
:param sign: number of bits for the sign
:param exponent: number of bits for the exponent
:param mantissa: number of bits for the mantissa
:return: string
"""
t = sign + exponent + mantissa
ival = int.from_bytes(struct.pack("<f", numpy.float32(value)), "little")
s = bin(ival)[2:]
s = "0" * (t - len(s)) + s
s1 = s[:sign]
Expand All @@ -32,6 +31,24 @@ def display_float32(value, sign=1, exponent=8, mantissa=23):
return ".".join([s1, s2, s3])


def display_float32(value, sign=1, exponent=8, mantissa=23):
"""
Displays a float32 into b.

:param value: value to display (float32)
:param sign: number of bits for the sign
:param exponent: number of bits for the exponent
:param mantissa: number of bits for the mantissa
:return: string
"""
return display_int(
int.from_bytes(struct.pack("<f", numpy.float32(value)), "little"),
sign=sign,
exponent=exponent,
mantissa=mantissa,
)


def display_float16(value, sign=1, exponent=5, mantissa=10):
"""
Displays a float32 into b.
Expand All @@ -42,14 +59,9 @@ def display_float16(value, sign=1, exponent=5, mantissa=10):
:param mantissa: number of bits for the mantissa
:return: string
"""
t = sign + exponent + mantissa
ival = numpy.float16(value).view("H") # pylint: disable=E1121
s = bin(ival)[2:]
s = "0" * (t - len(s)) + s
s1 = s[:sign]
s2 = s[sign : sign + exponent]
s3 = s[sign + exponent :]
return ".".join([s1, s2, s3])
return display_int(
numpy.float16(value).view("H"), sign=sign, exponent=exponent, mantissa=mantissa
)


def display_fexmx(value, sign, exponent, mantissa):
Expand All @@ -64,14 +76,7 @@ def display_fexmx(value, sign, exponent, mantissa):
:param mantissa: number of bits for the mantissa
:return: string
"""
t = sign + exponent + mantissa
ival = value
s = bin(ival)[2:]
s = "0" * (t - len(s)) + s
s1 = s[:sign]
s2 = s[sign : sign + exponent]
s3 = s[sign + exponent :]
return ".".join([s1, s2, s3])
return display_int(value, sign=sign, exponent=exponent, mantissa=mantissa)


def display_fe4m3(value, sign=1, exponent=4, mantissa=3):
Expand Down Expand Up @@ -534,7 +539,9 @@ def float32_to_fe4m3(x, fn: bool = True, uz: bool = False, saturate: bool = True
else:
ret |= ex << 3
ret |= m >> 20
if m & 0x80000:
if (m & 0x80000) and (
(m & 0x100000) or (m & 0x7FFFF)
): # round to nearest even
if (ret & 0x7F) < 0x7F:
# rounding
ret += 1
Expand Down Expand Up @@ -584,7 +591,7 @@ def float32_to_fe4m3(x, fn: bool = True, uz: bool = False, saturate: bool = True
if (ret & 0x7F) == 0x7F:
ret &= 0xFE
if (m & 0x80000) and (
(m & 0x100000) or (m & 0x7C000)
(m & 0x100000) or (m & 0x7FFFF)
): # round to nearest even
if (ret & 0x7F) < 0x7E:
# rounding
Expand Down Expand Up @@ -642,7 +649,9 @@ def float32_to_fe5m2(x, fn: bool = False, uz: bool = False, saturate: bool = Tru
ex = e - 111 # 127 - 16
ret |= ex << 2
ret |= m >> 21
if m & 0x100000:
if m & 0x100000 and (
(m & 0xFFFFF) or (m & 0x200000)
): # round to nearest even
if (ret & 0x7F) < 0x7F:
# rounding
ret += 1
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy