mirror of https://github.com/openXC7/prjxray.git
timfuz: min corner tweaks
Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
parent
2ad0bf82fc
commit
c965288e75
|
|
@ -33,34 +33,44 @@ def mkestimate(Anp, b):
|
|||
x0[coli] = min(x0[coli], ub)
|
||||
return x0
|
||||
|
||||
def save(outfn, res, names, corner):
|
||||
def save(outfn, xvals, names, corner):
|
||||
# ballpark minimum actual observed delay is around 7 (carry chain)
|
||||
# anything less than one is probably a solver artifact
|
||||
delta = 0.5
|
||||
corneri = corner_s2i[corner]
|
||||
|
||||
print('Writing resutls')
|
||||
# Round conservatively
|
||||
roundf = {
|
||||
'fast_max': math.ceil,
|
||||
'fast_min': math.floor,
|
||||
'slow_max': math.ceil,
|
||||
'slow_min': math.floor,
|
||||
}[corner]
|
||||
|
||||
print('Writing results')
|
||||
skips = 0
|
||||
keeps = 0
|
||||
with open(outfn, 'w') as fout:
|
||||
# write as one variable per line
|
||||
# this natively forms a bound if fed into linprog solver
|
||||
fout.write('ico,fast_max fast_min slow_max slow_min,rows...\n')
|
||||
for xval, name in zip(res.x, names):
|
||||
for xval, name in zip(xvals, names):
|
||||
row_ico = 1
|
||||
|
||||
# FIXME: only report for the given corner?
|
||||
# also review ceil vs floor choice for min vs max
|
||||
# lets be more conservative for now
|
||||
if xval < delta:
|
||||
#print('Skipping %s: %0.6f' % (name, xval))
|
||||
skips += 1
|
||||
continue
|
||||
keeps += 1
|
||||
#xvali = round(xval)
|
||||
|
||||
items = [str(row_ico), acorner2csv(math.ceil(xval), corneri)]
|
||||
items = [str(row_ico), acorner2csv(roundf(xval), corneri)]
|
||||
items.append('%u %s' % (1, name))
|
||||
fout.write(','.join(items) + '\n')
|
||||
print('Wrote: skip %u => %u / %u valid delays' % (skips, len(names) - skips, len(names)))
|
||||
print('Wrote: skip %u => %u / %u valid delays' % (skips, keeps, len(names)))
|
||||
assert keeps, 'Failed to estimate delay'
|
||||
|
||||
def run_corner(Anp, b, names, corner, verbose=False, opts={}, meta={}, outfn=None):
|
||||
# Given timing scores for above delays (-ps)
|
||||
|
|
@ -131,7 +141,7 @@ def run_corner(Anp, b, names, corner, verbose=False, opts={}, meta={}, outfn=Non
|
|||
print('Done')
|
||||
|
||||
if outfn:
|
||||
save(outfn, res, names, corner)
|
||||
save(outfn, res.x, names, corner)
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
|
@ -148,23 +158,19 @@ def main():
|
|||
parser.add_argument('--out', default=None, help='output timing delay .json')
|
||||
parser.add_argument(
|
||||
'fns_in',
|
||||
nargs='*',
|
||||
nargs='+',
|
||||
help='timing3.csv input files')
|
||||
args = parser.parse_args()
|
||||
# Store options in dict to ease passing through functions
|
||||
bench = Benchmark()
|
||||
|
||||
fns_in = args.fns_in
|
||||
if not fns_in:
|
||||
fns_in = glob.glob('specimen_*/timing3.csv')
|
||||
|
||||
sub_json = None
|
||||
if args.sub_json:
|
||||
sub_json = load_sub(args.sub_json)
|
||||
|
||||
try:
|
||||
timfuz_solve.run(run_corner=run_corner, sub_json=sub_json,
|
||||
fns_in=fns_in, corner=args.corner, massage=args.massage, outfn=args.out, verbose=args.verbose)
|
||||
fns_in=args.fns_in, corner=args.corner, massage=args.massage, outfn=args.out, verbose=args.verbose)
|
||||
finally:
|
||||
print('Exiting after %s' % bench)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ def save(outfn, xvals, names, corner):
|
|||
delta = 0.5
|
||||
corneri = corner_s2i[corner]
|
||||
|
||||
print('Writing resutls')
|
||||
print('Writing results')
|
||||
zeros = 0
|
||||
with open(outfn, 'w') as fout:
|
||||
# write as one variable per line
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@ corner_s2i = OrderedDict([
|
|||
class SimplifiedToZero(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def allow_zero_eqns():
|
||||
return os.getenv('ALLOW_ZERO_EQN', 'N') == 'Y'
|
||||
|
||||
def print_eqns(A_ubd, b_ub, verbose=0, lim=3, label=''):
|
||||
rows = len(b_ub)
|
||||
|
||||
|
|
@ -147,6 +151,13 @@ def simplify_rows(Ads, b_ub, remove_zd=False, corner=None):
|
|||
'slow_max': max,
|
||||
'slow_min': min,
|
||||
}[corner]
|
||||
# An outlier to make unknown values be ignored
|
||||
T_UNK = {
|
||||
'fast_max': 0,
|
||||
'fast_min': 10e9,
|
||||
'slow_max': 0,
|
||||
'slow_min': 10e9,
|
||||
}[corner]
|
||||
|
||||
sys.stdout.write('SimpR ')
|
||||
sys.stdout.flush()
|
||||
|
|
@ -173,7 +184,7 @@ def simplify_rows(Ads, b_ub, remove_zd=False, corner=None):
|
|||
continue
|
||||
|
||||
rowt = Ar_ds2t(rowd)
|
||||
eqns[rowt] = minmax(eqns.get(rowt, 0), b)
|
||||
eqns[rowt] = minmax(eqns.get(rowt, T_UNK), b)
|
||||
|
||||
print(' done')
|
||||
if len(eqns) == 0:
|
||||
|
|
|
|||
|
|
@ -80,8 +80,8 @@ def derive_eq_by_row(Ads, b, verbose=0, col_lim=0, tweak=False):
|
|||
How to do this in a reasonable time span?
|
||||
Also equations are sparse, which makes this harder to compute
|
||||
'''
|
||||
assert len(Ads) == len(b), 'Ads, b length mismatch'
|
||||
rows = len(Ads)
|
||||
assert rows == len(b)
|
||||
|
||||
# Index equations into hash maps so can lookup sparse elements quicker
|
||||
assert len(Ads) == len(b)
|
||||
|
|
@ -403,6 +403,8 @@ def massage_equations_inc_col_lim(Ads, b, verbose=False, corner=None):
|
|||
Remove these columns as necessary to speed up solving
|
||||
'''
|
||||
|
||||
assert len(Ads) == len(b), 'Ads, b length mismatch'
|
||||
|
||||
def debug(what):
|
||||
if verbose:
|
||||
print('')
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.optimize.linprog.html
|
||||
from scipy.optimize import linprog
|
||||
from timfuz import Benchmark, simplify_rows, loadc_Ads_b, index_names, A_ds2np, run_sub_json, print_eqns, Ads2bounds, instances, SimplifiedToZero
|
||||
from timfuz import Benchmark, simplify_rows, loadc_Ads_b, index_names, A_ds2np, run_sub_json, print_eqns, Ads2bounds, instances, SimplifiedToZero, allow_zero_eqns
|
||||
from timfuz_massage import massage_equations
|
||||
import numpy as np
|
||||
import glob
|
||||
|
|
@ -68,15 +68,30 @@ def check_feasible(A_ub, b_ub):
|
|||
raise Exception("Bad ")
|
||||
print(' done')
|
||||
|
||||
def filter_bounds(Ads, b, bounds):
|
||||
def filter_bounds(Ads, b, bounds, corner):
|
||||
'''Given min variable delays, remove rows that won't constrain solution'''
|
||||
#assert len(bounds) > 0
|
||||
|
||||
if 'max' in corner:
|
||||
# Keep delays possibly larger than current bound
|
||||
def keep(row_b, est):
|
||||
return row_b > est
|
||||
T_UNK = 0
|
||||
elif 'min' in corner:
|
||||
# Keep delays possibly smaller than current bound
|
||||
def keep(row_b, est):
|
||||
return row_b < est
|
||||
T_UNK = 1e9
|
||||
else:
|
||||
assert 0
|
||||
|
||||
ret_Ads = []
|
||||
ret_b = []
|
||||
for row_ds, row_b in zip(Ads, b):
|
||||
# some variables get estimated at 0
|
||||
est = sum([bounds.get(k, 0) * v for k, v in row_ds.items()])
|
||||
est = sum([bounds.get(k, T_UNK) * v for k, v in row_ds.items()])
|
||||
# will this row potentially constrain us more?
|
||||
if row_b > est:
|
||||
if keep(row_b, est):
|
||||
ret_Ads.append(row_ds)
|
||||
ret_b.append(row_b)
|
||||
return ret_Ads, ret_b
|
||||
|
|
@ -114,11 +129,14 @@ def run(fns_in, corner, run_corner, sub_json=None, sub_csv=None, dedup=True, mas
|
|||
if sub_csv:
|
||||
Ads2, b2 = loadc_Ads_b([sub_csv], corner, ico=True)
|
||||
bounds = Ads2bounds(Ads2, b2)
|
||||
assert len(bounds), 'Failed to load bounds'
|
||||
rows_old = len(Ads)
|
||||
Ads, b = filter_bounds(Ads, b, bounds)
|
||||
print('Filter bounds: %s => %s rows' % (rows_old, len(Ads)))
|
||||
Ads, b = filter_bounds(Ads, b, bounds, corner)
|
||||
print('Filter bounds: %s => %s + %s rows' % (rows_old, len(Ads), len(Ads2)))
|
||||
Ads = Ads + Ads2
|
||||
b = b + b2
|
||||
assert len(Ads) or allow_zero_eqns()
|
||||
assert len(Ads) == len(b), 'Ads, b length mismatch'
|
||||
|
||||
if verbose:
|
||||
print
|
||||
|
|
@ -126,6 +144,7 @@ def run(fns_in, corner, run_corner, sub_json=None, sub_csv=None, dedup=True, mas
|
|||
|
||||
#print
|
||||
#col_dist(A_ubd, 'final', names)
|
||||
print('b10', b[0:100])
|
||||
|
||||
'''
|
||||
Given:
|
||||
|
|
@ -142,7 +161,7 @@ def run(fns_in, corner, run_corner, sub_json=None, sub_csv=None, dedup=True, mas
|
|||
try:
|
||||
Ads, b = massage_equations(Ads, b, corner=corner)
|
||||
except SimplifiedToZero:
|
||||
if os.getenv('ALLOW_ZERO_EQN', 'N') != 'Y':
|
||||
if not allow_zero_eqns():
|
||||
raise
|
||||
print('WARNING: simplified to zero equations')
|
||||
Ads = []
|
||||
|
|
|
|||
Loading…
Reference in New Issue