Use a SharedArray.

--Tim

On Friday, May 01, 2015 05:57:54 PM Constantin Berzan wrote:
> I have a parallel application where I want to modify some objects from
> worker processes, and get the modified values back into the main process.
> Is there a clean way to do this in Julia?
> 
> Here is a contrived example illustrating the problem (run with "julia -p 2
> myfile.jl"):
> 
> @everywhere function mutate_arr!(arr, x)
> 
> >     println(arr)
> >     push!(arr, x)
> >     println(arr)
> >     nothing
> > 
> > end
> > 
> > 
> > arr = [1, 2, 3]
> > println(arr)
> > remotecall_fetch(2, mutate_arr!, arr, 4)
> > println(arr)
> 
> This fails with the following error:
> 
> exception on 2: ERROR: cannot resize array with shared data
> 
> >  in push! at ./array.jl:459
> >  in mutate_arr! at .../myfile.jl:3
> >  in anonymous at multi.jl:855
> >  in run_work_thunk at multi.jl:621
> >  in anonymous at task.jl:855
> 
> Is it the case that remotecall and @spawn do not allow modifying the
> function arguments? If so, this should be documented.
> 
> My second attempt uses a RemoteRef to pass the array explicitly:
> 
> @everywhere function mutate_arr!(arr, x)
> 
> >     println(arr)
> >     push!(arr, x)
> >     println(arr)
> >     nothing
> > 
> > end
> 
> @everywhere function wrapper_mutate_arr!(ref, x)
> 
> >     local_arr = take!(ref)
> >     mutate_arr!(local_arr, x)
> >     put!(ref, local_arr)
> >     nothing
> > 
> > end
> 
> arr = [1, 2, 3]
> 
> > println(arr)
> 
> arr_ref = RemoteRef(2)
> 
> > put!(arr_ref, arr)
> > remotecall_fetch(2, wrapper_mutate_arr!, arr_ref, 4)
> > arr = take!(arr_ref)
> > println(arr)
> 
> This fails with the same error ("cannot resize array with shared data").
> What is shared here, and why?
> 
> If I use replace local_arr = take!(ref) with local_arr = copy(take!(ref)),
> it works. But I think this creates an additional copy (one for the
> serialization, and one for the copy() call), which I would like to avoid.
> 
> In summary: If I have a function like mutate_arr! that I want to offload to
> a worker process, what is the right way to do it? Obviously the functional
> way of thinking is to avoid mutation entirely, but if I already have a
> function like that, what should I do? Just use an additional copy() as
> above?
> 
> (In case it matters, I'm using Julia 0.3.4.)
> 
> Thanks,
> Constantin

Reply via email to