Skip to content

Commit b05e462

Browse files
committed
save best programs in checkpoints
1 parent c00cc4e commit b05e462

File tree

2 files changed

+64
-4
lines changed

2 files changed

+64
-4
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ When resuming from a checkpoint:
7676
- The system loads all previously evolved programs and their metrics
7777
- Checkpoint numbering continues from where it left off (e.g., if loaded from checkpoint_50, the next checkpoint will be checkpoint_60)
7878
- All evolution state is preserved (best programs, feature maps, archives, etc.)
79+
- Each checkpoint directory contains a copy of the best program at that point in time
7980

8081
Example workflow with checkpoints:
8182

@@ -91,6 +92,32 @@ python openevolve-run.py examples/function_minimization/initial_program.py \
9192
--checkpoint examples/function_minimization/openevolve_output/checkpoints/checkpoint_50 \
9293
--iterations 50
9394
```
95+
96+
### Comparing Results Across Checkpoints
97+
98+
Each checkpoint directory contains the best program found up to that point, making it easy to compare solutions over time:
99+
100+
```
101+
checkpoints/
102+
checkpoint_10/
103+
best_program.py # Best program at iteration 10
104+
best_program_info.json # Metrics and details
105+
programs/ # All programs evaluated so far
106+
metadata.json # Database state
107+
checkpoint_20/
108+
best_program.py # Best program at iteration 20
109+
...
110+
```
111+
112+
You can compare the evolution of solutions by examining the best programs at different checkpoints:
113+
114+
```bash
115+
# Compare best programs at different checkpoints
116+
diff -u checkpoints/checkpoint_10/best_program.py checkpoints/checkpoint_20/best_program.py
117+
118+
# Compare metrics
119+
cat checkpoints/checkpoint_*/best_program_info.json | grep -A 10 metrics
120+
```
94121
### Docker
95122

96123
You can also install and execute via Docker:

openevolve/controller.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -346,17 +346,50 @@ def _log_iteration(
346346
def _save_checkpoint(self, iteration: int) -> None:
347347
"""
348348
Save a checkpoint
349-
349+
350350
Args:
351351
iteration: Current iteration number
352352
"""
353353
checkpoint_dir = os.path.join(self.output_dir, "checkpoints")
354354
os.makedirs(checkpoint_dir, exist_ok=True)
355-
356-
# Save the database
355+
356+
# Create specific checkpoint directory
357357
checkpoint_path = os.path.join(checkpoint_dir, f"checkpoint_{iteration}")
358+
os.makedirs(checkpoint_path, exist_ok=True)
359+
360+
# Save the database
358361
self.database.save(checkpoint_path, iteration)
359-
362+
363+
# Save the best program found so far
364+
best_program = None
365+
if self.database.best_program_id:
366+
best_program = self.database.get(self.database.best_program_id)
367+
else:
368+
best_program = self.database.get_best_program()
369+
370+
if best_program:
371+
# Save the best program at this checkpoint
372+
best_program_path = os.path.join(checkpoint_path, f"best_program{self.file_extension}")
373+
with open(best_program_path, "w") as f:
374+
f.write(best_program.code)
375+
376+
# Save metrics
377+
best_program_info_path = os.path.join(checkpoint_path, "best_program_info.json")
378+
with open(best_program_info_path, "w") as f:
379+
import json
380+
json.dump({
381+
"id": best_program.id,
382+
"generation": best_program.generation,
383+
"iteration": iteration,
384+
"metrics": best_program.metrics,
385+
"language": best_program.language,
386+
"timestamp": best_program.timestamp,
387+
"saved_at": time.time()
388+
}, f, indent=2)
389+
390+
logger.info(f"Saved best program at checkpoint {iteration} with metrics: "
391+
f"{', '.join(f'{name}={value:.4f}' for name, value in best_program.metrics.items())}")
392+
360393
logger.info(f"Saved checkpoint at iteration {iteration} to {checkpoint_path}")
361394

362395
def _save_best_program(self, program: Optional[Program] = None) -> None:

0 commit comments

Comments
 (0)