Skip to content

Adjoint variational solver #6212

Adjoint variational solver

Adjoint variational solver #6212

GitHub Actions / Firedrake real failed Oct 14, 2024 in 0s

8073 tests run, 7282 passed, 786 skipped, 5 failed.

Annotations

Check failure on line 136 in tests/demos/test_demos_run.py

See this annotation in the file changed.

@github-actions github-actions / Firedrake real

test_demos_run.test_demo_runs[full_waveform_inversion.py.rst]

subprocess.CalledProcessError: Command '['mpiexec', '-n', '2', '/__w/firedrake/firedrake_venv/bin/python', '/tmp/pytest-of-firedrake/pytest-0/popen-gw0/test_demo_runs_full_waveform_i0/full_waveform_inversion.py']' returned non-zero exit status 1.
Raw output
py_file = '/tmp/pytest-of-firedrake/pytest-0/popen-gw0/test_demo_runs_full_waveform_i0/full_waveform_inversion.py'
env = {'CI': 'true', 'COMPLEX': '', 'FIREDRAKE_CI_TESTS': '1', 'FIREDRAKE_TSFC_KERNEL_CACHE_DIR': '/__w/firedrake/firedrake_venv/.cache/tsfc', ...}

    @pytest.mark.skipcomplex  # Will need to add a seperate case for a complex demo.
    def test_demo_runs(py_file, env):
        # Add pytest skips for missing imports or packages
        if basename(py_file) in ("stokes.py", "rayleigh-benard.py", "saddle_point_systems.py", "navier_stokes.py", "netgen_mesh.py"):
            if "mumps" not in get_external_packages():
                pytest.skip("MUMPS not installed with PETSc")
    
        if basename(py_file) in ("stokes.py", "rayleigh-benard.py", "saddle_point_systems.py", "qg_1layer_wave.py"):
            if "hypre" not in get_external_packages():
                pytest.skip("hypre not installed with PETSc")
    
        if basename(py_file) == "qgbasinmodes.py":
            try:
                # Do not use `pytest.importorskip` to check for slepc4py:
                # It isn't sufficient to actually detect whether slepc4py
                # is installed. Both petsc4py and slepc4py require
                # `from xy4py import Xy`
                # to actually load the library.
                from slepc4py import SLEPc  # noqa: F401
            except ImportError:
                pytest.skip(reason="SLEPc unavailable, skipping qgbasinmodes.py")
    
        if basename(py_file) in ("DG_advection.py", "qgbasinmodes.py"):
            pytest.importorskip(
                "matplotlib",
                reason=f"Matplotlib unavailable, skipping {basename(py_file)}"
            )
    
        if basename(py_file) == "netgen_mesh.py":
            pytest.importorskip(
                "netgen",
                reason="Netgen unavailable, skipping Netgen test."
            )
            pytest.importorskip(
                "ngsPETSc",
                reason="ngsPETSc unavailable, skipping Netgen test."
            )
            try:
                from slepc4py import SLEPc  # noqa: F401, F811
            except ImportError:
                pytest.skip(reason="SLEPc unavailable, skipping netgen_mesh.py")
    
        if basename(py_file) in VTK_DEMOS:
            try:
                import vtkmodules.vtkCommonDataModel  # noqa: F401
            except ImportError:
                pytest.skip(reason=f"VTK unavailable, skipping {basename(py_file)}")
        if basename(py_file) in parallel_demos:
            if basename(py_file) == "full_waveform_inversion.py":
                processes = 2
            else:
                raise NotImplementedError("You need to specify the number of processes for this test")
    
            executable = ["mpiexec", "-n", str(processes), sys.executable, py_file]
        else:
            executable = [sys.executable, py_file]
    
>       subprocess.check_call(executable, env=env)

/__w/firedrake/firedrake/tests/demos/test_demos_run.py:136: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

popenargs = (['mpiexec', '-n', '2', '/__w/firedrake/firedrake_venv/bin/python', '/tmp/pytest-of-firedrake/pytest-0/popen-gw0/test_demo_runs_full_waveform_i0/full_waveform_inversion.py'],)
kwargs = {'env': {'CI': 'true', 'COMPLEX': '', 'FIREDRAKE_CI_TESTS': '1', 'FIREDRAKE_TSFC_KERNEL_CACHE_DIR': '/__w/firedrake/firedrake_venv/.cache/tsfc', ...}}
retcode = 1
cmd = ['mpiexec', '-n', '2', '/__w/firedrake/firedrake_venv/bin/python', '/tmp/pytest-of-firedrake/pytest-0/popen-gw0/test_demo_runs_full_waveform_i0/full_waveform_inversion.py']

    def check_call(*popenargs, **kwargs):
        """Run command with arguments.  Wait for command to complete.  If
        the exit code was zero then return, otherwise raise
        CalledProcessError.  The CalledProcessError object will have the
        return code in the returncode attribute.
    
        The arguments are the same as for the call function.  Example:
    
        check_call(["ls", "-l"])
        """
        retcode = call(*popenargs, **kwargs)
        if retcode:
            cmd = kwargs.get("args")
            if cmd is None:
                cmd = popenargs[0]
>           raise CalledProcessError(retcode, cmd)
E           subprocess.CalledProcessError: Command '['mpiexec', '-n', '2', '/__w/firedrake/firedrake_venv/bin/python', '/tmp/pytest-of-firedrake/pytest-0/popen-gw0/test_demo_runs_full_waveform_i0/full_waveform_inversion.py']' returned non-zero exit status 1.

/usr/lib/python3.12/subprocess.py:413: CalledProcessError

Check failure on line 768 in tests/regression/test_adjoint_operators.py

See this annotation in the file changed.

@github-actions github-actions / Firedrake real

test_adjoint_operators.test_consecutive_nonlinear_solves

AttributeError: 'Tape' object has no attribute 'recompute_count'
Raw output
@pytest.mark.skipcomplex  # Taping for complex-valued 0-forms not yet done
    def test_consecutive_nonlinear_solves():
        mesh = UnitSquareMesh(1, 1)
        V = FunctionSpace(mesh, "CG", 1)
        R = FunctionSpace(mesh, "R", 0)
        uic = Function(R, val=2.0)
        u1 = Function(V).assign(uic)
        u0 = Function(u1)
        v = TestFunction(V)
        F = v * u1**2 * dx - v*u0 * dx
        problem = NonlinearVariationalProblem(F, u1)
        solver = NonlinearVariationalSolver(problem)
        for i in range(3):
            u0.assign(u1)
            solver.solve()
        J = assemble(u1**16*dx)
        rf = ReducedFunctional(J, Control(uic))
>       assert taylor_test(rf, uic, Function(R, val=0.01)) > 1.9

tests/regression/test_adjoint_operators.py:768: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../firedrake_venv/src/pyadjoint/pyadjoint/verification.py:35: in taylor_test
    Jm = J(m)
../firedrake_venv/src/pyadjoint/pyadjoint/tape.py:110: in wrapper
    return function(*args, **kwargs)
../firedrake_venv/src/pyadjoint/pyadjoint/reduced_functional.py:215: in __call__
    blocks[i].recompute()
../firedrake_venv/src/pyadjoint/pyadjoint/block.py:358: in recompute
    output = self.recompute_component(inputs,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <firedrake.adjoint_utils.blocks.solving.NonlinearVariationalSolveBlock object at 0x7f3159772750>
inputs = [Coefficient(WithGeometry(FunctionSpace(<firedrake.mesh.MeshTopology object at 0x7f314b1a7ec0>, FiniteElement('Real', ...range', triangle, 1), dim=2), 7871)), 14019), Mesh(VectorElement(FiniteElement('Lagrange', triangle, 1), dim=2), 7871)]
block_variable = <pyadjoint.block_variable.BlockVariable object at 0x7f314b060770>
idx = 0
prepared = (Form([Integral(Product(Argument(WithGeometry(FunctionSpace(<firedrake.mesh.MeshTopology object at 0x7f314b1a7ec0>, Fi...ange', triangle, 1), name=None), Mesh(VectorElement(FiniteElement('Lagrange', triangle, 1), dim=2), 7871)), 14065), [])

    def recompute_component(self, inputs, block_variable, idx, prepared):
        tape = get_working_tape()
>       if self._ad_solvers["recompute_count"] == tape.recompute_count - 1:
E       AttributeError: 'Tape' object has no attribute 'recompute_count'

firedrake/adjoint_utils/blocks/solving.py:640: AttributeError

Check failure on line 843 in tests/regression/test_adjoint_operators.py

See this annotation in the file changed.

@github-actions github-actions / Firedrake real

test_adjoint_operators.test_assign_cofunction[linear_variational_solver]

AttributeError: 'Tape' object has no attribute 'recompute_count'
Raw output
solve_type = 'linear_variational_solver'

    @pytest.mark.skipcomplex  # Taping for complex-valued 0-forms not yet done
    @pytest.mark.parametrize("solve_type", ["solve", "linear_variational_solver"])
    def test_assign_cofunction(solve_type):
        # See https://github.com/firedrakeproject/firedrake/issues/3464 .
        # This function tests the case where Cofunction assigns a
        # Cofunction and a BaseForm.
        mesh = UnitSquareMesh(2, 2)
        V = FunctionSpace(mesh, "CG", 1)
        v = TestFunction(V)
        u = TrialFunction(V)
        k = Function(V).assign(1.0)
        a = k * u * v * dx
        b = Constant(1.0) * v * dx
        u0 = Cofunction(V.dual(), name="u0")
        u1 = Cofunction(V.dual(), name="u1")
        sol = Function(V, name="sol")
        if solve_type == "linear_variational_solver":
            problem = LinearVariationalProblem(lhs(a), rhs(a) + u1, sol)
            solver = LinearVariationalSolver(problem)
        J = 0
        for i in range(2):
            # This loop emulates a time-dependent problem, where the Cofunction
            # added on the right-hand of the equation is updated at each time step.
            u0.assign(assemble(b))
            u1.assign(i * u0 + b)
            if solve_type == "solve":
                solve(a == u1, sol)
            if solve_type == "linear_variational_solver":
                solver.solve()
            J += assemble(((sol + Constant(1.0)) ** 2) * dx)
        rf = ReducedFunctional(J, Control(k))
>       assert np.isclose(rf(k), J, rtol=1e-10)

tests/regression/test_adjoint_operators.py:843: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../firedrake_venv/src/pyadjoint/pyadjoint/tape.py:110: in wrapper
    return function(*args, **kwargs)
../firedrake_venv/src/pyadjoint/pyadjoint/reduced_functional.py:215: in __call__
    blocks[i].recompute()
../firedrake_venv/src/pyadjoint/pyadjoint/block.py:358: in recompute
    output = self.recompute_component(inputs,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <firedrake.adjoint_utils.blocks.solving.NonlinearVariationalSolveBlock object at 0x7f314ae59c10>
inputs = [Coefficient(WithGeometry(FunctionSpace(<firedrake.mesh.MeshTopology object at 0x7f314b779490>, FiniteElement('Lagrang...range', triangle, 1), dim=2), 8263)), 14551), Mesh(VectorElement(FiniteElement('Lagrange', triangle, 1), dim=2), 8263)]
block_variable = <pyadjoint.block_variable.BlockVariable object at 0x7f314ae2bdd0>
idx = 0
prepared = (FormSum([Form([Integral(Product(Argument(WithGeometry(FunctionSpace(<firedrake.mesh.MeshTopology object at 0x7f314b77...ange', triangle, 1), name=None), Mesh(VectorElement(FiniteElement('Lagrange', triangle, 1), dim=2), 8263)), 14592), [])

    def recompute_component(self, inputs, block_variable, idx, prepared):
        tape = get_working_tape()
>       if self._ad_solvers["recompute_count"] == tape.recompute_count - 1:
E       AttributeError: 'Tape' object has no attribute 'recompute_count'

firedrake/adjoint_utils/blocks/solving.py:640: AttributeError

Check failure on line 978 in tests/regression/test_adjoint_operators.py

See this annotation in the file changed.

@github-actions github-actions / Firedrake real

test_adjoint_operators.test_lvs_constant_jacobian[False]

AttributeError: 'Tape' object has no attribute 'recompute_count'
Raw output
constant_jacobian = False

    @pytest.mark.skipcomplex
    @pytest.mark.parametrize("constant_jacobian", [False, True])
    def test_lvs_constant_jacobian(constant_jacobian):
        mesh = UnitIntervalMesh(10)
        X = SpatialCoordinate(mesh)
        space = FunctionSpace(mesh, "Lagrange", 1)
        test = TestFunction(space)
        trial = TrialFunction(space)
    
        u = Function(space, name="u").interpolate(X[0] - 0.5)
        with stop_annotating():
            u_ref = u.copy(deepcopy=True)
        v = Function(space, name="v")
        problem = LinearVariationalProblem(
            inner(trial, test) * dx, inner(u, test) * dx, v,
            constant_jacobian=constant_jacobian)
        solver = LinearVariationalSolver(problem)
        solver.solve()
        J = assemble(v * v * dx)
    
        J_hat = ReducedFunctional(J, Control(u))
    
        dJ = J_hat.derivative(options={"riesz_representation": "l2"})
        assert np.allclose(dJ.dat.data_ro, 2 * assemble(inner(u_ref, test) * dx).dat.data_ro)
    
        u_ref = Function(space, name="u").interpolate(X[0] - 0.1)
>       J_hat(u_ref)

tests/regression/test_adjoint_operators.py:978: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../firedrake_venv/src/pyadjoint/pyadjoint/tape.py:110: in wrapper
    return function(*args, **kwargs)
../firedrake_venv/src/pyadjoint/pyadjoint/reduced_functional.py:215: in __call__
    blocks[i].recompute()
../firedrake_venv/src/pyadjoint/pyadjoint/block.py:358: in recompute
    output = self.recompute_component(inputs,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <firedrake.adjoint_utils.blocks.solving.NonlinearVariationalSolveBlock object at 0x7f3149f93a70>
inputs = [Coefficient(WithGeometry(FunctionSpace(<firedrake.mesh.MeshTopology object at 0x7f3149e34740>, FiniteElement('Lagrang...range', interval, 1), dim=1), 8529)), 14976), Mesh(VectorElement(FiniteElement('Lagrange', interval, 1), dim=1), 8529)]
block_variable = <pyadjoint.block_variable.BlockVariable object at 0x7f3149f728a0>
idx = 0
prepared = (Form([Integral(Product(Coefficient(WithGeometry(FunctionSpace(<firedrake.mesh.MeshTopology object at 0x7f3149e34740>,...ange', interval, 1), name=None), Mesh(VectorElement(FiniteElement('Lagrange', interval, 1), dim=1), 8529)), 15030), [])

    def recompute_component(self, inputs, block_variable, idx, prepared):
        tape = get_working_tape()
>       if self._ad_solvers["recompute_count"] == tape.recompute_count - 1:
E       AttributeError: 'Tape' object has no attribute 'recompute_count'

firedrake/adjoint_utils/blocks/solving.py:640: AttributeError

Check failure on line 978 in tests/regression/test_adjoint_operators.py

See this annotation in the file changed.

@github-actions github-actions / Firedrake real

test_adjoint_operators.test_lvs_constant_jacobian[True]

AttributeError: 'Tape' object has no attribute 'recompute_count'
Raw output
constant_jacobian = True

    @pytest.mark.skipcomplex
    @pytest.mark.parametrize("constant_jacobian", [False, True])
    def test_lvs_constant_jacobian(constant_jacobian):
        mesh = UnitIntervalMesh(10)
        X = SpatialCoordinate(mesh)
        space = FunctionSpace(mesh, "Lagrange", 1)
        test = TestFunction(space)
        trial = TrialFunction(space)
    
        u = Function(space, name="u").interpolate(X[0] - 0.5)
        with stop_annotating():
            u_ref = u.copy(deepcopy=True)
        v = Function(space, name="v")
        problem = LinearVariationalProblem(
            inner(trial, test) * dx, inner(u, test) * dx, v,
            constant_jacobian=constant_jacobian)
        solver = LinearVariationalSolver(problem)
        solver.solve()
        J = assemble(v * v * dx)
    
        J_hat = ReducedFunctional(J, Control(u))
    
        dJ = J_hat.derivative(options={"riesz_representation": "l2"})
        assert np.allclose(dJ.dat.data_ro, 2 * assemble(inner(u_ref, test) * dx).dat.data_ro)
    
        u_ref = Function(space, name="u").interpolate(X[0] - 0.1)
>       J_hat(u_ref)

tests/regression/test_adjoint_operators.py:978: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
../firedrake_venv/src/pyadjoint/pyadjoint/tape.py:110: in wrapper
    return function(*args, **kwargs)
../firedrake_venv/src/pyadjoint/pyadjoint/reduced_functional.py:215: in __call__
    blocks[i].recompute()
../firedrake_venv/src/pyadjoint/pyadjoint/block.py:358: in recompute
    output = self.recompute_component(inputs,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <firedrake.adjoint_utils.blocks.solving.NonlinearVariationalSolveBlock object at 0x7f3149f91790>
inputs = [Coefficient(WithGeometry(FunctionSpace(<firedrake.mesh.MeshTopology object at 0x7f3149ea9730>, FiniteElement('Lagrang...range', interval, 1), dim=1), 8566)), 15047), Mesh(VectorElement(FiniteElement('Lagrange', interval, 1), dim=1), 8566)]
block_variable = <pyadjoint.block_variable.BlockVariable object at 0x7f3149eaa870>
idx = 0
prepared = (Form([Integral(Product(Coefficient(WithGeometry(FunctionSpace(<firedrake.mesh.MeshTopology object at 0x7f3149ea9730>,...ange', interval, 1), name=None), Mesh(VectorElement(FiniteElement('Lagrange', interval, 1), dim=1), 8566)), 15091), [])

    def recompute_component(self, inputs, block_variable, idx, prepared):
        tape = get_working_tape()
>       if self._ad_solvers["recompute_count"] == tape.recompute_count - 1:
E       AttributeError: 'Tape' object has no attribute 'recompute_count'

firedrake/adjoint_utils/blocks/solving.py:640: AttributeError