Skip to content

Commit eca43a1

Browse files
committed
Add test for staggered timestep dependencies
This introduces a dependency between non-adjacent timesteps, which can trigger some incorrect behaviour depending on the checkpointing scheduler in use.
1 parent 8b54083 commit eca43a1

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

tests/firedrake/adjoint/test_assignment.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,42 @@ def test_adjoint_cleanup(scheduler, rg):
281281
dtemp = rg.uniform(u_0.function_space())
282282

283283
assert taylor_test(reduced_functional, u_0, dtemp) > 1.99999999
284+
285+
286+
@pytest.mark.skipcomplex
287+
@pytest.mark.parametrize("scheduler", (None, SingleMemoryStorageSchedule()))
288+
def test_adjoint_stagger(scheduler, rg):
289+
# This test checks that the adjoint does not discard too many checkpoint
290+
# variables. This is achieved by computing the derivative before conducting
291+
# the Taylor test. This extra derivative is the thing that would cause the
292+
# spurious discards.
293+
294+
# get tape
295+
tape = get_working_tape()
296+
tape.clear_tape()
297+
continue_annotation()
298+
299+
if scheduler is not None:
300+
tape.enable_checkpointing(scheduler)
301+
302+
mesh = SquareMesh(1, 1, 1, quadrilateral=True)
303+
304+
V = FunctionSpace(mesh, "CG", 1)
305+
R = FunctionSpace(mesh, "R", 0)
306+
307+
u_0 = Function(V).assign(1.0)
308+
u = Function(V).assign(u_0)
309+
r = Function(R)
310+
311+
for i in tape.timestepper(iter(range(10))):
312+
if i % 3 == 0:
313+
r.project(1.01 * u)
314+
u.project(r * u)
315+
316+
J = assemble(u ** 2 * dx)
317+
318+
pause_annotation()
319+
reduced_functional = ReducedFunctional(J, Control(u_0))
320+
321+
dtemp = rg.uniform(u_0.function_space())
322+
assert taylor_test(reduced_functional, u_0, dtemp) > 1.99999999

0 commit comments

Comments
 (0)