Exemple #1
0
def test_leaks():
    function_ids.clear()

    yield

    # Clear some internal storage that is allowed to keep references
    manager = _manager()
    manager._cp.clear(clear_refs=True)
    manager._cp_memory.clear()
    tlm_values = manager._tlm.values()  # noqa: F841
    manager._tlm.clear()
    tlm_eqs_values = manager._tlm_eqs.values()  # noqa: F841
    manager._tlm_eqs.clear()

    gc.collect()

    refs = 0
    for F in function_ids.values():
        F = F()
        if F is not None:
            info(f"{F.name():s} referenced")
            refs += 1
    if refs == 0:
        info("No references")

    function_ids.clear()
    assert refs == 0
def test_EmptySolver(setup_test, test_leaks):
    class EmptySolver(Equation):
        def __init__(self):
            super().__init__([], [], nl_deps=[], ic=False, adj_ic=False)

        def forward_solve(self, X, deps=None):
            pass

    space = FunctionSpace(100)
    space_0 = FunctionSpace(1)

    def forward(F):
        EmptySolver().solve()

        F_norm_sq = Function(space_0, name="F_norm_sq")
        NormSqSolver(F, F_norm_sq).solve()

        J = Functional(name="J", space=space_0)
        NormSqSolver(F_norm_sq, J.fn()).solve()
        return J

    F = Function(space, name="F")
    F.vector()[:] = np.arange(len(F.vector()), dtype=np.float64)

    start_manager()
    J = forward(F)
    stop_manager()

    manager = _manager()
    manager.finalize()
    manager.info()
    assert len(manager._blocks) == 1
    assert len(manager._blocks[0]) == 3
    assert len(manager._blocks[0][0].X()) == 0

    J_val = J.value()
    assert abs(J_val - (F.vector()**2).sum()**2) == 0.0

    dJ = compute_gradient(J, F)

    min_order = taylor_test(forward, F, J_val=J_val, dJ=dJ)
    assert min_order > 2.00

    ddJ = Hessian(forward)
    min_order = taylor_test(forward, F, J_val=J_val, ddJ=ddJ)
    assert min_order > 3.00

    min_order = taylor_test_tlm(forward, F, tlm_order=1)
    assert min_order > 2.00

    min_order = taylor_test_tlm_adjoint(forward, F, adjoint_order=1)
    assert min_order > 2.00

    min_order = taylor_test_tlm_adjoint(forward, F, adjoint_order=2)
    assert min_order > 2.00
    def forward(m, forward_run=False):
        class NewtonIterationSolver(Equation):
            def __init__(self, m, x0, x):
                super().__init__(x,
                                 deps=[x, x0, m],
                                 nl_deps=[x0, m],
                                 ic=False,
                                 adj_ic=False)

            def forward_solve(self, x, deps=None):
                _, x0, m = self.dependencies() if deps is None else deps
                function_set_values(
                    x, 0.5 *
                    (function_get_values(x0)**2 + function_get_values(m)) /
                    function_get_values(x0))

            def adjoint_jacobian_solve(self, adj_x, nl_deps, b):
                return b

            def adjoint_derivative_action(self, nl_deps, dep_index, adj_x):
                if dep_index == 1:
                    x0, m = nl_deps
                    F = function_new(x0)
                    function_set_values(
                        F, 0.5 * function_get_values(adj_x) *
                        (function_get_values(m) /
                         (function_get_values(x0)**2) - 1.0))
                    return F
                elif dep_index == 2:
                    x0, m = nl_deps
                    F = function_new(x0)
                    function_set_values(
                        F, -0.5 * function_get_values(adj_x) /
                        function_get_values(x0))
                    return F
                else:
                    raise EquationException("Unexpected dep_index")

        x0 = Constant(1.0, name="x0")
        x1 = Constant(0.0, name="x1")

        eq0 = NewtonIterationSolver(m, x0, x1)
        eq1 = AssignmentSolver(x1, x0)

        fp_eq = FixedPointSolver(
            [eq0, eq1],
            solver_parameters={
                "absolute_tolerance": 0.0,
                "relative_tolerance": 1.0e-14,
                "report": False
            })
        fp_eq.solve()

        if forward_run:
            manager = _manager()

            assert len(manager._to_drop_references) == 0
            for eq in [fp_eq, eq0, eq1]:
                assert not eq._references_dropped
                for dep in eq.dependencies():
                    assert not isinstance(dep, Replacement)
            del eq

            fp_eq = WeakAlias(fp_eq)

            assert len(manager._to_drop_references) == 1
            for eq in [fp_eq, eq0, eq1]:
                assert not eq._references_dropped
                for dep in eq.dependencies():
                    assert not isinstance(dep, Replacement)
            del eq

            manager.drop_references()

            assert len(manager._to_drop_references) == 0
            assert fp_eq._references_dropped
            for dep in fp_eq.dependencies():
                assert isinstance(dep, Replacement)
            for eq in [eq0, eq1]:
                assert not eq._references_dropped
                for dep in eq.dependencies():
                    assert not isinstance(dep, Replacement)
            del eq

        eq0.solve()
        eq1.solve()

        if forward_run:
            assert len(manager._to_drop_references) == 0
            for eq in [eq0, eq1]:
                assert not eq._references_dropped
                for dep in eq.dependencies():
                    assert not isinstance(dep, Replacement)
            del eq

            eq0 = WeakAlias(eq0)
            eq1 = WeakAlias(eq1)

            assert len(manager._to_drop_references) == 2
            for eq in [eq0, eq1]:
                assert not eq._references_dropped
                for dep in eq.dependencies():
                    assert not isinstance(dep, Replacement)
            del eq

            manager.drop_references()

            assert len(manager._to_drop_references) == 0
            for eq in [eq0, eq1]:
                assert eq._references_dropped
                for dep in eq.dependencies():
                    assert isinstance(dep, Replacement)
            del eq

        J = Functional(name="J")
        J.assign(x1)
        return J
    def forward(m, forward_run=False):
        class IdentityMatrix(Matrix):
            def __init__(self):
                super().__init__(nl_deps=[], ic=False, adj_ic=False)

            def forward_action(self, nl_deps, x, b, method="assign"):
                if method == "assign":
                    function_assign(b, x)
                else:
                    raise EquationException(f"Unexpected method '{method:s}'")

            def forward_solve(self, x, nl_deps, b):
                function_assign(x, b)

            def adjoint_solve(self, adj_x, nl_deps, b):
                return b

            def tangent_linear_rhs(self, M, dM, tlm_map, x):
                return None

        x = Constant(0.0, name="x")

        M = IdentityMatrix()
        b = NormSqRHS(m, M=M)
        linear_eq = LinearEquation([b, b], x, A=M)
        linear_eq.solve()

        if forward_run:
            manager = _manager()

            assert len(manager._to_drop_references) == 0
            assert not linear_eq._references_dropped
            assert not b._references_dropped
            assert not M._references_dropped
            for dep in linear_eq.dependencies():
                assert not isinstance(dep, Replacement)
            for dep in b.dependencies():
                assert not isinstance(dep, Replacement)

            linear_eq = WeakAlias(linear_eq)

            assert len(manager._to_drop_references) == 1
            assert not linear_eq._references_dropped
            assert not b._references_dropped
            assert not M._references_dropped
            for dep in linear_eq.dependencies():
                assert not isinstance(dep, Replacement)
            for dep in b.dependencies():
                assert not isinstance(dep, Replacement)

            manager.drop_references()

            assert len(manager._to_drop_references) == 0
            assert linear_eq._references_dropped
            assert not b._references_dropped
            assert not M._references_dropped
            for dep in linear_eq.dependencies():
                assert isinstance(dep, Replacement)
            for dep in b.dependencies():
                assert not isinstance(dep, Replacement)

        y = Constant(0.0, name="y")
        LinearEquation(b, y, A=M).solve()

        z = Constant(0.0, name="z")
        AxpySolver(x, 1.0, y, z).solve()

        if forward_run:
            manager.drop_references()

            assert len(manager._to_drop_references) == 0
            assert not b._references_dropped
            assert not M._references_dropped
            for dep in b.dependencies():
                assert not isinstance(dep, Replacement)

            M = WeakAlias(M)
            b = WeakAlias(b)

            assert len(manager._to_drop_references) == 1
            assert not b._references_dropped
            assert not M._references_dropped
            for dep in b.dependencies():
                assert not isinstance(dep, Replacement)

            manager.drop_references()

            assert len(manager._to_drop_references) == 0
            assert b._references_dropped
            assert M._references_dropped
            for dep in b.dependencies():
                assert isinstance(dep, Replacement)

        J = Functional(name="J")
        NormSqSolver(z, J.fn()).solve()
        return J