fixed synth scraping, best delay plotting

This commit is contained in:
Madeleine Masser-Frye 2022-05-26 20:51:00 +00:00
parent b13c3d5385
commit e76986b31e
2 changed files with 1295 additions and 1297 deletions

View File

@ -24,60 +24,69 @@ def synthsfromcsv(filename):
except: pass except: pass
allSynths[i] = Synth(*allSynths[i]) allSynths[i] = Synth(*allSynths[i])
def synthsintocsv(mod=None, width=None): def synthsintocsv():
''' writes a CSV with one line for every available synthesis ''' writes a CSV with one line for every available synthesis
each line contains the module, tech, width, target freq, and resulting metrics each line contains the module, tech, width, target freq, and resulting metrics
''' '''
specStr = ''
if mod != None:
specStr = mod
if width != None:
specStr += ('_'+str(width))
specStr += '*'
bashCommand = "grep 'Critical Path Length' runs/ppa_{}/reports/*qor*".format(specStr) bashCommand = "find . -path '*runs/ppa*rv32e*' -prune"
outputCPL = subprocess.check_output(['bash','-c', bashCommand]) output = subprocess.check_output(['bash','-c', bashCommand])
linesCPL = outputCPL.decode("utf-8").split('\n')[:-1] allSynths = output.decode("utf-8").split('\n')[:-1]
bashCommand = "grep 'Design Area' runs/ppa_{}/reports/*qor*".format(specStr) specReg = re.compile('[a-zA-Z0-9]+')
outputDA = subprocess.check_output(['bash','-c', bashCommand]) metricReg = re.compile('\d+\.\d+[e]?[-+]?\d*')
linesDA = outputDA.decode("utf-8").split('\n')[:-1]
bashCommand = "grep '100' runs/ppa_{}/reports/*power*".format(specStr)
outputP = subprocess.check_output(['bash','-c', bashCommand])
linesP = outputP.decode("utf-8").split('\n')[:-1]
cpl = re.compile('\d{1}\.\d{6}')
f = re.compile('_\d*_MHz')
wm = re.compile('ppa_\w*_\d*_qor')
da = re.compile('\d*\.\d{6}')
p = re.compile('\d+\.\d+[e-]*\d+')
t = re.compile('[a-zA-Z0-9]+nm')
file = open("ppaData.csv", "w") file = open("ppaData.csv", "w")
writer = csv.writer(file) writer = csv.writer(file)
writer.writerow(['Module', 'Tech', 'Width', 'Target Freq', 'Delay', 'Area', 'L Power (nW)', 'D energy (mJ)']) writer.writerow(['Module', 'Tech', 'Width', 'Target Freq', 'Delay', 'Area', 'L Power (nW)', 'D energy (mJ)'])
for i in range(len(linesCPL)): for oneSynth in allSynths:
line = linesCPL[i] module, width, risc, tech, freq = specReg.findall(oneSynth)[2:7]
mwm = wm.findall(line)[0][4:-4].split('_') tech = tech[:-2]
freq = int(f.findall(line)[0][1:-4]) metrics = []
delay = float(cpl.findall(line)[0]) for phrase in [['Path Length', 'qor'], ['Design Area', 'qor'], ['100', 'power']]:
area = float(da.findall(linesDA[i])[0]) bashCommand = 'grep "{}" '+ oneSynth[2:]+'/reports/*{}*'
mod = mwm[0] bashCommand = bashCommand.format(*phrase)
width = int(mwm[1]) try: output = subprocess.check_output(['bash','-c', bashCommand])
tech = t.findall(line)[0][:-2] except: print("At least one synth run doesn't have reports, try cleanup() first")
try: #fix nums = metricReg.findall(str(output))
power = p.findall(linesP[i]) nums = [float(m) for m in nums]
lpower = float(power[2]) metrics += nums
denergy = float(power[1])*delay delay = metrics[0]
except: area = metrics[1]
lpower = 0 lpower = metrics[4]
denergy = 0 denergy = (metrics[2] + metrics[3])*delay # (switching + internal powers)*delay
writer.writerow([mod, tech, width, freq, delay, area, lpower, denergy]) writer.writerow([module, tech, width, freq, delay, area, lpower, denergy])
file.close() file.close()
def cleanup():
''' removes runs that didn't work
'''
bashCommand = 'grep -r "Error" runs/ppa*/reports/*qor*'
try:
output = subprocess.check_output(['bash','-c', bashCommand])
allSynths = output.decode("utf-8").split('\n')[:-1]
for run in allSynths:
run = run.split('MHz')[0]
bc = 'rm -r '+ run + '*'
output = subprocess.check_output(['bash','-c', bc])
except: pass
bashCommand = "find . -path '*runs/ppa*rv32e*' -prune"
output = subprocess.check_output(['bash','-c', bashCommand])
allSynths = output.decode("utf-8").split('\n')[:-1]
for oneSynth in allSynths:
for phrase in [['Path Length', 'qor'], ['Design Area', 'qor'], ['100', 'power']]:
bashCommand = 'grep "{}" '+ oneSynth[2:]+'/reports/*{}*'
bashCommand = bashCommand.format(*phrase)
try: output = subprocess.check_output(['bash','-c', bashCommand])
except:
bc = 'rm -r '+ oneSynth[2:]
try: output = subprocess.check_output(['bash','-c', bc])
except: pass
print("All cleaned up!")
def getVals(tech, module, var, freq=None): def getVals(tech, module, var, freq=None):
''' for a specified tech, module, and variable/metric ''' for a specified tech, module, and variable/metric
returns a list of values for that metric in ascending width order with the appropriate units returns a list of values for that metric in ascending width order with the appropriate units
@ -112,7 +121,8 @@ def getVals(tech, module, var, freq=None):
m = oneSynth.delay m = oneSynth.delay
osdict = oneSynth._asdict() osdict = oneSynth._asdict()
met = osdict[var] met = osdict[var]
metric += [met] try: metric += [met]
except: pass
if ('flop' in module) & (var == 'area'): if ('flop' in module) & (var == 'area'):
metric = [m/2 for m in metric] # since two flops in each module metric = [m/2 for m in metric] # since two flops in each module
@ -144,9 +154,9 @@ def genLegend(fits, coefs, r2, techcolor):
eq += " + " + coefsr[ind] + "*Nlog2(N)" eq += " + " + coefsr[ind] + "*Nlog2(N)"
ind += 1 ind += 1
tech, c = techcolor tech, c, m = techcolor
legend_elements = [lines.Line2D([0], [0], color=c, label=eq), legend_elements = [lines.Line2D([0], [0], color=c, label=eq),
lines.Line2D([0], [0], color=c, ls='', marker='o', label=tech +' $R^2$='+ str(round(r2, 4)))] lines.Line2D([0], [0], color=c, ls='', marker=m, label=tech +' $R^2$='+ str(round(r2, 4)))]
return legend_elements return legend_elements
def oneMetricPlot(module, var, freq=None, ax=None, fits='clsgn'): def oneMetricPlot(module, var, freq=None, ax=None, fits='clsgn'):
@ -167,13 +177,13 @@ def oneMetricPlot(module, var, freq=None, ax=None, fits='clsgn'):
global techcolors global techcolors
global widths global widths
for combo in techcolors: for combo in techcolors:
tech, c = combo tech, c, m = combo
metric, units = getVals(tech, module, var, freq=freq) metric, units = getVals(tech, module, var, freq=freq)
if len(metric) == 5: if len(metric) == 5:
xp, pred, leg = regress(widths, metric, combo, fits) xp, pred, leg = regress(widths, metric, combo, fits)
fullLeg += leg fullLeg += leg
ax.scatter(widths, metric, color=c) ax.scatter(widths, metric, color=c, marker=m)
ax.plot(xp, pred, color=c) ax.plot(xp, pred, color=c)
ax.legend(handles=fullLeg) ax.legend(handles=fullLeg)
@ -183,7 +193,7 @@ def oneMetricPlot(module, var, freq=None, ax=None, fits='clsgn'):
ax.set_ylabel(str.title(var) + units) ax.set_ylabel(str.title(var) + units)
if singlePlot: if singlePlot:
titleStr = " (target " + str(freq)+ "MHz)" if freq != None else " (min delay)" titleStr = " (target " + str(freq)+ "MHz)" if freq != None else " (best delay)"
ax.set_title(module + titleStr) ax.set_title(module + titleStr)
plt.show() plt.show()
@ -266,8 +276,6 @@ def noOutliers(freqs, delays, areas):
f=[] f=[]
d=[] d=[]
a=[] a=[]
try:
ind = delays.index(min(delays)) ind = delays.index(min(delays))
med = freqs[ind] med = freqs[ind]
for i in range(len(freqs)): for i in range(len(freqs)):
@ -276,7 +284,6 @@ def noOutliers(freqs, delays, areas):
f += [freqs[i]] f += [freqs[i]]
d += [delays[i]] d += [delays[i]]
a += [areas[i]] a += [areas[i]]
except: pass
return f, d, a return f, d, a
@ -292,7 +299,7 @@ def freqPlot(tech, mod, width):
delaysL[ind] += [oneSynth.delay] delaysL[ind] += [oneSynth.delay]
areasL[ind] += [oneSynth.area] areasL[ind] += [oneSynth.area]
f, (ax1, ax2, ax3, ax4, ax5) = plt.subplots(5, 1, sharex=True) f, (ax1, ax2, ax3, ax4) = plt.subplots(4, 1, sharex=True)
for ind in [0,1]: for ind in [0,1]:
areas = areasL[ind] areas = areasL[ind]
@ -300,17 +307,15 @@ def freqPlot(tech, mod, width):
freqs = freqsL[ind] freqs = freqsL[ind]
if ('flop' in mod): areas = [m/2 for m in areas] # since two flops in each module if ('flop' in mod): areas = [m/2 for m in areas] # since two flops in each module
freqs, delays, areas = noOutliers(freqs, delays, areas) freqs, delays, areas = noOutliers(freqs, delays, areas) # comment out to see all syntheses
c = 'blue' if ind else 'green' c = 'blue' if ind else 'green'
adprod = adprodpow(areas, delays, 2) adprod = adprodpow(areas, delays, 1)
adpow = adprodpow(areas, delays, 3) adpow = adprodpow(areas, delays, 2)
adpow2 = adprodpow(areas, delays, 4)
ax1.scatter(freqs, delays, color=c) ax1.scatter(freqs, delays, color=c)
ax2.scatter(freqs, areas, color=c) ax2.scatter(freqs, areas, color=c)
ax3.scatter(freqs, adprod, color=c) ax3.scatter(freqs, adprod, color=c)
ax4.scatter(freqs, adpow, color=c) ax4.scatter(freqs, adpow, color=c)
ax5.scatter(freqs, adpow2, color=c)
legend_elements = [lines.Line2D([0], [0], color='green', ls='', marker='o', label='timing achieved'), legend_elements = [lines.Line2D([0], [0], color='green', ls='', marker='o', label='timing achieved'),
lines.Line2D([0], [0], color='blue', ls='', marker='o', label='slack violated')] lines.Line2D([0], [0], color='blue', ls='', marker='o', label='slack violated')]
@ -341,22 +346,26 @@ def plotPPA(mod, freq=None):
overlays data from both techs overlays data from both techs
''' '''
fig, axs = plt.subplots(2, 2) fig, axs = plt.subplots(2, 2)
oneMetricPlot(mod, 'delay', ax=axs[0,0], fits='clg', freq=freq) oneMetricPlot(mod, 'delay', ax=axs[0,0], fits='cg', freq=freq)
oneMetricPlot(mod, 'area', ax=axs[0,1], fits='s', freq=freq) oneMetricPlot(mod, 'area', ax=axs[0,1], fits='s', freq=freq)
oneMetricPlot(mod, 'lpower', ax=axs[1,0], fits='c', freq=freq) oneMetricPlot(mod, 'lpower', ax=axs[1,0], fits='s', freq=freq)
oneMetricPlot(mod, 'denergy', ax=axs[1,1], fits='s', freq=freq) oneMetricPlot(mod, 'denergy', ax=axs[1,1], fits='s', freq=freq)
titleStr = " (target " + str(freq)+ "MHz)" if freq != None else " (min delay)" titleStr = " (target " + str(freq)+ "MHz)" if freq != None else " (best delay)"
plt.suptitle(mod + titleStr) plt.suptitle(mod + titleStr)
plt.show() plt.show()
Synth = namedtuple("Synth", "module tech width freq delay area lpower denergy") if __name__ == '__main__':
techcolors = [['sky90', 'green'], ['tsmc28', 'blue']]
widths = [8, 16, 32, 64, 128]
synthsintocsv()
synthsfromcsv('ppaData.csv') # your csv here! # set up stuff, global variables
Synth = namedtuple("Synth", "module tech width freq delay area lpower denergy")
techcolors = [['sky90', 'green', 'o'], ['tsmc28', 'blue', '^']] # add another list here for gf32
widths = [8, 16, 32, 64, 128]
### examples # synthsintocsv() # slow, run only when new synth runs to add to csv
# oneMetricPlot('add', 'delay')
#freqPlot('sky90', 'add', 8) synthsfromcsv('ppaData.csv') # your csv here!
#plotPPA('add')
### examples
oneMetricPlot('add', 'delay')
freqPlot('sky90', 'comparator', 16)
plotPPA('add')

File diff suppressed because it is too large Load Diff