Skip to content

Commit 54085d2

Browse files
committed
[OptimizationMOI] improve performance of Jacobian and Hessian accesses
1 parent d6bea20 commit 54085d2

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

lib/OptimizationMOI/src/nlp.jl

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -273,16 +273,19 @@ function MOI.eval_constraint_jacobian(evaluator::MOIOptimizationNLPEvaluator, j,
273273
"automatically generate i with one of the autodiff backends." *
274274
"If you are using the ModelingToolkit symbolic interface, pass the `cons_j` kwarg set to `true` in `OptimizationProblem`.")
275275
end
276-
evaluator.f.cons_j(evaluator.J, x)
277-
if evaluator.J isa SparseMatrixCSC
278-
nnz = nonzeros(evaluator.J)
276+
# Get and cache the Jacobian object here once. `evaluator.J` calls
277+
# `getproperty`, which is expensive because it calls `fieldnames`.
278+
J = evaluator.J
279+
evaluator.f.cons_j(J, x)
280+
if J isa SparseMatrixCSC
281+
nnz = nonzeros(J)
279282
@assert length(j) == length(nnz)
280283
for (i, Ji) in zip(eachindex(j), nnz)
281284
j[i] = Ji
282285
end
283286
else
284287
for i in eachindex(j)
285-
j[i] = evaluator.J[i]
288+
j[i] = J[i]
286289
end
287290
end
288291
return
@@ -336,22 +339,25 @@ function MOI.eval_hessian_lagrangian(evaluator::MOIOptimizationNLPEvaluator{T},
336339
"automatically generate it with one of the autodiff backends." *
337340
"If you are using the ModelingToolkit symbolic interface, pass the `hess` kwarg set to `true` in `OptimizationProblem`.")
338341
end
342+
# Get and cache the Hessian object here once. `evaluator.H` calls
343+
# `getproperty`, which is expensive because it calls `fieldnames`.
344+
H = evaluator.H
339345
fill!(h, zero(T))
340346
k = 0
341-
evaluator.f.hess(evaluator.H, x)
342-
sparse_objective = evaluator.H isa SparseMatrixCSC
347+
evaluator.f.hess(H, x)
348+
sparse_objective = H isa SparseMatrixCSC
343349
if sparse_objective
344-
rows, cols, _ = findnz(evaluator.H)
350+
rows, cols, _ = findnz(H)
345351
for (i, j) in zip(rows, cols)
346352
if i <= j
347353
k += 1
348-
h[k] = σ * evaluator.H[i, j]
354+
h[k] = σ * H[i, j]
349355
end
350356
end
351357
else
352-
for i in 1:size(evaluator.H, 1), j in 1:i
358+
for i in 1:size(H, 1), j in 1:i
353359
k += 1
354-
h[k] = σ * evaluator.H[i, j]
360+
h[k] = σ * H[i, j]
355361
end
356362
end
357363
# A count of the number of non-zeros in the objective Hessian is needed if

0 commit comments

Comments
 (0)