From e76e84f72c765aaf2e5066b84f92739c4516d317 Mon Sep 17 00:00:00 2001 From: John McMaster Date: Wed, 29 Aug 2018 16:05:10 -0700 Subject: [PATCH] timfuz: csv_flat2group Signed-off-by: John McMaster --- timfuz/csv_flat2group.py | 71 ++++++++++++++++++++++++++++++++++++++++ timfuz/csv_group2flat.py | 16 +++++---- timfuz/timfuz.py | 26 ++++++++++++--- timfuz/timfuz_solve.py | 8 +---- 4 files changed, 103 insertions(+), 18 deletions(-) create mode 100644 timfuz/csv_flat2group.py diff --git a/timfuz/csv_flat2group.py b/timfuz/csv_flat2group.py new file mode 100644 index 00000000..7a050585 --- /dev/null +++ b/timfuz/csv_flat2group.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 + +# https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.optimize.linprog.html +from scipy.optimize import linprog +from timfuz import Benchmark, Ar_di2np, Ar_ds2t, A_di2ds, A_ds2di, simplify_rows, loadc_Ads_b, index_names, A_ds2np, load_sub, run_sub_json, A_ub_np2d, print_eqns, print_eqns_np, Ads2bounds, loadc_Ads_raw, instances +from timfuz_massage import massage_equations +import numpy as np +import glob +import json +import math +from collections import OrderedDict +from fractions import Fraction +import sys +import datetime +import os +import time + +def gen_group(fnin, sub_json, strict=False, verbose=False): + print('Loading data') + # FIXME: preserve corners + Ads, b = loadc_Ads_b([fnin], corner=None, ico=True) + + print('Sub: %u rows' % len(Ads)) + iold = instances(Ads) + names_old = index_names(Ads) + run_sub_json(Ads, sub_json, strict=strict, verbose=verbose) + names = index_names(Ads) + print("Sub: %u => %u names" % (len(names_old), len(names))) + print('Sub: %u => %u instances' % (iold, instances(Ads))) + + for row_ds, row_b in zip(Ads, b): + yield row_ds, [row_b for _ in range(4)] + +def run(fnin, fnout, sub_json, corner=None, strict=False, verbose=False): + with open(fnout, 'w') as fout: + fout.write('ico,fast_max fast_min slow_max slow_min,rows...\n') + for row_ds, row_bs in gen_group(fnin, sub_json, strict=strict): + row_ico = 1 + items = [str(row_ico), ' '.join([str(x) for x in row_bs])] + for k, v in sorted(row_ds.items()): + items.append('%u %s' % (v, k)) + fout.write(','.join(items) + '\n') + +def main(): + import argparse + + parser = argparse.ArgumentParser( + description= + 'Solve timing solution' + ) + + parser.add_argument('--verbose', action='store_true', help='') + parser.add_argument('--massage', action='store_true', help='') + parser.add_argument('--strict', action='store_true', help='') + parser.add_argument('--sub-csv', help='') + parser.add_argument('--sub-json', required=True, help='Group substitutions to make fully ranked') + parser.add_argument('fnin', default=None, help='input timing delay .csv') + parser.add_argument('fnout', default=None, help='output timing delay .csv') + args = parser.parse_args() + # Store options in dict to ease passing through functions + bench = Benchmark() + + sub_json = load_sub(args.sub_json) + + try: + run(args.fnin, args.fnout, sub_json=sub_json, strict=args.strict, verbose=args.verbose) + finally: + print('Exiting after %s' % bench) + +if __name__ == '__main__': + main() diff --git a/timfuz/csv_group2flat.py b/timfuz/csv_group2flat.py index c88b6992..14f51b60 100644 --- a/timfuz/csv_group2flat.py +++ b/timfuz/csv_group2flat.py @@ -47,10 +47,15 @@ def gen_flat(fnin, sub_json): for zero in zeros - violations: yield zero, 0 -def run(fnin, fnout, sub_json, corner=None, verbose=False): +def run(fnin, fnout, sub_json, corner=None, sort=False, verbose=False): + if sort: + sortf = sorted + else: + sortf = lambda x: x + with open(fnout, 'w') as fout: fout.write('ico,fast_max fast_min slow_max slow_min,rows...\n') - for name, delay in sorted(gen_flat(fnin, sub_json)): + for name, delay in sortf(gen_flat(fnin, sub_json)): row_ico = 1 corners = [delay for _ in range(4)] items = [str(row_ico), ' '.join([str(x) for x in corners])] @@ -67,6 +72,7 @@ def main(): parser.add_argument('--verbose', action='store_true', help='') parser.add_argument('--massage', action='store_true', help='') + parser.add_argument('--sort', action='store_true', help='') parser.add_argument('--sub-csv', help='') parser.add_argument('--sub-json', required=True, help='Group substitutions to make fully ranked') parser.add_argument('fnin', default=None, help='input timing delay .csv') @@ -75,12 +81,10 @@ def main(): # Store options in dict to ease passing through functions bench = Benchmark() - sub_json = None - if args.sub_json: - sub_json = load_sub(args.sub_json) + sub_json = load_sub(args.sub_json) try: - run(args.fnin, args.fnout, sub_json=sub_json, verbose=args.verbose) + run(args.fnin, args.fnout, sub_json=sub_json, sort=args.sort, verbose=args.verbose) finally: print('Exiting after %s' % bench) diff --git a/timfuz/timfuz.py b/timfuz/timfuz.py index ec9bfe28..6f2f8918 100644 --- a/timfuz/timfuz.py +++ b/timfuz/timfuz.py @@ -724,7 +724,7 @@ def load_sub(fn): return j -def row_sub_syms(row, sub_json, verbose=False): +def row_sub_syms(row, sub_json, strict=False, verbose=False): zero = Fraction(0) zero = 0 @@ -751,10 +751,10 @@ def row_sub_syms(row, sub_json, verbose=False): n = row[pivot] print(' pivot %u %s' % (n, pivot)) + #pivots = set(sub_json['pivots'].values()).intersection(row.keys()) for group, pivot in sorted(sub_json['pivots'].items()): if pivot not in row: continue - # take the sub out n times # note constants may be negative n = row[pivot] @@ -779,11 +779,21 @@ def row_sub_syms(row, sub_json, verbose=False): # after all constants are applied, the row should end up positive? # numeric precision issues previously limited this # Ex: AssertionError: ('PIP_BSW_2ELSING0', -2.220446049250313e-16) - if 0: + if strict: + # verify no subs are left + for subs in sub_json['subs'].values(): + for sub in subs: + assert sub not in row, 'Unexpected element %s' % sub + + # Verify all constants are positive for k, v in sorted(row.items()): assert v > 0, (k, v) -def run_sub_json(Ads, sub_json, verbose=False): +def run_sub_json(Ads, sub_json, strict=False, verbose=False): + ''' + strict: complain if a sub doesn't go in evenly + ''' + nrows = 0 nsubs = 0 @@ -801,7 +811,7 @@ def run_sub_json(Ads, sub_json, verbose=False): print('Row %u w/ %u elements' % (rowi, len(row))) row_orig = dict(row) - row_sub_syms(row, sub_json, verbose=verbose) + row_sub_syms(row, sub_json, strict=strict, verbose=verbose) nrows += 1 if row_orig != row: nsubs += 1 @@ -845,3 +855,9 @@ def Ads2bounds(Ads, b): assert v == 1 ret[k] = row_b return ret + +def instances(Ads): + ret = 0 + for row_ds in Ads: + ret += sum(row_ds.values()) + return ret diff --git a/timfuz/timfuz_solve.py b/timfuz/timfuz_solve.py index 4fdf5dbf..c6343e70 100644 --- a/timfuz/timfuz_solve.py +++ b/timfuz/timfuz_solve.py @@ -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, Ar_di2np, Ar_ds2t, A_di2ds, A_ds2di, simplify_rows, loadc_Ads_b, index_names, A_ds2np, load_sub, run_sub_json, A_ub_np2d, print_eqns, print_eqns_np, Ads2bounds +from timfuz import Benchmark, Ar_di2np, Ar_ds2t, A_di2ds, A_ds2di, simplify_rows, loadc_Ads_b, index_names, A_ds2np, load_sub, run_sub_json, A_ub_np2d, print_eqns, print_eqns_np, Ads2bounds, instances from timfuz_massage import massage_equations import numpy as np import glob @@ -68,12 +68,6 @@ def check_feasible(A_ub, b_ub): raise Exception("Bad ") print(' done') -def instances(Ads): - ret = 0 - for row_ds in Ads: - ret += sum(row_ds.values()) - return ret - def filter_bounds(Ads, b, bounds): '''Given min variable delays, remove rows that won't constrain solution''' ret_Ads = []