-
Notifications
You must be signed in to change notification settings - Fork 5
WIP: Sandu projection #162
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
base: main
Are you sure you want to change the base?
Conversation
Would it make sense and be feasible to put JuMP.jl in an extension as it is not very lightweight and not necessary for every user, such that we save the additional loading time if no Sandu projection is used? |
Is 25a8127 what you had in mind? |
Yes, looks good. Thanks! |
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Pull Request Test Coverage Report for Build 17466558065Details
💛 - Coveralls |
…grators.jl into sk/sandu_projection
|
||
There are two independent linear invariants. The function `linear_invariants_stratreac_scaled` returns the invariance matrix.``. | ||
""" | ||
prob_ode_stratreac_scaled = ODEProblem(f_stratreac_scaled, u0, (4.32e4, 3.024e5)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a scaled version of the stratospheric reaction problem and can be solved using SanduProjection
and Clarabel
with default settings.
Unfortunately, scaling destroys the "conservation structure" of a PDS, i.e. terms that canceled before scaling, do not afterwards. I was not able to find a PDS representation of the scaled statospheric problem, which could be solved as good as the original one by MPRK schemes. That's why there is only an ODE version of this problem.
""" | ||
prob_ode_stratreac_scaled = ODEProblem(f_stratreac_scaled, u0, (4.32e4, 3.024e5)) | ||
|
||
function linear_invariants_stratreac_scaled() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we only have an ODE version of the scaled stratospheric reaction problem (see comment above). I introduced this auxiliary function to get corresponding invariance matrix.
ext/SanduProjectionExt.jl
Outdated
@@ -0,0 +1,127 @@ | |||
module SanduProjectionExt | |||
|
|||
using StaticArrays: StaticArray, SVector # Why do we need this here, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have expected that using StaticArrays
is not necessary in the extension, as it is used in the parent package.
If there are some instabilities within Clarabel.jl, I would not worry about them too much here unless they really hurt the performance (in which case we might have a look at their source code). I am more worried about the red parts of the residual computation. It looks like we lose quite a lot of performance there. Would you mind trying to setup a minimal working example? Does it happen for every simple ODE using function doit(ode, cb; n = 1)
for _ in 1:n
solve(ode, ROS2();
save_everystep = false, callback = cb)
end
end and |
Using the following function fixes the problem! I'll modify the stratospheric reaction problems accordingly. function f(u, p, t)
if one(t) < t
sigma = t
else
sigma = zero(t)
end
return @SVector [sigma * u[1]]
end |
I will revise the other stratospheric reaction functions in another PR, since this should also affect the corresponding benchmark results. |
I compared the runtime of all QP packages supported by JuMP, which could solve the statrospheric reaction problem with default settings. With the choice julia> using JuMP
julia> using Clarabel
julia> @benchmark solve(prob_ode_stratreac_scaled, ROS2(); abstol = 1e-7, reltol = 1e-6,
save_everystep = false, callback = SanduProjection(Model(Clarabel.Optimizer), AT, b))
BenchmarkTools.Trial: 18 samples with 1 evaluation per sample.
Range (min … max): 253.762 ms … 333.667 ms ┊ GC (min … max): 0.00% … 3.45%
Time (median): 279.162 ms ┊ GC (median): 0.00%
Time (mean ± σ): 290.035 ms ± 27.314 ms ┊ GC (mean ± σ): 3.14% ± 4.25%
▁ ▁▁ ▁ █ ▁ █ ▁ █▁▁ ▁ ▁▁ ▁
█▁▁██▁▁█▁▁▁█▁█▁▁▁█▁▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███▁▁▁▁▁▁▁▁▁█▁▁▁▁▁██▁█ ▁
254 ms Histogram: frequency by time 334 ms <
Memory estimate: 72.78 MiB, allocs estimate: 1463271.
julia> using COSMO
julia> @benchmark solve(prob_ode_stratreac_scaled, ROS2(); abstol = 1e-7, reltol = 1e-6,
save_everystep = false, callback = SanduProjection(Model(COSMO.Optimizer), AT, b))
BenchmarkTools.Trial: 11 samples with 1 evaluation per sample.
Range (min … max): 466.016 ms … 559.975 ms ┊ GC (min … max): 3.37% … 8.98%
Time (median): 489.071 ms ┊ GC (median): 6.41%
Time (mean ± σ): 495.325 ms ± 32.541 ms ┊ GC (mean ± σ): 5.08% ± 3.55%
█▁ ▁ ▁ ▁ ▁ ▁▁ ▁ ▁
██▁█▁▁▁█▁▁▁▁▁▁█▁▁▁█▁▁▁▁██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█▁▁▁▁▁█ ▁
466 ms Histogram: frequency by time 560 ms <
Memory estimate: 195.80 MiB, allocs estimate: 3746332.
julia> using DAQP
julia> @benchmark solve(prob_ode_stratreac_scaled, ROS2(); abstol = 1e-7, reltol = 1e-6,
save_everystep = false, callback = SanduProjection(Model(DAQP.Optimizer), AT, b))
BenchmarkTools.Trial: 22 samples with 1 evaluation per sample.
Range (min … max): 201.188 ms … 338.161 ms ┊ GC (min … max): 0.00% … 22.10%
Time (median): 213.586 ms ┊ GC (median): 0.00%
Time (mean ± σ): 230.957 ms ± 41.720 ms ┊ GC (mean ± σ): 5.28% ± 8.39%
▄ █▁▁▁
▆▆█▆████▁▆▁▆▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▆▁▆▁▁▁▁▆▁▁▁▁▁▁▁▁▆ ▁
201 ms Histogram: frequency by time 338 ms <
Memory estimate: 70.27 MiB, allocs estimate: 1582602.
julia> using MadNLP
julia> @benchmark solve(prob_ode_stratreac_scaled, ROS2(); abstol = 1e-7, reltol = 1e-6,
save_everystep = false, callback = SanduProjection(Model(MadNLP.Optimizer), AT, b))
BenchmarkTools.Trial: 16 samples with 1 evaluation per sample.
Range (min … max): 290.044 ms … 361.920 ms ┊ GC (min … max): 0.00% … 6.26%
Time (median): 329.323 ms ┊ GC (median): 4.70%
Time (mean ± σ): 325.449 ms ± 19.264 ms ┊ GC (mean ± σ): 4.20% ± 2.68%
█ ▁ ▁ ▁ ▁ █ █ █ ▁▁ ▁ ▁
█▁▁▁▁▁▁▁▁▁▁█▁▁▁▁█▁▁▁▁▁▁▁█▁▁█▁▁▁█▁▁▁█▁▁█▁██▁▁▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁█ ▁
290 ms Histogram: frequency by time 362 ms <
Memory estimate: 129.43 MiB, allocs estimate: 1539207.
julia> using SCS
julia> @benchmark solve(prob_ode_stratreac_scaled, ROS2(); abstol = 1e-7, reltol = 1e-6,
save_everystep = false, callback = SanduProjection(Model(SCS.Optimizer), AT, b))
BenchmarkTools.Trial: 38 samples with 1 evaluation per sample.
Range (min … max): 115.246 ms … 156.251 ms ┊ GC (min … max): 0.00% … 18.74%
Time (median): 132.393 ms ┊ GC (median): 0.00%
Time (mean ± σ): 133.455 ms ± 9.553 ms ┊ GC (mean ± σ): 2.00% ± 4.84%
█▁ ▁ ▁▄ ▄
▆▁▁▆▁▆▁▁▁▁▁▁▁▆▁▆▆██▆█▆▆▆▁██▆▁▆█▁▆▁▆▁▁▆▆▁▁▁▁▆▁▁▁▁▆▆▁▁▁▁▆▁▁▁▁▆▆ ▁
115 ms Histogram: frequency by time 156 ms <
Memory estimate: 26.02 MiB, allocs estimate: 337759.
![]() The projection takes about 30% of the runtime. But also with The big question for me is if the instabilities come from our side or not? So how should we proceed? |
Well, it's better to have a useful feature that might not be perfect than to not have the option to use it. Did Sandu give any hints about solving the optimization problem? |
Sandu uses the Goldfarb and Idnani algorithm and states that additional adaptions to the specific minimization problem were made. |
I did some experiments solving a simple minimization problem without any ODE stuff using different optimization packages within JuMP as well as using Clarabel or COSMO directly. All flame graphs showed significant run-time dispatch. So I guess the problem is not on our side and would leave this as it currently is. |
This implements Sandu's projection method, see #124.