From d99d853ef990df7d5589dc4c8ce69d9745f33367 Mon Sep 17 00:00:00 2001 From: Rob Taylor Date: Sun, 20 Dec 2020 23:19:31 +0000 Subject: [PATCH 1/2] Faster version of liberty_float - gives a 25% to 50% speedup This also fixes a bug in liberty_float for numbers with a magnitute between 9 and 15. Previously: >>> liberty_float(1e15) '1000000000000000' >>> liberty_float(1e10) '10000000000.' >>> liberty_float(1e9) '1000000000.0' >>> liberty_float(1e16) '1.000000e+16' Now: >>> liberty_float(1e15) '1.000000e+15' >>> liberty_float(1e10) '1.000000e+10' >>> liberty_float(1e9) '1000000000.0' >>> liberty_float(1e16) '1.000000e+16' --- .../skywater_pdk/liberty.py | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/scripts/python-skywater-pdk/skywater_pdk/liberty.py b/scripts/python-skywater-pdk/skywater_pdk/liberty.py index 6cbda80..b14ec3e 100755 --- a/scripts/python-skywater-pdk/skywater_pdk/liberty.py +++ b/scripts/python-skywater-pdk/skywater_pdk/liberty.py @@ -31,12 +31,15 @@ from collections import defaultdict from typing import Tuple, List, Dict +from math import frexp, log2 + from . import sizes from .utils import sortable_extracted_numbers debug = False +LOG2_10 = log2(10) class TimingType(enum.IntFlag): """ @@ -792,36 +795,25 @@ def liberty_float(f): """ try: - f2 = float(f) + r = float(f) except (ValueError, TypeError): - f2 = None + r = None if isinstance(f, bool): - f2 = None + r = None - if f is None or f2 != f: + if f is None or r != f: raise ValueError("%r is not a float" % f) - WIDTH = len(str(0.0083333333)) + width = 11 - s = json.dumps(f) - if 'e' in s: - a, b = s.split('e') - if '.' not in a: - a += '.' - while len(a)+len(b)+1 < WIDTH: - a += '0' - s = "%se%s" % (a, b) - elif '.' in s: - while len(s) < WIDTH: - s += '0' + mag = int(frexp(r)[1]/LOG2_10) + if mag > 9: + return f'%{width}e' % r + if mag < 0: + return f"%{width+1}.{width-1}f" % r else: - if len(s) < WIDTH: - s += '.' - while len(s) < WIDTH: - s += '0' - return s - + return f"%{width+1}.{width-mag-1}f" % r LIBERTY_ATTRIBUTE_TYPES = { 'boolean': liberty_bool, From 9d39c63f51ae10807711fe5be5e4baa796519b45 Mon Sep 17 00:00:00 2001 From: Rob Taylor Date: Mon, 21 Dec 2020 23:33:09 +0000 Subject: [PATCH 2/2] Add doctests for liberty_float edge case Issue #280 --- scripts/python-skywater-pdk/skywater_pdk/liberty.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/python-skywater-pdk/skywater_pdk/liberty.py b/scripts/python-skywater-pdk/skywater_pdk/liberty.py index b14ec3e..77f2bb5 100755 --- a/scripts/python-skywater-pdk/skywater_pdk/liberty.py +++ b/scripts/python-skywater-pdk/skywater_pdk/liberty.py @@ -769,6 +769,15 @@ def liberty_float(f): >>> liberty_float(1) '1.0000000000' + >>> liberty_float(1e9) + '1000000000.0' + + >>> liberty_float(1e10) + '1.000000e+10' + + >>> liberty_float(1e15) + '1.000000e+15' + >>> liberty_float(True) Traceback (most recent call last): ...