"""PDC benchmarks via compiled C backend (Sequential, OpenMP, POSIX Threads).""" import subprocess import sys from pathlib import Path CHART_CATEGORIES = [ "Sequential", "OpenMP (2)", "OpenMP (4)", "POSIX Threads (4)", ] APP_DIR = Path(__file__).resolve().parent BACKEND_DIR = APP_DIR / "c_backend" PROJECT_ROOT = APP_DIR.parent def _bench_binary() -> Path: name = "search_bench.exe" if sys.platform == "win32" else "search_bench" for base in (BACKEND_DIR, PROJECT_ROOT): candidate = base / name if candidate.exists(): return candidate return BACKEND_DIR / name def _bench_cwd(bench: Path) -> Path: return bench.parent def _label_for(method: str, workers: int) -> str: if method == "Sequential": return "Sequential" if method == "OpenMP": return f"OpenMP ({workers})" if method == "POSIX Threads": return f"POSIX Threads ({workers})" return method def run_backend_benchmark(method_type: str, worker_count: int, keyword: str) -> float: bench = _bench_binary() if not bench.exists(): raise FileNotFoundError(_build_help()) proc = subprocess.run( [str(bench), method_type, str(worker_count), keyword], capture_output=True, text=True, cwd=str(_bench_cwd(bench)), ) if proc.returncode != 0: raise RuntimeError(proc.stderr.strip() or "C benchmark failed") return float(proc.stdout.strip()) def _build_help() -> str: return ( "Compiled benchmark not found.\n" "Build locally:\n" " cd c_backend && gcc -O2 -fopenmp -pthread search_bench.c hostel_mock_data.c " "-o search_bench -lm" ) def _parse_row(line: str) -> dict: parts = line.split() if parts[0] == "POSIX" and len(parts) > 1 and parts[1] == "Threads": method = "POSIX Threads" workers = int(parts[2]) fee_t, search_t, total_t = float(parts[3]), float(parts[4]), float(parts[5]) found, speedup = int(parts[6]), float(parts[7]) else: method = parts[0] workers = int(parts[1]) fee_t, search_t, total_t = float(parts[2]), float(parts[3]), float(parts[4]) found, speedup = int(parts[5]), float(parts[6]) return { "Method": method, "Workers": workers, "Fee (s)": fee_t, "Search (s)": search_t, "Time (s)": total_t, "Found": found, "Speedup": speedup, "Label": _label_for(method, workers), } def run_all_benchmarks(students, keyword="Ali"): del students bench = _bench_binary() if not bench.exists(): raise FileNotFoundError(_build_help()) proc = subprocess.run( [str(bench), "all", keyword], capture_output=True, text=True, cwd=str(_bench_cwd(bench)), ) if proc.returncode != 0: raise RuntimeError(proc.stderr.strip() or "C benchmark failed") rows = [_parse_row(line) for line in proc.stdout.strip().splitlines() if line.strip()] if not rows: raise RuntimeError("No benchmark results from C backend") return rows, keyword