commit d2df45970923fb76c33ba452d1acfe6d914c3f7c Author: Yingchi Long Date: Mon Mar 24 22:13:13 2025 +0800 project init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..505a3b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +# Python-generated files +__pycache__/ +*.py[oc] +build/ +dist/ +wheels/ +*.egg-info + +# Virtual environments +.venv diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..8183943 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,7 @@ +[project] +name = "speccpulib" +version = "0.1.0" +description = "Scripts that helps debugging SPEC CPU benchmark suite." +readme = "README.md" +requires-python = ">=3.9" +dependencies = [] diff --git a/src/speccpu/__init__.py b/src/speccpu/__init__.py new file mode 100644 index 0000000..080074d --- /dev/null +++ b/src/speccpu/__init__.py @@ -0,0 +1,22 @@ +import copy +import os +from pathlib import Path + + +def get_spec_env(spec_dir: Path): + new_env = copy.deepcopy(os.environ) + new_env["SPEC"] = str(spec_dir) + new_env["PATH"] = os.pathsep.join( + [ + str(spec_dir / "bin"), + *new_env["PATH"].split(os.pathsep), + ] + ) + return new_env + +def find_build(build_dir: Path) -> Path: + entries = list(sorted(os.listdir(build_dir))) + for entry in entries: + if entry.startswith("build"): + return build_dir / entry + raise RuntimeError(f"SPEC build directory not found at {build_dir}") diff --git a/src/speccpu/x264.py b/src/speccpu/x264.py new file mode 100644 index 0000000..b3bc5b2 --- /dev/null +++ b/src/speccpu/x264.py @@ -0,0 +1,84 @@ +import os +import shutil +from pathlib import Path +from subprocess import run + + +def get_mc_path(build): + return build / "src" / "common" / "mc.c" + + +def get_ref_add_pragma(mc_lines): + # Initialize variables + modified_lines = [] + pragma_added = False + + pragma_str = "#pragma clang loop vectorize(disable)" + + # Iterate through each line to find the target for loop + for i, line in enumerate(mc_lines): + # If there are already #pragma string, skip it. + if i > 1 and pragma_str in mc_lines[i - 1]: + continue + if "for( int x = 0; x < i_width; x++ )" in line: + modified_lines.append("#pragma clang loop vectorize(disable)\n") + pragma_added = True + + modified_lines.append(line) + + return modified_lines, pragma_added + + +def disable_mc_loop_vectorize(mc_path: Path) -> bool: + """ + Disable x264 mc.c loop vectorizing, mainly for "get_ref" performance. + If needed, update the file located at mc_path, returns true if that file is updated. + """ + # Read the content of mc.c + with open(mc_path, "r") as mc_file: + mc_lines = mc_file.readlines() + + mc_pragma_lines, mc_modified = get_ref_add_pragma(mc_lines) + + if mc_modified: + with open(mc_path, "w") as mc: + mc.writelines(mc_pragma_lines) + + return mc_modified + + +def update_exe(build_exe, exe_dir): + exe_file = exe_dir / "x264_s_base.mytest-m64" + + shutil.copy2(build_exe, exe_file) + print(f"Copied to {exe_file}") + + +def make(build, spec_env): + build_exe = build / "x264_s" + + run( + [ + "make", + "TARGET=s", + ], + check=True, + env=spec_env, + cwd=build, + ) + + # Copy "s" into run_dir + if not build_exe.exists(): + raise RuntimeError(f"x264 exe not generated! Please verify make process") + return build_exe + + +def recompile_mc(mc_path: Path, build: Path, spec_env: os._Environ): + # Recompile mc.o + mc_o_path = mc_path.with_suffix(".o") + if mc_o_path.exists(): + print(f"Found exist mc.o file at {mc_o_path}") + mc_o_path.unlink() + + # Run "make" + return make(build, spec_env)