Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parallel programming in Julia

I have been following the docs for parallel programming in julia and for my mind, which thinks like openMP or MPI, I find the design choice quite strange.

I have an application where I want data to be distributed among processes, and then I want to tell each process to apply some operation to whatever data it is assigned, yet I do not see a way of doing this in Julia. Here is an example

julia> r = remotecall(2, rand, 2)
RemoteRef{Channel{Any}}(2,1,30)

julia> fetch(r)
2-element Array{Float64,1}:
 0.733308
 0.45227 

so on process 2 lives a random array with 2 elements. I can apply some function to this array via

julia> remotecall_fetch(2, getindex, r, 1)
0.7333080770447185

but why does it not work if i apply a function which should change the vector, like:

julia> remotecall_fetch(2, setindex!, r, 1,1)
ERROR: On worker 2:
MethodError: `setindex!` has no method matching setindex!(::RemoteRef{Channel{Any}}, ::Int64, ::Int64)
 in anonymous at multi.jl:892
 in run_work_thunk at multi.jl:645
 [inlined code] from multi.jl:892
 in anonymous at task.jl:63
 in remotecall_fetch at multi.jl:731
 in remotecall_fetch at multi.jl:734

I don't quite know how to describe it, but it seems like the workers can only return "new" things. I don't see how I can send some variables and a function to a worker and have the function modify the variables in place. In the above example, I'd like the array to live on a single process and ideally I'd be able to tell that process to perform some operations on that array. After all the operations are finished I could then fetch results etc.

like image 438
Lindon Avatar asked Feb 05 '16 23:02

Lindon


1 Answers

I think you can achive this with the macro @spawnat:

julia> addprocs(2)
2-element Array{Int64,1}:
 2
 3

julia> r = remotecall(2, rand, 2)
RemoteRef{Channel{Any}}(2,1,3)

julia> fetch(r)
2-element Array{Float64,1}:
 0.149753
 0.687653

julia> remotecall_fetch(2, getindex, r, 1)
0.14975250913699378

julia> @spawnat 2 setindex!(fetch(r), 320.0, 1)
RemoteRef{Channel{Any}}(2,1,6)

julia> fetch(r)
2-element Array{Float64,1}:
 320.0
   0.687653

julia> @spawnat 2 setindex!(fetch(r), 950.0, 2)
RemoteRef{Channel{Any}}(2,1,8)

julia> fetch(r)
2-element Array{Float64,1}:
 320.0
 950.0

But with remotecall_fetch, it looks like the returned array is really a copy:

julia> remotecall_fetch(2, setindex!, fetch(r), 878.99, 1)
2-element Array{Float64,1}:
 878.99
 950.0

julia> remotecall_fetch(2, setindex!, fetch(r), 232.99, 2)
2-element Array{Float64,1}:
 320.0
 232.99

julia> fetch(r)
2-element Array{Float64,1}:
 320.0
 950.0

with: Julia Version 0.4.3

like image 98
Gomiero Avatar answered Sep 19 '22 16:09

Gomiero