Wait.... #6#v is the name of a variable? How is that possible? On 17 June 2015 at 14:25, David Gold <[email protected]> wrote:
> Actually, it seems that @sync is also responsible for setting the variable > #6#v equal to the return object of the call to Base.pfor and then returning > #6#v after calling Base.sync_end(). > > On Wednesday, June 17, 2015 at 8:22:08 AM UTC-4, David Gold wrote: >> >> Have you tried macroexpanding the expression? Doing so yields >> >> 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. >> >> On Wednesday, June 17, 2015 at 5:49:58 AM UTC-4, Daniel Carrera wrote: >>> >>> >>> On Wednesday, 17 June 2015 10:28:37 UTC+2, Nils Gudat wrote: >>>> >>>> I haven't used @everywhere in combination with begin..end blocks, I >>>> usually pair @sync with @parallel - see an example here >>>> <https://github.com/nilshg/LearningModels/blob/master/NHL/NHL_6_Bellman.jl>, >>>> where I've parallelized the entire nested loop ranging from lines 25 to 47. >>>> >>> >>> >>> Aha! Thanks. Copying your example I was able to produce this: >>> >>> N = 5 >>> tmp = SharedArray(Int, (N)) >>> >>> for i = 1:N >>> # Compute tmp in parallel # >>> @sync @parallel for j = (i + 1):N >>> tmp[j] = i * j >>> end >>> >>> # Consume tmp in serial # >>> for j = (i + 1):N >>> println(tmp[j]) >>> end >>> end >>> >>> >>> This seems to work correctly and gives the same answer as the serial >>> code. Can you help me understand how it works? What does "@sync @parallel" >>> do? I feel like I half-understand it, but the concept is not clear in my >>> head. >>> >>> Thanks. >>> >>> Daniel. >>> >> -- When an engineer says that something can't be done, it's a code phrase that means it's not fun to do.
