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
strange behavior of @guvectorize #5948
Comments
@pyrot23 thanks for reporting this, I can reproduce! It seems somewhat odd, indeed. |
I took another look at this today, and I believe the issue is caused by assigning
https://numba.pydata.org/numba-doc/latest/user/vectorize.html#the-guvectorize-decorator If I remove the assignment I see:
In both cases. @pyrot23 can you try that and report back if you see the same? |
but the result should be a list of 10, not 0. I think the document states that function decorated with @guvectorize doesn't use return statement, instead one should pass a pointer into the function to get the return value. Let's forget about the variable
so no res or any assignment is involved in this case, the output is
I only got the correct result, a list of 10, by pre-creating a |
@pyrot23 thanks for reporting back. I can confirm what you observe. While I am not yet 100% certain as to the root cause of the issue, I am tending towards looking at how the @guvectorize([(int64[:], int64, int64[:])], '(n),()->(n)')
def g(x, y, res):
for i in range(x.shape[0]):
res[i] = x[i] + y And then:
So, in this case, the initialization of the If we now change that code to:
So instead of plain assignment we use the sum assignment operator. If we now run the function and observe the return value, we will receive a different value each time. Here are some samples:
I speculate that the reason this is happening is because So, what we need to do now, is initialize the a = np.arange(5)
r = np.zeros(5, dtype="int64")
g(a, 2, r) And then we get the correct result again. How does this relate to your problem and the strange behavior you are seeing? So, first of all, the code is also using the sum-assignment so a correct initialization of the import numpy as np
from numba import guvectorize, float32
# a simple matrix-vector multiplication
@guvectorize([(float32[:, :], float32[:], float32[:])], '(n,m),(m)->(n)', nopython=True) #
def g(x, y, res):
n, m = x.shape
for ii in range(n):
for jj in range(m):
res[ii] += x[ii, jj] * y[jj]
if __name__ == "__main__":
# 10 by 10 matrix times 10 by 1 vector, all entries are 1, should give a vector of 10s
sz = 10
x = np.ones((sz, sz), dtype=np.float32)
y = np.ones(sz, dtype=np.float32)
res = np.zeros(sz, dtype=np.float32)
# ------------------------------------------------
print("Before calculation :")
print("# -----------------------------------")
print("x = ")
print(x)
print("y = ")
print(y)
print("res = ")
print(res) # <<< I have to print out the res first, otherwise the result is wrong !!!
# ------------------------------------------------
g(x, y, res)
print("# -----------------------------------")
print("After calculation :")
print("# -----------------------------------")
print("res = ")
print(res) It prints the following, correct, result:
The question remains, why you are seeing an array of |
thanks for the extensive explanation. I think that is just my misunderstanding. the result argument is not a reference/pointer, but rather a declaration. |
Reporting a bug
visible in the change log (https://github.com/numba/numba/blob/master/CHANGE_LOG).
to write one see http://matthewrocklin.com/blog/work/2018/02/28/minimal-bug-reports).
I am not sure where the bug is, but as the following example shows, there is very strange behavior
output when
res
is NOT printed out, results are 1 greater than they should be (see below last row of the output)output when
res
is printed out, everything is rightThe text was updated successfully, but these errors were encountered: