-
Notifications
You must be signed in to change notification settings - Fork 81
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
[MOI] Set Gurobi-specific attributes #211
Comments
Hi, Any pointers will be highly appreciated. |
Please provide a link if you post in multiple places: https://discourse.julialang.org/t/setting-constraints-as-lazy-with-jump-0-19-and-gurobi/24516/7?u=odow. I have replied on Discourse. |
2.5 months later I finally have time to work on this! I am trying something based on the suggestion above but it is not working, at least not the way I am trying. My goal is to get this to work after a model is created using
model = Model(with_optimizer(Gurobi.Optimizer))
@variable(model, x >= 0)
@constraint(model, c, 2x >= 1)
grb_model = model.moi_backend.optimizer.model
grb_model[index(c)] The output is a |
We can forget about JuMP for now. It is already possible to set MOI attributes. See, e.g., using JuMP, Gurobi
model = Model(with_optimizer(Gurobi.Optimizer))
@variable(model, x >= 0)
@constraint(model, c, 2x >= 1)
MOI.set(model, MOI.ConstraintName(), c, "my_c")
@assert name(c) == "my_c" What we need to do is define the equivalent of MOI.set(model, Gurobi.ConstraintAttribute("Lazy"), c, 1) The rough steps are as follows. (All the code should go in Define struct ConstraintAttribute <: MOI.AbstractConstraintAttribute
name::String
end Here is the documentation for the MOI super-types. Then, we need a function MOI.set(
model::Optimizer, key::ConstraintAttribute,
c::ConstraintIndex{MOI.ScalarAffineFunction{Float64}, <:Any}, value::Int
)
set_intattr!(model.inner, key.name, _info(model, c).row, value)
return
end Somehow, we need to deal with the different types of attributes ( Does this make sense? You might want to hold off making changes until #216 is merged. |
Thank you, it does make sense, I will wait until #216 is merged then do as you suggest. |
Just a quick note, I cannot have both Gurobi 0.7.0 and JuMP 0.19 installed at the same time. If I install Gurobi#master then install JuMP, it installs JuMP 0.18.6. If I install JuMP#master then Gurobi, it installs Gurobi 0.6.0. If I try to install both with #master, there is an unsatisfiable requirement for MathOptInterface. Is this normal or is there something wrong with my setup? I think I need both Gurobi 0.7 and JuMP 0.19 to be able to add the MOI feature described above. |
You need to use this branch of JuMP for it to work with MOI v0.9: jump-dev/JuMP.jl#2003 |
After tinkering a bit I am stuck, since |
You need to do |
Thank you! Is this call expensive? If yes, is there any way to check if the model is already "attached"? |
Yes but if you call attach and it's already attached it's a no-op so it shouldn't harm. Anyway, you can check that state with |
Note that touching |
Thanks again, I somehow did not realise that this documentation existed, that's on me. On my system the first call to using JuMP, Gurobi, CPUTime
model = Model(with_optimizer(Gurobi.Optimizer))
@variable(model, x >= 0)
@constraint(model, c, 2x >= 1)
@objective(model, Min, x)
@CPUtime MOIU.attach_optimizer(model) elapsed CPU time: 370.165058 seconds This is using JuMP#master and Gurobi 0.7.0. |
Thanks, I had no idea, I am discovering the whole code (as made obvious from my questions above). The reason why I am trying to do this is to be able to use |
Are you on Julia 1.2? 370s is way too long. How long does optimize! take? |
Yes, this is Julia 1.2. |
You've probably hit JuliaLang/julia#32167. I suggest that you revert to Julia 1.1 until we tag a new version of MOI (and JuMP) with a fix. |
EDIT: this is in fact solved by calling
using JuMP, Gurobi
model = JuMP.direct_model(Gurobi.Optimizer())
@variable(model, x >= 0)
@constraint(model, c, 2x >= 1)
@objective(model, Min, x)
opzr = backend(model)
Gurobi.set_intattrelement!(opzr.inner, "Lazy", Gurobi._info(opzr, index(c)).row, 2)
Gurobi.get_intattrelement(opzr.inner, "Lazy", Gurobi._info(opzr, index(c)).row)
|
After setting or modifying any attribute that requires an updated, you should call |
Thanks, it's great that these functions exist. Is there any reason why they are not systematically called in Gurobi setters and getters? Formulated differently: is there any attribute that does not require an update following modification? |
We attempted to keep the low-level API similar to the C API, so at that level it's the user's job to call update. This is not the case in the MOI level, so we do it using the functions outlined above.
No. The only exception is that Gurobi will update the model on a call to |
First pull request: #243 I only included constraint attributes so far. If people are satisfied with what I did, I can add variable and model attributes too. |
More pull requests submitted, we now have variable attributes and soon model attributes too. I would also like to have methods that are more convenient to call, I think this needs to be added to JuMP, any idea where I should add this? I'm thinking about something like this: using JuMP, Gurobi
model = JuMP.direct_model(Gurobi.Optimizer())
@variable(model, x >= 0)
@constraint(model, c, 2x >= 1)
@objective(model, Min, x)
MOI.set(c, "Lazy", 2) Or if that is not possible, something like MOI.set(model, c, "Lazy", 2) |
This should work: using JuMP, Gurobi
model = JuMP.direct_model(Gurobi.Optimizer())
@variable(model, x >= 0)
@constraint(model, c, 2x >= 1)
@objective(model, Min, x)
MOI.set(model, Gurobi.ConstraintAttribute("Lazy"), c, 2)
optimize!(model) It's pretty convenient. It just needs to be documented: jump-dev/JuMP.jl#2057 |
It should be noted here that the constraints need to be set as lazy individually. If you have a set of constraints defined together, you can't set them as lazy all together. For example, if you have
Instead, you need
|
As raised in this Discourse post, we should implement Gurobi-specific MOI attributes to allow the getting and setting of attributes from JuMP.
A sketch of the idea looks like:
Here is the list of Gurobi attributes
http://www.gurobi.com/documentation/8.1/refman/attributes.html
Here is the list of Gurobi.jl attribute getters and setters
https://github.com/JuliaOpt/Gurobi.jl/blob/master/src/grb_attrs.jl
Note that different functions need to be called based on the type of the attribute (e.g.,
get_intattr
,get_dblattr
,get_strattr
).Here is the list of abstract MOI attributes
https://github.com/JuliaOpt/MathOptInterface.jl/blob/06216dc6907b5ec76390c8380e4655065c83ea22/src/attributes.jl#L16-L35
We should repeat the Julia code above for the other types of attributes listed in the Gurobi documentation, defining new structs as needed.
We probably need to check that the string attribute names match the right
int
/dbl
/str
type.Any code also needs tests and documentation.
For anyone working on this, make some small changes, and then open a pull-request. It doesn't need to be complete. We can workshop the changes before you spend too much time trying to implement everything.
Also, if you have a better idea for how to implement this, say so.
The text was updated successfully, but these errors were encountered: