Merge remote-tracking branch 'origin/ganesh_dev' into dev

This commit is contained in:
Ganesh Gore 2019-08-25 21:41:38 -06:00
commit 38e1d1bbff
8 changed files with 202 additions and 52 deletions

View File

@ -10,10 +10,10 @@ if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
#make #make
mkdir build mkdir build
cd build cd build
cmake .. -DCMAKE_BUILD_TYPE=debug -DENABLE_VPR_GRAPHICS=off cmake .. -DCMAKE_BUILD_TYPE=debug -DENABLE_VPR_GRAPHICS=off
make -j16 make -j16
alias python3.5="python3" alias python3.5="python3"
ln -s /opt/local/bin/python3 /opt/loca/bin/python3.5 ln -s /opt/local/bin/python3 /opt/local/bin/python3.5
else else
# For linux, we enable full package compilation # For linux, we enable full package compilation
#make #make
@ -30,4 +30,4 @@ $SPACER
cd - cd -
# python3.5 ./openfpga_flow/scripts/run_fpga_task.py regression/regression_quick # python3.5 ./openfpga_flow/scripts/run_fpga_task.py regression/regression_quick
chmod 755 run_test.sh chmod 755 run_test.sh
./run_test.sh python3.5 openfpga_flow/scripts/run_fpga_task.py blif_vpr_flow

1
docs/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
_build/

View File

@ -28,7 +28,7 @@ placement_time = "Placement took ([0-9.]+) seconds", str
routing_time = "Routing took ([0-9.]+) seconds", str routing_time = "Routing took ([0-9.]+) seconds", str
average_net_length = "average net length: ([0-9.]+)", str average_net_length = "average net length: ([0-9.]+)", str
critical_path = "Final critical path: ([0-9.]+) ([a-z])s", scientific critical_path = "Final critical path: ([0-9.]+) ([a-z])s", scientific
total_time_taken = "Routing took ([0-9.]+) seconds", float total_routing_time = "Routing took ([0-9.]+) seconds", float
[DEFAULT_PARSE_RESULT_POWER] [DEFAULT_PARSE_RESULT_POWER]
pb_type_power="PB Types\s+([0-9]+)", str pb_type_power="PB Types\s+([0-9]+)", str

View File

@ -535,10 +535,23 @@ def run_pro_blif_3arg():
def collect_files_for_vpr(): def collect_files_for_vpr():
# Sanitize provided Benchmark option
if len(args.benchmark_files) > 1: if len(args.benchmark_files) > 1:
logger.error("Expecting Single Benchmark BLif file.") logger.error("Expecting Single Benchmark BLif file.")
if not os.path.isfile(args.benchmark_files[0] or ""):
clean_up_and_exit("Provided Blif file not found")
shutil.copy(args.benchmark_files[0], args.top_module+".blif") shutil.copy(args.benchmark_files[0], args.top_module+".blif")
# Sanitize provided Activity file option
if not os.path.isfile(args.activity_file or ""):
logger.error("Activity File - %s" % args.activity_file)
clean_up_and_exit("Provided activity file not found")
shutil.copy(args.activity_file, args.top_module+"_ace_out.act") shutil.copy(args.activity_file, args.top_module+"_ace_out.act")
# Sanitize provided Benchmark option
if not os.path.isfile(args.base_verilog or ""):
logger.error("Base Verilog File - %s" % args.base_verilog)
clean_up_and_exit("Provided base_verilog file not found")
shutil.copy(args.base_verilog, args.top_module+"_output_verilog.v") shutil.copy(args.base_verilog, args.top_module+"_output_verilog.v")

View File

@ -1,4 +1,5 @@
[GENERAL CONFIGURATION] [GENERAL CONFIGURATION]
task_dir=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks task_dir=${PATH:OPENFPGA_PATH}/openfpga_flow/tasks
misc_dir=${PATH:OPENFPGA_PATH}/openfpga_flow/misc misc_dir=${PATH:OPENFPGA_PATH}/openfpga_flow/misc
python_path=python3.5
script_default=${PATH:OPENFPGA_PATH}/openfpga_flow/scripts/run_fpga_flow.py script_default=${PATH:OPENFPGA_PATH}/openfpga_flow/scripts/run_fpga_flow.py

View File

@ -12,9 +12,9 @@ import subprocess
import threading import threading
import csv import csv
from string import Template from string import Template
import run_fpga_flow
import pprint import pprint
from importlib import util from importlib import util
from collections import OrderedDict
if util.find_spec("humanize"): if util.find_spec("humanize"):
import humanize import humanize
@ -23,7 +23,7 @@ if util.find_spec("humanize"):
# Configure logging system # Configure logging system
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
logging.basicConfig(level=logging.INFO, stream=sys.stdout, logging.basicConfig(level=logging.INFO, stream=sys.stdout,
format='%(levelname)s (%(threadName)-9s) - %(message)s') format='%(levelname)s (%(threadName)10s) - %(message)s')
logger = logging.getLogger('OpenFPGA_Task_logs') logger = logging.getLogger('OpenFPGA_Task_logs')
@ -71,7 +71,7 @@ def main():
else: else:
pprint.pprint(job_run_list) pprint.pprint(job_run_list)
logger.info("Task execution completed") logger.info("Task execution completed")
exit() exit(0)
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Subroutines starts here # Subroutines starts here
@ -80,8 +80,8 @@ def main():
def clean_up_and_exit(msg): def clean_up_and_exit(msg):
logger.error(msg) logger.error(msg)
logger.error("Existing . . . . . .") logger.error("Exiting . . . . . .")
exit() exit(1)
def validate_command_line_arguments(): def validate_command_line_arguments():
@ -112,8 +112,8 @@ def generate_each_task_actions(taskname):
curr_run_dir = "run%03d" % (max(run_dirs+[0, ])+1) curr_run_dir = "run%03d" % (max(run_dirs+[0, ])+1)
try: try:
os.mkdir(curr_run_dir) os.mkdir(curr_run_dir)
if os.path.islink('latest'): if os.path.islink('latest') or os.path.exists('latest'):
os.unlink("latest") os.remove("latest")
os.symlink(curr_run_dir, "latest") os.symlink(curr_run_dir, "latest")
logger.info('Created "%s" directory for current task run' % logger.info('Created "%s" directory for current task run' %
curr_run_dir) curr_run_dir)
@ -128,12 +128,17 @@ def generate_each_task_actions(taskname):
task_conf.read_dict(script_env_vars) task_conf.read_dict(script_env_vars)
task_conf.read_file(open(curr_task_conf_file)) task_conf.read_file(open(curr_task_conf_file))
required_sec = ["GENERAL", "BENCHMARKS", "ARCHITECTURES", "POST_RUN"] required_sec = ["GENERAL", "BENCHMARKS", "ARCHITECTURES"]
missing_section = list(set(required_sec)-set(task_conf.sections())) missing_section = list(set(required_sec)-set(task_conf.sections()))
if missing_section: if missing_section:
clean_up_and_exit("Missing sections %s" % " ".join(missing_section) + clean_up_and_exit("Missing sections %s" % " ".join(missing_section) +
" in task configuration file") " in task configuration file")
# Declare varibles to access sections
TaskFileSections = task_conf.sections()
SynthSection = task_conf["SYNTHESIS_PARAM"]
GeneralSection = task_conf["GENERAL"]
# Check if specified architecture files exist # Check if specified architecture files exist
archfile_list = [] archfile_list = []
for _, arch_file in task_conf["ARCHITECTURES"].items(): for _, arch_file in task_conf["ARCHITECTURES"].items():
@ -143,10 +148,16 @@ def generate_each_task_actions(taskname):
else: else:
clean_up_and_exit("Architecture file not found: " + clean_up_and_exit("Architecture file not found: " +
"%s " % arch_file) "%s " % arch_file)
if not len(archfile_list) == len(list(set(archfile_list))):
clean_up_and_exit("Found duplicate architectures in config file")
# Check if specified benchmark files exist # Check if specified benchmark files exist
benchmark_list = [] benchmark_list = []
for bech_name, each_benchmark in task_conf["BENCHMARKS"].items(): for bech_name, each_benchmark in task_conf["BENCHMARKS"].items():
# Declare varible to store paramteres for current benchmark
CurrBenchPara = {}
# Parse benchmark file
bench_files = [] bench_files = []
for eachpath in each_benchmark.split(","): for eachpath in each_benchmark.split(","):
files = glob.glob(eachpath) files = glob.glob(eachpath)
@ -155,15 +166,51 @@ def generate_each_task_actions(taskname):
" with path %s " % (eachpath)) " with path %s " % (eachpath))
bench_files += files bench_files += files
ys_for_task = task_conf.get("SYNTHESIS_PARAM", "bench_yosys_common", # Read provided benchmark configurations
fallback="") # Common configurations
benchmark_list.append({ ys_for_task_common = SynthSection.get("bench_yosys_common")
"files": bench_files, chan_width_common = SynthSection.get("bench_chan_width_common")
"top_module": task_conf.get("SYNTHESIS_PARAM", bech_name+"_top",
fallback="top"), # Individual benchmark configuration
"ys_script": task_conf.get("SYNTHESIS_PARAM", bech_name+"_yosys", CurrBenchPara["files"] = bench_files
fallback=ys_for_task), CurrBenchPara["top_module"] = SynthSection.get(bech_name+"_top",
}) fallback="top")
CurrBenchPara["ys_script"] = SynthSection.get(bech_name+"_yosys",
fallback=ys_for_task_common)
CurrBenchPara["chan_width"] = SynthSection.get(bech_name+"_chan_width",
fallback=chan_width_common)
logger.info('Running "%s" flow' %
GeneralSection.get("fpga_flow", fallback="yosys_vpr"))
if GeneralSection.get("fpga_flow") == "vpr_blif":
# Check if activity file exist
if not SynthSection.get(bech_name+"_act"):
clean_up_and_exit("Missing argument %s" % (bech_name+"_act") +
"for vpr_blif flow")
CurrBenchPara["activity_file"] = SynthSection.get(bech_name+"_act")
# Check if base verilog file exists
if not SynthSection.get(bech_name+"_verilog"):
clean_up_and_exit("Missing argument %s for vpr_blif flow" %
(bech_name+"_verilog"))
CurrBenchPara["verilog_file"] = SynthSection.get(
bech_name+"_verilog")
# Add script parameter list in current benchmark
ScriptSections = [x for x in TaskFileSections if "SCRIPT_PARAM" in x]
script_para_list = {}
for eachset in ScriptSections:
command = []
for key, values in task_conf[eachset].items():
command += ["--"+key, values] if values else ["--"+key]
# Set label for Sript Parameters
set_lbl = eachset.replace("SCRIPT_PARAM", "")
set_lbl = set_lbl[1:] if set_lbl else "Common"
script_para_list[set_lbl] = command
CurrBenchPara["script_params"] = script_para_list
benchmark_list.append(CurrBenchPara)
# Create OpenFPGA flow run commnad for each combination of # Create OpenFPGA flow run commnad for each combination of
# architecture, benchmark and parameters # architecture, benchmark and parameters
@ -171,16 +218,21 @@ def generate_each_task_actions(taskname):
flow_run_cmd_list = [] flow_run_cmd_list = []
for indx, arch in enumerate(archfile_list): for indx, arch in enumerate(archfile_list):
for bench in benchmark_list: for bench in benchmark_list:
flow_run_dir = get_flow_rundir(arch, bench["top_module"]) for lbl, param in bench["script_params"].items():
cmd = create_run_command( flow_run_dir = get_flow_rundir(arch, bench["top_module"], lbl)
flow_run_dir, arch, bench, task_conf) command = create_run_command(
flow_run_cmd_list.append({ curr_job_dir=flow_run_dir,
"arch": arch, archfile=arch,
"bench": bench, benchmark_obj=bench,
"name": "%s_arch%d" % (bench["top_module"], indx), param=param,
"run_dir": flow_run_dir, task_conf=task_conf)
"commands": cmd, flow_run_cmd_list.append({
"status": False}) "arch": arch,
"bench": bench,
"name": "%02d_arch%s_%s" % (indx, bench["top_module"], lbl),
"run_dir": flow_run_dir,
"commands": command,
"status": False})
return flow_run_cmd_list return flow_run_cmd_list
@ -193,7 +245,7 @@ def get_flow_rundir(arch, top_module, flow_params=None):
return os.path.abspath(os.path.join(*path)) return os.path.abspath(os.path.join(*path))
def create_run_command(curr_job_dir, archfile, benchmark_obj, task_conf): def create_run_command(curr_job_dir, archfile, benchmark_obj, param, task_conf):
""" """
Create_run_script function accepts run directory, architecture list and Create_run_script function accepts run directory, architecture list and
fpga_flow configuration file and prepare final executable fpga_flow script fpga_flow configuration file and prepare final executable fpga_flow script
@ -217,23 +269,37 @@ def create_run_command(curr_job_dir, archfile, benchmark_obj, task_conf):
os.makedirs(curr_job_dir) os.makedirs(curr_job_dir)
# Make execution command to run Open FPGA flow # Make execution command to run Open FPGA flow
task_gc = task_conf["GENERAL"]
command = [archfile] + benchmark_obj["files"] command = [archfile] + benchmark_obj["files"]
command += ["--top_module", benchmark_obj["top_module"]] command += ["--top_module", benchmark_obj["top_module"]]
command += ["--run_dir", curr_job_dir] command += ["--run_dir", curr_job_dir]
if task_conf.getboolean("GENERAL", "power_analysis", fallback=False):
if task_gc.get("fpga_flow"):
command += ["--fpga_flow", task_gc.get("fpga_flow")]
if benchmark_obj.get("activity_file"):
command += ["--activity_file", benchmark_obj.get("activity_file")]
if benchmark_obj.get("verilog_file"):
command += ["--base_verilog", benchmark_obj.get("verilog_file")]
if benchmark_obj.get("ys_script"):
command += ["--yosys_tmpl", benchmark_obj["ys_script"]]
if task_gc.getboolean("power_analysis"):
command += ["--power"] command += ["--power"]
command += ["--power_tech", command += ["--power_tech", task_gc.get("power_tech_file")]
task_conf.get("GENERAL", "power_tech_file")]
if task_conf.getboolean("GENERAL", "spice_output", fallback=False): if task_gc.getboolean("spice_output"):
command += ["--vpr_fpga_spice"] command += ["--vpr_fpga_spice"]
if task_conf.getboolean("GENERAL", "verilog_output", fallback=False):
if task_gc.getboolean("verilog_output"):
command += ["--vpr_fpga_verilog"] command += ["--vpr_fpga_verilog"]
command += ["--vpr_fpga_verilog_dir", "."] command += ["--vpr_fpga_verilog_dir", "."]
command += ["--vpr_fpga_x2p_rename_illegal_port"] command += ["--vpr_fpga_x2p_rename_illegal_port"]
# Add other paramters to pass # Add other paramters to pass
for key, values in task_conf["SCRIPT_PARAM"].items(): command += param
command += ["--"+key, values] if values else ["--"+key]
if args.debug: if args.debug:
command += ["--debug"] command += ["--debug"]
@ -260,9 +326,13 @@ def run_single_script(s, eachJob):
try: try:
logfile = "%s_out.log" % name logfile = "%s_out.log" % name
with open(logfile, 'w+') as output: with open(logfile, 'w+') as output:
process = subprocess.Popen(["python3.5", output.write("* "*20 + '\n')
gc["script_default"]] + output.write("RunDirectory : %s\n" % os.getcwd())
eachJob["commands"], command = [gc["python_path"], gc["script_default"]] + \
eachJob["commands"]
output.write(" ".join(command) + '\n')
output.write("* "*20 + '\n')
process = subprocess.Popen(command,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, stderr=subprocess.STDOUT,
universal_newlines=True) universal_newlines=True)
@ -272,6 +342,8 @@ def run_single_script(s, eachJob):
sys.stdout.buffer.flush() sys.stdout.buffer.flush()
output.write(line) output.write(line)
process.wait() process.wait()
if process.returncode:
raise subprocess.CalledProcessError(0, [])
eachJob["status"] = True eachJob["status"] = True
except: except:
logger.exception("Failed to execute openfpga flow - " + logger.exception("Failed to execute openfpga flow - " +
@ -280,7 +352,8 @@ def run_single_script(s, eachJob):
timediff = timedelta(seconds=(eachJob["endtime"]-eachJob["starttime"])) timediff = timedelta(seconds=(eachJob["endtime"]-eachJob["starttime"]))
timestr = humanize.naturaldelta(timediff) if "humanize" in sys.modules \ timestr = humanize.naturaldelta(timediff) if "humanize" in sys.modules \
else str(timediff) else str(timediff)
logger.info("%s Finished, Time Taken %s " % (name, timestr)) logger.info("%s Finished with returncode %d, Time Taken %s " %
(name, process.returncode, timestr))
def run_actions(job_run_list): def run_actions(job_run_list):
@ -301,6 +374,7 @@ def collect_results(job_run_list):
task_result = [] task_result = []
for run in job_run_list: for run in job_run_list:
if not run["status"]: if not run["status"]:
logger.warning("Skipping %s run", run["name"])
continue continue
# Check if any result file exist # Check if any result file exist
if not glob.glob(os.path.join(run["run_dir"], "*.result")): if not glob.glob(os.path.join(run["run_dir"], "*.result")):
@ -311,8 +385,10 @@ def collect_results(job_run_list):
interpolation=ExtendedInterpolation()) interpolation=ExtendedInterpolation())
vpr_res.read_file( vpr_res.read_file(
open(os.path.join(run["run_dir"], "vpr_stat.result"))) open(os.path.join(run["run_dir"], "vpr_stat.result")))
result = dict(vpr_res["RESULTS"]) result = OrderedDict()
result["name"] = run["name"] result["name"] = run["name"]
result["TotalRunTime"] = int(run["endtime"]-run["starttime"])
result.update(vpr_res["RESULTS"])
task_result.append(result) task_result.append(result)
if len(task_result): if len(task_result):

View File

@ -18,18 +18,17 @@ arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/winbond90/k6_N10_rram_memory_bank
[BENCHMARKS] [BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/MCNC_Verilog/s298/s298.v bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/MCNC_Verilog/s298/s298.v
bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/MCNC_Verilog/alu4/alu4.v bench1=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/MCNC_Verilog/elliptic/elliptic.v
# bench2=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/MCNC_Verilog/s38417/s38417.v
[SYNTHESIS_PARAM] [SYNTHESIS_PARAM]
bench_yosys_common=${PATH:OPENFPGA_PATH}/vtr_flow/yosys/typical_run.yosys
bench0_top = s298 bench0_top = s298
bench1_top = alu4 bench1_top = elliptic
bench2_top = s38417
bench0_yosys=${PATH:OPENFPGA_PATH}/vtr_flow/yosys/typical_run.yosys
[SCRIPT_PARAM] [SCRIPT_PARAM_1]
min_route_chan_width=30 min_route_chan_width=1.3
[SCRIPT_PARAM_2]
min_route_chan_width=1.8
[POST_RUN] [POST_RUN]
# Not Implemented yet # Not Implemented yet

View File

@ -0,0 +1,60 @@
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# Configuration file for running experiments
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
# timeout_each_job : FPGA Task script splits fpga flow into multiple jobs
# Each job execute fpga_flow script on combination of architecture & benchmark
# timeout_each_job is timeout for each job
# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
[GENERAL]
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
power_analysis = true
spice_output=false
verilog_output=true
timeout_each_job = 20*60
fpga_flow=vpr_blif
[ARCHITECTURES]
# arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/template/k6_N10_sram_chain_HC_DPRAM_template.xml
arch1=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/template/k6_N10_sram_chain_HC_template.xml
arch2=${PATH:OPENFPGA_PATH}/openfpga_flow/arch/template/k8_N10_sram_chain_FC_template.xml
[BENCHMARKS]
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/Test_Modes/test_modes.blif
[SYNTHESIS_PARAM]
bench0_top = test_modes
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/Test_Modes/test_modes.act
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/Test_Modes/test_modes.v
bench0_chan_width = 300
[SCRIPT_PARAM_1]
fix_route_chan_width=300
vpr_fpga_verilog_include_icarus_simulator=
vpr_fpga_verilog_formal_verification_top_netlist=
vpr_fpga_verilog_include_timing=
vpr_fpga_verilog_include_signal_init=
vpr_fpga_verilog_print_autocheck_top_testbench=
vpr_fpga_bitstream_generator=
vpr_fpga_verilog_print_user_defined_template=
vpr_fpga_verilog_print_report_timing_tcl=
vpr_fpga_verilog_print_sdc_pnr=
vpr_fpga_verilog_print_sdc_analysis=
vpr_fpga_x2p_compact_routing_hierarchy=
end_flow_with_test=
# [SCRIPT_PARAM_2]
# fix_route_chan_width=200
# vpr_fpga_verilog_include_icarus_simulator=
# vpr_fpga_verilog_formal_verification_top_netlist=
# vpr_fpga_verilog_include_timing=
# vpr_fpga_verilog_include_signal_init=
# vpr_fpga_verilog_print_autocheck_top_testbench=
# vpr_fpga_bitstream_generator=
# vpr_fpga_verilog_print_user_defined_template=
# vpr_fpga_verilog_print_report_timing_tcl=
# vpr_fpga_verilog_print_sdc_pnr=
# vpr_fpga_verilog_print_sdc_analysis=
# vpr_fpga_x2p_compact_routing_hierarchy=
# end_flow_with_test=