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.
>>
>

Reply via email to