Confusing scoping rules under @distributed macro in julia

Viewed 75

I am trying to parallelize a code in Julia but ran into a weird scoping issue. I do not understand the scoping rules when passing a local variable to a function in the @distributed for loop. You get the expected behavior when executing the following code

using Distributed
addprocs(4)

@everywhere function k(x)
    println("x = ", x)
    return x
end

sumk = 0
sumk += @distributed (+) for i in 2:nprocs()
        k(myid())
    end
println("sumk = ", sumk)

Running this code gives

      From worker 4:    x = 4
      From worker 2:    x = 2
      From worker 3:    x = 3
      From worker 5:    x = 5
14

sumk = 14

Now, I modify the code a little bit to

using Distributed
addprocs(4)

@everywhere function k(x)
    println("x = ", x)
    return x
end

@everywhere x = myid()

sumk = 0
sumk += @distributed (+) for i in 2:nprocs()
        k(x)
    end
println("sumk = ", sumk)

which gives the following result upon execution:

      From worker 2:    x = 1
      From worker 4:    x = 1
      From worker 5:    x = 1
      From worker 3:    x = 1
4

sumk = 4

Here, I do not understand why myid() works locally but x is taken from the process 1 only.

Thank you for your help.

1 Answers

It looks like the right-hand side of the @everywhere macro is evaluated locally.

You could do:

remote_do.( Ref(()->global x = myid()), workers())

And now:

@distributed (+) for i in 2:nprocs()
               k(x)
           end
      From worker 3:    x = 3
      From worker 2:    x = 2
      From worker 5:    x = 5
      From worker 4:    x = 4
14
Related