-
-
Notifications
You must be signed in to change notification settings - Fork 10.9k
Numpy.dot silently returns all zero matrix when the out argument is the same as the input. #8440
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
Comments
What numpy version? |
I am using the $ conda list numpy
numpy 1.11.2 py27_0 |
Does #8043 fix this? (The patch is long, and I'm not sure how |
I skimmed #8043 (and the associated #1683) and those changes seem to be fixing an orthogonal issue, I think FWIW, since this feature of in place multiplication of a tall thin matrix @cython.initializedcheck(False)
@cython.wraparound(False)
@cython.boundscheck(False)
@cython.overflowcheck(False)
cdef np.ndarray[float,ndim=2] matrix_multiply_impl1(
np.ndarray[float,ndim=2] a,
np.ndarray[float,ndim=2] b):
cdef:
unsigned int i = 0
char trans = 't'
int m=b.shape[0], n=b.shape[1], incx=1, incy=1
int lda=m
float alpha=1, x, beta=0
np.ndarray[float,ndim=1] y = np.zeros((m,), dtype='float32', order='C')
for i in range(a.shape[0]):
# (char *trans, int *m, int *n, float *alpha, float *a, int *lda, float *x, int *incx, float *beta, float *y, int *incy)
blas.sgemv(&trans, &m, &n, &alpha, &b[0, 0], &lda, &a[i,0], &incx, &beta, &y[0], &incy)
a[i,:] = y
return a
def matmul(a, b, method=1):
assert method == 1
a=np.ascontiguousarray(a)
b=np.asfortranarray(b)
return matrix_multiply_impl1(a,b) |
In general the rule in numpy has been that passing overlapping arrays as both inputs and outputs produces undefined behavior. This is because there simply wasn't any fast and reliable way to detect whether this was happening, so rather than slow everything down with super-expensive checks we just punted and made it the user's problem. (It's not trivial: consider things like So for
Right now we're at step (0) on this list. Each item on the list is strictly more complicated to implement than the one before, so incremental progress means moving down the list step-by-step. |
gh-8043 only deals with ufuncs. If dot is supposed to behave similarly as ufuncs here, a temporary copy should be made (but that's a matter for a separate PR). |
Hello, I lost 3 hours today because of this. Thanks. |
If your matrix is triangular and in fortran format then you can use the
wrapper of `trmv` found in scipy.linalg.blas.
Otherwise, you'll have to loop through the array on your own, basically do
the multiplication one row/column at a time
so that the row/column that you overwrote is not reused later on. My gist
linked above shows a way of doing this in cython.
…On Wed, Jan 18, 2017 at 4:11 AM, Jean-Sébastien B. ***@***.*** > wrote:
Hello, I lost 3 hours today because of this.
I agree with @njsmith <https://github.com/njsmith> about performance and
useless checks, but at least, documentation must be updated with a big
warning.
How can I do an "in-place" dot if I can't pass the same array as out? Why
is it forbidden?
Thanks.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#8440 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/ACMdtLTIoAasAHCEgOZP8_ABPpdOialwks5rTddDgaJpZM4LYytM>
.
|
Thanks @se4u |
Currently the numpy
dot
operation allows for specifying theout
parameter. Although the documentation warns people that this is a performance feature and therefore this code will throw an exception if theout
argument does not have the right type, it does not throw an exception if someone tries to overwrite the original matrix.The ideal fix for this will be to do something smart, by doing the matrix multiplication in a memory efficient way by keeping only a column/row of scratch space [1], but short of that it will be better to throw an exception in case someone provides the
out
matrix as the same as either of the two matrices being multiplied instead of returning an all zero matrix and turning all the values in the input to zero.The patch below suggests one possible error message that can be shown to people, and the python session illustrates the current wrong behavior.
[1] I looked into scipy.lapack.blas and it exposes the
*trmm
methods which allow for inplace modification of output when the input matrix is triangular but there is nothing for general rectangular times square matrix.The text was updated successfully, but these errors were encountered: