Spaces:
Sleeping
Sleeping
File size: 4,558 Bytes
5b33b3c 2898fad 5b33b3c 2898fad 5b33b3c 2898fad 5b33b3c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | import os
import subprocess
import time
import psutil
import tempfile
import shutil
class CppCompiler:
def __init__(self, workdir: str = None):
self.workdir = workdir or tempfile.mkdtemp(prefix="algo_finder_")
os.makedirs(self.workdir, exist_ok=True)
def compile(self, filename: str, source_code: str) -> dict:
if shutil.which("g++") is None:
return {
"compiled": False,
"binary_path": None,
"compile_error": "g++ not found. On Hugging Face Spaces add 'g++' to packages.txt; locally install a C++ toolchain (e.g. 'apt install g++').",
"compile_stderr": "",
}
source_path = os.path.join(self.workdir, f"{filename}.cpp")
binary_path = os.path.join(self.workdir, filename)
if os.name == "nt" and not binary_path.lower().endswith(".exe"):
binary_path = binary_path + ".exe"
with open(source_path, "w", encoding="utf-8") as f:
f.write(source_code)
compile_cmd = ["g++", "-std=c++17", "-O2", source_path, "-o", binary_path]
try:
compile_result = subprocess.run(
compile_cmd,
capture_output=True,
text=True,
timeout=60,
)
except subprocess.TimeoutExpired:
return {
"compiled": False,
"binary_path": None,
"compile_error": "Compilation timed out (60s limit)",
"compile_stderr": "",
}
except FileNotFoundError as e:
return {
"compiled": False,
"binary_path": None,
"compile_error": f"g++ executable not found: {e}. Install g++ (packages.txt on Spaces).",
"compile_stderr": "",
}
except OSError as e:
return {
"compiled": False,
"binary_path": None,
"compile_error": f"Compilation failed to start: {e}",
"compile_stderr": "",
}
if compile_result.returncode != 0:
return {
"compiled": False,
"binary_path": None,
"compile_error": compile_result.stderr.strip(),
"compile_stderr": compile_result.stderr.strip(),
}
return {
"compiled": True,
"binary_path": binary_path,
"compile_error": None,
"compile_stderr": None,
}
def run(self, binary_path: str, timeout: int = 30) -> dict:
if not binary_path or not os.path.exists(binary_path):
return {
"ran": False,
"returncode": None,
"stdout": "",
"stderr": "Binary not found",
"execution_time_s": None,
"memory_kb": None,
}
process = psutil.Process()
start_time = time.perf_counter()
try:
run_result = subprocess.run(
[binary_path],
capture_output=True,
text=True,
timeout=timeout,
)
end_time = time.perf_counter()
execution_time = end_time - start_time
try:
mem_info = process.memory_info()
memory_kb = mem_info.rss / 1024
except Exception:
memory_kb = None
return {
"ran": True,
"returncode": run_result.returncode,
"stdout": run_result.stdout.strip(),
"stderr": run_result.stderr.strip(),
"execution_time_s": round(execution_time, 6),
"memory_kb": round(memory_kb, 2) if memory_kb is not None else None,
}
except subprocess.TimeoutExpired:
return {
"ran": False,
"returncode": None,
"stdout": "",
"stderr": f"Execution timed out ({timeout}s limit)",
"execution_time_s": timeout,
"memory_kb": None,
}
except Exception as e:
return {
"ran": False,
"returncode": None,
"stdout": "",
"stderr": str(e),
"execution_time_s": None,
"memory_kb": None,
}
def cleanup(self):
if os.path.exists(self.workdir):
shutil.rmtree(self.workdir, ignore_errors=True)
|