Skip to content

Test that control checkpoints survive recompute (fixes #5082)#5093

Open
sghelichkhani wants to merge 1 commit into
mainfrom
sghelichkhani/fix-checkpoint-control-tests
Open

Test that control checkpoints survive recompute (fixes #5082)#5093
sghelichkhani wants to merge 1 commit into
mainfrom
sghelichkhani/fix-checkpoint-control-tests

Conversation

@sghelichkhani
Copy link
Copy Markdown
Contributor

Companion to dolfin-adjoint/pyadjoint#257, which fixes the underlying bug in CheckpointManager where direct writes to BlockVariable._checkpoint bypassed the is_control guard and wiped the user-supplied control value during forward replay. With that pyadjoint fix in place the control's checkpoint now legitimately survives across replays, which makes two changes necessary here.

The first is that _check_forward, _check_recompute and _check_reverse in tests/firedrake/adjoint/test_burgers_newton.py were asserting that every block-variable checkpoint must be None after replay. That assertion codified the buggy behaviour — under the fix, the control's block variable correctly retains its checkpoint between calls to rf(new_value) and rf.derivative(). The helpers now take an optional list of controls (accepting either Control objects or the underlying overloaded variables) and skip those block variables in the clear-down sweeps. All existing call sites in test_burgers_newton.py and test_checkpointing_multistep.py are updated to thread the controls through.

The second is a regression test test_control_value_survives_recompute in test_checkpointing_multistep.py that captures Steph's MFE from #5082 directly: four timesteps of J = sum_k m**2, evaluated at m0 = 2, must give a derivative of 16. Before the pyadjoint fix this returned 8 because the adjoint replay saw the stale underlying m = 1.

Depends on dolfin-adjoint/pyadjoint#257 — without it the new regression test will fail.

The clear-down assertions in _check_forward, _check_recompute, and
_check_reverse swept every block variable and required _checkpoint to
be None after recompute. That codified the pre-fix behaviour where
the checkpoint manager would silently clobber the control's checkpoint
during forward replay. Now that the manager goes through the
BlockVariable setter and respects the is_control guard, the control's
block variable legitimately retains the user-supplied value across
replays. The helpers now take an optional list of controls and skip
those block variables.

Also add a regression test for #5082: a
4-step model with J = sum(m**2) evaluated at m0 = 2 must have
derivative 16 (the bug produced 8 because the adjoint replay saw the
original m = 1).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant