@everywhere for broadcasting variables #9118 Closed amitmurthy opened this Issue on Nov 23, 2014 · 12 comments Projects None yet Labels parallel Milestone No milestone Assignees No one assigned 5 participants @amitmurthy @ViralBShah @blakejohnson @bjarthur @CorySimon Notifications You’re not receiving notifications from this thread. @amitmurthy The Julia Language member amitmurthy commented on Nov 23, 2014 addprocs(1) foo=1 @everywhere bar=foo results in julia> @everywhere bar=foo exception on 2: ERROR: foo not defined in eval at /home/tan/julia/julia/base/sysimg.jl:7 While @spawnat 2 global bar=foo remotecall_fetch(2, ()->bar) works perfectly fine. Shouldn't @everywhere which runs in the scope of Main be a perfectly appropriate method to broadcast variables? @ViralBShah ViralBShah added the parallel label on Nov 23, 2014 @ViralBShah The Julia Language member ViralBShah commented on Nov 23, 2014 @everwhere global bar=foo works, and seems to be clearer to read. @amitmurthy The Julia Language member amitmurthy commented on Nov 23, 2014 No, it doesn't.....I think you did not do an addprocs....or foo was already defined. $ julia -p 1 _ _ _ _(_)_ | A fresh approach to technical computing (_) | (_) (_) | Documentation: http://docs.julialang.org _ _ _| |_ __ _ | Type "help()" for help. | | | | | | |/ _` | | | | |_| | | | (_| | | Version 0.4.0-dev+1762 (2014-11-22 22:37 UTC) _/ |\__'_|_|_|\__'_| | Commit 7d41d6e (0 days old master) |__/ | x86_64-linux-gnu julia> foo=1 1 julia> @everywhere bar=foo exception on 2: ERROR: foo not defined in eval at /home/tan/julia/julia/base/sysimg.jl:7 in anonymous at multi.jl:1395 in anonymous at multi.jl:820 in run_work_thunk at multi.jl:593 in run_work_thunk at multi.jl:602 in anonymous at task.jl:6 julia> @everywhere global bar=foo exception on 2: ERROR: foo not defined in eval at /home/tan/julia/julia/base/sysimg.jl:7 in anonymous at multi.jl:1395 in anonymous at multi.jl:820 in run_work_thunk at multi.jl:593 in run_work_thunk at multi.jl:602 in anonymous at task.jl:6 @ViralBShah The Julia Language member ViralBShah commented on Nov 23, 2014 I did do addprocs, but I may have set the variable everywhere and not needing a broadcast. The point here that you are making is that @everywhere should broadcast things that are only on the client. The current reason for @everywhere , as I understand, is to just execute the same code everywhere. Automatically broadcasting seems a bit too magical, especially if some variables were local and others were broadcasted as part of an expression. Perhaps we should have explicit broadcasting: @everywhere bar=bcast(foo) @amitmurthy The Julia Language member amitmurthy commented on Nov 23, 2014 Well, from a user point of view why should the behavior be different between @spawnat p expr which runs expr on process p and @everywhere which runs expr on all processes under Main @ViralBShah The Julia Language member ViralBShah commented on Nov 23, 2014 That is a reasonable point. I have usually always thought of @spawnat taking local data and executing it on a different processor, and @everywhere to simply execute a piece of code on all processors without specific reference to any particular environment. It doesn't have to be that way. Perhaps @everywhere could be instead called @spawnall with the same behaviour as @spawnat. @blakejohnson blakejohnson commented on Nov 24, 2014 We need to preserve some syntax for evaluation in the remote context. i.e. we still need an equivalent of @everywhere println(myid()) that returns the local ID on each process. That said, this problem has definitely caused me grief before, and it currently takes too much effort to broadcast a variable. @bjarthur bjarthur referenced this issue on Dec 19, 2014 Closed @everywhere is not fully documented #9413 @bjarthur bjarthur commented on Dec 19, 2014 note that amit's @spawnat trick to broadcast variables to other processes does not work for ARGS: test.jl: addprocs(1) @spawnat 2 global bar = ARGS[1] println(remotecall_fetch(2,()->bar)) tmp = "foo" @spawnat 2 global bar = tmp println(remotecall_fetch(2,()->bar)) tmp = ARGS[1] @spawnat 2 global bar = tmp println(remotecall_fetch(2,()->bar)) on the unix command line: $ julia test.jl pooh --bind-to foo pooh not sure whether to consider this a bug or feature but it took me long enough to figure out a work around that i thought i'd post the solution. @bjarthur bjarthur commented on Dec 19, 2014 note also that the remote variable name has to be different than the local: julia> addprocs(1) 1-element Array{Any,1}: 2 julia> bar = "bar" "bar" julia> @spawnat 2 global bar = bar RemoteRef(exception on 2: 2,1,3) julia> println(remotecall_fetch(2,()->bar)) ERROR: bar not defined in anonymous at multi.jl:1533 in anonymous at multi.jl:844 in run_work_thunk at multi.jl:603 in run_work_thunk at multi.jl:612 in anonymous at task.jl:6 exception on 2: ERROR: bar not defined in anonymous at none:1 in anonymous at multi.jl:852 in run_work_thunk at multi.jl:603 in anonymous at task.jl:852 UndefVarError(:bar) @bjarthur bjarthur commented on Dec 24, 2014 how about adding something like this to Base? macro constant(varname, varvalue) tmp = eval(varvalue) quote for i in procs() @spawnat i global const $varname = $tmp end end end one could then simply broadcast a global const as follows: addprocs(1) @constant tmp1 "pooh" foo = "fooval" @constant tmp2 foo @constant tmp3 ARGS[1] @CorySimon CorySimon commented on Jan 9, 2015 A simple function to broadcast vars to all cores would be great! Someone wrote a sol'n here too http://stackoverflow.com/questions/27677399/julia-how-to-copy-data-to-another-processor-in-julia/27724240#27724240 @malmaud malmaud referenced this issue on Oct 16, 2015 Open Think about simplified scoping rules for parallel macros #13649 0 of 9 tasks complete @bjarthur bjarthur commented on Apr 19 local variables can be broadcast to remote workers by preceeding @everywhere with an @eval and interpolating the symbol of the local variable: julia> addprocs(1) 1-element Array{Int64,1}: 2 julia> foo=1 1 julia> @eval @everywhere bar=$foo julia> remotecall_fetch(()->bar,2) 1 julia> bar 1 shall we close this issue? @amitmurthy The Julia Language member amitmurthy commented on Apr 20 Lets document this and then close the issue. The difference in behavior between @spawnat and @everywhere is because @spawnat creates a closure that is then executed remotely while @everywhere ships the expression as is. @amitmurthy amitmurthy referenced this issue on Apr 20 Merged document use of @eval with @everywhere for broadcast of local variables. #15960 @amitmurthy amitmurthy closed this in #15960 on Apr 21