Skip to content

Commit 5bc67fd

Browse files
2 parents 3ea4d00 + 16d7014 commit 5bc67fd

File tree

8 files changed

+73
-47
lines changed

8 files changed

+73
-47
lines changed

src/codeevolve/cli.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -172,9 +172,7 @@ def main() -> int:
172172

173173
global_data: GlobalSyncData = GlobalSyncData(
174174
best_sol=global_best_sol,
175-
early_stop_counter=mp.Value(
176-
ctypes.c_int, early_stop_counter, lock=False
177-
),
175+
early_stop_counter=mp.Value(ctypes.c_int, early_stop_counter, lock=False),
178176
early_stop_aux=mp.Value(ctypes.c_int, 0, lock=False),
179177
lock=mp.Lock(),
180178
barrier=mp.Barrier(parties=evolve_config["num_islands"]),

src/codeevolve/evaluator.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,7 @@ def execute(
222222
eval_metrics: Dictionary of evaluation metrics if successful
223223
"""
224224
effective_timeout: int = timeout_s if timeout_s is not None else self.timeout_s
225-
self.logger.info(
226-
f"Attempting to evaluate program (timeout={effective_timeout}s)..."
227-
)
225+
self.logger.info(f"Attempting to evaluate program (timeout={effective_timeout}s)...")
228226

229227
extension: str = LANGUAGE_TO_EXTENSION.get(prog.language, DEFAULT_EXTENSION)
230228
returncode: int = 1

src/codeevolve/evolution.py

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -719,13 +719,22 @@ def _do_checkpoint(epoch_num: int) -> None:
719719
if isl_data.id == 0:
720720
elapsed_s: float = get_elapsed_time(global_data)
721721
cpus: int = global_data.cpu_count.value
722-
save_run_metadata(args["out_dir"], epoch_num, elapsed_s, cpus, global_data.best_sol,global_data.early_stop_counter.value)
722+
save_run_metadata(
723+
args["out_dir"],
724+
epoch_num,
725+
elapsed_s,
726+
cpus,
727+
global_data.best_sol,
728+
global_data.early_stop_counter.value,
729+
)
723730
logger.info(f"Saved run metadata for epoch {epoch_num}.")
724731

725732
meta_prompting: bool = evolve_config.get("meta_prompting", False)
726733
use_map_elites: bool = evolve_config.get("use_map_elites", False)
727734
exploration_rate: float = (
728-
exploration_scheduler.value if exploration_scheduler is not None else evolve_config["exploration_rate"]
735+
exploration_scheduler.value
736+
if exploration_scheduler is not None
737+
else evolve_config["exploration_rate"]
729738
)
730739
eval_budget: str = format_eval_budget(
731740
timeout_s=evaluator.timeout_s, max_mem_b=evaluator.max_mem_b
@@ -806,13 +815,13 @@ def _do_checkpoint(epoch_num: int) -> None:
806815

807816
child_timeout: Optional[int] = None
808817
if not gen_init_pop and timeout_scheduler is not None:
809-
child_timeout = int(timeout_scheduler(
810-
epoch=epoch,
811-
best_fitness=sol_db.programs[sol_db.best_prog_id].fitness,
812-
))
813-
eval_budget = format_eval_budget(
814-
timeout_s=child_timeout, max_mem_b=evaluator.max_mem_b
818+
child_timeout = int(
819+
timeout_scheduler(
820+
epoch=epoch,
821+
best_fitness=sol_db.programs[sol_db.best_prog_id].fitness,
822+
)
815823
)
824+
eval_budget = format_eval_budget(timeout_s=child_timeout, max_mem_b=evaluator.max_mem_b)
816825

817826
child_sol, evolve_success = await generate_solution(
818827
ensemble=ensemble,
@@ -1356,9 +1365,15 @@ def setup_codeevolve_components(
13561365
init_sol: Program
13571366

13581367
if args["load_ckpt"]:
1359-
prompt_db, sol_db, evolve_state, init_prompt, init_sol, exploration_scheduler, timeout_scheduler = (
1360-
_initialize_from_checkpoint(args, exploration_scheduler, timeout_scheduler)
1361-
)
1368+
(
1369+
prompt_db,
1370+
sol_db,
1371+
evolve_state,
1372+
init_prompt,
1373+
init_sol,
1374+
exploration_scheduler,
1375+
timeout_scheduler,
1376+
) = _initialize_from_checkpoint(args, exploration_scheduler, timeout_scheduler)
13621377
else:
13631378
prompt_db, sol_db, evolve_state, init_prompt, init_sol = _initialize_new_run(
13641379
config, evolve_config, args, isl_data.id, evaluator, logger
@@ -1442,7 +1457,7 @@ async def codeevolve(
14421457
components.logger.info("Waiting for other islands to finish setup...")
14431458
global_data.barrier.wait()
14441459
components.logger.info("All islands finished. Starting CodeEvolve loop.")
1445-
1460+
14461461
await codeevolve_loop(
14471462
components.start_epoch,
14481463
components.evolve_state,

src/codeevolve/runner.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,9 @@ def async_run_codeevolve(
138138
try:
139139
isl_logs_dir: Path = run_args.get("logs_dir")
140140
if isl_logs_dir:
141-
_write_island_crash_log(isl_logs_dir, error_msg, full_traceback, int(global_data.start_time.value))
141+
_write_island_crash_log(
142+
isl_logs_dir, error_msg, full_traceback, int(global_data.start_time.value)
143+
)
142144
except Exception:
143145
pass
144146

@@ -247,7 +249,9 @@ def cleanup_log_daemon(
247249
# ---------------------------------------------------------------------------
248250

249251

250-
def _write_island_crash_log(isl_logs_dir: Path, error_msg: str, full_traceback: str, time: int = 0) -> None:
252+
def _write_island_crash_log(
253+
isl_logs_dir: Path, error_msg: str, full_traceback: str, time: int = 0
254+
) -> None:
251255
"""Writes detailed crash information to an island's crash log file.
252256
253257
Called from within the child process where the exception occurred.
@@ -269,7 +273,9 @@ def _write_island_crash_log(isl_logs_dir: Path, error_msg: str, full_traceback:
269273
f.write(f"{'='*60}\n\n")
270274

271275

272-
def _write_crash_summary(out_dir: Path, island_id: int, exit_code: int, message: str, time: int = 0) -> None:
276+
def _write_crash_summary(
277+
out_dir: Path, island_id: int, exit_code: int, message: str, time: int = 0
278+
) -> None:
273279
"""Writes crash summary to the main output directory's crash log.
274280
275281
Called from the parent process when it detects an island has crashed.
@@ -289,7 +295,9 @@ def _write_crash_summary(out_dir: Path, island_id: int, exit_code: int, message:
289295
f.write(f"Island: {island_id}\n")
290296
f.write(f"Exit Code: {exit_code}\n")
291297
f.write(f"Message: {message}\n")
292-
f.write(f"See island_{island_id}/logs/{CRASH_LOG_FILE.format(time=time)} for full traceback.\n")
298+
f.write(
299+
f"See island_{island_id}/logs/{CRASH_LOG_FILE.format(time=time)} for full traceback.\n"
300+
)
293301
f.write(f"{'='*60}\n\n")
294302

295303

src/codeevolve/scheduler.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,6 @@ def reset(self, value: Optional[float] = None) -> None:
9191
self.value = value
9292

9393

94-
9594
class ExponentialScheduler(Scheduler):
9695
"""Exponential scheduler that scales a value geometrically over epochs.
9796
@@ -107,9 +106,7 @@ class ExponentialScheduler(Scheduler):
107106
initial_value: Value at epoch 0 (used for reset).
108107
"""
109108

110-
def __init__(
111-
self, value: float, max_value: float, min_value: float, weight: float
112-
):
109+
def __init__(self, value: float, max_value: float, min_value: float, weight: float):
113110
"""
114111
Initialize the exponential scheduler.
115112
@@ -276,9 +273,7 @@ class CosineScheduler(Scheduler):
276273
cycle_length: Number of epochs per complete cosine cycle.
277274
"""
278275

279-
def __init__(
280-
self, value: float, max_value: float, min_value: float, cycle_length: int
281-
):
276+
def __init__(self, value: float, max_value: float, min_value: float, cycle_length: int):
282277
"""Initialize the cosine annealing scheduler.
283278
284279
Args:

src/codeevolve/utils/ckpt.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ def save_run_metadata(
129129
elapsed_time: float,
130130
cpu_count: int,
131131
global_best_sol: GlobalBestProg,
132-
early_stop_counter: int
132+
early_stop_counter: int,
133133
) -> None:
134134
"""Saves run metadata to a JSON file.
135135
@@ -164,7 +164,7 @@ def save_run_metadata(
164164
"depth": global_best_sol.depth.value,
165165
"eval_metrics": dict(global_best_sol.eval_metrics),
166166
},
167-
"early_stop_counter": early_stop_counter
167+
"early_stop_counter": early_stop_counter,
168168
}
169169

170170
with open(metadata_file, "w") as f:

tests/test_ckpt.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,12 @@ def test_save_and_load_metadata(self, tmp_path: Path):
210210
best_sol.depth.value = 5
211211

212212
save_run_metadata(
213-
tmp_path, epoch=10, elapsed_time=120.5, cpu_count=8, global_best_sol=best_sol,early_stop_counter=5
213+
tmp_path,
214+
epoch=10,
215+
elapsed_time=120.5,
216+
cpu_count=8,
217+
global_best_sol=best_sol,
218+
early_stop_counter=5,
214219
)
215220

216221
metadata: Optional[Dict[str, Any]] = load_run_metadata(tmp_path, epoch=10)
@@ -229,7 +234,12 @@ def test_load_missing_epoch(self, tmp_path: Path):
229234
"""Tests loading metadata for a missing epoch returns empty dict."""
230235
best_sol: GlobalBestProg = GlobalBestProg()
231236
save_run_metadata(
232-
tmp_path, epoch=10, elapsed_time=100.0, cpu_count=4, global_best_sol=best_sol, early_stop_counter=5
237+
tmp_path,
238+
epoch=10,
239+
elapsed_time=100.0,
240+
cpu_count=4,
241+
global_best_sol=best_sol,
242+
early_stop_counter=5,
233243
)
234244

235245
metadata: Optional[Dict[str, Any]] = load_run_metadata(tmp_path, epoch=99)
@@ -239,10 +249,20 @@ def test_metadata_accumulates(self, tmp_path: Path):
239249
"""Tests that multiple saves accumulate in the same file."""
240250
best_sol: GlobalBestProg = GlobalBestProg()
241251
save_run_metadata(
242-
tmp_path, epoch=10, elapsed_time=100.0, cpu_count=4, global_best_sol=best_sol, early_stop_counter=5
252+
tmp_path,
253+
epoch=10,
254+
elapsed_time=100.0,
255+
cpu_count=4,
256+
global_best_sol=best_sol,
257+
early_stop_counter=5,
243258
)
244259
save_run_metadata(
245-
tmp_path, epoch=20, elapsed_time=200.0, cpu_count=4, global_best_sol=best_sol, early_stop_counter=10
260+
tmp_path,
261+
epoch=20,
262+
elapsed_time=200.0,
263+
cpu_count=4,
264+
global_best_sol=best_sol,
265+
early_stop_counter=10,
246266
)
247267

248268
metadata_file: Path = tmp_path / RUN_METADATA_FILE

tests/test_scheduler.py

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,9 @@ def test_creation(self):
3939
def test_invalid_weight(self):
4040
"""Tests that non-positive weight raises ValueError."""
4141
with pytest.raises(ValueError):
42-
ExponentialScheduler(
43-
value=0.5, max_value=1.0, min_value=0.01, weight=0.0
44-
)
42+
ExponentialScheduler(value=0.5, max_value=1.0, min_value=0.01, weight=0.0)
4543
with pytest.raises(ValueError):
46-
ExponentialScheduler(
47-
value=0.5, max_value=1.0, min_value=0.01, weight=-1.0
48-
)
44+
ExponentialScheduler(value=0.5, max_value=1.0, min_value=0.01, weight=-1.0)
4945

5046
def test_decay_over_epochs(self):
5147
"""Tests that value decays over epochs with weight < 1."""
@@ -261,16 +257,12 @@ class TestSchedulerBase:
261257
def test_invalid_min_max_value(self):
262258
"""Tests that min_value > max_value raises ValueError."""
263259
with pytest.raises(ValueError):
264-
ExponentialScheduler(
265-
value=0.5, max_value=0.1, min_value=0.9, weight=0.99
266-
)
260+
ExponentialScheduler(value=0.5, max_value=0.1, min_value=0.9, weight=0.99)
267261

268262
def test_value_outside_bounds(self):
269263
"""Tests that value outside [min_value, max_value] raises ValueError."""
270264
with pytest.raises(ValueError):
271-
ExponentialScheduler(
272-
value=1.5, max_value=1.0, min_value=0.0, weight=0.99
273-
)
265+
ExponentialScheduler(value=1.5, max_value=1.0, min_value=0.0, weight=0.99)
274266

275267
def test_reset_with_invalid_value(self):
276268
"""Tests that reset with value outside bounds raises ValueError."""

0 commit comments

Comments
 (0)