Bug 146 - create python bindings to reference FP implementation
Summary: create python bindings to reference FP implementation
Status: RESOLVED FIXED
Alias: None
Product: Libre-SOC's first SoC
Classification: Unclassified
Component: Formal Verification (show other bugs)
Version: unspecified
Hardware: All All
: --- enhancement
Assignee: Jacob Lifshay
URL:
Depends on:
Blocks: 122 145
  Show dependency treegraph
 
Reported: 2019-10-15 02:00 BST by Jacob Lifshay
Modified: 2020-01-28 07:43 GMT (History)
3 users (show)

See Also:
NLnet milestone: NLnet.2019.02
total budget (EUR) for completion of task and all subtasks: 300
budget (EUR) for this task, excluding subtasks' budget: 300
parent task for budget allocation: 122
child tasks for budget allocation:
The table of payments (in EUR) for this task; TOML format:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jacob Lifshay 2019-10-15 02:00:00 BST

    
Comment 1 Jacob Lifshay 2019-10-15 02:21:00 BST
I have WIP bindings to the algebraics crate already written (python-support branch of algebraics repo), just need to finish writing tests, resolve issues with PyLong <-> BigInt conversion in PyO3, and may need to wait on PyO3 releasing a new version.

PyLong <-> BigInt conversion:
https://github.com/PyO3/pyo3/pull/622#issuecomment-541866678

We will need to write bindings to the FP emulation library written on top of algebraics.

As mentioned on mailing list, I think we should have different bindings to avoid needing global variables for rounding mode, exceptions, and similar. I'm thinking we add a FPEnv object that holds all of that and all the FP number objects have a reference to the FPEnv object. That way, we can avoid needing to pass the FPEnv to all the operations, we only need to pass it to the operations that produce a FP number without any FP numbers as input (mostly type conversions from integer or bits).
Comment 2 Jacob Lifshay 2019-10-28 05:45:09 GMT
I published version 0.1.2 of algebraics which includes the new Python bindings.

https://pypi.org/project/algebraics/
https://crates.io/crates/algebraics

Working on implementing soft-float library that will use algebraics:
https://salsa.debian.org/Kazan-team/simple-soft-float
Comment 3 Jacob Lifshay 2019-11-02 00:29:33 GMT
(In reply to Jacob Lifshay from comment #2)
> Working on implementing soft-float library that will use algebraics:
> https://salsa.debian.org/Kazan-team/simple-soft-float

Got add/sub to work! implementing mul/div/fma/sqrt/rsqrt/int-to-fp/fp-to-int next.

FP is really complicated... more than 150 lines of code to round FP numbers in all 5 supported rounding modes -- and that only handles finite numbers!

Building the simple-soft-float library to be able to handle all implemented forms of FP without compile-time configuration (unlike softfloat). Additionally handles generating the correct FP exceptions for when traps are handled rather than ignored (needed for non-RISC-V FP).
Comment 4 Jacob Lifshay 2019-11-13 08:20:44 GMT
I completed the Python bindings, though they're based off of the Rust API rather than sfpy.

I figured that changing the preexisting Python code to use the new API wouldn't take much work due to there not being a huge number of places where it's used.

I do need to write some documentation though.

smoke tests:
https://salsa.debian.org/Kazan-team/simple-soft-float/blob/master/tests/test_simple_soft_float.py

Do you think I can mark this bug and #145 as resolved or should I finish the documentation first?

I still need to finish writing the NaN propagation code, but since RISC-V always generates the canonical NaN rather than propagating NaNs (for operations other than simple bit manipulation -- such as neg and abs), it doesn't affect RISC-V.
Comment 5 Luke Kenneth Casson Leighton 2019-11-13 15:18:22 GMT
nice, a wrapper can be written in python, don't worry about it.

yes if you are happy it's complete set them as done, can make new milestones for docs and further work.
Comment 6 Jacob Lifshay 2019-11-15 15:37:53 GMT
got all the method signatures to show up from python, went down the __text_signature__ rabbit hole.
Comment 7 Jacob Lifshay 2019-11-19 16:11:37 GMT
getting started switching to simple_soft_float:

installation instructions:
install rust using rustup (you probably already did that).

create cpython 3.5 to 3.7 virtualenv (not sure if 3.8 is supported yet)

install python bindings build tool:
pip install maturin

get source:
git clone https://salsa.debian.org/Kazan-team/simple-soft-float.git
cd simple-soft-float

change source dir to use specific version of rust nightly:
(must be in simple-soft-float dir):
rustup override set nightly-2019-07-19

build & test (like setup.py develop):
cargo test --features python # runs tests from Rust
# build and install to python
maturin develop --cargo-extra-args="--features python-extension"
python -m unittest # runs smoke tests from Python

build Rust docs:
cargo doc --features python # ignore warning about rand_core name collision
open docs in default browser:
xdg-open target/doc/simple_soft_float/struct.DynamicFloat.html

build python docs:
pip install pdoc3
pdoc3 simple_soft_float --html -o target/python-docs
xdg-open target/python-docs/simple_soft_float.html


Example code for FP add:

import simple_soft_float as ssf

# note 2 underlines in PlatformProperties_RISC_V,
# caused by PyO3 issues with not supporting constant static
# members of classes. Will eventually switch to
# PlatformProperties.RISC_V when fixed.
platform = ssf.PlatformProperties_RISC_V
f32_properties = ssf.FloatProperties.standard(32, platform)

a_bits = 0x7F800000 # bits of 1.0f32
b_bits = 0x7F800000

# construct 32-bit floats from bits
a = ssf.DynamicFloat(properties=f32_properties, bits=a_bits)
b = ssf.DynamicFloat(properties=f32_properties, bits=b_bits)
result = a + b # compute sum
result_bits = result.bits # get bits of result
assert isinstance(result_bits, int)

All the other settings can be ignored for now since our HW doesn't implement handling status flags yet.
Comment 8 Jacob Lifshay 2019-11-25 00:06:23 GMT
currently working on pull request on PyO3 (Rust/Python bindings library) that adds support for setting __text_signature__:
https://github.com/PyO3/pyo3/pull/675
Comment 9 Jacob Lifshay 2019-12-06 23:33:41 GMT
(In reply to Jacob Lifshay from comment #8)
> currently working on pull request on PyO3 (Rust/Python bindings library)
> that adds support for setting __text_signature__:
> https://github.com/PyO3/pyo3/pull/675

The PyO3 pull request should be merged soon, resolved all raised issues.
Comment 10 Jacob Lifshay 2019-12-10 03:07:26 GMT
(In reply to Jacob Lifshay from comment #9)
> (In reply to Jacob Lifshay from comment #8)
> > currently working on pull request on PyO3 (Rust/Python bindings library)
> > that adds support for setting __text_signature__:
> > https://github.com/PyO3/pyo3/pull/675
> 
> The PyO3 pull request should be merged soon, resolved all raised issues.

The PyO3 pull request was merged. I should be done with the simple-soft-float documentation in a few days at most.
Comment 11 Jacob Lifshay 2019-12-13 03:28:26 GMT
Finished (finally) writing the documentation for both the Rust and Python APIs.