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.

Reply via email to