Skip to content

abstract solver type and behavior #26

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
merged 3 commits into from
Sep 9, 2022
Merged

abstract solver type and behavior #26

merged 3 commits into from
Sep 9, 2022

Conversation

dpo
Copy link
Member

@dpo dpo commented Jul 12, 2022

The objective of this PR is to introduce a simple AbstractSolver type from which other solvers can derive.

The end goal is to be able to perform efficient re-solves without reallocating a stats structure. If a user wants special storage for certain components of the stats structure (e.g., sparse vectors for bound constraints multipliers), they can allocate their own GenericExecutionStats and call solve!(solver, model, stats) directly.

cf: #3
related: #25
cc @sshin23

@codecov
Copy link

codecov bot commented Jul 12, 2022

Codecov Report

Base: 93.57% // Head: 92.41% // Decreases project coverage by -1.15% ⚠️

Coverage data is based on head (a381459) compared to base (c4c047e).
Patch coverage: 60.00% of modified lines in pull request are covered.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #26      +/-   ##
==========================================
- Coverage   93.57%   92.41%   -1.16%     
==========================================
  Files           2        3       +1     
  Lines         140      145       +5     
==========================================
+ Hits          131      134       +3     
- Misses          9       11       +2     
Impacted Files Coverage Δ
src/solver.jl 60.00% <60.00%> (ø)

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@github-actions
Copy link
Contributor

Package name latest stable
CaNNOLeS.jl
DCI.jl
DerivativeFreeSolvers.jl
JSOSolvers.jl
NLPModelsIpopt.jl
Percival.jl
RipQP.jl
SolverTest.jl

@abelsiqueira
Copy link
Member

What about creating AbstractOptSolver as well, to differentiate what Krylov methods can derive from. Or should we leave that for traits?

Copy link
Member

@tmigot tmigot left a comment

Choose a reason for hiding this comment

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

That's a good idea. I made a suggestion of a docstring, feel free to adapt. You could also make a short unit test for this using dummy_solver to increase coverage.

@tmigot
Copy link
Member

tmigot commented Jul 12, 2022

If I understand correctly, the stats is not stored within the solver structure, which is what is done in Krylov.jl for instance.

@github-actions
Copy link
Contributor

Package name latest stable
CaNNOLeS.jl
DCI.jl
DerivativeFreeSolvers.jl
JSOSolvers.jl
NLPModelsIpopt.jl
Percival.jl
RipQP.jl
SolverTest.jl

@geoffroyleconte
Copy link
Member

Should we export AbstractSolver and solve! ?

@dpo
Copy link
Member Author

dpo commented Jul 12, 2022

If I understand correctly, the stats is not stored within the solver structure, which is what is done in Krylov.jl for instance.

Well, good point. We should talk about that. Krylov.jl is a bit different because there are different stats structures, so a user would be supposed to know which kind they should pass to which solver. I guess storing stats inside the solver makes that part easier for the user.

Another difference is that Krylov solvers return the solver object at the end.

From a conceptual point of view, I find it quite logical that

  1. a solver object holds storage necessary to perform a solve;
  2. a stats object holds storage necessary to represent the result of a solve;
  3. solving returns a stats object.

But perhaps others see things differently?!

@dpo
Copy link
Member Author

dpo commented Jul 12, 2022

What about creating AbstractOptSolver as well, to differentiate what Krylov methods can derive from. Or should we leave that for traits?

Let's discuss that too. I like the idea of traits; we're not using them enough. How do people feel?

@github-actions
Copy link
Contributor

Package name latest stable
CaNNOLeS.jl
DCI.jl
DerivativeFreeSolvers.jl
JSOSolvers.jl
NLPModelsIpopt.jl
Percival.jl
RipQP.jl
SolverTest.jl

@abelsiqueira
Copy link
Member

Well, good point. We should talk about that. Krylov.jl is a bit different because there are different stats structures, so a user would be supposed to know which kind they should pass to which solver. I guess storing stats inside the solver makes that part easier for the user.

Another difference is that Krylov solvers return the solver object at the end.

From a conceptual point of view, I find it quite logical that

  1. a solver object holds storage necessary to perform a solve;
  2. a stats object holds storage necessary to represent the result of a solve;
  3. solving returns a stats object.

But perhaps others see things differently?!

I agree with your points. But that means we change Krylov (in the future)?
About the stats being different structures, is it the case that we should allow that for Opt solvers as well? Should we have AbstractSolverOutput and Krylov outputs derived from that?

@dpo
Copy link
Member Author

dpo commented Jul 25, 2022

I agree with your points. But that means we change Krylov (in the future)?
About the stats being different structures, is it the case that we should allow that for Opt solvers as well? Should we have AbstractSolverOutput and Krylov outputs derived from that?

Maybe, and maybe :-). I guess Krylov and optimization solvers should be consistent. A difference is that Krylov stats don't have a solver_specific part. We should evaluate whether solver_specific makes solve!() type unstable or not.

@dpo
Copy link
Member Author

dpo commented Aug 6, 2022

Rebased and added the AbstractOptimizationSolver type so Krylov.jl can do things differently, at least in the near future.

Adding @amontoison to the conversation.

@github-actions
Copy link
Contributor

github-actions bot commented Aug 6, 2022

Package name latest stable
CaNNOLeS.jl
DCISolver.jl
DerivativeFreeSolvers.jl
JSOSolvers.jl
NLPModelsIpopt.jl
Percival.jl
RipQP.jl
SolverBenchmark.jl
SolverTest.jl

Copy link
Member

@tmigot tmigot left a comment

Choose a reason for hiding this comment

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

Just two very minor comments. The rest looks good to me. We can add unit tests with dummy_solver in a separate PR.

@dpo
Copy link
Member Author

dpo commented Aug 12, 2022

Still working on the dummy solver. Trying to make it a good example to follow.

@github-actions
Copy link
Contributor

Package name latest stable
CaNNOLeS.jl
DCISolver.jl
DerivativeFreeSolvers.jl
JSOSolvers.jl
NLPModelsIpopt.jl
Percival.jl
RipQP.jl
SolverBenchmark.jl
SolverTest.jl

@dpo
Copy link
Member Author

dpo commented Aug 12, 2022

@github-actions
Copy link
Contributor

Package name latest stable
CaNNOLeS.jl
DCISolver.jl
DerivativeFreeSolvers.jl
JSOSolvers.jl
NLPModelsIpopt.jl
Percival.jl
RipQP.jl
SolverBenchmark.jl
SolverTest.jl

@geoffroyleconte
Copy link
Member

geoffroyleconte commented Aug 12, 2022

Something broke: https://github.com/JuliaSmoothOptimizers/SolverCore.jl/runs/7812176580?check_suite_focus=true#step:6:222. Where is that coming from?

Could it be that some matrix that was previously dense and is now sparse? Maybe jac in dummy_solver? I've had similar warnings with the SolverBenchmark tests, but the tests still passed so I though it was normal.

@dpo
Copy link
Member Author

dpo commented Aug 14, 2022

Yes I guess ADNLPModel's jac now returns a sparse matrix and A' \ b doesn't work for sparse A: JuliaSparse/SparseArrays.jl#115

@tmigot Could you confirm that that's due to a change in ADNLPModels?

@dpo
Copy link
Member Author

dpo commented Aug 14, 2022

See #34.

@tmigot
Copy link
Member

tmigot commented Aug 15, 2022

Yes I guess ADNLPModel's jac now returns a sparse matrix and A' \ b doesn't work for sparse A: JuliaSparse/SparseArrays.jl#115

@tmigot Could you confirm that that's due to a change in ADNLPModels?

Yes, I can confirm that jac is now sparse in ADNLPModels (same goes for jac_lin and jac_nln).

@tmigot tmigot mentioned this pull request Aug 15, 2022
@github-actions
Copy link
Contributor

github-actions bot commented Sep 2, 2022

Package name latest stable
CaNNOLeS.jl
DCISolver.jl
DerivativeFreeSolvers.jl
JSOSolvers.jl
NLPModelsIpopt.jl
Percival.jl
RipQP.jl
SolverBenchmark.jl
SolverTest.jl

@github-actions
Copy link
Contributor

github-actions bot commented Sep 2, 2022

Package name latest stable
CaNNOLeS.jl
DCISolver.jl
DerivativeFreeSolvers.jl
JSOSolvers.jl
NLPModelsIpopt.jl
Percival.jl
RipQP.jl
SolverBenchmark.jl
SolverTest.jl

@dpo
Copy link
Member Author

dpo commented Sep 2, 2022

Finally got around to revising the dummy solver that's in here. If it looks ok, we could extract it and use it in the documentation.

@github-actions
Copy link
Contributor

github-actions bot commented Sep 2, 2022

Package name latest stable
CaNNOLeS.jl
DCISolver.jl
DerivativeFreeSolvers.jl
JSOSolvers.jl
NLPModelsIpopt.jl
Percival.jl
RipQP.jl
SolverBenchmark.jl
SolverTest.jl

@dpo dpo requested review from tmigot and removed request for abelsiqueira September 2, 2022 18:18
Copy link
Member

@tmigot tmigot left a comment

Choose a reason for hiding this comment

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

Thank you! This looks great.

@github-actions
Copy link
Contributor

github-actions bot commented Sep 2, 2022

Package name latest stable
CaNNOLeS.jl
DCISolver.jl
DerivativeFreeSolvers.jl
JSOSolvers.jl
NLPModelsIpopt.jl
Percival.jl
RipQP.jl
SolverBenchmark.jl
SolverTest.jl

@dpo
Copy link
Member Author

dpo commented Sep 6, 2022

This is still not ideal. If the user wants to check the iteration counter, it must be done via the stats. We have to decide whether the contents of stats can be trusted in the callback (e.g., what about the multipliers? Or the solver-specific data?)

@amontoison
Copy link
Member

Rebased and added the AbstractOptimizationSolver type so Krylov.jl can do things differently, at least in the near future.

Adding @amontoison to the conversation.

Hi guys! Why is it relevant to have KrylovSolver <: AbstractOptimizationSolver?

@dpo
Copy link
Member Author

dpo commented Sep 6, 2022

Hi guys! Why is it relevant to have KrylovSolver <: AbstractOptimizationSolver?

It's not. It should be KrylovSolver <: Solver, so they can behave differently than optimization solvers.

@tmigot
Copy link
Member

tmigot commented Sep 7, 2022

This is still not ideal. If the user wants to check the iteration counter, it must be done via the stats. We have to decide whether the contents of stats can be trusted in the callback (e.g., what about the multipliers? Or the solver-specific data?)

Is this connected with this precise PR?

I think it should be sufficient to be precise in the docstring what fields of the stats are updated by algorithm? And add a reset!(stats) at the beginning of each algorithm.

@dpo
Copy link
Member Author

dpo commented Sep 7, 2022

I agree. I should at least modify the dummy solver to illustrate how to do it.

@dpo
Copy link
Member Author

dpo commented Sep 8, 2022

@tmigot I added a test to demo the callback feature and modified the dummy solver accordingly.

@github-actions
Copy link
Contributor

github-actions bot commented Sep 8, 2022

Package name latest stable
CaNNOLeS.jl
DCISolver.jl
DerivativeFreeSolvers.jl
FletcherPenaltySolver.jl
JSOSolvers.jl
NLPModelsIpopt.jl
Percival.jl
RipQP.jl
SolverBenchmark.jl
SolverTest.jl

@tmigot
Copy link
Member

tmigot commented Sep 9, 2022

This looks great, thanks!

@dpo
Copy link
Member Author

dpo commented Sep 9, 2022

CirrusCI is apparently having some unrelated issues. I'm going to go ahead and merge.

@dpo dpo merged commit a394b3a into main Sep 9, 2022
@dpo dpo deleted the abstract-solver branch September 9, 2022 14:16
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.

5 participants