I’d like to be able to verify / list available linear solvers on any given machine before running a model. My stack is
Ipopt, which means I can do something like this:
import Ipopt; import JuMP; optimizer = JuMP.with_optimizer(Ipopt.Optimizer, linear_solver="ma97"); model = JuMP.Model(optimizer)
optimizer is of type
JuMP.OptimizerFactory, and seems to be lazily evaluated since at this point in time
model has no issues even if one types garbage into the
From my understanding, JuMP sends this factory info to Ipopt.jl, which uses MOI to then do a bunch of
ccalls to run everything once
JuMP.optimize!(model) is called, and not before.
By default Ipopt.jl packages the MUMPS linear solver, although there are more efficient ones out there: HSL MA97 as an example (as set in
In my specific case, I want to be able to prioritize certain linear solvers over others, depending on solvers available on a users system. By default, Ipopt will use MA27 if it’s compiled with HSL, but I’m needing MA97 if available and would fall back to MUMPS if not.
The only ways I can find to check if MA97 is extant at the moment is to run
JuMP.optimize!(model) and wait for it to fail via the MOI
ccall attempt via
addOption at the JuMP level.
Which ultimately could be simplified to invoking something at the Ipopt.jl level by building some dummy
IpoptProblem and capture the error:
prob = Ipopt.createProblem(1,[1.],[1.],1,[1.],[1.],1,1,sum,sum,sum,sum); try Ipopt.addOption(prob, "linear_solver", "ma97") println("HSL installed") catch println("Use MUMPS") end
Is there a cleaner way to do this at all that I’ve just overlooked? This of course gets pretty messy if I want a list of installed solvers rather than just one check and a fallback.
Update: as a followup - I’ve realized this solution isn’t even enough. The
addOption call will pass so long as it is possible to be accepted in Ipopt’s settings here. For example, I don’t have “pardiso” installed, but I won’t receive an error at this point if I try to test with it. Thus I need to actually call
Ipopt.solveProblem(prob) as well and capture on that output instead.