timfuz: build all four corners

Signed-off-by: John McMaster <johndmcmaster@gmail.com>
This commit is contained in:
John McMaster 2018-09-12 13:51:44 -07:00
parent 2dbe379200
commit e148ed5f91
5 changed files with 89 additions and 29 deletions

View File

@ -0,0 +1,42 @@
# Run corner specific calculations
TIMFUZ_DIR=$(XRAY_DIR)/fuzzers/007-timing
CORNER=slow_max
all: build/$(CORNER)/tilea.json
run:
$(MAKE) clean
$(MAKE) all
touch run.ok
clean:
rm -rf specimen_[0-9][0-9][0-9]/ seg_clblx.segbits __pycache__ run.ok
rm -rf vivado*.log vivado_*.str vivado*.jou design *.bits *.dcp *.bit
rm -rf build
.PHONY: all run clean
build/$(CORNER):
mkdir build/$(CORNER)
build/$(CORNER)/leastsq.csv: build/sub.json build/grouped.csv build/checksub build/$(CORNER)
# Create a rough timing model that approximately fits the given paths
python3 $(TIMFUZ_DIR)/solve_leastsq.py --sub-json build/sub.json build/grouped.csv --corner $(CORNER) --out build/$(CORNER)/leastsq.csv.tmp
mv build/$(CORNER)/leastsq.csv.tmp build/$(CORNER)/leastsq.csv
build/$(CORNER)/linprog.csv: build/$(CORNER)/leastsq.csv build/grouped.csv
# Tweak rough timing model, making sure all constraints are satisfied
python3 $(TIMFUZ_DIR)/solve_linprog.py --sub-json build/sub.json --sub-csv build/$(CORNER)/leastsq.csv --massage build/grouped.csv --corner $(CORNER) --out build/$(CORNER)/linprog.csv.tmp
mv build/$(CORNER)/linprog.csv.tmp build/$(CORNER)/linprog.csv
build/$(CORNER)/flat.csv: build/$(CORNER)/linprog.csv
# Take separated variables and back-annotate them to the original timing variables
python3 $(TIMFUZ_DIR)/csv_group2flat.py --sub-json build/sub.json --corner $(CORNER) --sort build/$(CORNER)/linprog.csv build/$(CORNER)/flat.csv.tmp
mv build/$(CORNER)/flat.csv.tmp build/$(CORNER)/flat.csv
build/$(CORNER)/tilea.json: build/$(CORNER)/flat.csv
# Final processing
# Insert timing delays into actual tile layouts
python3 $(TIMFUZ_DIR)/tile_annotate.py --tile-json $(TIMFUZ_DIR)/timgrid/build/timgrid.json build/$(CORNER)/flat.csv build/$(CORNER)/tilea.json

View File

@ -1,11 +1,30 @@
# project.mk: build specimens (run vivado), compute rref
# corner.mk: run corner specific calculations
N := 1
SPECIMENS := $(addprefix specimen_,$(shell seq -f '%03.0f' $(N)))
SPECIMENS_OK := $(addsuffix /OK,$(SPECIMENS))
CSVS := $(addsuffix /timing3.csv,$(SPECIMENS))
TIMFUZ_DIR=$(XRAY_DIR)/fuzzers/007-timing
CORNER=slow_max
RREF_CORNER=slow_max
all: build/tilea.json
TILEA_JSONS=build/fast_max/tilea.json build/fast_min/tilea.json build/slow_max/tilea.json build/slow_min/tilea.json
all: $(TILEA_JSONS)
# make build/checksub first
build/fast_max/tilea.json: build/checksub
$(MAKE) -f $(TIMFUZ_DIR)/projects/corner.mk CORNER=fast_max
build/fast_min/tilea.json: build/checksub
$(MAKE) -f $(TIMFUZ_DIR)/projects/corner.mk CORNER=fast_min
build/slow_max/tilea.json: build/checksub
$(MAKE) -f $(TIMFUZ_DIR)/projects/corner.mk CORNER=slow_max
build/slow_min/tilea.json: build/checksub
$(MAKE) -f $(TIMFUZ_DIR)/projects/corner.mk CORNER=slow_min
fast_max: build/fast_max/tilea.json
fast_min: build/fast_min/tilea.json
slow_max: build/slow_max/tilea.json
slow_min: build/slow_min/tilea.json
$(SPECIMENS_OK):
bash generate.sh $(subst /OK,,$@)
@ -21,13 +40,15 @@ clean:
rm -rf vivado*.log vivado_*.str vivado*.jou design *.bits *.dcp *.bit
rm -rf build
.PHONY: database pushdb run clean
.PHONY: all run clean
# rref should be the same regardless of corner
build/sub.json: $(SPECIMENS_OK)
mkdir -p build
# Discover which variables can be separated
# This is typically the longest running operation
python3 $(TIMFUZ_DIR)/rref.py --corner $(CORNER) --simplify --out build/sub.json.tmp $(CSVS)
python3 $(TIMFUZ_DIR)/rref.py --corner $(RREF_CORNER) --simplify --out build/sub.json.tmp $(CSVS)
mv build/sub.json.tmp build/sub.json
build/grouped.csv: $(SPECIMENS_OK) build/sub.json
@ -40,23 +61,3 @@ build/checksub: build/grouped.csv build/sub.json
python3 $(TIMFUZ_DIR)/checksub.py --sub-json build/sub.json build/grouped.csv
touch build/checksub
build/leastsq.csv: build/sub.json build/grouped.csv build/checksub
# Create a rough timing model that approximately fits the given paths
python3 $(TIMFUZ_DIR)/solve_leastsq.py --sub-json build/sub.json build/grouped.csv --corner $(CORNER) --out build/leastsq.csv.tmp
mv build/leastsq.csv.tmp build/leastsq.csv
build/linprog.csv: build/leastsq.csv build/grouped.csv
# Tweak rough timing model, making sure all constraints are satisfied
python3 $(TIMFUZ_DIR)/solve_linprog.py --sub-json build/sub.json --sub-csv build/leastsq.csv --massage build/grouped.csv --corner $(CORNER) --out build/linprog.csv.tmp
mv build/linprog.csv.tmp build/linprog.csv
build/flat.csv: build/linprog.csv
# Take separated variables and back-annotate them to the original timing variables
python3 $(TIMFUZ_DIR)/csv_group2flat.py --sub-json build/sub.json --corner $(CORNER) --sort build/linprog.csv build/flat.csv.tmp
mv build/flat.csv.tmp build/flat.csv
build/tilea.json: build/flat.csv
# Final processing
# Insert timing delays into actual tile layouts
python3 $(TIMFUZ_DIR)/tile_annotate.py --tile-json $(TIMFUZ_DIR)/timgrid/build/timgrid.json build/flat.csv build/tilea.json

View File

@ -12,7 +12,7 @@ import os
import time
import timfuz_solve
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
@ -24,7 +24,7 @@ def save(outfn, res, names, corner):
# 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?
@ -40,6 +40,12 @@ def save(outfn, res, names, corner):
print('Wrote: zeros %u => %u / %u constrained delays' % (zeros, len(names) - zeros, len(names)))
def run_corner(Anp, b, names, corner, verbose=False, opts={}, meta={}, outfn=None):
if len(Anp) == 0:
print('WARNING: zero equations')
if outfn:
save(outfn, [], [], corner)
return
# Given timing scores for above delays (-ps)
assert type(Anp[0]) is np.ndarray, type(Anp[0])
assert type(b) is np.ndarray, type(b)
@ -126,7 +132,7 @@ def run_corner(Anp, b, names, corner, verbose=False, opts={}, meta={}, outfn=Non
print('Delay on %d / %d' % (nonzeros, len(res.x)))
if outfn:
save(outfn, res, names, corner)
save(outfn, res.x, names, corner)
def main():
import argparse

View File

@ -37,6 +37,10 @@ corner_s2i = OrderedDict([
('slow_min', 3),
])
# Equations are filtered out until nothing is left
class SimplifiedToZero(Exception):
pass
def print_eqns(A_ubd, b_ub, verbose=0, lim=3, label=''):
rows = len(b_ub)
@ -172,6 +176,8 @@ def simplify_rows(Ads, b_ub, remove_zd=False, corner=None):
eqns[rowt] = minmax(eqns.get(rowt, 0), b)
print(' done')
if len(eqns) == 0:
raise SimplifiedToZero()
#A_ub_ret = eqns.keys()
A_ubd_ret, b_ub_ret = Ab_ub_dt2d(eqns)

View File

@ -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, instances
from timfuz import Benchmark, simplify_rows, loadc_Ads_b, index_names, A_ds2np, run_sub_json, print_eqns, Ads2bounds, instances, SimplifiedToZero
from timfuz_massage import massage_equations
import numpy as np
import glob
@ -139,7 +139,12 @@ def run(fns_in, corner, run_corner, sub_json=None, sub_csv=None, dedup=True, mas
This creates derived constraints to provide more realistic results
'''
if massage:
Ads, b = massage_equations(Ads, b, corner=corner)
try:
Ads, b = massage_equations(Ads, b, corner=corner)
except SimplifiedToZero:
print('WARNING: simplified to zero equations')
Ads = []
b = []
print('Converting to numpy...')
names, Anp = A_ds2np(Ads)