|
9 | 9 | from pathlib import Path |
10 | 10 | from openevolve.evaluation_result import EvaluationResult |
11 | 11 | import logging |
| 12 | +import os |
| 13 | + |
| 14 | +THIS_FILE_DIR = Path(os.path.dirname(os.path.realpath(__file__))) |
| 15 | + |
12 | 16 | logger = logging.getLogger("examples.rust_adaptive_sort.evaluator") |
13 | 17 |
|
14 | 18 |
|
@@ -63,127 +67,28 @@ async def _evaluate(program_path: str) -> EvaluationResult: |
63 | 67 | dst.write(lib_content) |
64 | 68 |
|
65 | 69 | # Create main.rs with benchmark code |
66 | | - main_content = """ |
67 | | -use sort_test::{adaptive_sort, run_benchmark}; |
68 | | -use std::time::Instant; |
69 | | -
|
70 | | -fn main() { |
71 | | - // Generate test datasets with different characteristics |
72 | | - let test_data = vec![ |
73 | | - // Random data |
74 | | - generate_random_data(1000), |
75 | | - generate_random_data(10000), |
76 | | - |
77 | | - // Nearly sorted data |
78 | | - generate_nearly_sorted_data(1000, 0.05), |
79 | | - generate_nearly_sorted_data(10000, 0.05), |
80 | | - |
81 | | - // Reverse sorted data |
82 | | - generate_reverse_sorted_data(1000), |
83 | | - generate_reverse_sorted_data(10000), |
84 | | - |
85 | | - // Data with many duplicates |
86 | | - generate_data_with_duplicates(1000, 10), |
87 | | - generate_data_with_duplicates(10000, 100), |
88 | | - |
89 | | - // Partially sorted data |
90 | | - generate_partially_sorted_data(1000, 0.3), |
91 | | - generate_partially_sorted_data(10000, 0.3), |
92 | | - ]; |
93 | | - |
94 | | - let results = run_benchmark(test_data); |
95 | | - |
96 | | - // Calculate metrics |
97 | | - let all_correct = results.correctness.iter().all(|&c| c); |
98 | | - let correctness_score = if all_correct { 1.0 } else { 0.0 }; |
99 | | - |
100 | | - let avg_time: f64 = results.times.iter().sum::<f64>() / results.times.len() as f64; |
101 | | - |
102 | | - // Performance score (normalized, assuming baseline of 0.1 seconds for largest dataset) |
103 | | - let performance_score = 1.0 / (1.0 + avg_time * 10.0); |
104 | | - |
105 | | - // Output results as JSON |
106 | | - println!("{{"); |
107 | | - println!(" \\"correctness\\": {},", correctness_score); |
108 | | - println!(" \\"avg_time\\": {},", avg_time); |
109 | | - println!(" \\"performance_score\\": {},", performance_score); |
110 | | - println!(" \\"adaptability_score\\": {},", results.adaptability_score); |
111 | | - println!(" \\"times\\": {:?},", results.times); |
112 | | - println!(" \\"all_correct\\": {}", all_correct); |
113 | | - println!("}}"); |
114 | | -} |
115 | | -
|
116 | | -fn generate_random_data(size: usize) -> Vec<i32> { |
117 | | - (0..size).map(|_| rand::random::<i32>() % 10000).collect() |
118 | | -} |
119 | | -
|
120 | | -fn generate_nearly_sorted_data(size: usize, disorder_rate: f64) -> Vec<i32> { |
121 | | - let mut data: Vec<i32> = (0..size as i32).collect(); |
122 | | - let swaps = (size as f64 * disorder_rate) as usize; |
123 | | - |
124 | | - for _ in 0..swaps { |
125 | | - let i = rand::random::<usize>() % size; |
126 | | - let j = rand::random::<usize>() % size; |
127 | | - data.swap(i, j); |
128 | | - } |
129 | | - |
130 | | - data |
131 | | -} |
132 | | -
|
133 | | -fn generate_reverse_sorted_data(size: usize) -> Vec<i32> { |
134 | | - (0..size as i32).rev().collect() |
135 | | -} |
136 | | -
|
137 | | -fn generate_data_with_duplicates(size: usize, unique_values: usize) -> Vec<i32> { |
138 | | - (0..size).map(|_| rand::random::<i32>() % unique_values as i32).collect() |
139 | | -} |
140 | | -
|
141 | | -fn generate_partially_sorted_data(size: usize, sorted_fraction: f64) -> Vec<i32> { |
142 | | - let sorted_size = (size as f64 * sorted_fraction) as usize; |
143 | | - let mut data = Vec::with_capacity(size); |
144 | | - |
145 | | - // Add sorted portion |
146 | | - data.extend((0..sorted_size as i32)); |
147 | | - |
148 | | - // Add random portion |
149 | | - data.extend((0..(size - sorted_size)).map(|_| rand::random::<i32>() % 10000)); |
150 | | - |
151 | | - data |
152 | | -} |
153 | | -
|
154 | | -// Simple random implementation |
155 | | -mod rand { |
156 | | - use std::cell::Cell; |
157 | | - use std::time::{SystemTime, UNIX_EPOCH}; |
158 | | - |
159 | | - thread_local! { |
160 | | - static SEED: Cell<u64> = Cell::new( |
161 | | - SystemTime::now() |
162 | | - .duration_since(UNIX_EPOCH) |
163 | | - .unwrap() |
164 | | - .as_secs() |
165 | | - ); |
166 | | - } |
167 | | - |
168 | | - pub fn random<T>() -> T |
169 | | - where |
170 | | - T: From<u64>, |
171 | | - { |
172 | | - SEED.with(|seed| { |
173 | | - let mut x = seed.get(); |
174 | | - x ^= x << 13; |
175 | | - x ^= x >> 7; |
176 | | - x ^= x << 17; |
177 | | - seed.set(x); |
178 | | - T::from(x) |
179 | | - }) |
180 | | - } |
181 | | -} |
182 | | -""" |
| 70 | + project_source_dir = THIS_FILE_DIR / "sort_test" |
| 71 | + main_file_source = project_source_dir / "src" / "main.rs" |
| 72 | + with open(main_file_source, "r") as f: |
| 73 | + main_content = f.read() |
183 | 74 | main_path = project_dir / "src" / "main.rs" |
184 | 75 | with open(main_path, "w") as f: |
185 | 76 | f.write(main_content) |
186 | 77 |
|
| 78 | + cargo_toml_source = project_source_dir / "Cargo.toml" |
| 79 | + with open(cargo_toml_source, "r") as f: |
| 80 | + cargo_toml_content = f.read() |
| 81 | + cargo_toml_path = project_dir / "Cargo.toml" |
| 82 | + with open(cargo_toml_path, "w") as f: |
| 83 | + f.write(cargo_toml_content) |
| 84 | + |
| 85 | + cargo_lock_source = project_source_dir / "Cargo.lock" |
| 86 | + with open(cargo_lock_source, "r") as f: |
| 87 | + cargo_lock_content = f.read() |
| 88 | + cargo_lock_path = project_dir / "Cargo.lock" |
| 89 | + with open(cargo_lock_path, "w") as f: |
| 90 | + f.write(cargo_lock_content) |
| 91 | + |
187 | 92 | # Build the project |
188 | 93 | build_result = subprocess.run( |
189 | 94 | ["cargo", "build", "--release"], |
|
0 commit comments