Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OptimizationMOI] improve performance of Jacobian and Hessian accesses #680

Merged
merged 1 commit into from
Jan 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@
"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 @@
"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
Loading