-
Notifications
You must be signed in to change notification settings - Fork 0
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
Gurobi Output Typing Errors #9
Comments
I found the source of this issue, turned out to be in Gurobi! In their documentation for the
When Unfortunately this means the issue can't be fixed on our end, it's just a case of Gurobi's typing not being mature yet. We've used the correct typing which is what matters as far as the interpreter is concerned, though there may be some false flag errors produced like this which might make debugging harder than it would be otherwise. ExampleTo see an example of this, take Gurobi's print(type(x.X), x.X)
print(f"Obj: {m.ObjVal:g}") The output when running will then end with Optimal solution found (tolerance 1.00e-04)
Best objective 3.000000000000e+00, best bound 3.000000000000e+00, gap 0.0000%
<class 'numpy.ndarray'> [1. 0. 1.]
Obj: 3 showing that (constant) X: float which highlights the conflict, and subsequent error which would occur if typing was enforced. |
Well done on getting to the bottom of this. Gurobi's Python interface is clearly not mature. |
Do you know how they handle typing through other language's APIs? Curious why their choice of type for |
In C, C++ or Fortran, what's passed is (a pointer to) the memory address of an object of a particular type. When compiled, the types on both the call and method have to match. In C and C++ (at least) there are subtleties like "pass by reference" (so changes in what's passed affect the calling method) and "pass by value" where changes aren't passed back. Passing by reference isn't possible in Python, which may say something about the disconnect between the calling and called code. Modified values are passed back in the return value - that may be a tuple |
I see, makes sense that the same issue isn't in those languages because it's all pointers and references. This isn't a priority issue now so I won't go down the rabbit hole searching for a fix, but off the back of what you've said I did just have a quick look how this is handled in the Java API. It has typing but (if my limited Java serves me right), doesn't have pointers, so was curious how it was handled there. In their Java QP example, they define the model variables using GRBVar[] vars = model.addVars(lb, ub, null, vtype, null); and then after for (int j = 0; j < cols; j++)
vars[j].get(GRB.DoubleAttr.X); In other words, it seems like when the variable is initialised the API creates an The Python behaviour seems more intuitive, but I wonder whether the Python API expects similar typing behaviour to Java, but (in Pythonic fashion) works regardless which way round the model variables are typed. Given how recently Gurobi added typing too it makes sense that the Python example might be inconsistent with the current API behaviour. |
Pylance reports that Gurobi is sometimes returning a
float
value when anumpy.ndarray
is expected.Background
The solver functions have appropriate
numpy.typing
return types, specified for example asand then returned with
where
w.X
andmodel.ObjVal
are the outputs from Gurobi.Issue
Sometimes, but not always, Pylance flags that Gurobi is returning a
float
type object forw.X
, producing an error like the below.When
w.X
is examined though it's clearly anumpy.ndarray
, andtype(...)
returns what we'd expect, so I can only assume either:MVar.X
,MVar.X
(note this was only even added in v11)MVar
's type incorrectly forw
The text was updated successfully, but these errors were encountered: