Skip to content

Add PrecompileTools to speed up time-to-first-solve#967

Merged
odow merged 2 commits into
masterfrom
od/precompile-tools
May 7, 2025
Merged

Add PrecompileTools to speed up time-to-first-solve#967
odow merged 2 commits into
masterfrom
od/precompile-tools

Conversation

@odow

@odow odow commented Apr 24, 2025

Copy link
Copy Markdown
Collaborator

Closes #899

Speedup for this example is 20 seconds -> 7 seconds.

Before

(base) oscar@MacBookPro /tmp % julia --project=power-models-old
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.10.9 (2025-03-10)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

(power-models-old) pkg> st
Status `/private/tmp/power-models-old/Project.toml`
  [b6b21f68] Ipopt v1.10.1
  [c36e90e8] PowerModels v0.21.3 `https://github.com/lanl-ansi/PowerModels.jl.git#master`

julia> @time using PowerModels, Ipopt
  2.292246 seconds (1.54 M allocations: 105.444 MiB, 7.98% gc time, 23.45% compilation time: 40% of which was recompilation)

julia> filename = "/Users/oscar/.julia/dev/PowerModels/test/data/matpower/case3.m"
"/Users/oscar/.julia/dev/PowerModels/test/data/matpower/case3.m"

julia> @time result = solve_ac_opf(filename, Ipopt.Optimizer)
[info | PowerModels]: extending matpower format with constant data: const_int
[info | PowerModels]: extending matpower format with constant data: const_float
[info | PowerModels]: extending matpower format with data: bus_data 3x3
[info | PowerModels]: extending matpower format with data: branch_names 3x3
[info | PowerModels]: extending matpower format with data: areas_cells 2x6
[info | PowerModels]: extending matpower format with data: areas_named_cells 2x6
[info | PowerModels]: extending matpower format with data: areas_named 2x3
[info | PowerModels]: extending matpower format with data: component 1x3
[info | PowerModels]: extending matpower format with data: areas 2x3
[info | PowerModels]: extending matpower format with constant data: const_str
[info | PowerModels]: extending matpower format with data: load_data 2x2
[info | PowerModels]: extending matpower format with data: branch_limit 3x3
[warn | PowerModels]: added zero cost function data for dclines
[info | PowerModels]: extending matpower format by appending matrix "branch_limit" in to "branch"
[info | PowerModels]: extending matpower format by appending matrix "branch_names" in to "branch"
[info | PowerModels]: extending matpower format by appending matrix "bus_data" in to "bus"
[warn | PowerModels]: no reference bus found
[warn | PowerModels]: no reference bus found, setting bus 1 as reference based on generator 1
[info | PowerModels]: removing 3 cost terms from generator 3: Float64[]
[info | PowerModels]: removing 3 cost terms from dcline 1: Float64[]

******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit https://github.com/coin-or/Ipopt
******************************************************************************

This is Ipopt version 3.14.17, running with linear solver MUMPS 5.7.3.

Number of nonzeros in equality constraint Jacobian...:       84
Number of nonzeros in inequality constraint Jacobian.:       18
Number of nonzeros in Lagrangian Hessian.............:      134

Total number of variables............................:       27
                     variables with only lower bounds:        0
                variables with lower and upper bounds:       24
                     variables with only upper bounds:        0
Total number of equality constraints.................:       20
Total number of inequality constraints...............:        9
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        3
        inequality constraints with only upper bounds:        6

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  6.3949934e+00 1.20e+00 2.54e+01  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  3.7786723e+03 2.38e-01 1.40e+02  -1.0 1.80e+00    -  5.79e-03 8.01e-01h  1
   2  4.1854574e+03 1.83e-01 1.08e+02  -1.0 4.16e-01    -  6.49e-01 2.33e-01h  1
   3  4.3122875e+03 1.67e-01 9.87e+01  -1.0 3.13e-01    -  2.84e-01 8.82e-02h  1
   4  5.1593473e+03 8.73e-02 1.60e+02  -1.0 4.26e-01    -  2.12e-01 5.98e-01h  1
   5  5.5669007e+03 3.75e-02 3.71e+01  -1.0 2.04e-01    -  8.47e-01 6.39e-01h  1
   6  5.6334313e+03 3.43e-02 5.77e+01  -1.0 1.07e-01    -  9.90e-01 2.67e-01h  1
   7  5.6639586e+03 4.30e-02 1.31e+02  -1.0 1.86e-01    -  2.87e-01 1.57e-01h  1
   8  5.6670493e+03 4.39e-02 2.28e+02  -1.0 1.44e-01    -  4.23e-02 1.76e-02h  1
   9  5.9038108e+03 2.24e-03 1.71e+02  -1.0 1.28e-01    -  2.16e-01 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  5.9095024e+03 1.02e-05 4.37e-01  -1.0 4.21e-03    -  1.00e+00 1.00e+00h  1
  11  5.9074978e+03 4.66e-06 5.75e-03  -1.7 2.96e-03    -  1.00e+00 1.00e+00f  1
  12  5.9068858e+03 2.13e-07 3.57e-04  -3.8 7.95e-04    -  1.00e+00 1.00e+00f  1
  13  5.9068795e+03 3.64e-11 5.98e-08  -5.7 1.21e-05    -  1.00e+00 1.00e+00h  1
  14  5.9068794e+03 1.72e-15 3.00e-12  -8.6 7.05e-08    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 14

                                   (scaled)                 (unscaled)
Objective...............:   1.1813758833436352e+03    5.9068794167181759e+03
Dual infeasibility......:   3.0001291524902349e-12    1.5000645762451174e-11
Constraint violation....:   1.7208456881689926e-15    1.7208456881689926e-15
Variable bound violation:   1.0962198482289409e-08    1.0962198482289409e-08
Complementarity.........:   2.5073461206267793e-09    1.2536730603133896e-08
Overall NLP error.......:   2.5073461206267793e-09    1.2536730603133896e-08


Number of objective function evaluations             = 15
Number of objective gradient evaluations             = 15
Number of equality constraint evaluations            = 15
Number of inequality constraint evaluations          = 15
Number of equality constraint Jacobian evaluations   = 15
Number of inequality constraint Jacobian evaluations = 15
Number of Lagrangian Hessian evaluations             = 14
Total seconds in IPOPT                               = 3.192

EXIT: Optimal Solution Found.
 23.031706 seconds (29.06 M allocations: 1.923 GiB, 2.71% gc time, 99.82% compilation time)
Dict{String, Any} with 8 entries:
  "solve_time"         => 4.87266
  "optimizer"          => "Ipopt"
  "termination_status" => LOCALLY_SOLVED
  "dual_status"        => FEASIBLE_POINT
  "primal_status"      => FEASIBLE_POINT
  "objective"          => 5906.88
  "solution"           => Dict{String, Any}("dcline"=>Dict{String, Any}("1"=>Dict{String, Any}("qf"=
  "objective_lb"       => -Inf

This PR

(base) oscar@MacBookPro /tmp % julia --project=power-models
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.10.9 (2025-03-10)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

(power-models) pkg> st
Status `/private/tmp/power-models/Project.toml`
  [b6b21f68] Ipopt v1.10.1
  [c36e90e8] PowerModels v0.21.3 `~/.julia/dev/PowerModels`

julia> @time using PowerModels, Ipopt
  2.579206 seconds (1.72 M allocations: 115.959 MiB, 4.58% gc time, 22.27% compilation time: 38% of which was recompilation)

julia> filename = "/Users/oscar/.julia/dev/PowerModels/test/data/matpower/case3.m"
"/Users/oscar/.julia/dev/PowerModels/test/data/matpower/case3.m"

julia> @time result = solve_ac_opf(filename, Ipopt.Optimizer)
[info | PowerModels]: extending matpower format with constant data: const_int
[info | PowerModels]: extending matpower format with constant data: const_float
[info | PowerModels]: extending matpower format with data: bus_data 3x3
[info | PowerModels]: extending matpower format with data: branch_names 3x3
[info | PowerModels]: extending matpower format with data: areas_cells 2x6
[info | PowerModels]: extending matpower format with data: areas_named_cells 2x6
[info | PowerModels]: extending matpower format with data: areas_named 2x3
[info | PowerModels]: extending matpower format with data: component 1x3
[info | PowerModels]: extending matpower format with data: areas 2x3
[info | PowerModels]: extending matpower format with constant data: const_str
[info | PowerModels]: extending matpower format with data: load_data 2x2
[info | PowerModels]: extending matpower format with data: branch_limit 3x3
[warn | PowerModels]: added zero cost function data for dclines
[info | PowerModels]: extending matpower format by appending matrix "branch_limit" in to "branch"
[info | PowerModels]: extending matpower format by appending matrix "branch_names" in to "branch"
[info | PowerModels]: extending matpower format by appending matrix "bus_data" in to "bus"
[warn | PowerModels]: no reference bus found
[warn | PowerModels]: no reference bus found, setting bus 1 as reference based on generator 1
[info | PowerModels]: removing 3 cost terms from generator 3: Float64[]
[info | PowerModels]: removing 3 cost terms from dcline 1: Float64[]

******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit https://github.com/coin-or/Ipopt
******************************************************************************

This is Ipopt version 3.14.17, running with linear solver MUMPS 5.7.3.

Number of nonzeros in equality constraint Jacobian...:       84
Number of nonzeros in inequality constraint Jacobian.:       18
Number of nonzeros in Lagrangian Hessian.............:      134

Total number of variables............................:       27
                     variables with only lower bounds:        0
                variables with lower and upper bounds:       24
                     variables with only upper bounds:        0
Total number of equality constraints.................:       20
Total number of inequality constraints...............:        9
        inequality constraints with only lower bounds:        0
   inequality constraints with lower and upper bounds:        3
        inequality constraints with only upper bounds:        6

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  6.3949934e+00 1.20e+00 2.54e+01  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  3.7786723e+03 2.38e-01 1.40e+02  -1.0 1.80e+00    -  5.79e-03 8.01e-01h  1
   2  4.1854574e+03 1.83e-01 1.08e+02  -1.0 4.16e-01    -  6.49e-01 2.33e-01h  1
   3  4.3122875e+03 1.67e-01 9.87e+01  -1.0 3.13e-01    -  2.84e-01 8.82e-02h  1
   4  5.1593473e+03 8.73e-02 1.60e+02  -1.0 4.26e-01    -  2.12e-01 5.98e-01h  1
   5  5.5669007e+03 3.75e-02 3.71e+01  -1.0 2.04e-01    -  8.47e-01 6.39e-01h  1
   6  5.6334313e+03 3.43e-02 5.77e+01  -1.0 1.07e-01    -  9.90e-01 2.67e-01h  1
   7  5.6639586e+03 4.30e-02 1.31e+02  -1.0 1.86e-01    -  2.87e-01 1.57e-01h  1
   8  5.6670493e+03 4.39e-02 2.28e+02  -1.0 1.44e-01    -  4.23e-02 1.76e-02h  1
   9  5.9038108e+03 2.24e-03 1.71e+02  -1.0 1.28e-01    -  2.16e-01 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  5.9095024e+03 1.02e-05 4.37e-01  -1.0 4.21e-03    -  1.00e+00 1.00e+00h  1
  11  5.9074978e+03 4.66e-06 5.75e-03  -1.7 2.96e-03    -  1.00e+00 1.00e+00f  1
  12  5.9068858e+03 2.13e-07 3.57e-04  -3.8 7.95e-04    -  1.00e+00 1.00e+00f  1
  13  5.9068795e+03 3.64e-11 5.98e-08  -5.7 1.21e-05    -  1.00e+00 1.00e+00h  1
  14  5.9068794e+03 1.72e-15 3.00e-12  -8.6 7.05e-08    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 14

                                   (scaled)                 (unscaled)
Objective...............:   1.1813758833436352e+03    5.9068794167181759e+03
Dual infeasibility......:   3.0001291524902349e-12    1.5000645762451174e-11
Constraint violation....:   1.7208456881689926e-15    1.7208456881689926e-15
Variable bound violation:   1.0962198482289409e-08    1.0962198482289409e-08
Complementarity.........:   2.5073461206267793e-09    1.2536730603133896e-08
Overall NLP error.......:   2.5073461206267793e-09    1.2536730603133896e-08


Number of objective function evaluations             = 15
Number of objective gradient evaluations             = 15
Number of equality constraint evaluations            = 15
Number of inequality constraint evaluations          = 15
Number of equality constraint Jacobian evaluations   = 15
Number of inequality constraint Jacobian evaluations = 15
Number of Lagrangian Hessian evaluations             = 14
Total seconds in IPOPT                               = 2.950

EXIT: Optimal Solution Found.
  7.158142 seconds (8.48 M allocations: 569.498 MiB, 3.30% gc time, 99.58% compilation time)
Dict{String, Any} with 8 entries:
  "solve_time"         => 4.4105
  "optimizer"          => "Ipopt"
  "termination_status" => LOCALLY_SOLVED
  "dual_status"        => FEASIBLE_POINT
  "primal_status"      => FEASIBLE_POINT
  "objective"          => 5906.88
  "solution"           => Dict{String, Any}("dcline"=>Dict{String, Any}("1"=>Dict{String, Any}("qf"=…
  "objective_lb"       => -Inf

@codecov

codecov Bot commented Apr 24, 2025

Copy link
Copy Markdown

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 93.75%. Comparing base (685fbb2) to head (8f6da2f).
Report is 1 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #967      +/-   ##
==========================================
+ Coverage   93.71%   93.75%   +0.03%     
==========================================
  Files          43       43              
  Lines        9635     9648      +13     
==========================================
+ Hits         9029     9045      +16     
+ Misses        606      603       -3     
Files with missing lines Coverage Δ
src/PowerModels.jl 80.95% <100.00%> (+30.95%) ⬆️

... and 1 file with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 685fbb2...8f6da2f. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ccoffrin

ccoffrin commented Apr 25, 2025

Copy link
Copy Markdown
Member

Nice! @noahrhodes and I need to think a bit about the exact set of stuff that should go in @setup_workload. We can merge this now and open an issue to expand the list; or we can hold this open for a ~1 week in the hopes I will find some time to work it, your call.

@odow

odow commented Apr 25, 2025

Copy link
Copy Markdown
Collaborator Author

Let's discuss next week

Comment thread src/PowerModels.jl Outdated
Comment thread src/PowerModels.jl Outdated
@odow odow added this to the v0.21.4 milestone Apr 30, 2025
@odow odow force-pushed the od/precompile-tools branch from 0fd3583 to fd40fa1 Compare May 1, 2025 02:39
@odow

odow commented May 4, 2025

Copy link
Copy Markdown
Collaborator Author

With jump-dev/Ipopt.jl#487 I've got this down to

EXIT: Optimal Solution Found.
  4.780973 seconds (5.48 M allocations: 370.507 MiB, 8.31% gc time, 99.38% compilation time: 20% of which was recompilation)
Dict{String, Any} with 8 entries:
  "solve_time"         => 1.89057
  "optimizer"          => "Ipopt"
  "termination_status" => LOCALLY_SOLVED
  "dual_status"        => FEASIBLE_POINT
  "primal_status"      => FEASIBLE_POINT
  "objective"          => 5906.88
  "solution"           => Dict{String, Any}("dcline"=>Dict{String, Any}("1"=>Dict{String, Any}("qf"=
  "objective_lb"       => -Inf

@ccoffrin

ccoffrin commented May 4, 2025

Copy link
Copy Markdown
Member

Nice!

Comment thread src/PowerModels.jl Outdated
@odow odow merged commit 05f1a14 into master May 7, 2025
9 checks passed
@odow odow deleted the od/precompile-tools branch May 7, 2025 23:39
Comment thread src/PowerModels.jl
# this must come last to support automated export
include("core/export.jl")

PrecompileTools.@setup_workload begin

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@odow you should turn off the logger in this so that it doesn't print the logs when precompiling. It throws users off

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm okay. Will do. I just assumed people ignored the stuff that happens during precompilation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add PrecompileTools to reduce compilation latency

3 participants