import argparse import os import shutil import subprocess import time from pathlib import Path def run_command(command, cwd=None): """Run a shell command in the specified directory and return its output.""" result = subprocess.run( command, shell=True, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False, ) return result.stdout.decode("utf-8"), result.stderr.decode("utf-8") def build_test_cases(makefile_dir, iterations): """Run the Makefile with the specified iterations.""" make_command = f"make clean && make ITERATIONS={iterations}" stdout, stderr = run_command(make_command, cwd=makefile_dir) if stderr: raise RuntimeError(f"Error during make: {stderr}") def main(simulator_path, makefile_dir): # Directory for generated test cases generated_dir = makefile_dir.parent / "workspace" os.makedirs(generated_dir, exist_ok=True) # Define the iterations iterations_list = [10, 20, 30] # 15 value up to 6.000.000 evenly apart on a log scale iterations_list = [ 1, 2, 4, 8, 17, 34, 69, 141, 287, 582, 1182, 2401, 4878, 9910, 20133, 40914, 83103, 168830, 343042, 696712, 1414641, 2874878, 5837995, ] for iteration in iterations_list: try: # Update the Makefile with the current ITERATIONS value build_test_cases(makefile_dir, iteration) except RuntimeError as e: print(f"Error during compilation with ITERATIONS={iteration}: {e}") continue # Run the simulator with the generated test case exe = makefile_dir / "dhrystone.elf" if not exe.is_file(): exit(f"{exe} does not exist") verbose_exe = generated_dir / "bin" / f"dhrystone_{iteration}.elf" os.makedirs(verbose_exe.parent, exist_ok=True) shutil.copy(exe, verbose_exe) backends = ["interp", "llvm", "tcc", "asmjit"] for backend in backends: log_file = os.path.join(generated_dir, f"{backend}_{iteration}.log") sim_command = f"{simulator_path} -f {exe} --backend {backend}" start_time = time.time() sim_stdout, sim_stderr = run_command(sim_command) end_time = time.time() elapsed_time = end_time - start_time # Save the output to the logfile with open(log_file, "w", encoding="utf8") as f: f.write(sim_stdout) if sim_stderr: f.write(f"\nErrors:\n{sim_stderr}") print( f"Ran {backend} in {elapsed_time:.2f} s, Output saved to {backend}_{iteration}.log" ) if __name__ == "__main__": parser = argparse.ArgumentParser( description="Run simulations with generated test cases." ) parser.add_argument("simulator_path", help="Path to the simulator executable.") args = parser.parse_args() dhrystone_path = Path(__file__).parent / "dhrystone" main(args.simulator_path, dhrystone_path)