I haven't used @everywhere in combination with begin..end blocks, I usually pair @sync with @parallel - see an example here, where I've parallelized the entire nested loop ranging from lines 25 to 47.
julia> macroexpand(:( for i = 1:N
@sync @parallel for j = (i + 1):N
tmp[j] = i * j
end
end ))
:(for i = 1:N # line 2:
begin # task.jl, line 342:
Base.sync_begin() # line 343:
#6#v = begin # multi.jl, line 1487:
Base.pfor($(Expr(:localize, :(()->begin # expr.jl, line 113:
begin # multi.jl, line 1460:
function (#7#lo::Base.Int,#8#hi::Base.Int) # multi.jl, line 1461:
for j = (i + 1:N)[#7#lo:#8#hi] # line 1462:
begin # line 3:
tmp[j] = i * j
end
end
end
end
end))),Base.length(i + 1:N))
end # line 344:
Base.sync_end() # line 345:
#6#v
end
end)It looks like @parallel does the work of setting up a properly formatted call to Base.pfor. In particular, it builds an Expr object with head :localize and argument a zero-arg anonymous function, and then passes the interpolation of that expression along with `Base.length(i + 1:N)` to Base.pfor. The body of the anonymous function declares another function with arguments `#7#lo`, `#8#hi`. The latter variables somehow annotate the delimiters of your inner loop, which gets reproduced inside the body of the declared function. I'm *guessing* that the anonymous function is used as a vehicle to pass the code of the annotated inner loop to Base.pfor without executing it beforehand. But I could be wrong.
Then @sync just wraps all the above between calls to `Base.sync_begin` and `Base.sync_end`.
I also should note I have zero experience with Julia's parallel machinery and am entirely unfamiliar with the internals of Base.pfor. I just enjoy trying to figure out macros.
julia> macro foo()
quote
v = 5
return v
end
end
julia> macroexpand(:( @foo ))
quote # none, line 3:
#15#v = 5 # line 4:
return #15#v
endjulia> v = gensym("v")
symbol("##v#8970")
julia> v
symbol("##v#8970")