Skip to content

Conversation

@sshin23
Copy link
Member

@sshin23 sshin23 commented Oct 8, 2025

Tried MadNLPGPU as well, but it seems not to be working as of now

@codecov
Copy link

codecov bot commented Oct 8, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 69.60%. Comparing base (cd82ea7) to head (ef0ecfc).

❗ There is a different number of reports uploaded between BASE (cd82ea7) and HEAD (ef0ecfc). Click for more details.

HEAD has 3 uploads less than BASE
Flag BASE (cd82ea7) HEAD (ef0ecfc)
7 4
Additional details and impacted files
@@             Coverage Diff             @@
##           master     #496       +/-   ##
===========================================
- Coverage   84.69%   69.60%   -15.10%     
===========================================
  Files          49       14       -35     
  Lines        4398     1033     -3365     
===========================================
- Hits         3725      719     -3006     
+ Misses        673      314      -359     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

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

@sshin23 sshin23 requested a review from amontoison October 11, 2025 21:52
@amontoison
Copy link
Member

amontoison commented Oct 12, 2025

@sshin23 We can check if we have the HSL linear solvers available with HSL.libhsl_functional().
I propose to check it and not precompile MadNLPHSL if it is false.
Sometimes the compilation can be done on a node of a cluster without the official HSL_jll.jl but another node has it.

@sshin23 sshin23 changed the title Adding MadNLPHSL precompile Improved precompilation Oct 20, 2025
@sshin23
Copy link
Member Author

sshin23 commented Oct 20, 2025

@frapac @amontoison With these changes, we can eliminate the TTFS

[sushin@shin-macbook-pro:~/git/MadNLP.jl]$ julia
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.12.1 (2025-10-17)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org release
|__/                   |

julia> using MadNLP

julia> nlp = MadNLP.HS15Model(); @trace_compile madnlp(nlp)
This is MadNLP version v0.8.12, running with MUMPS v5.8.1

Number of nonzeros in constraint Jacobian............:        4
Number of nonzeros in Lagrangian Hessian.............:        3

Total number of variables............................:        2
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        0
                     variables with only upper bounds:        1
Total number of equality constraints.................:        0
Total number of inequality constraints...............:        2
        inequality constraints with only lower bounds:        2
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du inf_compl lg(mu) lg(rg) alpha_pr ir ls
   0  1.0000000e+00 1.01e+00 1.00e+00 5.00e-01  -1.0     -   0.00e+00  1  0 
   1  9.9758855e-01 1.00e+00 4.61e+01 3.80e-01  -1.0     -   9.80e-03  1  1h
   2  9.9664309e-01 1.00e+00 5.00e+02 2.35e-03  -1.0     -   9.93e-05  1  1h
   3  1.3615174e+00 9.99e-01 4.41e+02 2.44e-03  -1.0     -   4.71e-04  1  1H
   4  1.3742697e+00 9.99e-01 3.59e+02 1.40e-01  -1.0     -   2.68e-05  1  1h
   5  1.4692139e+00 9.99e-01 4.94e+02 2.31e+00  -1.0     -   1.46e-04  1  1h
   6  3.1727722e+00 9.97e-01 3.76e+02 2.36e+00  -1.0     -   9.77e-04  1 11h
   7  3.1746542e+00 9.96e-01 1.53e+02 3.13e-03  -1.0    4.0  7.98e-04  1  1h
   8  8.2322585e+00 9.85e-01 2.47e+02 5.06e-03  -1.0     -   7.81e-03  1  8h
   9  8.2886187e+00 9.84e-01 4.78e+02 1.51e-04  -1.0     -   2.48e-04  1  1h
iter    objective    inf_pr   inf_du inf_compl lg(mu) lg(rg) alpha_pr ir ls
  10  4.0285541e+01 8.72e-01 4.57e+02 6.32e-04  -1.0     -   6.25e-02  1  5h
  11  2.8602305e+02 2.66e-01 4.91e+02 5.99e-04  -1.0     -   5.00e-01  1  2h
  12  3.9870638e+02 6.41e-03 4.21e+02 3.32e-03  -1.0     -   1.00e+00  1  1h
  13  3.4928112e+02 2.93e-02 2.62e+01 1.02e+00  -1.0     -   1.00e+00  1  1h
  14  3.5909050e+02 6.98e-03 1.66e+00 6.15e-02  -1.0     -   1.00e+00  1  1h
  15  3.6047026e+02 6.05e-05 1.44e-02 6.46e-02  -1.0     -   1.00e+00  1  1h
  16  3.6038251e+02 2.50e-07 7.99e-05 1.89e-03  -2.5     -   1.00e+00  1  1h
  17  3.6037976e+02 2.63e-10 7.93e-08 1.27e-06  -5.7     -   1.00e+00  1  1h
  18  3.6037976e+02 2.22e-16 5.96e-14 1.58e-09  -8.6     -   1.00e+00  2  1h

Number of Iterations....: 18

                                   (scaled)                 (unscaled)
Objective...............:   3.6037976240508465e+02    3.6037976240508465e+02
Dual infeasibility......:   5.9563010060664213e-14    5.9563010060664213e-14
Constraint violation....:   2.2204460492503131e-16    2.2204460492503131e-16
Complementarity.........:   1.5755252336090733e-09    1.5755252336090733e-09
Overall NLP error.......:   1.5755252336090733e-09    1.5755252336090733e-09

Number of objective function evaluations              = 46
Number of objective gradient evaluations              = 19
Number of constraint evaluations                      = 46
Number of constraint Jacobian evaluations             = 19
Number of Lagrangian Hessian evaluations              = 18

Total wall secs in initialization                     =  0.001
Total wall secs in linear solver                      =  0.001
Total wall secs in NLP function evaluations           =  0.000
Total wall secs in solver (w/o init./fun./lin. alg.)  =  0.004
Total wall secs                                       =  0.007

EXIT: Optimal Solution Found (tol = 1.0e-08).
"Execution stats: Optimal Solution Found (tol = 1.0e-08)."

~ 1 sec is spent for loading julia nad MadNLP

@@ -0,0 +1,17 @@
module MadNLPJuMPExt
Copy link
Member Author

Choose a reason for hiding this comment

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

One of the pain points in this implementation is that whenver we import a package that extends the function;
e.g.,

struct MyModel <: AbstractNLPModel{Float64,Vector{Float64}} end
NLPModels.obj(m::MyModel, x::AbstractVector) = 0.

Any function that is dependent on NLPModels.obj will be invalidated and needs to be recompiled. Because of this behavior, we need to do precompilation whenever we import e.g., ExaModels, MOI, JuMP, etc.

@sshin23
Copy link
Member Author

sshin23 commented Oct 20, 2025

@amontoison @frapac @apozharski

Due to the invalidation issue, I was wondering if we can revisit our overall package structure. We can individually write precompilation scripts e.g., MadNLPHSLJuMPExt, MadNLPPardisioJuMPExt, etc., but we'll need $N\times M$ extensions when we have $N$ linear solver extensions and $M$ modeling interfaces.

I wonder if we can introduce MadNLPCore, which aims to be minimalistic (so that other packages like MadIPM, MadMPEC can import it), and make MadNLP more user friendly. There, we import HSL, Mumps, MKL_jll, Metis, AMD, etc., without feeling too guilty about making the package heavy. In that way, we can write $M$ extesnsions that do precompiling. Since julia v1.12 introduced julia app, removing precompilation would be a great feature for users. E.g., we may want something like madnlp hs15.nl on command line

@apozharski
Copy link
Contributor

apozharski commented Oct 20, 2025

I wonder if we can introduce MadNLPCore, which aims to be minimalistic (so that other packages like MadIPM, MadMPEC can import it), and make MadNLP more user friendly. There, we import HSL, Mumps, MKL_jll, Metis, AMD, etc., without feeling too guilty about making the package heavy. In that way, we can write M extesnsions that do precompiling. Since julia v1.12 introduced julia app, removing precompilation would be a great feature for users. E.g., we may want something like madnlp hs15.nl on command line

The one concern I would have is about the impact of this on the c interface in libmad as it would probably need to import MadNLP with all the bells and whistles. That notwithstanding (as this can probably be worked around in the end) I think this is generally a good way to go.

Edit: On the other hand, it won't need to maintain it's own precompile ideally which would be a benefit.

@sshin23 sshin23 mentioned this pull request Oct 20, 2025
Copy link
Member

@frapac frapac left a comment

Choose a reason for hiding this comment

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

It overall looks good to me, except a few minor comments. Just out of curiosity, by how much do we improve the time-to-first-solve with this PR, compared to master?

J[3] = 1.0 # (2, 1)
J[4] = 2*x[2] # (2, 2)
return J
return
Copy link
Member

Choose a reason for hiding this comment

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

I think NLPModels' API's require returning explicitly the Jacobian J

Instantiate a new `MadNLPSolver` associated to the nonlinear program
`nlp::AbstractNLPModel`. The options are passed as optional arguments.
function MadNLPSolver(nlp::AbstractNLPModel; kwargs...)
@nospecialize
Copy link
Member

Choose a reason for hiding this comment

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

is there any reason why we need @nospecialize? I would maybe add a comment explaining why we need this macro

Copy link
Member Author

Choose a reason for hiding this comment

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

Without @nospecialize, MadNLP tries to specialize this function to nlp's type. That is, if you have an ExaModel input, which has a complicated type signature, MadNLP will try to compile MadNLPSolver specialied for that data type. You end up having to compile lots of madnlp functions for these different types. This change allows to compile MadNLP only once

Copy link
Member

Choose a reason for hiding this comment

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

I see, thank you for the clarification! It makes sense to use @nospecialize in that case. I think not compiling MadNLP on every ExaModels instance is an improvement.


get_counters(nlp::NLPModels.AbstractNLPModel) = nlp.counters
get_counters(nlp::NLPModels.AbstractNLSModel) = nlp.counters.counters
get_counters(@nospecialize(nlp::NLPModels.AbstractNLPModel)) = nlp.counters
Copy link
Member

Choose a reason for hiding this comment

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

can we move this macro outside the function's arguments (I confess I am not an expert of @nospecialize, so feel free to discard this comment)?

@KSepetanc
Copy link

KSepetanc commented Dec 2, 2025

For compilation of MadNLPGPU underlying issue is probably GPUCompiler #611. GPU instructions leak as CPU instructions during compilation. Help is needed to make better MWE so it can be filed upstream to Julia issues.

@frapac frapac mentioned this pull request Jan 7, 2026
9 tasks
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.

6 participants