Refactor tests: R2N#271
Refactor tests: R2N#271MaxenceGollier wants to merge 12 commits intoJuliaSmoothOptimizers:masterfrom
Conversation
|
LSR1 is allocating, will try to fix in LinearOperators.jl |
|
Thank you @MaxenceGollier very thoughtful, having the algorithms tested on different problems (toys, bpdn and others) will be very useful! |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #271 +/- ##
===========================================
+ Coverage 61.53% 84.72% +23.19%
===========================================
Files 11 13 +2
Lines 1292 1624 +332
===========================================
+ Hits 795 1376 +581
+ Misses 497 248 -249 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@dpo, @MohamedLaghdafHABIBOULLAH, maybe we merge this first and then do the other solvers ? Or do I just do everything at once here ? |
|
@MaxenceGollier I think you should keep this PR tested only with R2N, so that it is easy to review and we will add the other solvers in different PR! |
| # Remove the x0 entry from solver_kwargs | ||
| optimized_solver_kwargs = Base.structdiff(solver_kwargs, NamedTuple{(:x0,)}) | ||
| solve!(solver, reg_nlp, stats_optimized; x = x0, optimized_solver_kwargs...) # It would be interesting to check for allocations here as well but depending on | ||
| # the structure of solver_kwargs, some variables might get boxed, resulting in |
There was a problem hiding this comment.
could you open an issue for this comment?
There was a problem hiding this comment.
I think it is just a bad idea to add the allocations tests inside this function because this means that you can not assign a variable to one of the solver_constructor_kwargs or solver_kwargs, or else they will get boxed and result in allocations.
To be clearer @wrappedallocs works in such a way that even if
@wrappedallocs solve!(solver, reg_nlp, stats; atol = 1e-3)
returns 0,
tol = 1e-3
@wrappedallocs solve!(solver, reg_nlp, stats; atol = tol)
doesn't.
I think adding this constraint is very confusing so we should just leave the allocation tests out of this function.
I want to keep the comment though so that users will understand why we did not add the allocation tests there, but it might be more precise.
There was a problem hiding this comment.
Can't we have a function wrappedallocsv2 to avoid this?
There was a problem hiding this comment.
No, there is nothing "easy" we can do, keyword arguments will get boxed, this is a Julia issue.
| solve!(solver, reg_nlp, stats, σk = 1.0, β = 1e16, atol = 1e-6, rtol = 1e-6) | ||
| ) == 0 | ||
|
|
||
| #test_solver(reg_nlp, # FIXME: divide by 0 error in the LBFGS approximation |
There was a problem hiding this comment.
@MaxenceGollier
I checked this in detail. The issue is actually related to R2DH, and we should probably open a dedicated issue. The problem occurs when
Although this quantity may be small, it is not negligible. When we compute its root, the resulting value can be larger than expected, which may prevent the algorithm from terminating.
A simple and reasonable fix is to assume instead that
There was a problem hiding this comment.
I never understood why we added this term to
There was a problem hiding this comment.
That term is there to compensate for catastrophic cancellation between
@MohamedLaghdafHABIBOULLAH Could you please show the run of R2DH where you observed
There was a problem hiding this comment.
@MohamedLaghdafHABIBOULLAH, I agree with Dominique, could you provide us a run where this occurs ?
There was a problem hiding this comment.
Sorry I just saw the message, yes of course.
dpo
left a comment
There was a problem hiding this comment.
This looks great, thank you! I agree that we can have this PR focus on R2N only, and open future PRs for other solvers.
| @@ -0,0 +1,48 @@ | |||
| function test_solver( | |||
| reg_nlp::R, | |||
| solver_name::String; | |||
There was a problem hiding this comment.
Just pass the function name instead of a string.
| solver_fun = getfield(RegularizedOptimization, Symbol(solver_name)) | ||
| stats_basic = solver_fun( | ||
| reg_nlp.model, | ||
| reg_nlp.h, |
There was a problem hiding this comment.
You should be able to just pass reg_nlp.
|
|
||
| # Remove the x0 entry from solver_kwargs | ||
| optimized_solver_kwargs = Base.structdiff(solver_kwargs, NamedTuple{(:x0,)}) | ||
| solve!(solver, reg_nlp, stats_optimized; x = x0, optimized_solver_kwargs...) # It would be interesting to check for allocations here as well but depending on |
There was a problem hiding this comment.
Testing for allocations would be the main point I think, because the first set of test (where you call solver_fun) already call solver_contructor and solve!(). I wonder if something like @wrappedallocs @eval solve!(solver, reg_nlp, stats; atol = $atol) would work. I agree that allocation tests need not be in this function, but, in general, it should be possible to construct the expression of the solve call and measure allocations.
@dpo @MohamedLaghdafHABIBOULLAH, related to #130.
This is very much WIP, but you can already take a look.
I did a proof of concept with R2N, all solvers will eventually have similar tests.
test-solver.jl