Skip to content

Commit b853204

Browse files
test: cover issue #207 config persistence round-trip
Added tests that the five new config keys (use_min_dll/min_dll/ maxincs/use_grad_norm/min_nd) round-trip through state_dict()/ from_state_dict(), and that a simulated pre-#207 payload (format_ version 3, missing those keys) still loads and falls back to the Fortran defaults. Also documented, at the format_version check itself, why it deliberately was not bumped for this change (prior precedent #52/#53 bumped it; the additive-only new keys don't need to). PR #213 review finding 6.
1 parent 581900d commit b853204

2 files changed

Lines changed: 66 additions & 0 deletions

File tree

pamica/tests/torch_tests/test_ng_convergence.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,3 +621,58 @@ def test_disabled_stops_default_path_matches_max_iter_on_short_run(real_data):
621621
ng.fit(real_data[:, :8192], max_iter=15, verbose=False)
622622
assert ng.stop_reason == "max_iter"
623623
assert len(ng.ll_history) == 15
624+
625+
626+
# --- persistence: issue #207 config keys (PR #213 review finding 6) --------
627+
628+
629+
def test_convergence_config_round_trips_through_state_dict(real_data):
630+
"""The five issue #207 config keys (use_min_dll/min_dll/maxincs/
631+
use_grad_norm/min_nd) must persist through state_dict()/from_state_dict()
632+
like every other constructor argument (issue #36 persistence contract),
633+
not just the fitted parameter tensors. Non-default values throughout so a
634+
bug that silently fell back to the constructor defaults would be caught."""
635+
ng = _fresh_ng(
636+
seed=1,
637+
use_min_dll=False,
638+
min_dll=1e-4,
639+
maxincs=2,
640+
use_grad_norm=False,
641+
min_nd=1e-3,
642+
)
643+
ng.fit(real_data[:, :2048], max_iter=3, verbose=False)
644+
state = ng.state_dict()
645+
assert state["config"]["use_min_dll"] is False
646+
assert state["config"]["min_dll"] == 1e-4
647+
assert state["config"]["maxincs"] == 2
648+
assert state["config"]["use_grad_norm"] is False
649+
assert state["config"]["min_nd"] == 1e-3
650+
651+
loaded = AMICATorchNG.from_state_dict(state, device="cpu")
652+
assert loaded.use_min_dll is False
653+
assert loaded.min_dll == 1e-4
654+
assert loaded.maxincs == 2
655+
assert loaded.use_grad_norm is False
656+
assert loaded.min_nd == 1e-3
657+
658+
659+
def test_missing_convergence_keys_fall_back_to_fortran_defaults(real_data):
660+
"""A state_dict payload saved before issue #207 has ``format_version==3``
661+
(deliberately not bumped -- see the comment at the ``format_version``
662+
check in ``AMICATorchNG.from_state_dict``) but no
663+
use_min_dll/min_dll/maxincs/use_grad_norm/min_nd keys in its ``config``.
664+
``from_state_dict`` must still load such a payload, falling back to the
665+
constructor's Fortran-faithful defaults for those five keys -- not
666+
raising, and not silently defaulting to some other value."""
667+
ng = _fresh_ng(seed=1, use_min_dll=True, use_grad_norm=True)
668+
ng.fit(real_data[:, :2048], max_iter=3, verbose=False)
669+
state = ng.state_dict()
670+
for key in ("use_min_dll", "min_dll", "maxincs", "use_grad_norm", "min_nd"):
671+
del state["config"][key] # simulate a pre-#207 payload
672+
673+
loaded = AMICATorchNG.from_state_dict(state, device="cpu")
674+
assert loaded.use_min_dll is True
675+
assert loaded.min_dll == 1e-9
676+
assert loaded.maxincs == 5
677+
assert loaded.use_grad_norm is True
678+
assert loaded.min_nd == 1e-7

pamica/torch_impl/core.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2840,6 +2840,17 @@ def from_state_dict(
28402840
picks a default when ``None``); ``dtype`` always comes from the saved
28412841
``config``.
28422842
"""
2843+
# format_version stays 3 here -- deliberately NOT bumped for issue
2844+
# #207, unlike PR #52's 1->2 (adaptive PDF) and PR #53's 2->3
2845+
# (keep_best). The check below is strict equality, so bumping would
2846+
# break loading genuinely older (pre-#53) files for no reason: the
2847+
# five new config keys (use_min_dll/min_dll/maxincs/use_grad_norm/
2848+
# min_nd) are additive-only, and a payload saved before #207 simply
2849+
# lacks them in its ``config`` dict, so ``cls(device=device,
2850+
# **config)`` below falls back to the constructor's own
2851+
# Fortran-faithful defaults for whichever keys are missing -- see
2852+
# test_missing_convergence_keys_fall_back_to_fortran_defaults in
2853+
# test_ng_convergence.py.
28432854
version = state.get("format_version")
28442855
if version != 3:
28452856
raise ValueError(

0 commit comments

Comments
 (0)