Skip to content

Commit

Permalink
[OptimizationMOI] improve performance of Jacobian and Hessian accesses
Browse files Browse the repository at this point in the history
  • Loading branch information
odow committed Jan 16, 2024
1 parent d6bea20 commit 54085d2
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions lib/OptimizationMOI/src/nlp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -273,16 +273,19 @@ function MOI.eval_constraint_jacobian(evaluator::MOIOptimizationNLPEvaluator, j,
"automatically generate i with one of the autodiff backends." *
"If you are using the ModelingToolkit symbolic interface, pass the `cons_j` kwarg set to `true` in `OptimizationProblem`.")
end
evaluator.f.cons_j(evaluator.J, x)
if evaluator.J isa SparseMatrixCSC
nnz = nonzeros(evaluator.J)
# Get and cache the Jacobian object here once. `evaluator.J` calls
# `getproperty`, which is expensive because it calls `fieldnames`.
J = evaluator.J
evaluator.f.cons_j(J, x)
if J isa SparseMatrixCSC
nnz = nonzeros(J)

Check warning on line 281 in lib/OptimizationMOI/src/nlp.jl

View check run for this annotation

Codecov / codecov/patch

lib/OptimizationMOI/src/nlp.jl#L278-L281

Added lines #L278 - L281 were not covered by tests
@assert length(j) == length(nnz)
for (i, Ji) in zip(eachindex(j), nnz)
j[i] = Ji
end
else
for i in eachindex(j)
j[i] = evaluator.J[i]
j[i] = J[i]

Check warning on line 288 in lib/OptimizationMOI/src/nlp.jl

View check run for this annotation

Codecov / codecov/patch

lib/OptimizationMOI/src/nlp.jl#L288

Added line #L288 was not covered by tests
end
end
return
Expand Down Expand Up @@ -336,22 +339,25 @@ function MOI.eval_hessian_lagrangian(evaluator::MOIOptimizationNLPEvaluator{T},
"automatically generate it with one of the autodiff backends." *
"If you are using the ModelingToolkit symbolic interface, pass the `hess` kwarg set to `true` in `OptimizationProblem`.")
end
# Get and cache the Hessian object here once. `evaluator.H` calls
# `getproperty`, which is expensive because it calls `fieldnames`.
H = evaluator.H

Check warning on line 344 in lib/OptimizationMOI/src/nlp.jl

View check run for this annotation

Codecov / codecov/patch

lib/OptimizationMOI/src/nlp.jl#L344

Added line #L344 was not covered by tests
fill!(h, zero(T))
k = 0
evaluator.f.hess(evaluator.H, x)
sparse_objective = evaluator.H isa SparseMatrixCSC
evaluator.f.hess(H, x)
sparse_objective = H isa SparseMatrixCSC

Check warning on line 348 in lib/OptimizationMOI/src/nlp.jl

View check run for this annotation

Codecov / codecov/patch

lib/OptimizationMOI/src/nlp.jl#L347-L348

Added lines #L347 - L348 were not covered by tests
if sparse_objective
rows, cols, _ = findnz(evaluator.H)
rows, cols, _ = findnz(H)

Check warning on line 350 in lib/OptimizationMOI/src/nlp.jl

View check run for this annotation

Codecov / codecov/patch

lib/OptimizationMOI/src/nlp.jl#L350

Added line #L350 was not covered by tests
for (i, j) in zip(rows, cols)
if i <= j
k += 1
h[k] = σ * evaluator.H[i, j]
h[k] = σ * H[i, j]

Check warning on line 354 in lib/OptimizationMOI/src/nlp.jl

View check run for this annotation

Codecov / codecov/patch

lib/OptimizationMOI/src/nlp.jl#L354

Added line #L354 was not covered by tests
end
end
else
for i in 1:size(evaluator.H, 1), j in 1:i
for i in 1:size(H, 1), j in 1:i

Check warning on line 358 in lib/OptimizationMOI/src/nlp.jl

View check run for this annotation

Codecov / codecov/patch

lib/OptimizationMOI/src/nlp.jl#L358

Added line #L358 was not covered by tests
k += 1
h[k] = σ * evaluator.H[i, j]
h[k] = σ * H[i, j]

Check warning on line 360 in lib/OptimizationMOI/src/nlp.jl

View check run for this annotation

Codecov / codecov/patch

lib/OptimizationMOI/src/nlp.jl#L360

Added line #L360 was not covered by tests
end
end
# A count of the number of non-zeros in the objective Hessian is needed if
Expand Down

0 comments on commit 54085d2

Please sign in to comment.