|
| 1 | +# Copyright (c) 2024 Graphcore Ltd. All rights reserved. |
| 2 | +from typing import Callable |
| 3 | +import ml_dtypes |
| 4 | +import numpy as np |
| 5 | +import pytest |
| 6 | + |
| 7 | +from gfloat import FloatClass, Domain, decode_float, decode_ndarray |
| 8 | +from gfloat.formats import * |
| 9 | + |
| 10 | + |
| 11 | +def spec_is_normal(fi: FormatInfo, x: int): |
| 12 | + r""" |
| 13 | + Copy from spec: |
| 14 | +
|
| 15 | + \Case{\isNormal*<f>(x \in \{0, \NInf, \Inf, \NaN\}) \gives \False}\\ |
| 16 | + \Case{\isNormal*<f>(x) \gives |
| 17 | + \begin{cases} |
| 18 | + (x \mod 2^{\k_f - 1}) \div 2^{\p_f - 1} > 0 & \If \s_f = \Signed \\ |
| 19 | + x \div 2^{\p_f - 1} > 0 & \If \s_f = \Unsigned |
| 20 | + \end{cases} |
| 21 | + } |
| 22 | + """ |
| 23 | + if x in (fi.code_of_zero, fi.code_of_posinf, fi.code_of_neginf, fi.code_of_nan): |
| 24 | + return False |
| 25 | + |
| 26 | + k_f = fi.k |
| 27 | + p_f = fi.precision |
| 28 | + if fi.is_signed: |
| 29 | + # (x \mod 2^{\k_f - 1}) \div 2^{\p_f - 1} > 0 |
| 30 | + return (x % 2 ** (k_f - 1)) // 2 ** (p_f - 1) > 0 |
| 31 | + else: |
| 32 | + # x \div 2^{\p_f - 1} > 0 |
| 33 | + return x // 2 ** (p_f - 1) > 0 |
| 34 | + |
| 35 | + |
| 36 | +_p3109_formats_to_test = ( |
| 37 | + (2, 1), |
| 38 | + (2, 2), |
| 39 | + (3, 1), |
| 40 | + (3, 2), |
| 41 | + (3, 3), |
| 42 | + (4, 1), |
| 43 | + (4, 2), |
| 44 | + (4, 3), |
| 45 | + (4, 4), |
| 46 | + (6, 1), |
| 47 | + (6, 5), |
| 48 | + (8, 3), |
| 49 | + (8, 1), |
| 50 | + (11, 3), |
| 51 | +) |
| 52 | + |
| 53 | + |
| 54 | +@pytest.mark.parametrize("k,p", _p3109_formats_to_test) |
| 55 | +def test_p3109_specials_signed(k: int, p: int) -> None: |
| 56 | + fi = format_info_p3109(k, p, Domain.Extended) |
| 57 | + |
| 58 | + for i in range(2**fi.k): |
| 59 | + fv = decode_float(fi, i) |
| 60 | + assert spec_is_normal(fi, i) == (fv.fclass == FloatClass.NORMAL) |
0 commit comments