def run(fns_in, fnout, tile_json_fn, verbose=False): # modified in place tilej = json.load(open(tile_json_fn, 'r')) for fnin in fns_in: Ads, bs = loadc_Ads_bs([fnin], ico=True) bounds = Ads2bounds(Ads, bs) for tile in tilej['tiles'].values(): pips = tile['pips'] for k, v in pips.items(): pips[k] = bounds.get('PIP_' + v, [None, None, None, None]) wires = tile['wires'] for k, v in wires.items(): wires[k] = bounds.get('WIRE_' + v, [None, None, None, None]) timfuz.tilej_stats(tilej) json.dump( tilej, open(fnout, 'w'), sort_keys=True, indent=4, separators=(',', ': '))
def gen_flat(fns_in, sub_json, corner=None): Ads, bs = loadc_Ads_bs(fns_in, ico=True) bounds = Ads2bounds(Ads, bs) zeros = set() nonzeros = set() for bound_name, bound_bs in bounds.items(): sub = sub_json['subs'].get(bound_name, None) if sub: # put entire delay into pivot pivot = sub_json['pivots'][bound_name] assert pivot not in zeros nonzeros.add(pivot) non_pivot = set(sub.keys() - set([pivot])) #for name in non_pivot: # assert name not in nonzeros, (pivot, name, nonzeros) zeros.update(non_pivot) yield pivot, bound_bs else: nonzeros.add(bound_name) yield bound_name, bound_bs # non-pivots can appear multiple times, but they should always be zero # however, due to substitution limitations, just warn violations = zeros.intersection(nonzeros) if len(violations): print('WARNING: %s non-0 non-pivot' % (len(violations))) # XXX: how to best handle these? # should they be fixed 0? if corner: zero_row = [None, None, None, None] zero_row[corner_s2i[corner]] = 0 for zero in zeros - violations: yield zero, zero_row
def gen_flat(fns_in, sub_json, corner=None): Ads, bs = loadc_Ads_bs(fns_in) bounds = Ads2bounds(Ads, bs) # Elements with zero delay assigned due to sub group group_zeros = set() # Elements with a concrete delay nonzeros = set() if corner: zero_row = [None, None, None, None] zero_row[corner_s2i[corner]] = 0 else: zero_row = None for bound_name, bound_bs in bounds.items(): sub = sub_json['subs'].get(bound_name, None) if bound_name in sub_json['zero_names']: if zero_row: yield bound_name, 0 elif sub: #print('sub', sub) # put entire delay into pivot pivot = sub_json['pivots'][bound_name] assert pivot not in group_zeros nonzeros.add(pivot) non_pivot = set(sub.keys() - set([pivot])) #for name in non_pivot: # assert name not in nonzeros, (pivot, name, nonzeros) group_zeros.update(non_pivot) #print('yield PIVOT', pivot) yield pivot, bound_bs else: nonzeros.add(bound_name) yield bound_name, bound_bs # non-pivots can appear multiple times, but they should always be zero # however, due to substitution limitations, just warn violations = group_zeros.intersection(nonzeros) if len(violations): print('WARNING: %s non-0 non-pivot' % (len(violations))) # XXX: how to best handle these? # should they be fixed 0? if zero_row: # ZERO names should always be zero #print('ZEROs: %u' % len(sub_json['zero_names'])) for zero in sub_json['zero_names']: #print('yield ZERO', zero) yield zero, zero_row real_zeros = group_zeros - violations print( 'Zero candidates: %u w/ %u non-pivot conflicts => %u zeros as solved' % (len(group_zeros), len(violations), len(real_zeros))) # Only yield elements not already yielded for zero in real_zeros: #print('yield solve-0', zero) yield zero, zero_row
def run(fns_in, fnout, tile_json_fn, verbose=False): # modified in place tilej = json.load(open(tile_json_fn, 'r')) for fnin in fns_in: Ads, bs = loadc_Ads_bs([fnin]) bounds = Ads2bounds(Ads, bs) bounds_pw, bounds_sites = sep_bounds(bounds) print(len(bounds), len(bounds_pw), len(bounds_sites)) add_pip_wire(tilej, bounds_pw) add_sites(tilej, bounds_sites) timfuz.tilej_stats(tilej) json.dump(tilej, open(fnout, 'w'), sort_keys=True, indent=4, separators=(',', ': '))
def run(fns_in, corner, run_corner, sub_json=None, bounds_csv=None, dedup=True, massage=False, outfn=None, verbose=False, **kwargs): print('Loading data') Ads, b = loadc_Ads_b(fns_in, corner, ico=True) # Remove duplicate rows # is this necessary? # maybe better to just add them into the matrix directly if dedup: oldn = len(Ads) iold = instances(Ads) Ads, b = simplify_rows(Ads, b, corner=corner) 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) names_old = index_names(Ads) run_sub_json(Ads, sub_json, verbose=verbose) names = index_names(Ads) print("Sub: %u => %u names" % (len(names_old), len(names))) print('Sub: %u => %u instances' % (iold, instances(Ads))) else: names = index_names(Ads) ''' Substitution .csv Special .csv containing one variable per line Used primarily for multiple optimization passes, such as different algorithms or additional constraints ''' if bounds_csv: Ads2, b2 = loadc_Ads_b([bounds_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, 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 print_eqns(Ads, b, verbose=verbose) #print #col_dist(A_ubd, 'final', names) if massage: try: Ads, b = massage_equations(Ads, b, corner=corner) except SimplifiedToZero: if not allow_zero_eqns(): raise print('WARNING: simplified to zero equations') Ads = [] b = [] print('Converting to numpy...') names, Anp = A_ds2np(Ads) run_corner(Anp, np.asarray(b), names, corner, outfn=outfn, verbose=verbose, **kwargs)