"""Validate tools.export_onnx with a tiny synthetic model.""" from __future__ import annotations import json from pathlib import Path import pytest import torch from tools.export_onnx import ( _check_flow_parity, _check_scroll_parity, export_flow_model, export_scroll_decoder, ) @pytest.fixture def tiny_flow_ckpt(tmp_path: Path) -> Path: """A flow model with seq_len=8, d_model=16, 1 layer — small but valid.""" from tools.models import TrajectoryFlowModel cfg = { "seq_len": 8, "d_model": 16, "nhead": 2, "num_layers": 1, "dim_feedforward": 32, "cond_dim": 3, } model = TrajectoryFlowModel(**cfg, dropout=0.0) model.eval() out = tmp_path / "flow_ckpt" out.mkdir() torch.save(model.state_dict(), out / "flow_model.pt") (out / "train_config.json").write_text(json.dumps(cfg)) return out @pytest.fixture def tiny_scroll_ckpt(tmp_path: Path) -> Path: """A scroll model with seq_len=4, latent=4, hidden=8.""" from tools.scroll.models import ScrollCVAE cfg = {"seq_len": 4, "latent_dim": 4, "hidden": 8, "cond_dim": 7} model = ScrollCVAE(**cfg) model.eval() out = tmp_path / "scroll_ckpt" out.mkdir() torch.save(model.state_dict(), out / "scroll_model.pt") (out / "scroll_config.json").write_text(json.dumps(cfg)) return out def test_export_flow_model_parity(tiny_flow_ckpt: Path, tmp_path: Path) -> None: out_dir = tmp_path / "out" onnx_path = export_flow_model(tiny_flow_ckpt, out_dir) assert onnx_path.exists() _check_flow_parity(tiny_flow_ckpt, onnx_path) # raises on failure def test_export_scroll_decoder_parity(tiny_scroll_ckpt: Path, tmp_path: Path) -> None: out_dir = tmp_path / "out" onnx_path = export_scroll_decoder(tiny_scroll_ckpt, out_dir) assert onnx_path.exists() _check_scroll_parity(tiny_scroll_ckpt, onnx_path)