Python matrix api with non-writable numpy float64 array error: buffer source array is read-only
回答済みCode to duplicate the error (float32 type is OK - seems the api trying to do calculation in place for the float64 type):
import numpy as np
import gurobipy as gp
model = gp.Model('gurobi_test')
v = model.addMVar(2, vtype=gp.GRB.CONTINUOUS, lb=0.0, ub=[1,2])
c = np.array([1,2], dtype=np.float64)
c.flags.writeable = False
model.setObjective((c * v).sum(), gp.GRB.MINIMIZE)
Error:
ValueError Traceback (most recent call last)
Cell In[121], line 7 5 c = np.array([1,2], dtype=np.float64)
6 c.flags.writeable = False ----> 7 model.setObjective((c * v).sum(), GRB.MINIMIZE)
File src\\gurobipy\\mvar.pxi:406, in gurobipy._matrixapi.MVar.__rmul__()
File src\\gurobipy\\mlinexpr.pxi:1821, in gurobipy._matrixapi.MLinExpr.__rmul__()
File src\\gurobipy\\mlinexpr.pxi:1640, in gurobipy._matrixapi.MLinExpr.__mul__()
File src\\gurobipy\\mlinexpr.pxi:1743, in gurobipy._matrixapi.MLinExpr._mul_compact_ndarray()
File src\\gurobipy\\mlinexpr.pxi:1484, in gurobipy._matrixapi.MLinExpr.__imul__()
File src\\gurobipy\\mlinexpr.pxi:1554, in gurobipy._matrixapi.MLinExpr._imul_compact_ndarray()
File <stringsource>:663, in View.MemoryView.memoryview_cwrapper()
File <stringsource>:353, in View.MemoryView.memoryview.__cinit__()
ValueError: buffer source array is read-only
-
Hi Sean,
I'll ask our dev team to take a look. Which version of gurobipy are you using?Thanks,
Riley0 -
Thanks Riley. Gurobipy version: '12.0.0'.
0 -
Hi Sean,
I can confirm this is unintended behavior and we've added an item to our development backlog to patch it in a future release.
We don't do the calculation in place, and we don't modify the array, but we haven't promised the compiler that we won't modify it either so we get an error when the float64 array has flags.writeable=False.
Are you running into this problem in production, or was this just to demonstrate the bug for us?
If you need to keep flags.writeable=True and consequently need a workaround there's a couple of options. For this specific example,
(c*v).sum()
is the dot product and is equivalent toc@v
, and this latter form does not produce the error (and is faster to build).Otherwise you can use the array's copy function to produce a temporary copy which by default will have flags.writeable=True, i.e.
model.setObjective((c.copy() * v).sum(), gp.GRB.MINIMIZE)
Thanks,
Riley0 -
Thanks Riley for the quick response.
Some data manipulation using pandas / polars DataFrame will lead to flags.writable=False.
I am currently using the array's copy as a workaround.
0
サインインしてコメントを残してください。
コメント
4件のコメント