|
5 | 5 | hard-pins ~95 deps including litellm, numpy==1.26.4, fastapi — those would |
6 | 6 | break the main treemapper env if installed in-process). |
7 | 7 |
|
8 | | -Spawn-once, reuse-many: a single helper process is kept alive across all |
9 | | -instances in a run, so we pay aider's import cost (~1-2s) once per |
10 | | -benchmark file, not 1500 times. |
| 8 | +Spawn-once, reuse-many: one helper process per worker process is kept alive |
| 9 | +across all instances assigned to that worker, so we pay aider's import |
| 10 | +cost (~1-2s) once per worker, not once per instance. |
11 | 11 | """ |
12 | 12 |
|
13 | 13 | from __future__ import annotations |
14 | 14 |
|
| 15 | +import functools |
15 | 16 | import json |
16 | 17 | import os |
17 | 18 | import shutil |
@@ -234,24 +235,36 @@ def _aider_eval( |
234 | 235 | pass |
235 | 236 |
|
236 | 237 |
|
| 238 | +_AIDER_PROC: _AiderProcess | None = None |
| 239 | + |
| 240 | + |
| 241 | +def _noop_shutdown() -> None: |
| 242 | + pass |
| 243 | + |
| 244 | + |
| 245 | +def _pool_eval_aider( |
| 246 | + repos_dir_str: str, |
| 247 | + request_timeout: float, |
| 248 | + aider_mode: str, |
| 249 | + instance: BenchmarkInstance, |
| 250 | + params: RunParams, |
| 251 | +) -> EvalResult: |
| 252 | + global _AIDER_PROC |
| 253 | + if _AIDER_PROC is None: |
| 254 | + _AIDER_PROC = _AiderProcess() |
| 255 | + evaluator = UniversalEvaluator() |
| 256 | + worktree_dir = Path(repos_dir_str) / "worktrees" / f"w{os.getpid()}" |
| 257 | + worktree_dir.mkdir(parents=True, exist_ok=True) |
| 258 | + return _aider_eval(instance, params, evaluator, worktree_dir, _AIDER_PROC, request_timeout, aider_mode) |
| 259 | + |
| 260 | + |
237 | 261 | def make_aider_eval_fn( |
238 | 262 | repos_dir: Path, |
239 | 263 | request_timeout: float = 300.0, |
240 | 264 | aider_mode: str = "fair", |
241 | 265 | ): |
242 | 266 | if aider_mode not in {"fair", "oracle"}: |
243 | 267 | raise ValueError(f"aider_mode must be 'fair' or 'oracle', got {aider_mode!r}") |
244 | | - |
245 | | - evaluator = UniversalEvaluator() |
246 | | - worktrees_root = repos_dir / "worktrees" |
247 | | - aider = _AiderProcess() |
248 | | - |
249 | | - def eval_fn(instance: BenchmarkInstance, params: RunParams) -> EvalResult: |
250 | | - import os |
251 | | - |
252 | | - worktree_dir = worktrees_root / f"w{os.getpid()}" |
253 | | - worktree_dir.mkdir(parents=True, exist_ok=True) |
254 | | - return _aider_eval(instance, params, evaluator, worktree_dir, aider, request_timeout, aider_mode) |
255 | | - |
256 | | - eval_fn.shutdown = aider.shutdown # type: ignore[attr-defined] |
257 | | - return eval_fn |
| 268 | + fn = functools.partial(_pool_eval_aider, str(repos_dir), request_timeout, aider_mode) |
| 269 | + fn.shutdown = _noop_shutdown # type: ignore[attr-defined] |
| 270 | + return fn |
0 commit comments