Skip to content

Commit bd7a48b

Browse files
population_evolve: parallelize init + mutation via batch_llm_call
- Remove serial spawn_individual + sequential init_population - New init_population builds all prompts and fires batch_llm_call at once - Remove serial mutate() + crossover() helpers - New next-gen loop builds mutation/crossover prompts in batch, fires once - Population spawn: N sequential LLM calls → 1 parallel batch_llm_call - Per-generation: N sequential mutations → 1 parallel batch_llm_call Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 04db0c7 commit bd7a48b

1 file changed

Lines changed: 57 additions & 65 deletions

File tree

examples/demos/population_evolve.omc

Lines changed: 57 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -46,79 +46,44 @@ fn compute_fitness(code, test_cases) {
4646

4747
# ── Population initialization ─────────────────────────────────────────────────
4848

49-
fn spawn_individual(problem_description, index) {
49+
50+
fn init_population(problem, pop_size) {
51+
# Build all spawn prompts at once and fire in parallel via batch_llm_call
52+
h variety_hint = ["", " Think creatively.", " Use a different algorithm.", " Optimize for readability.", " Use recursion if possible."]
5053
h sys = str_concat(
51-
"Write an OMC function named target_fn that solves: ", problem_description, "\n",
54+
"Write an OMC function named target_fn that solves: ", problem, "\n",
5255
"Use h for bindings, fn for functions, while for loops.\n",
5356
"Return ONLY the OMC code, no explanation."
5457
)
55-
h variety_hint = ["", " Think creatively.", " Use a different algorithm.", " Optimize for readability.", " Use recursion if possible."]
56-
h hint = variety_hint[index % arr_len(variety_hint)]
57-
h prompt = str_concat("Write target_fn for: ", problem_description, hint)
58-
h code = llm_call(prompt, MODEL, sys)
59-
if str_contains(code, "```") {
60-
h parts = str_split(code, "```")
61-
if arr_len(parts) >= 3 { code = str_trim(parts[1]) }
62-
if str_starts_with(code, "omc\n") { code = str_slice(code, 4, str_len(code)) }
63-
}
64-
return str_trim(code)
65-
}
66-
67-
fn init_population(problem, pop_size) {
68-
h population = []
58+
h prompts = []
6959
h i = 0
7060
while i < pop_size {
71-
print(str_concat(" Spawning individual ", to_str(i + 1), "/", to_str(pop_size)))
72-
h individual = spawn_individual(problem, i)
73-
arr_push(population, {code: individual, fitness: 0.0})
61+
h hint = variety_hint[i % arr_len(variety_hint)]
62+
h p = str_concat("Write target_fn for: ", problem, hint)
63+
arr_push(prompts, {prompt: p, system: sys})
7464
i = i + 1
7565
}
66+
print(str_concat(" Spawning ", to_str(pop_size), " individuals in parallel..."))
67+
h raw_codes = batch_llm_call(prompts, MODEL)
68+
h population = []
69+
h ci = 0
70+
while ci < arr_len(raw_codes) {
71+
h code = raw_codes[ci]
72+
if str_contains(code, "```") {
73+
h parts = str_split(code, "```")
74+
if arr_len(parts) >= 3 {
75+
code = str_trim(parts[1])
76+
if str_starts_with(code, "omc\n") { code = str_slice(code, 4, str_len(code)) }
77+
}
78+
}
79+
arr_push(population, {code: str_trim(code), fitness: 0.0})
80+
ci = ci + 1
81+
}
7682
return population
7783
}
7884

7985
# ── Genetic operators ─────────────────────────────────────────────────────────
8086

81-
fn mutate(code, problem_description) {
82-
h sys = "You write OMC code. Return ONLY code, no markdown, no explanation."
83-
h mutation_types = [
84-
"refactor for clarity",
85-
"add input validation and edge case handling",
86-
"optimize the algorithm",
87-
"rewrite using a different approach",
88-
"improve variable naming"
89-
]
90-
h mt_idx = (str_len(code) % arr_len(mutation_types))
91-
h mutation = mutation_types[mt_idx]
92-
h prompt = str_concat(
93-
"Mutate this OMC function (", mutation, "):\n\n",
94-
code, "\n\n",
95-
"The function must still solve: ", problem_description, "\n",
96-
"Return only the mutated OMC code."
97-
)
98-
h result = llm_call(prompt, MODEL, sys)
99-
if str_contains(result, "```") {
100-
h parts = str_split(result, "```")
101-
if arr_len(parts) >= 3 { return str_trim(parts[1]) }
102-
}
103-
return str_trim(result)
104-
}
105-
106-
fn crossover(code_a, code_b, problem) {
107-
h sys = "You write OMC code. Return ONLY code, no markdown, no explanation."
108-
h prompt = str_concat(
109-
"Combine the best aspects of these two OMC functions into one better implementation.\n\n",
110-
"Function A:\n", code_a, "\n\n",
111-
"Function B:\n", code_b, "\n\n",
112-
"Task: ", problem, "\n",
113-
"Return only the combined OMC function named target_fn."
114-
)
115-
h result = llm_call(prompt, MODEL, sys)
116-
if str_contains(result, "```") {
117-
h parts = str_split(result, "```")
118-
if arr_len(parts) >= 3 { return str_trim(parts[1]) }
119-
}
120-
return str_trim(result)
121-
}
12287

12388
# ── Selection ─────────────────────────────────────────────────────────────────
12489

@@ -210,21 +175,48 @@ fn evolve(problem, test_cases, pop_size, generations, elite_count) {
210175
ei = ei + 1
211176
}
212177

213-
# Fill rest with mutation + crossover
178+
# Build mutation/crossover prompts in batch for parallelism
179+
h mutation_types = ["refactor for clarity", "add edge case handling", "optimize the algorithm", "rewrite using a different approach", "improve variable naming"]
180+
h mut_sys = "You write OMC code. Return ONLY code, no markdown, no explanation."
181+
h batch_prompts = []
214182
h ni = 0
215183
while ni < pop_size - elite_count {
216184
h parent_a = tournament_select(population)
217-
h new_code = ""
185+
h mut_type = mutation_types[ni % arr_len(mutation_types)]
186+
h p = ""
218187
if ni % 3 == 0 and arr_len(population) >= 2 {
219188
h parent_b = tournament_select(population)
220-
new_code = crossover(parent_a["code"], parent_b["code"], problem)
189+
p = str_concat(
190+
"Combine the best aspects of these two OMC functions into one better implementation.\n\n",
191+
"Function A:\n", parent_a["code"], "\n\n",
192+
"Function B:\n", parent_b["code"], "\n\n",
193+
"Task: ", problem, "\n",
194+
"Return only the combined OMC function named target_fn."
195+
)
221196
} else {
222-
new_code = mutate(parent_a["code"], problem)
197+
p = str_concat(
198+
"Mutate this OMC function (", mut_type, "):\n\n",
199+
parent_a["code"], "\n\n",
200+
"Must still solve: ", problem, "\nReturn only the mutated OMC code."
201+
)
223202
}
224-
arr_push(next_pop, {code: new_code, fitness: 0.0})
203+
arr_push(batch_prompts, {prompt: p, system: mut_sys})
225204
ni = ni + 1
226205
}
227206

207+
# Fire all mutations/crossovers in parallel
208+
h mut_results = batch_llm_call(batch_prompts, MODEL)
209+
h mri = 0
210+
while mri < arr_len(mut_results) {
211+
h code = mut_results[mri]
212+
if str_contains(code, "```") {
213+
h parts = str_split(code, "```")
214+
if arr_len(parts) >= 3 { code = str_trim(parts[1]) }
215+
}
216+
arr_push(next_pop, {code: str_trim(code), fitness: 0.0})
217+
mri = mri + 1
218+
}
219+
228220
population = next_pop
229221
gen = gen + 1
230222
}

0 commit comments

Comments
 (0)