mirror of https://github.com/openXC7/prjxray.git
timfuz: linprog write output csv
Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
parent
5ecbd135ce
commit
e83866af72
|
|
@ -111,6 +111,36 @@ def run_corner(Anp, b, names, verbose=False, opts={}, meta={}, outfn=None):
|
|||
print('Writing %s' % fn_out)
|
||||
np.save(fn_out, (3, c, A_ub, b_ub, bounds, names, res, meta))
|
||||
|
||||
if outfn:
|
||||
# ballpark minimum actual observed delay is around 7 (carry chain)
|
||||
# anything less than one is probably a solver artifact
|
||||
delta = 0.5
|
||||
|
||||
print('Writing resutls')
|
||||
skips = 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):
|
||||
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
|
||||
#xvali = round(xval)
|
||||
xvali = math.ceil(xval)
|
||||
corners = [xvali for _ in range(4)]
|
||||
items = [str(row_ico), ' '.join([str(x) for x in corners])]
|
||||
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)))
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
|
|
@ -121,6 +151,7 @@ def main():
|
|||
|
||||
parser.add_argument('--verbose', action='store_true', help='')
|
||||
parser.add_argument('--massage', action='store_true', help='')
|
||||
parser.add_argument('--sub-csv', help='')
|
||||
parser.add_argument('--sub-json', help='Group substitutions to make fully ranked')
|
||||
parser.add_argument('--corner', default="slow_max", help='')
|
||||
parser.add_argument('--out', default=None, help='output timing delay .json')
|
||||
|
|
@ -141,7 +172,7 @@ def main():
|
|||
sub_json = load_sub(args.sub_json)
|
||||
|
||||
try:
|
||||
timfuz_solve.run(run_corner=run_corner, sub_json=sub_json,
|
||||
timfuz_solve.run(run_corner=run_corner, sub_json=sub_json, sub_csv=args.sub_csv,
|
||||
fns_in=fns_in, corner=args.corner, massage=args.massage, outfn=args.out, verbose=args.verbose)
|
||||
finally:
|
||||
print('Exiting after %s' % bench)
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ def check_feasible(A_ub, b_ub):
|
|||
Delays should be in order of ns, so a 10 ns delay should be way above what anything should be
|
||||
Series can have several hundred delay elements
|
||||
Max delay in ballpark
|
||||
'''
|
||||
'''
|
||||
xs = [1e9 for _i in range(cols)]
|
||||
|
||||
# FIXME: use the correct np function to do this for me
|
||||
|
|
@ -74,7 +74,29 @@ def instances(Ads):
|
|||
ret += sum(row_ds.values())
|
||||
return ret
|
||||
|
||||
def run(fns_in, corner, run_corner, sub_json=None, dedup=True, massage=False, outfn=None, verbose=False, **kwargs):
|
||||
def Ads2bounds(Ads, b):
|
||||
ret = {}
|
||||
for row_ds, row_b in zip(Ads, b):
|
||||
assert len(row_ds) == 1
|
||||
k, v = list(row_ds.items())[0]
|
||||
assert v == 1
|
||||
ret[k] = row_b
|
||||
return ret
|
||||
|
||||
def filter_bounds(Ads, b, bounds):
|
||||
'''Given min variable delays, remove rows that won't constrain solution'''
|
||||
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()])
|
||||
# will this row potentially constrain us more?
|
||||
if row_b > est:
|
||||
ret_Ads.append(row_ds)
|
||||
ret_b.append(row_b)
|
||||
return ret_Ads, ret_b
|
||||
|
||||
def run(fns_in, corner, run_corner, sub_json=None, sub_csv=None, dedup=True, massage=False, outfn=None, verbose=False, **kwargs):
|
||||
print('Loading data')
|
||||
Ads, b = loadc_Ads_b(fns_in, corner, ico=True)
|
||||
|
||||
|
|
@ -87,7 +109,7 @@ def run(fns_in, corner, run_corner, sub_json=None, dedup=True, massage=False, ou
|
|||
Ads, b = simplify_rows(Ads, b)
|
||||
print('Simplify %u => %u rows' % (oldn, len(Ads)))
|
||||
print('Simplify %u => %u instances' % (iold, instances(Ads)))
|
||||
|
||||
|
||||
if sub_json:
|
||||
print('Sub: %u rows' % len(Ads))
|
||||
iold = instances(Ads)
|
||||
|
|
@ -99,6 +121,23 @@ def run(fns_in, corner, run_corner, sub_json=None, dedup=True, massage=False, ou
|
|||
else:
|
||||
names = index_names(Ads)
|
||||
|
||||
# post substitution csv
|
||||
# actually this might not be strictly necessary since subs would just not apply
|
||||
# however, I wanted to do some filtering based on expected form
|
||||
if sub_csv:
|
||||
Ads2, b2 = loadc_Ads_b([sub_csv], corner, ico=True)
|
||||
if 0:
|
||||
Ads = Ads + Ads2
|
||||
b = b + b2
|
||||
else:
|
||||
bounds = Ads2bounds(Ads2, b2)
|
||||
rows_old = len(Ads)
|
||||
Ads, b = filter_bounds(Ads, b, bounds)
|
||||
print('Filter bounds: %s => %s rows' % (rows_old, len(Ads)))
|
||||
if 1:
|
||||
Ads = Ads + Ads2
|
||||
b = b + b2
|
||||
|
||||
if verbose:
|
||||
print
|
||||
print_eqns(Ads, b, verbose=verbose)
|
||||
|
|
@ -115,7 +154,7 @@ def run(fns_in, corner, run_corner, sub_json=None, dedup=True, massage=False, ou
|
|||
However, a better solution is something like
|
||||
a = 10
|
||||
b = 90
|
||||
This creates derived constraints to provide more realistic results
|
||||
This creates derived constraints to provide more realistic results
|
||||
'''
|
||||
if massage:
|
||||
Ads, b = massage_equations(Ads, b)
|
||||
|
|
|
|||
Loading…
Reference in New Issue