-
Notifications
You must be signed in to change notification settings - Fork 38
RFC: new default solver mechanism compatible with Julia 0.6 #150
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
Conversation
|
I would even be in favour of making the solver a required (rather than optional) argument. The "you don't have to worry about choosing a solver (if you don't want to)" approach has always seemed a bit too magical for me. When I first started using JuMP it led to some confusion where I used to change solvers by (un)commenting different |
|
I'd be open to considering that. What we still need though is a way to print a useful message if the user doesn't provide a solver giving them a suggestion for which solvers could work for their class of problem. |
function buildlp(c::InputVector, A::AbstractMatrix, rowlb::InputVector, rowub::InputVector, lb::InputVector, ub::InputVector, solver::AbstractMathProgSolver)
# as above
end
function buildlp(c::InputVector, A::AbstractMatrix, rowlb::InputVector, rowub::InputVector, lb::InputVector, ub::InputVector)
error("""
You haven't specified a linear solver.
You can use any solver listed on the solvers table of http://www.juliaopt.org/ that has a tick in the Linear/Quadratic column.
A (free) example is Cbc.jl. You can install it (if you haven't already) by going
julia> Pkg.add("Cbc")
""")
end |
|
Can we do something like function loadfirst(solverlist)
for (pkgname, _) in solverlist
try
eval(Expr(:import, pkgname))
# stop when we've found a working solver in this category
continue
end
end
end
loaddefaultLPsolver() = loadfirst(LPsolvers)to make it possible to load only the solver needed ? function defaultLPsolver_autoload()
loaddefaultLPsolver()
defaultLPsolver()
end |
No, it would return a solver "from the future". Its implementation of |
|
@odow, that gets trickier for JuMP because of the multiple problem classes. It would be nice if this were more programmatic (jump-dev/JuMP.jl#83). |
|
@mlubin so the function would work but would not. |
|
@blegat, it's safe to put |
|
Can't the error messages just be left to JuMP? Then you can do something with I don't think MathProgBase is the place to be doing magical loading of solvers or telling users what they should install. Make the solver a required argument and pass the buck up to JuMP and Convex (who can probably give more informative error messages aimed at their different users anyway). Or you could do something like # In MathProgBase
function recommendsolver(solvertype, solvers)
suggestions = join(["$(solvername)(), from the package $(pkgname).jl" for (pkgname,solvername) in solvers], '\n')
error("No ",$solvertype, " solver chosen. Try using one of the following solvers:\n\n", suggestions, "\n\nIf the package is not installed, you will need to install it and restart Julia.")
end
recommendLPsolvers() = recommendsolver("Linear", MathProgBase.LPsolvers)
# ... and so on ...
# in JuMP
function recommendsolver(::JuMP.UnsetSolver, traits::ProblemTraits)
if traits.nlp
MathProgBase.recommendNLPsolvers()
elseif traits.int || traits.sos
MathProgBase.recommendMIPsolvers()
elseif traits.sdp
MathProgBase.recommendSDPsolvers()
elseif traits.conic
MathProgBase.recommendConicsolvers()
elseif traits.qp || traits.qc
MathProgBase.recommendQPsolvers()
else
MathProgBase.recommendLPsolvers()
end
end
recommendsolver(solver, traits::ProblemTraits) = nothing |
|
@odow, another use case is for packages that embed optimization. Their users may not know much about which solvers to choose, and it would nice to have a way to just call out to a MIP solver if one is needed. Then again you could argue that those packages should be responsible for dealing with the whole situation in a way that makes sense in their specific context. CC @ccoffrin |
|
If a package is embedding optimisation that requires a MIP solver and doesn't expect the user to know what one is, it should have a dependency on Cbc (for example). It might choose to allow the user to specify a different one if they so desired. It should be the choice of the package developer to make the solver appear magically, rather than at a MathProgBase level. |
|
@odow I am not sure that packages embedding optimizations should have a dependency on a specific solver. I think that one role of MBP is to make other package independent of any solver to reduce their maintainance cost. If one day the solver everybody used to use is not so fast anymore and a new one is preferred as a default, it would be better if this changes only needs to be done in MPB. Then if one package wants to sort them differently it can do something else. Also, since the default mechanism is not easy to implement, it is better if it is implemented only once. Requiring the user to give the solver everytime seems reasonable but yet it would be better if there was some automatic choosing by default. |
|
@odow, I'm hesitant to remove the ability to call |
|
So the plan as of now would be to remove the default solver functionality from MathProgBase and move it into JuMP, with an explicit warning printed whenever a default solver is used. Any objections? |
|
Discussion continues in #151. |
In 0.6, we can essentially no longer run
evalto load solver packages at runtime when we feel like it. Here's a new design for the default solver mechanism that works.Module-level constants like
MathProgBase.defaultLPsolverbecome methodsMathProgBase.defaultLPsolver()which return solver objects. On 0.6 and later, the methods can only look at loaded packages. It's now the user's responsibility to load a capable solver package before solving a model. As a convenience, we provideMathProgBase.loaddefaultsolvers()which can be put at the top of a script to make everything magically work. On 0.5, I've implemented it to print a helpful warning in the use case that will become an error on 0.6.This will become MathProgBase 0.6 since it's a breaking change.
CC @blegat @joehuchette @tkelman @jrevels @odow @joaquimg
Closes #148