You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Nonlinear] sparsity pattern of Hessian with :(x * y) #2527
As discussed with @mlubin during JuMP-dev 2024, we recently observed with Guillaume Dalle (@gdalle) that JuMP detects additional non-zeros on the diagonal of the Hessian than what is needed.
I think this is expected. We don't try to compress the non-zero terms, even in trivial cases. Is there any evidence that this is a performance concern?
As a trivial example, a problem with one variable can have > 1 element in the Hessian:
julia>using JuMP, Ipopt
julia> model =Model(Ipopt.Optimizer)
A JuMP Model
Feasibility problem with:
Variables:0
Model mode: AUTOMATIC
CachingOptimizer state: EMPTY_OPTIMIZER
Solver name: Ipopt
julia>@variable(model, x)
x
julia>@objective(model, Min, sin(x))
sin(x)
julia>@constraint(model, sin(x) >=0)
sin(x) -0.0≥0
julia>optimize!(model)
This is Ipopt version 3.14.14, running with linear solver MUMPS 5.6.2.
Number of nonzeros in equality constraint Jacobian...: 0
Number of nonzeros in inequality constraint Jacobian.: 1
Number of nonzeros in Lagrangian Hessian.............: 2
The issue is not that you don't compress the non-zero terms; it is that you detect non-zero terms where there are zeros in the Hessian.
If these additional nnz and on the diagonal, it doesn't impact the coloring and thus the performance.
You just allocate more storage than needed (+n in the worst case).
If the detected non-zeros are not on the diagonal, you might require more colors (and thus more directional derivatives) to retrieve all non-zeros of the Hessian of the Lagrangian.
I think I'm going to close this issue. There's certainly scope for writing a new AD backend, but I'm very reticent to go making changes to our existing one. The case of x * y isn't the issue because the false non-zeros appear on the diagonal (we think that H[x, x] is non-zero). The larger question of detecting sparsity with separable affine expressions is much more complicated to fix with the current design.
Activity
odow commentedon Jul 22, 2024
I think this is expected. We don't try to compress the non-zero terms, even in trivial cases. Is there any evidence that this is a performance concern?
[-][NLP] Sparsity pattern of Hessian [/-][+][Nonlinear] sparsity pattern of Hessian [/+]odow commentedon Jul 22, 2024
As a trivial example, a problem with one variable can have > 1 element in the Hessian:
amontoison commentedon Jul 22, 2024
The issue is not that you don't compress the non-zero terms; it is that you detect non-zero terms where there are zeros in the Hessian.
If these additional nnz and on the diagonal, it doesn't impact the coloring and thus the performance.
You just allocate more storage than needed (
+nin the worst case).If the detected non-zeros are not on the diagonal, you might require more colors (and thus more directional derivatives) to retrieve all non-zeros of the Hessian of the Lagrangian.
odow commentedon Jul 22, 2024
Do you have an example?
odow commentedon Jul 22, 2024
Is the claim something like this:
Where
(2, 2)in the Hessian is always0.0?Are there examples there this matters?
amontoison commentedon Jul 22, 2024
amontoison commentedon Jul 22, 2024
It seems that the new nonlinear API fixed something 🤔
Benoît helped me to support it today and I never tested it before tonight.
Update: I don't use the non linear API in that case, the constraints are quadratic.
odow commentedon Jul 22, 2024
Your
@NLconstraintsare actually quadratic, so you don't need to do AD on them.Here's the underlying issue:
odow commentedon Jul 22, 2024
So I assume somewhere we are detecting Hessian sparsity and if
op(x, y)then we are adding(x, x), (x, y), and (y, y). We should special-case*.[-][Nonlinear] sparsity pattern of Hessian [/-][+][Nonlinear] sparsity pattern of Hessian with :(x * y)[/+]amontoison commentedon Jul 22, 2024
Nice catch Oscar 👍
I will try to isolate an example tomorrow with additional non-zeros that are not on the diagonal.
amontoison commentedon Jul 22, 2024
@odow I found a simple example with a coefficient off-diagonal:
I don't understand why
H[5,2]is a non-zero.I tried:
instead of
and
H[5,2]is not considered anymore as a non-zero.amontoison commentedon Jul 22, 2024
The Hessian is completely dense 😨
odow commentedon Jul 23, 2024
I think this is even somewhat expected from our sparsity algorithm. We don't recognize that
sum(x) / yis decomposable. The sparsity algorithm trades simplicity for some false positives. I guess the sparseconnectivitytracer trades exactness for some cases where it is much slower than JuMP. I can see how this one might be problematic:https://github.com/JuliaSmoothOptimizers/OptimizationProblems.jl/blob/458d8141bbe7ffc4552c713ec755241de7b4fa15/src/PureJuMP/tetra.jl#L37-L62
I'm still interested in seeing a model where our choice makes an important runtime difference (other than artificial examples like the one above).
odow commentedon Sep 18, 2024
Perhaps this issue is really asking for better insight on how different formulations might perform:
gdalle commentedon Sep 19, 2024
That's a really cool insight actually!
odow commentedon Dec 17, 2024
This came up again in https://discourse.julialang.org/t/too-many-nonzeroes-for-nlp-in-jump-and-examodels/123901
odow commentedon Jan 14, 2025
I think I'm going to close this issue. There's certainly scope for writing a new AD backend, but I'm very reticent to go making changes to our existing one. The case of
x * yisn't the issue because the false non-zeros appear on the diagonal (we think thatH[x, x]is non-zero). The larger question of detecting sparsity with separable affine expressions is much more complicated to fix with the current design.jump-dev/JuMP.jl#3664 can add support for analyzing the Hessian structure.
blegat commentedon Oct 16, 2026
Reopening since there is now a simple way to fix it with #3105