Disclaimer: I am not an expert in Threads.@threads
or friends.
Applying any of the changes below makes it work correctly on v1.9.1
:
- add a
local
in front ofv_re, v_im
inside the loop body - rename
v_re, v_im
inside the loop body - rename or remove
v_re, v_im
outside the loop
Someone correct me, but this smells like a bug in Threads.@threads
.
EDIT: As clarified in the comments below, this is intended but also bad behavior. What is happening is that by the current scoping rules, using the names v_re, v_im
also after the loop body makes them being shared between threads, which causes a data race.
Here is the fixed version:
function coefs_w_threads(N)
v = zeros(ComplexF64, N)
Threads.@threads for k in 1:N-1
local v_re = 0.5*k
local v_im = -0.5*k
v[k+1] = v_re + 1im*v_im
end
v_re = 0.25
v_im = -0.25
v[1] = v_re + 1im*v_im
return v
end
function coefs(N)
v = zeros(ComplexF64, N)
for k in 1:N-1
v_re = 0.5*k
v_im = -0.5*k
v[k+1] = v_re + 1im*v_im
end
v_re = 0.25
v_im = -0.25
v[1] = v_re + 1im*v_im
return v
end
ref = coefs(1000)
threads = coefs_w_threads(1000)
# display(sum(ref) == sum(threads))
display(all(ref .== threads)) # more reliable test
EDIT: I had added the local
to the coefs
version instead of coefs_w_threads
…