diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..74229f2 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,25 @@ +# Copyright 2024 ETH Zurich and University of Bologna. +# Licensed under the Apache License, Version 2.0, see LICENSE for details. +# SPDX-License-Identifier: Apache-2.0 + +name: Test PyFlexFloat library +on: [push, pull_request] + +jobs: + test: + name: Build and test package + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: "3.9" + - name: Build + run: pip install . + - name: Install requirements + run: pip install -r requirements.txt + - name: Test + run: ./test/test.py diff --git a/README.md b/README.md index 2c557e1..d345a9e 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,20 @@ ## PyFlexFloat -A Python wrapper around OPRECOMP's [FlexFloat](https://github.com/oprecomp/flexfloat) library. +A Python wrapper around OPRECOMP's [FlexFloat](https://github.com/oprecomp/flexfloat) library, enabling arbitrary precision floating-point arithmetic emulation in Python. ## Installation -Clone the repository: -` -git clone https://github.com/colluca/pyflexfloat.git -` +Simply install via pip: +``` +pip install pyflexfloat +``` -Enter the local repository folder: -` -cd pyflexfloat -` +For developers, you can create an editable installation, to test your changes to the source code: +``` +pip install -e . +``` -Install in your active Python environment: -` -pip install . -` - -Test installation: -` +Test the installation: +``` ./test/test.py -` +``` diff --git a/pyflexfloat/FlexFloat.py b/pyflexfloat/FlexFloat.py index bca8657..1b21364 100755 --- a/pyflexfloat/FlexFloat.py +++ b/pyflexfloat/FlexFloat.py @@ -80,7 +80,7 @@ def __init__(self, desc, val=None): lib.ff_init(self.ptr, desc[0]) def __str__(self): - return str(lib.ff_get_double(self.ptr)) + return str(float(self)) def _uniformize(self, other): """Ensures that `self` and `other` have compatible types. @@ -193,6 +193,9 @@ def __neg__(self): def __abs__(self): return -self if self < 0 else self + def __float__(self): + return lib.ff_get_double(self.ptr) + def sqrt(self): result = FlexFloat(self.desc) lib.ff_sqrt(result.ptr, self.ptr) diff --git a/pyproject.toml b/pyproject.toml index c5d4546..7f32349 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,7 @@ [build-system] requires = [ - "setuptools>=60", + "setuptools>=65.0", "setuptools-scm>=8.0", - "cmake_build_extension==0.5.2.dev15", "cffi" ] build-backend = "setuptools.build_meta" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..24ce15a --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +numpy diff --git a/setup.py b/setup.py index 436ae79..4c8d58a 100644 --- a/setup.py +++ b/setup.py @@ -4,12 +4,11 @@ # # Author: Luca Colagrande import setuptools -import cmake_build_extension +from setuptools.command.build import build import subprocess from pathlib import Path - -class CMakeBuild(setuptools.command.build.build): +class CMakeBuild(build): def run(self): # Required to generate "flexfloat_config.h" diff --git a/test/test.py b/test/test.py index 50783b3..8d87759 100755 --- a/test/test.py +++ b/test/test.py @@ -69,6 +69,7 @@ # Test FlexFloat initialization from bytes print('= FlexFloat(..., bytes) =') + a = FlexFloat('e5m2', 3.14) b = FlexFloat('e5m2', a.bits().to_bytes(1, 'big')) print(f'bits: {b.bitstring()}') print(f'hex: {hex(b.bits())}') @@ -86,3 +87,13 @@ print(f'a: {a}') print(f'-a: {-a}') print(f'abs(a): {abs(a)}') + + # Casting + print('= Casting =') + A = np.random.rand(length).astype(np.float32) + B = ff.array(A, 'fp32') + C = B.astype(np.float32) + D = B.astype(np.float64) + E = B.astype(np.float16) + F = ff.array(A, 'fp16') + print(A, B, C, D, E, F)