-
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
Refactor GRBupdatemodel calls #552
Conversation
I don't have much advice here. It was hard to get things working without knowing the internal details. So perhaps I've papered over other mistakes that are now showing themselves. |
It's alright Oscar, I only have import gurobipy as gp
m = gp.Model()
x = m.addVar()
y = m.addVars(100)
c = m.addConstr(x + y.sum() <= 1)
m.setObjective(-x)
# Update before setting
m.update()
x.VBasis = 0
m.update()
c.CBasis = -1
for i in range(100):
m.update()
y[i].VBasis = -1
# Also update before getting
m.update()
print(x.VBasis)
m.optimize() This sets the basis correctly but we get a lot (100) of intermediate warnings like:
It might just be easier to have the user manually call |
As a comment, ideally we should not have to do this. The goal of MOI is to abstract across solvers. In the default case, user's won't have access to an object that they can call Does the Python example throw the same warnings? When is the warning actually printed? I think very few people are actually setting the starting basis. But getting is a common operation. |
We already update here: Gurobi.jl/src/MOI_wrapper/MOI_wrapper.jl Lines 3691 to 3698 in 4d204e2
So is the only thing missing an update at the start of set ?Gurobi.jl/src/MOI_wrapper/MOI_wrapper.jl Lines 3734 to 3752 in 4d204e2
|
Yes the warnings are from the Python example, and they will be printed every time we call update without a complete basis so once for every variable except the last one. |
I'm okay if we throw the same warnings as Python. But perhaps you could fix this internally to only throw a warning if |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #552 +/- ##
==========================================
+ Coverage 80.36% 80.46% +0.09%
==========================================
Files 6 6
Lines 2908 2928 +20
==========================================
+ Hits 2337 2356 +19
- Misses 571 572 +1 ☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't change any tests and everything is still passing so LGTM.
Simon has a better idea of how to handle this: two kinds of update flags.
Let me have another go |
@torressa it looks like you have Just to spell it out to make sure we're on the same page: is the aim here to ensure that an update is done if the user is about to:
? (Side note: is there really anything to worry about with deletes? Or would JuMP error out earlier than this if the user tries to query an attribute on a deleted variable or constraint?) |
I did, yes, some
Exactly, that's the aim.
I'm not sure what the workflow is in practice, but in the tests, we have things like: Gurobi.jl/test/MOI/MOI_wrapper.jl Lines 285 to 303 in 69d2d6e
This will fail without updating after deleting |
Got it, thanks, that makes sense now.
Great, ok, so
At least for variables (constraints may need special handling per #516), it seems like a forced update immediately after the delete isn't needed. It should instead need |
Thanks Simon! You are right, sorry I missed this. |
@@ -1038,6 +1038,7 @@ function MOI.delete(model::Optimizer, indices::Vector{<:MOI.VariableIndex}) | |||
# We throw away name_to_constraint_index so we will rebuild VariableIndex | |||
# constraint names without v. | |||
model.name_to_constraint_index = nothing | |||
# _require_update(model, model_change = true) | |||
_update_if_necessary(model, force = true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the only update remaining for variable deletion as is needed for the test_Buffered_deletion_test
case (linked earlier)
Co-authored-by: Oscar Dowson <[email protected]>
@odow if you are also happy with this, I think we can merge it! |
Okay. Does this solve #516? Or should we still buffer the deletions? |
I think so. I changed some deletions that don't require a forced update (e.g. those that only change an attribute), but the others have to stay as they were to pass the tests (force an update at the end). |
Motivated by the large performance difference in Discourse: Problem with JuMP + Gurobi.jl.
The idea is to only call
GRBupdatemodel
beforeGRBget*
only. I've tried to adhere to calling_update_if_required
at the start of the function or at the end. Additionally, adding theforce
argument to this function avoids having to use_require_update
.Some tests are failing still:
test_Buffered_deletion_test
,test_modify_after_delete*
(indexing should also be updated with delete? This is not expected from our other APIs)test_linear_SOS1_integration
test_set_basis
. When setting + getting[V|C]Basis
we need to update beforehand. Doing this on theMOI.set/get
leads to a lot of warning messages and (potentially) performance issues.Work for the update part of #516