-
Notifications
You must be signed in to change notification settings - Fork 92
[Nonlinear.ReverseAD] fix performance bug in Hessian computation #2783
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
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Yes, silly Oscar, I should have noticed that 6 seconds was much too long: |
Nice catch! |
Just to double check: https://github.com/jump-dev/MathOptInterface.jl/actions/runs/16183057627 |
Original benchmark: julia> using Revise
julia> using JuMP
julia> import PowerModels
julia> import Ipopt
julia> begin
PowerModels.silence()
pm = PowerModels.instantiate_model(
"pglib_opf_case9241_pegase.m",
PowerModels.ACPPowerModel,
PowerModels.build_opf,
)
set_optimizer(pm.model, Ipopt.Optimizer)
set_optimizer_attribute(pm.model, "max_iter", 10)
optimize!(pm.model)
nlp_block = JuMP.MOI.get(JuMP.unsafe_backend(pm.model), JuMP.MOI.NLPBlock())
total_callback_time =
nlp_block.evaluator.eval_objective_timer +
nlp_block.evaluator.eval_objective_gradient_timer +
nlp_block.evaluator.eval_constraint_timer +
nlp_block.evaluator.eval_constraint_jacobian_timer +
nlp_block.evaluator.eval_hessian_lagrangian_timer
println("")
println(" callbacks time:")
println(" * obj.....: $(nlp_block.evaluator.eval_objective_timer)")
println(" * grad....: $(nlp_block.evaluator.eval_objective_gradient_timer)")
println(" * cons....: $(nlp_block.evaluator.eval_constraint_timer)")
println(" * jac.....: $(nlp_block.evaluator.eval_constraint_jacobian_timer)")
println(" * hesslag.: $(nlp_block.evaluator.eval_hessian_lagrangian_timer)")
end
[info | PowerModels]: Suppressing information and warning messages for the rest of this session. Use the Memento package for more fine-grained control of logging.
This is Ipopt version 3.14.17, running with linear solver MUMPS 5.8.0.
Number of nonzeros in equality constraint Jacobian...: 395686
Number of nonzeros in inequality constraint Jacobian.: 92610
Number of nonzeros in Lagrangian Hessian.............: 713775
Total number of variables............................: 85568
variables with only lower bounds: 0
variables with lower and upper bounds: 76327
variables with only upper bounds: 0
Total number of equality constraints.................: 82679
Total number of inequality constraints...............: 46305
inequality constraints with only lower bounds: 0
inequality constraints with lower and upper bounds: 14207
inequality constraints with only upper bounds: 32098
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
0 3.2558304e+06 2.84e+01 1.00e+02 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
1 3.3372098e+06 2.78e+01 9.84e+01 -1.0 4.34e+01 - 1.24e-02 1.94e-02h 1
2 3.4280547e+06 2.71e+01 9.72e+01 -1.0 2.28e+01 - 4.12e-03 2.66e-02h 1
3 3.5289937e+06 2.58e+01 9.56e+01 -1.0 3.02e+01 - 6.36e-03 4.59e-02h 1
4 3.5702968e+06 2.45e+01 9.32e+01 -1.0 1.07e+02 - 1.79e-02 5.04e-02h 1
5 3.5683907e+06 2.33e+01 9.08e+01 -1.0 3.09e+02 - 2.17e-02 4.89e-02h 1
6 3.5755535e+06 2.17e+01 8.64e+01 -1.0 4.37e+02 - 4.46e-02 6.90e-02h 1
7 3.6404373e+06 1.99e+01 8.12e+01 -1.0 4.61e+02 - 5.66e-02 8.20e-02h 1
8 3.8204827e+06 1.73e+01 7.37e+01 -1.0 4.59e+02 - 8.46e-02 1.33e-01H 1
9 4.0996155e+06 1.46e+01 6.99e+01 -1.0 4.05e+02 - 3.36e-02 1.58e-01h 1
iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
10 4.3347590e+06 1.27e+01 6.25e+01 -1.0 3.14e+02 - 1.02e-01 1.29e-01h 1
Number of Iterations....: 10
(scaled) (unscaled)
Objective...............: 3.1946168015315146e+04 4.3347589898830801e+06
Dual infeasibility......: 6.2495182233300511e+01 8.4799389047321492e+03
Constraint violation....: 1.2668657111871276e+01 1.2668657111871276e+01
Variable bound violation: 0.0000000000000000e+00 0.0000000000000000e+00
Complementarity.........: 2.6555734531625495e+06 3.6033338627257758e+08
Overall NLP error.......: 2.6555734531625495e+06 3.6033338627257758e+08
Number of objective function evaluations = 12
Number of objective gradient evaluations = 11
Number of equality constraint evaluations = 12
Number of inequality constraint evaluations = 12
Number of equality constraint Jacobian evaluations = 11
Number of inequality constraint Jacobian evaluations = 11
Number of Lagrangian Hessian evaluations = 10
Total seconds in IPOPT = 10.166
EXIT: Maximum Number of Iterations Exceeded.
callbacks time:
* obj.....: 0.0
* grad....: 0.0
* cons....: 0.993605375289917
* jac.....: 0.4068117141723633
* hesslag.: 1.6697413921356201 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Closes #2782
I bisected this to #2730
I obviously didn't notice the logic change that was hidden in the refactoring. We go from zeroing a small number of elements, to repeatedly zeroing a very large vector.
I learned that
fill!(x, 0.0)
doesn't show up on ProfileView because it isn't implemented in Julia. It just showed as a blank time with no hits. But PProf.jl showed:which gave the game away because what is
bzero
doing off to the side and taking 80% of the total runtime!I think this is a great example of how difficult it is to make even very minor seeming changes to the ReverseAD code. It is very temperamental. I assume that when we did the other PRs, we benchmarked against
master
instead of the last release, and so we missed this innocuous first regression.