evaluate_genomes_gpu в gpu/batch_sweep.py — общий раундовый симулятор (_simulate_states) для sweep и эволюции, та же формула фитнеса, что в objective.evaluate (КПД либо -1+доля пройденных ступеней). run_evolution получил use_gpu: поколение целиком уходит в батч-интегратор (на сервере cupy/GTX 1070), полировка остаётся точной на CPU. search_mode=evolve-gpu(...). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
82 lines
3.0 KiB
Python
82 lines
3.0 KiB
Python
import random
|
|
|
|
from gausse.components.database import ComponentDatabase
|
|
from gausse.optim.evolutionary import polish_best, run_evolution
|
|
from gausse.optim.search_space import SearchBounds, sample_genome
|
|
from gausse.storage.database import count_runs, fetch_runs, open_connection
|
|
|
|
DB = ComponentDatabase.load()
|
|
|
|
|
|
def test_run_evolution_writes_all_evaluations_and_returns_summary(tmp_path):
|
|
db_path = tmp_path / "runs.sqlite3"
|
|
bounds = SearchBounds(max_stages=2)
|
|
|
|
summary = run_evolution(
|
|
db_path,
|
|
n_generations=2,
|
|
population_size=6,
|
|
bounds=bounds,
|
|
n_workers=2,
|
|
seed=7,
|
|
polish=False,
|
|
)
|
|
|
|
assert summary["n_evaluated"] == 12 # 2 поколения x 6 особей
|
|
assert "best_fitness" in summary
|
|
|
|
conn = open_connection(db_path)
|
|
assert count_runs(conn) == 12
|
|
rows = fetch_runs(conn)
|
|
assert all(r.search_mode == "evolve" for r in rows)
|
|
conn.close()
|
|
|
|
|
|
def test_evolution_is_reproducible_given_same_seed(tmp_path):
|
|
bounds = SearchBounds(max_stages=2)
|
|
summary_a = run_evolution(
|
|
tmp_path / "a.sqlite3", n_generations=2, population_size=6, bounds=bounds,
|
|
n_workers=1, seed=99, polish=False,
|
|
)
|
|
summary_b = run_evolution(
|
|
tmp_path / "b.sqlite3", n_generations=2, population_size=6, bounds=bounds,
|
|
n_workers=1, seed=99, polish=False,
|
|
)
|
|
assert summary_a["best_fitness"] == summary_b["best_fitness"]
|
|
assert summary_a["best_efficiency"] == summary_b["best_efficiency"]
|
|
|
|
|
|
def test_polish_does_not_make_the_best_genome_worse():
|
|
rng = random.Random(15)
|
|
bounds = SearchBounds(max_stages=2)
|
|
# ищем реализуемый геном как стартовую точку доводки
|
|
genome = None
|
|
for _ in range(30):
|
|
candidate = sample_genome(DB, bounds, rng)
|
|
from gausse.optim.objective import evaluate
|
|
result = evaluate(candidate, DB, bounds)
|
|
if result.feasible:
|
|
genome = candidate
|
|
baseline_fitness = result.fitness
|
|
break
|
|
assert genome is not None, "не нашли реализуемый геном за 30 попыток"
|
|
|
|
_, polished_result = polish_best(genome, DB, bounds)
|
|
assert polished_result.fitness >= baseline_fitness - 1e-9
|
|
|
|
|
|
def test_run_evolution_gpu_batch_mode(tmp_path):
|
|
"""GPU-режим эволюции (батч-оценка поколения; здесь numpy-бэкенд):
|
|
пишет прогоны в ту же БД и находит реализуемые конфигурации."""
|
|
from gausse.storage.database import count_runs, fetch_runs, open_connection
|
|
|
|
db_path = tmp_path / "evo_gpu.sqlite3"
|
|
summary = run_evolution(
|
|
db_path, n_generations=3, population_size=40, seed=5, polish=False, use_gpu=True
|
|
)
|
|
assert summary["n_evaluated"] == 120
|
|
conn = open_connection(db_path)
|
|
assert count_runs(conn) >= 120
|
|
rows = fetch_runs(conn, limit=5)
|
|
assert all(r.search_mode.startswith("evolve-gpu") for r in rows)
|