-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
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
weave.blitz produces different code for equal numpy ranges #2422
Comments
I've been testing this (I'm the one who answered that SO question) and I think the actual issue is that assignment inside a blitz expression to a slice of the form Assignment to import numpy as np
from scipy.weave import blitz
import numpy.testing as npt
def test_no_bug():
"""Assignment to arr[:i] does not fail inside blitz expression."""
N = 4
expr_buggy = 'arr_blitz_buggy[:{0}] = arr[:{0}]'
expr_not_buggy = 'arr_blitz_not_buggy[0:{0}] = arr[:{0}]'
np.random.seed(7)
arr = np.random.randn(N)
for lim in [1, 2]:
arr_blitz_buggy, arr_blitz_not_buggy, arr_np = np.zeros(N), np.zeros(N), np.zeros(N)
blitz(expr_buggy.format(lim))
blitz(expr_not_buggy.format(lim))
arr_np[:lim] = arr[:lim]
npt.assert_allclose(arr_blitz_buggy, arr_np)
npt.assert_allclose(arr_blitz_not_buggy, arr_np) Running it in scipy '0.13.0.dev-639ef30' gives a bunch of deprecation warnings, though. |
I believe I've tracked it down. The explanation is a bit wordy, but this At first, I was able to write a blitz-only example showing the problem: #include <iostream>
#include <blitz/array.h>
int _beg = blitz::fromStart;
int _end = blitz::toEnd;
blitz::Range _all = blitz::Range::all();
int main() {
blitz::Array<float, 1> A(4), B(4), C(4), D(4);
A = 1, 2, 3, 4;
B = 0, 0, 0, 0;
C = 0, 0, 0, 0;
D = 0, 0, 0, 0;
// Buggy, it's similar to the code generated by the buggy blitz expr
B(blitz::Range(0, _end)) = A(blitz::Range(0, _end));
std::cout << B << std::endl;
// Works OK, similar to the code generated by the non buggy expr
C(blitz::Range(0, 3)) = A(blitz::Range(0, _end));
std::cout << C << std::endl;
// Works fine!? Seems equivalent to the buggy version...
D(blitz::Range(0, blitz::toEnd)) = A(blitz::Range(0, _end));
std::cout << D << std::endl;
} From that, it was clear that #include <iostream>
#include <blitz/array.h>
#include <climits>
/*
In the blitz version shipped by scipy, `blitz::toEnd` is defined in
https://github.com/scipy/scipy/blob/master/scipy/weave/blitz/blitz/range.h#L44
as `INT_MIN` from `climits` or `limits.h`.
In the latest version from sourceforge,
it is defined as `const int toEnd = INT_MAX;`
*/
int _end = blitz::toEnd;
int mx = INT_MAX;
int main() {
std::cout << "INT_MAX " << mx << std::endl;
std::cout << "_end " << _end << std::endl;
std::cout << "toEnd " << blitz::toEnd << std::endl;
/*
Output (blitz 0.10)
INT_MAX 2147483647
_end 0
toEnd 2147483647
Output (shipped by scipy)
INT_MAX 2147483647
_end 0
toEnd -2147483648
*/
} After that, the blitz dependency could be removed in the test case I also added a test case where it seemed more appropriate I'd appreciate any comments or anything I have overlooked. Thanks! |
Good sleuthing! This is a minimal example:
The problem seems to be that The fix is indeed to declare |
Thank you Pauli! I only kept the |
I'd prefer |
It turns out that _end is an undocumented global symbol, maybe in the C++ standard library which has a value of 0. Declaring it as static is enough to avoid the problem.
OK, I changed that. |
Fixed in 7164bb6 |
When blitz is used to inline numpy expressions the outcome depends on the formating of the ranges, even if they are the same. For example a different result is produced for u[0:x] and u[:x] however the result should be the same.
See also:
http://stackoverflow.com/questions/16230848/blitz-code-produces-different-output
The text was updated successfully, but these errors were encountered: