Skip to content

Commit 599cd54

Browse files
authored
Merge pull request #181 from richardcsuwandi/main
Add AlgoTune tasks for OpenEvolve
2 parents 5a5bd3b + c0850f1 commit 599cd54

File tree

6 files changed

+1568
-1
lines changed

6 files changed

+1568
-1
lines changed

examples/algotune/README.md

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
# AlgoTune Task Adapter for OpenEvolve
2+
3+
This directory contains tools to convert AlgoTune tasks to OpenEvolve format for evolutionary optimization.
4+
5+
## Overview
6+
7+
The `AlgoTuneTaskAdapter` extracts tasks from an external AlgoTune repository and converts them to OpenEvolve format, creating:
8+
- `initial_program.py` - The initial implementation to be evolved
9+
- `evaluator.py` - Evaluation logic with baseline comparison
10+
- `config.yaml` - OpenEvolve configuration
11+
12+
## Prerequisites
13+
14+
**AlgoTune Repository**: Clone the AlgoTune repository
15+
```bash
16+
git clone https://github.com/oripress/AlgoTune.git
17+
```
18+
19+
20+
## Usage
21+
22+
### Basic Usage
23+
24+
```python
25+
from task_adapter import AlgoTuneTaskAdapter
26+
27+
# Initialize with AlgoTune repository path
28+
adapter = AlgoTuneTaskAdapter(algotune_path="/path/to/AlgoTune")
29+
30+
# List available tasks
31+
tasks = adapter.list_available_tasks()
32+
print(f"Available tasks: {tasks}")
33+
34+
# Create OpenEvolve files for a specific task
35+
output_dir = adapter.create_task_files("svm")
36+
print(f"Created files in: {output_dir}")
37+
```
38+
39+
### Command Line Usage
40+
41+
#### List Available Tasks
42+
```bash
43+
python generate_all_tasks.py --algotune-path /path/to/AlgoTune --list
44+
```
45+
46+
#### Generate Files for a Specific Task
47+
```bash
48+
python create_task.py --algotune-path /path/to/AlgoTune --task svm
49+
```
50+
51+
#### Generate All Tasks
52+
```bash
53+
python generate_all_tasks.py --algotune-path /path/to/AlgoTune
54+
```
55+
56+
## File Structure
57+
58+
For each task, the adapter creates:
59+
60+
```
61+
task_name/
62+
├── initial_program.py # Initial implementation to evolve
63+
├── evaluator.py # Evaluation logic with baseline comparison
64+
└── config.yaml # OpenEvolve configuration
65+
```
66+
67+
## Configuration
68+
69+
The adapter automatically generates OpenEvolve configurations with:
70+
- Baseline comparison against original AlgoTune implementations
71+
- Speedup-based fitness scoring
72+
- Cascade evaluation for efficiency
73+
- Task-specific problem generation
74+
75+
## Evaluation Features
76+
77+
The generated evaluators include:
78+
- **Baseline Comparison**: Compares evolved solutions against original AlgoTune implementations
79+
- **Speedup Measurement**: Calculates performance improvements
80+
- **Correctness Validation**: Ensures solutions are valid
81+
82+
## Example: SVM Task
83+
84+
Here's an example of how the adapter transforms an AlgoTune SVM task:
85+
86+
### Generated Initial Program (`initial_program.py`)
87+
88+
```python
89+
# EVOLVE-BLOCK-START
90+
"""
91+
SVM Task
92+
Given labels y ∈ {-1, 1}^n and a feature matrix X ∈ R^{n x p} with rows x_1,...,x_n,
93+
solve the support vector machine (SVM) task
94+
95+
min 1/2 || β ||_2^2 + C sum_{i=1}^n ξ_i
96+
β,β_0,ξ
97+
98+
subject to ξ_i ≥ 0, i = 1,...,n
99+
y_i (x_i^T β + β_0) ≥ 1 - ξ_i, i = 1,...,n
100+
101+
Input: Dictionary with keys "X", "y", "C"
102+
Output: Dictionary with keys "beta0", "beta", "optimal_value", "misclass_error"
103+
"""
104+
import cvxpy as cp
105+
import numpy as np
106+
107+
class SVMTask:
108+
def solve(self, problem):
109+
"""Solve the SVM problem using CVXPY."""
110+
X = np.array(problem["X"])
111+
y = np.array(problem["y"])[:, None]
112+
C = float(problem["C"])
113+
114+
p, n = X.shape[1], X.shape[0]
115+
beta = cp.Variable((p, 1))
116+
beta0 = cp.Variable()
117+
xi = cp.Variable((n, 1))
118+
119+
objective = cp.Minimize(0.5 * cp.sum_squares(beta) + C * cp.sum(xi))
120+
constraints = [
121+
xi >= 0,
122+
cp.multiply(y, X @ beta + beta0) >= 1 - xi,
123+
]
124+
125+
problem_cp = cp.Problem(objective, constraints)
126+
problem_cp.solve()
127+
128+
return {
129+
"beta0": float(beta0.value),
130+
"beta": beta.value.flatten().tolist(),
131+
"optimal_value": float(problem_cp.value),
132+
"misclass_error": self._compute_misclassification_error(X, y, beta.value, beta0.value)
133+
}
134+
# EVOLVE-BLOCK-END
135+
```
136+
137+
### Generated Configuration (`config.yaml`)
138+
139+
```yaml
140+
# Configuration for svm task
141+
max_iterations: 100
142+
checkpoint_interval: 10
143+
144+
# LLM configuration
145+
llm:
146+
primary_model: "gpt-4o-mini"
147+
temperature: 0.7
148+
max_tokens: 4096
149+
150+
# Prompt configuration
151+
prompt:
152+
system_message: "You are an expert programmer specializing in convex_optimization algorithms. Your task is to improve the svm algorithm implementation..."
153+
154+
# AlgoTune task-specific configuration
155+
algotune:
156+
num_trials: 5
157+
data_size: 5
158+
timeout: 30
159+
```
160+
161+
### Generated Evaluator (`evaluator.py`)
162+
163+
The evaluator:
164+
- Loads the evolved solve method from `initial_program.py`
165+
- Generates test problems using the original AlgoTune task
166+
- Runs the evolved solution and measures performance
167+
- Validates correctness using the original task's validation method
168+
- Compares against reference solutions from AlgoTune
169+
170+
## Files
171+
172+
- `task_adapter.py` - Main adapter that converts AlgoTune tasks to OpenEvolve format
173+
- `create_task.py` - Script to create OpenEvolve files for a single task
174+
- `generate_all_tasks.py` - Script to generate all 155 AlgoTune tasks
175+
176+
## Integration with OpenEvolve
177+
178+
Once files are generated, you can run OpenEvolve:
179+
180+
```bash
181+
# Navigate to the task directory
182+
cd svm/
183+
184+
# Run OpenEvolve on the task
185+
python ../../../openevolve-run.py ./initial_program.py ./evaluator.py \
186+
--config ./config.yaml \
187+
--output openevolve_output/
188+
```

examples/algotune/create_task.py

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to create OpenEvolve task files from AlgoTune tasks.
4+
5+
This script demonstrates how to use the AlgoTuneTaskAdapter to convert
6+
AlgoTune tasks to OpenEvolve format using external AlgoTune repositories.
7+
"""
8+
9+
import sys
10+
import argparse
11+
from pathlib import Path
12+
from task_adapter import AlgoTuneTaskAdapter
13+
14+
def main():
15+
"""Main function to create OpenEvolve task files."""
16+
17+
parser = argparse.ArgumentParser(description="Create OpenEvolve task files from AlgoTune tasks")
18+
parser.add_argument(
19+
"--task",
20+
type=str,
21+
required=True,
22+
help="Task name to create OpenEvolve files for"
23+
)
24+
25+
parser.add_argument(
26+
"--algotune-path",
27+
type=str,
28+
required=True,
29+
help="Path to AlgoTune repository directory (e.g., /path/to/AlgoTune)"
30+
)
31+
32+
args = parser.parse_args()
33+
34+
try:
35+
# Initialize the adapter with AlgoTune path
36+
adapter = AlgoTuneTaskAdapter(algotune_path=args.algotune_path, task=args.task)
37+
38+
# List available tasks
39+
available_tasks = adapter.list_available_tasks()
40+
print(f"Available tasks: {len(available_tasks)}")
41+
print(available_tasks)
42+
43+
task_name = args.task
44+
45+
# Check if the task exists
46+
if task_name not in available_tasks:
47+
print(f"Error: Task '{task_name}' not found")
48+
print(f"Available tasks: {available_tasks[:10]}...")
49+
return 1
50+
51+
# Create the OpenEvolve files
52+
print(f"\nCreating OpenEvolve files for task: {task_name}")
53+
output_dir = adapter.create_task_files(task_name)
54+
print(f"✅ Created files in: {output_dir}")
55+
56+
# List the created files
57+
output_path = Path(output_dir)
58+
created_files = list(output_path.glob("*"))
59+
print("Created files:")
60+
for file in created_files:
61+
print(f" - {file.name}")
62+
63+
print(f"\n✅ Successfully created OpenEvolve files for '{task_name}'")
64+
return 0
65+
66+
except Exception as e:
67+
print(f"Error: {e}")
68+
print("\nExample usage:")
69+
print(" python create_task.py --algotune-path /path/to/AlgoTune --task svm")
70+
return 1
71+
72+
if __name__ == "__main__":
73+
sys.exit(main())
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to generate OpenEvolve task files for all AlgoTune tasks.
4+
5+
This script uses the AlgoTuneTaskAdapter to convert all available AlgoTune tasks
6+
to OpenEvolve format using external AlgoTune repositories.
7+
"""
8+
9+
import sys
10+
import argparse
11+
from pathlib import Path
12+
from task_adapter import AlgoTuneTaskAdapter
13+
14+
def main():
15+
"""Main function to generate OpenEvolve task files."""
16+
17+
parser = argparse.ArgumentParser(description="Generate OpenEvolve task files from AlgoTune tasks")
18+
parser.add_argument(
19+
"--algotune-path",
20+
type=str,
21+
required=True,
22+
help="Path to AlgoTune repository directory (e.g., /path/to/AlgoTune)"
23+
)
24+
parser.add_argument(
25+
"--list",
26+
action="store_true",
27+
help="List all available tasks"
28+
)
29+
parser.add_argument(
30+
"--output-dir",
31+
type=str,
32+
help="Output directory for generated files (default: task name subdirectories)"
33+
)
34+
35+
args = parser.parse_args()
36+
37+
try:
38+
# Initialize the adapter with AlgoTune path
39+
adapter = AlgoTuneTaskAdapter(algotune_path=args.algotune_path)
40+
41+
# List available tasks
42+
available_tasks = adapter.list_available_tasks()
43+
print(f"Found {len(available_tasks)} available AlgoTune tasks")
44+
45+
if args.list:
46+
print("\nAvailable tasks:")
47+
for i, task_name in enumerate(available_tasks, 1):
48+
print(f" {i:3d}. {task_name}")
49+
return 0
50+
51+
# Generate files for all tasks
52+
tasks_to_process = available_tasks
53+
print(f"\nGenerating OpenEvolve files for {len(tasks_to_process)} tasks...")
54+
55+
successful = 0
56+
failed = 0
57+
58+
for i, task_name in enumerate(tasks_to_process, 1):
59+
try:
60+
print(f"[{i:3d}/{len(tasks_to_process)}] Processing {task_name}...")
61+
output_dir = adapter.create_task_files(task_name, args.output_dir)
62+
print(f" ✅ Success: {output_dir}")
63+
successful += 1
64+
except Exception as e:
65+
print(f" ❌ Failed: {e}")
66+
failed += 1
67+
68+
print(f"\nSummary:")
69+
print(f" Successful: {successful}")
70+
print(f" Failed: {failed}")
71+
print(f" Total: {len(tasks_to_process)}")
72+
73+
if failed > 0:
74+
print(f"\nSome tasks failed to generate. Check the errors above.")
75+
return 1
76+
77+
return 0
78+
79+
except Exception as e:
80+
print(f"Error: {e}")
81+
print("\nExample usage:")
82+
print(" python generate_all_tasks.py --algotune-path /path/to/AlgoTune")
83+
return 1
84+
85+
if __name__ == "__main__":
86+
sys.exit(main())

examples/algotune/requirements.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
botorch>=0.10.0
2+
orjson>=3.11.1
3+
cvxopt>=1.3.2
4+
numpy
5+
pandas
6+
cython
7+
numba
8+
dask
9+
pulp
10+
scipy
11+
ortools>=9.7.0,<9.8.0
12+
pyomo
13+
highspy
14+
networkx
15+
python-sat
16+
jax
17+
diffrax
18+
sympy
19+
faiss-cpu
20+
cryptography
21+
scikit-learn
22+
hdbscan
23+
cvxpy
24+
torch
25+
pot
26+
ecos
27+
litellm
28+
google-generativeai
29+
pylint
30+
line_profiler
31+
toml
32+
pyaml
33+
pillow
34+
pythran
35+
dace
36+
psutil

0 commit comments

Comments
 (0)