blob: 74a0fc66d89d8e11e36011def80225c68f685055 [file] [log] [blame] [edit]
""" Gathers statistics from VPR runs, like pack/place/route runtimes and Fmax.
"""
import argparse
import csv
import os
import sys
import subprocess
def scan_runtime(step, fname):
""" Find runtime of VPR log (if any), else returns empty str. """
try:
with open(fname, 'r') as f:
step_runtime = 0
total_runtime = 0
for line in f:
if line.startswith("# {} took".format(step)):
step_runtime = float(line.split()[3])
if line.startswith('The entire flow of VPR took'):
total_runtime = float(line.split()[6])
step_overhead = total_runtime - step_runtime
return str(step_runtime), str(step_overhead)
except FileNotFoundError:
return ""
def scan_critical(fname):
""" Find critical path and Fmax from VPR log (if any).
Returns
-------
critical_path : str
Critical path delay in nsec
fmax : str
Fmax in MHz.
"""
try:
with open(fname, 'r') as f:
final_cpd = 0.0
final_fmax = 0.0
final_cpd_geomean = 0.0
final_fmax_geomean = 0.0
for line in f:
if line.startswith('Final critical path delay'):
parts = line.split()
if len(parts) >= 9:
# Final critical path delay (least slack): 16.8182 ns, Fmax: 59.4592 MHz
final_cpd = float(parts[6])
final_fmax = float(parts[9])
elif len(parts) == 8 and parts[7].strip() == 'ns':
# Final critical path delay (least slack): 17.9735 ns
final_cpd = float(parts[6])
final_fmax = 1000. / final_cpd
if line.startswith(
'Final geomean non-virtual intra-domain period'):
parts = line.split()
final_cpd_geomean = parts[5]
if final_cpd_geomean == "nan":
final_cpd_geomean = "N/A"
final_fmax_geomean = "N/A"
continue
final_cpd_geomean = float(parts[5])
final_fmax_geomean = 1000. / final_cpd_geomean
return str(final_cpd), str(final_fmax), str(
final_cpd_geomean
), str(final_fmax_geomean)
except FileNotFoundError:
pass
return "", ""
def get_last_n_dirs(path, n):
dirs = path.split("/")
return "/".join(dirs[-n:])
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("build_dir")
args = parser.parse_args()
fields = [
"path",
"pack time (sec)",
"pack overhead (sec)",
"place time (sec)",
"place overhead (sec)",
"route time (sec)",
"route overhead (sec)",
"t_crit (ns)",
"Fmax (MHz)",
"t_crit geomean (ns)",
"Fmax geomean (MHz)",
]
print(
''.join(
subprocess.
getoutput('git show --oneline -s --decorate --color=never')
),
file=sys.stdout
)
w = csv.DictWriter(sys.stdout, fields)
w.writeheader()
rows = list()
for root, dirs, files in os.walk(args.build_dir):
if 'pack.log' in files:
d = {}
# Get step runtimes with the respective overhead
pack_time, pack_overhead = scan_runtime(
"Packing", os.path.join(root, 'pack.log')
)
place_time, place_overhead = scan_runtime(
"Placement", os.path.join(root, 'place.log')
)
route_time, route_overhead = scan_runtime(
"Routing", os.path.join(root, 'route.log')
)
final_cpd, final_fmax, final_cpd_geomean, final_fmax_geomean = scan_critical(
os.path.join(root, 'route.log')
)
d['path'] = get_last_n_dirs(root, 2)
d['pack time (sec)'] = pack_time
d['pack overhead (sec)'] = pack_overhead
d['place time (sec)'] = place_time
d['place overhead (sec)'] = place_overhead
d['route time (sec)'] = route_time
d['route overhead (sec)'] = route_overhead
d['t_crit (ns)'] = final_cpd
d['Fmax (MHz)'] = final_fmax
d['t_crit geomean (ns)'] = final_cpd_geomean
d['Fmax geomean (MHz)'] = final_fmax_geomean
rows.append(d)
rows = sorted(rows, key=lambda row: row['path'])
for row in rows:
w.writerow(row)
if __name__ == "__main__":
main()