Skip to content
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

Compatibility with JuMP 0.19? #130

Closed
stakaz opened this issue Mar 12, 2019 · 15 comments · Fixed by #150
Closed

Compatibility with JuMP 0.19? #130

stakaz opened this issue Mar 12, 2019 · 15 comments · Fixed by #150

Comments

@stakaz
Copy link

stakaz commented Mar 12, 2019

Hello, just to have an idea of the road map of NLopt. Are there any plans to update the package such that it can be used with JuMP version > 0.18?

@mlubin
Copy link
Member

mlubin commented Mar 13, 2019

The JuMP team doesn't have any immediate plans to update NLopt for JuMP 0.19. We're happy to provide guidance on how to do so, however.
CC @jlperla

@stevengj
Copy link
Collaborator

Is there documentation on what has changed?

@rodrigorandel
Copy link

The JuMP team doesn't have any immediate plans to update NLopt for JuMP 0.19. We're happy to provide guidance on how to do so, however.
CC @jlperla

Hello @mlubin, where can I find the guidance? =)

@stevengj
Copy link
Collaborator

I see, it needs to be changed to use MathOptInterface, I guess?

@odow
Copy link
Member

odow commented Mar 26, 2019

Yes, the easiest example to follow is probably Ipopt.

Compare and contrast the MOI wrapper https://github.com/JuliaOpt/Ipopt.jl/blob/master/src/MOI_wrapper.jl with the MPB wrapper https://github.com/JuliaOpt/Ipopt.jl/blob/master/src/MPB_wrapper.jl

@mlubin
Copy link
Member

mlubin commented Mar 27, 2019

And feel free to ask questions at https://gitter.im/JuliaOpt/JuMP-dev.

@stevengj
Copy link
Collaborator

Slowly working on this, but in general I find the API a bit bewildering and the docs rather terse; I find myself having to read a lot of source code.

Since NLopt doesn't allow you to add variables to an existing Opt object (the dimension is immutable), although you can mutate constraints, it seems that I need to use the "Allocate-Load Interface". An example of this that may be helpful is

https://github.com/JuliaOpt/SemidefiniteOptInterface.jl/tree/master/src

I just released NLopt 2.6.0 with functions set_lower_bound and set_upper_bound to set one bound at a time, since it seems like the MOI API likes to provide one constraint at a time and I didn't want setting n bounds to take O(n²) time.

@mlubin
Copy link
Member

mlubin commented Apr 13, 2019

it seems that I need to use the "Allocate-Load" Interface

The allocate-load interface is complex and underdocumented, but you don't need to use it. It's an optimization that makes bridges more efficient. The minimal interface you can support is implementing MOI.copy_to. You're given a MOI.ModelLike and copy the whole model in one shot. No need to support adding constraints one at a time.

The MOI docs state:

If the solver does not support loading the problem incrementally, do not implement add_variable and add_constraint as implementing them would require caching the problem. Let users or JuMP decide whether to use a CachingOptimizer instead. Write either a custom implementation of copy_to or implement the Allocate-Load API.

Perhaps we should highlight that implementing copy_to is simpler than implementing allocate-load. @blegat

Here's an example with Cbc:

https://github.com/JuliaOpt/Cbc.jl/blob/eaef881a81d1e5a14dcd8a824c8efad5f6feb546/src/MOI_wrapper.jl#L320

@blegat
Copy link
Member

blegat commented Apr 13, 2019

The allocate-load interface is complex and underdocumented, but you don't need to use it.

There is http://www.juliaopt.org/MathOptInterface.jl/stable/apireference/#Allocate-Load-API-1 but I think it misses examples, @stevengj let me know if you think something would be useful to add.

It's an optimization that makes bridges more efficient

In more details, if you just implement MOI.copy_to and use bridges then you need 2 caches but if you implement Allocate-Load, in the future once bridges implement the Allocate-Load API you will only need one cache (see http://www.juliaopt.org/MathOptInterface.jl/stable/apimanual/#Implementing-copy-1).

Perhaps we should highlight that implementing copy_to is simpler than implementing allocate-load.

I sort of feel that while implementing copy_to is simpler at first, it is more prone to bugs and will provide less consistent error messages. Since you manually get things from the src model, you might only take what you support and not throw any error for the unsupported elements of the model that could be present. When you use allocate_load or default_copy_to, each element of the model is thrown at you so you can either handle it or a consistent error will be thrown so it seems easier to get it right. For this reason, I would prefer improving the documentation of Allocate-Load than having many implementation use MOI.copy_to and then users will get bugs from JuMP which are due to incorrect wrappers. With Allocate-Load we kind of keep more control. Also, once we change something in MOI, I feel like the implementation of MOI.copy_to might need to be updated more frequently than those using Allocate-Load or default_copy_to.
In general, if every wrapper start doing completely different things, it will less easy to manage than if they follow more standardized pattern.
So from a long-term perspective, it might be better to improve the documentation of Allocate-Load rather than recommend using MOI.copy_to.

@blegat
Copy link
Member

blegat commented Apr 13, 2019

An example of this that may be helpful is

https://github.com/JuliaOpt/SemidefiniteOptInterface.jl/tree/master/src

SemidefiniteOptInterface is rather complicated because it contains hardcoded variable bridges (see jump-dev/MathOptInterface.jl#710). IMO The simplest implementation of Allocate-Load is ECOS:
https://github.com/JuliaOpt/ECOS.jl/blob/master/src/MOI_wrapper.jl

@stevengj
Copy link
Collaborator

Thanks, that's helpful.

@mlubin
Copy link
Member

mlubin commented Apr 13, 2019

I sort of feel that while implementing copy_to is simpler at first, it is more prone to bugs and will provide less consistent error messages. Since you manually get things from the src model, you might only take what you support and not throw any error for the unsupported elements of the model that could be present.

That's a good point. It's easier to implement copy_to incorrectly and end up silently solving the wrong problem.

Thinking about it more, another issue is that our recommendation:

If the solver does not support loading the problem incrementally, do not implement add_variable and add_constraint as implementing them would require caching the problem.

is based on an assumption that doesn't apply to NLopt. Specifically, NLopt doesn't really store problem data. It uses callbacks to query function values and gradients. The wrapper must cache the part of the problem that's not part of the NLPBlockData, regardless of whether it uses allocate-load. There's no benefit in terms of the number of copies of the model data between allocate-load and the full incremental interface. For this reason, Ipopt implements the full incremental interface even though the underlying solver has no support for adding variables or constraints individually.

@stevengj Is there a reason you don't want to copy the design of the Ipopt wrapper? Like NLopt, Ipopt internally doesn't support adding constraints or variables dynamically. The wrapper maintains a cache and build the Ipopt problem only during optimize!.

@diegozea
Copy link

diegozea commented May 7, 2019

I've just found this error while trying to use the example in the README:

julia> m = Model(solver=NLoptSolver(algorithm=:LD_MMA))
ERROR: The solver= keyword is no longer available in JuMP 0.19 and later. See the JuMP documentation (http://www.juliaopt.org/JuMP.jl/latest/) for latest syntax.

@Christl96
Copy link

Are there news on the compatibility of the solver with JuMP? In my case also the algorithm variable definition doesn't work. Is there an overview of all possible algorithm values and their implementation?

@mlubin
Copy link
Member

mlubin commented Jul 8, 2020

I'm not aware of any progress on an NLopt/MOI wrapper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

8 participants