I have what I thought was a really basic usage of SharedArrays. But it says the array is undefined on the worker processes and I have no idea why it would be. I have the following code in a file “test.jl”. I run it with julia -p 4 test.jl
using SharedArrays
const arr = SharedArray{Int64, 2}((5,5))
for i in 1:5
arr[i, :] = fill(i, 5)
end
@everywhere function test()
return arr[myid(), :]
end
remotecall_fetch(test, 2)
it exits with
ERROR: LoadError: On worker 2:
UndefVarError: arr not defined
arr = SharedArray{Int64, 2}((5,5))
@distributed for i in 1:5
arr[i, :] = fill(i, 5)
end
@everywhere function test()
return arr[myid(), :]
end
remotecall_fetch(test, 2)
I don’t think that’s right. I think the @distributed macro just creates copies similar to how @spawnat does. You can take a look at the documentation here Parallel Computing · The Julia Language. It talks about implicit data movement.
If for example, you add arr[2,2] = 10 after the distributed loop but before the test function, the remote call and fetch still only outputs [2, 2, 2, 2, 2]. Additionally, if you run your code with a regular array instead of a shared array (see below), it works the same which is evidence for the implicit data movement.
arr = Array{Int64, 2}(undef, 5,5)
@distributed for i in 1:5
arr[i, :] = fill(i, 5)
end
arr[2,2] = 10
@everywhere function test()
return arr[myid(), :]
end
println(remotecall_fetch(test, 2))
My understanding is that you avoid implicit data movement if you loop through a SharedArray in this way. But I may have to spend a little bit more time reading the documentation.
With that said, This should be a posted as a new question; my differ based on whether I run the code as a script or via the REPL.
Via REPL (using Julia V1.3.0) I get [2,10,2,2,2] when I run the following
That’s very weird. Going back to my original example, it appears to work if you add a fetchfrom the process of interest first. I might submit an issue on github since it doesn’t make sense.
@everywhere using SharedArrays
const arr = SharedArray{Int64, 2}((5,5))
for i in 1:5
arr[i, :] = fill(i, 5)
end
@everywhere function test()
arr[myid(), myid()] = 10
return arr[myid(), :]
end
println(remotecall_fetch(test, 2)) # doesn't work
@fetchfrom 2 arr
println(remotecall_fetch(test, 2)) # works now
println(remotecall_fetch(test, 3)) # still doesn't work on this worker though
println(arr)