optim/sweep.py: ProcessPoolExecutor workers sample+evaluate genomes in parallel; each result (feasible or not) is pushed through the queue-backed single writer built in Stage 5. Verified with real multiprocessing (not mocks): 12-run sweep across 2 worker processes lands all 12 rows in SQLite with parseable genome/summary JSON, and two independent sweeps with the same seed produce byte-identical results. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
54 lines
2.3 KiB
Python
54 lines
2.3 KiB
Python
import json
|
|
|
|
from gausse.optim.search_space import SearchBounds, genome_from_dict
|
|
from gausse.optim.sweep import MODEL_VERSION, run_sweep
|
|
from gausse.storage.database import count_runs, fetch_runs, open_connection
|
|
|
|
|
|
def test_sweep_runs_all_seeds_and_records_everything(tmp_path):
|
|
db_path = tmp_path / "runs.sqlite3"
|
|
bounds = SearchBounds(max_stages=2) # маленькое пространство -> быстрый тест
|
|
|
|
summary = run_sweep(db_path, n_runs=12, bounds=bounds, n_workers=2, seed=123)
|
|
|
|
assert summary["n_runs"] == 12
|
|
conn = open_connection(db_path)
|
|
assert count_runs(conn) == 12
|
|
# хотя бы какие-то честно попали и в успех, и в провал -- иначе тест
|
|
# пространства слишком узкий/широкий, чтобы быть показательным
|
|
rows = fetch_runs(conn)
|
|
assert len(rows) == 12
|
|
for row in rows:
|
|
assert row.search_mode == "sweep"
|
|
assert row.model_version == MODEL_VERSION
|
|
# genome_json должен быть валидным и декодируемым геномом
|
|
genome = genome_from_dict(json.loads(row.genome_json))
|
|
assert len(genome.stages) >= 1
|
|
summary_dict = json.loads(row.decoded_summary_json)
|
|
assert "stages" in summary_dict
|
|
if row.feasible:
|
|
assert row.efficiency is not None
|
|
assert row.infeasible_reason is None
|
|
else:
|
|
assert row.infeasible_reason is not None
|
|
assert row.efficiency is None
|
|
conn.close()
|
|
|
|
|
|
def test_sweep_is_deterministic_given_same_seed(tmp_path):
|
|
bounds = SearchBounds(max_stages=2)
|
|
db_path_a = tmp_path / "a.sqlite3"
|
|
db_path_b = tmp_path / "b.sqlite3"
|
|
|
|
run_sweep(db_path_a, n_runs=8, bounds=bounds, n_workers=1, seed=42)
|
|
run_sweep(db_path_b, n_runs=8, bounds=bounds, n_workers=1, seed=42)
|
|
|
|
conn_a = open_connection(db_path_a)
|
|
conn_b = open_connection(db_path_b)
|
|
rows_a = sorted(fetch_runs(conn_a), key=lambda r: r.genome_json)
|
|
rows_b = sorted(fetch_runs(conn_b), key=lambda r: r.genome_json)
|
|
assert [r.genome_json for r in rows_a] == [r.genome_json for r in rows_b]
|
|
assert [r.efficiency for r in rows_a] == [r.efficiency for r in rows_b]
|
|
conn_a.close()
|
|
conn_b.close()
|