-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
make test-complex
fails on 32-bit Linux (Heisenbug?)
#10027
Comments
I have no idea why this error occurs. The tests were newly introduced by #8291; they appear to be deeper bugs that happen to be exposed by the complex rounding code. |
Out of curiosity, what happens if you dump the bits for the NaN value? function my_round(z::Complex)
rrz = round(real(z))
riz = round(imag(z))
@show bits(rrz), bits(riz)
Complex(rrz, riz)
end |
@jiahao : Heisenbugginess julia> function my_round(z::Complex)
rrz = round(real(z))
riz = round(imag(z))
@show bits(rrz), bits(riz)
Complex(rrz, riz)
end
my_round (generic function with 1 method)
julia> my_round(Complex(1.5,0.5))
(bits(rrz),bits(riz)) = ("0100000000000000000000000000000000000000000000000000000000000000","0000000000000000000000000000000000000000000000000000000000000000")
2.0 + 0.0im
|
Memory access error? stumped |
Maybe help? julia> function my_round2(z::Complex)
rrz = round(real(z))
riz = round(imag(z))
Complex(rrz, riz)
end
my_round2 (generic function with 1 method)
julia> my_round2(Complex(1.5,0.5))
2.0 + NaN*im
julia> bits(imag(my_round2(Complex(1.5,0.5))))
"1111111111111000000000000000000000000000000000000000000000000000"
|
I was wondering if the NaN payload could tell us anything, but it's all zeroed. |
Here's another look: julia> function my_round5(z::Complex)
rrz = round(real(z))
riz = round(imag(z))
my_cmplx = zero(Complex)
my_cmplx += rrz
my_cmplx += riz*im
my_cmplx
end
my_round5 (generic function with 1 method)
julia> my_round5(Complex(1.5,0.5))
2.0 + 0.0im
|
Does this narrow it down to the constructor? julia> function my_round6(z::Complex)
rrz = round(real(z))
riz = round(imag(z))
rrz + im*riz
end
my_round6 (generic function with 1 method)
julia> my_round6(Complex(1.5,0.5))
2.0 + 0.0im
|
I believe so. @StefanKarpinski any ideas? |
How about trying the inner constructor? function my_round{T}(z::Complex{T})
rrz = round(real(z))
riz = round(imag(z))
Complex{T}(rrz, riz)
end |
julia> function my_round{T}(z::Complex{T})
rrz = round(real(z))
riz = round(imag(z))
Complex{T}(rrz, riz)
end
my_round (generic function with 1 method)
julia> my_round(Complex(1.5,0.5))
2.0 + NaN*im
|
There seems to be something weird going on from the
That |
That's just fine — it's the standard idiom for initializing a new aggregate type in LLVM. See the reference for insertvalue, particularly the example. You start with an object full of undefs and iteratively fill its elements. |
Complex numbers don't round trip correctly to C. That will be fixed very soon in my PR jn/ccall3 |
We're not calling a C function with complex numbers though, are we? |
I don't believe so. Any C function calls are on the real and imaginary parts separately. |
i'm getting invalid native code if i run this test with a sysimg, but seem to be getting correct results if a sysimg is not involved. however, i think this might be fixed in llvm3.5 |
FWIW it happens with LLVM 3.3, 3.4 and 3.5 when building Fedora packages. E.g with 3.5: |
We haven't had new nightlies for a week because of this. I think we should revert #8291 until either we figure out how to do it without breaking 32 bit, or we've upgraded LLVM and hopefully it's fixed there. |
This is a bit slower and uses a bit more RAM, but works on my 32-bit Fedora. Maybe a temporary workaround? julia> @time round(Complex(1.5,0.5))
elapsed time: 2.3746e-5 seconds (100 bytes allocated)
2.0 + NaN*im
julia> @time round(Complex(1.5,0.5))
elapsed time: 2.3956e-5 seconds (100 bytes allocated)
2.0 + NaN*im
julia> @time round(Complex(1.5,0.5))
elapsed time: 3.0242e-5 seconds (100 bytes allocated)
2.0 + NaN*im
julia> my_round(z::Complex) = Complex(map(round,reim(z))...) # <----- New Function Def
my_round (generic function with 1 method)
julia> @time my_round(Complex(1.5,0.5))
elapsed time: 0.006331542 seconds (19 kB allocated)
2.0 + 0.0im
julia> @time my_round(Complex(1.5,0.5))
elapsed time: 2.9893e-5 seconds (148 bytes allocated)
2.0 + 0.0im
julia> @time my_round(Complex(1.5,0.5))
elapsed time: 2.7448e-5 seconds (148 bytes allocated)
2.0 + 0.0im
julia> @time my_round(Complex(1.5,0.5))
elapsed time: 2.8426e-5 seconds (148 bytes allocated)
2.0 + 0.0im
julia> @time my_round(Complex(1.5,0.5))
elapsed time: 2.6959e-5 seconds (148 bytes allocated)
2.0 + 0.0im
|
@rickhg12hs would you be able to put together a PR that I could run on my buildbots to see if it does indeed fix the problem? |
That'll fix it, but only because it very effectively defeats llvm optimization. Simply preventing inlining of round would have the same effect |
@staticfloat : PR made. #10145 @vtjnash : Played with |
would probably look something like:
i realize that's a bit awkward, but annotating |
…ound Update base/complex.jl for Complex round (Fix/Workaround #10027)
+1 to @vtjnash 's suggestion. That would be a much better workaround. Even better if it is only done on 32-bit systems where the problem exists. |
Since this is "working" now, should it be closed? Comment in code mentions it's a workaround. Will this prompt a revisit with new LLVM version? Is there a "workaround" issue tag that could be applied to prompt future look. |
Perhaps we should have a |
This probably works better now that we restrict to >= pentium4 |
this was fixed with the sret fixes some time back. I'll remove the workaround code in #16219 |
I poked around a bit and noted some curious symptoms. Are some intermediary results getting clobbered somewhere?
The text was updated successfully, but these errors were encountered: