def run(path: Path, sdfg_names: Union[str, Iterable[str]], args: Iterable[Any]): # Set environment variables os.environ["DACE_compiler_fpga_vendor"] = "intel_fpga" os.environ["DACE_compiler_use_cache"] = "0" os.environ["DACE_compiler_default_data_types"] = "C" # We would like to use DACE_cache=hash, but we want to have access to the # program's build folder os.environ["DACE_cache"] = "name" os.environ["DACE_compiler_intel_fpga_mode"] = "emulator" os.environ["DACE_optimizer_transform_on_call"] = "0" os.environ["DACE_optimizer_interface"] = "" os.environ["DACE_optimizer_autooptimize"] = "0" path = DACE_DIR / path if not path.exists(): print_error(f"Path {path} does not exist.") return False base_name = f"{Colors.UNDERLINE}{path.stem}{Colors.END}" if isinstance(sdfg_names, str): sdfg_names = [sdfg_names] for sdfg_name in sdfg_names: build_folder = TEST_DIR / ".dacecache" / sdfg_name / "build" if build_folder.exists(): # There is a potential conflict between the synthesis folder # generated by Xilinx and the one generated by Intel FPGA sp.run(["make", "clean"], cwd=build_folder, stdout=sp.PIPE, stderr=sp.PIPE, check=True, timeout=60) # Simulation in software print_status(f"{base_name}: Running emulation.") try: proc = sp.Popen(map(str, [sys.executable, path] + args), cwd=TEST_DIR, stdout=sp.PIPE, stderr=sp.PIPE, encoding="utf-8") sim_out, sim_err = proc.communicate(timeout=TEST_TIMEOUT) except sp.TimeoutExpired: dump_logs(proc) print_error(f"{base_name}: Emulation timed out " f"after {TEST_TIMEOUT} seconds.") return False if proc.returncode != 0: dump_logs((sim_out, sim_err)) print_error(f"{base_name}: Emulation failed.") return False print_success(f"{base_name}: Emulation successful.") for sdfg_name in sdfg_names: build_folder = TEST_DIR / ".dacecache" / sdfg_name / "build" if not build_folder.exists(): print_error(f"Invalid SDFG name {sdfg_name} for {base_name}.") return False open(build_folder / "simulation.out", "w").write(sim_out) open(build_folder / "simulation.err", "w").write(sim_err) return True
def run(path: Path, sdfg_names: Union[str, Iterable[str]], run_synthesis: bool, assert_ii_1: bool, args: Iterable[Any]): # Set environment variables env = os.environ.copy() env["DACE_compiler_fpga_vendor"] = "xilinx" env["DACE_compiler_use_cache"] = "0" # We would like to use DACE_cache=hash, but we need to know which folder to # run synthesis in. env["DACE_cache"] = "name" env["DACE_compiler_xilinx_mode"] = "simulation" os.environ["DACE_optimizer_transform_on_call"] = "0" os.environ["DACE_optimizer_interface"] = "" os.environ["DACE_optimizer_autooptimize"] = "0" path = DACE_DIR / path if not path.exists(): print_error(f"Path {path} does not exist.") return False base_name = f"{Colors.UNDERLINE}{path.stem}{Colors.END}" # Simulation in software print_status(f"{base_name}: Running simulation.") if "rtl" in path.parts: env["DACE_compiler_xilinx_mode"] = "hardware_emulation" if "LIBRARY_PATH" not in env: env["LIBRARY_PATH"] = "" env["LIBRARY_PATH"] += ":/usr/lib/x86_64-linux-gnu" try: proc = sp.Popen(map(str, [sys.executable, path] + args), env=env, cwd=TEST_DIR, stdout=sp.PIPE, stderr=sp.PIPE, encoding="utf-8") sim_out, sim_err = proc.communicate(timeout=TEST_TIMEOUT) except sp.TimeoutExpired: dump_logs(proc) print_error(f"{base_name}: Simulation timed out " f"after {TEST_TIMEOUT} seconds.") return False if proc.returncode != 0: dump_logs((sim_out, sim_err)) print_error(f"{base_name}: Simulation failed.") return False print_success(f"{base_name}: Simulation successful.") if isinstance(sdfg_names, str): sdfg_names = [sdfg_names] for sdfg_name in sdfg_names: build_folder = TEST_DIR / ".dacecache" / sdfg_name / "build" if not build_folder.exists(): print_error(f"Invalid SDFG name {sdfg_name} for {base_name}.") return False open(build_folder / "simulation.out", "w").write(sim_out) open(build_folder / "simulation.err", "w").write(sim_err) # High-level synthesis if run_synthesis: print_status( f"{base_name}: Running high-level synthesis for {sdfg_name}.") try: proc = sp.Popen(["make", "xilinx_synthesis"], env=env, cwd=build_folder, stdout=sp.PIPE, stderr=sp.PIPE, encoding="utf=8") syn_out, syn_err = proc.communicate(timeout=TEST_TIMEOUT) except sp.TimeoutExpired: dump_logs(proc) print_error(f"{base_name}: High-level synthesis timed out " f"after {TEST_TIMEOUT} seconds.") return False if proc.returncode != 0: dump_logs(proc) print_error(f"{base_name}: High-level synthesis failed.") return False print_success(f"{base_name}: High-level synthesis " f"successful for {sdfg_name}.") open(build_folder / "synthesis.out", "w").write(syn_out) open(build_folder / "synthesis.err", "w").write(syn_err) # Check if loops were pipelined with II=1 if assert_ii_1: loops_found = False for f in build_folder.iterdir(): if "hls.log" in f.name: hls_log = f break else: print_error(f"{base_name}: HLS log file not found.") return False hls_log = open(hls_log, "r").read() for m in re.finditer(r"Final II = ([0-9]+)", hls_log): loops_found = True if int(m.group(1)) != 1: dump_logs((syn_out, syn_err)) print_error(f"{base_name}: Failed to achieve II=1.") return False if not loops_found: dump_logs((syn_out, syn_err)) print_error("{base_name}: No pipelined loops found.") return False print_success(f"{base_name}: II=1 achieved.") return True