4

In a parallel application mimicking distributed inference, I would like to have an "initialization step" where all the "slaves" receive some initial information from the "master" then start their task.

At the moment I have a working implementation based on the sendTo function (the code was found here on stack overflow) but I don't think it guarantees that the worker won't start its task before it has received the initial objects.

Here's a rough MWE

function sendTo(p::Int; args...)
    for (nm, val) in args
        @spawnat(p, eval(Main, Expr(:(=), nm, val)))
    end
end

a = 5

addprocs(4)

[sendTo(worker,a=a+randn()) for worker in workers()]

@everywhere begin
    println(a)
end

The above "works" but how can I be sure that the commands in the @everywhere block does not get executed before the worker has received the definition of a?

Rmk: for the context I'm working in, I would like to keep two distinct blocks, one that spreads the data and one that does stuff on it.

Other rmk: apologies if this is trivial, I'm quite new to dealing with parallelism (and quite new to Julia too)

Community
  • 1
  • 1
tibL
  • 287
  • 2
  • 8
  • 1
    You may also be interested in this question (http://stackoverflow.com/questions/37287020/how-and-when-to-use-async-and-sync-in-julia/37287021#37287021) which discusses the operation of the `@sync` and `@async` macros and how they can be used to accomplish the types of tasks you are interested in. – Michael Ohlrogge May 19 '16 at 15:05

1 Answers1

5

you can just fetch the results for every process. See the example in the docs

function sendTo(p::Int; args...)
    r = []
    for (nm, val) in args
        s = @spawnat(p, eval(Main, Expr(:(=), nm, val)))
        vcat([s],r)
    end
end
#...
[fetch(r) for r in [sendTo(worker,a=a+randn()) for worker in workers()]]
Felipe Lema
  • 2,700
  • 12
  • 19
  • This does accomplish the goal. But isn't there any easier way to do it without this need to add in this extra set of fetching? I had initially thought that the sync macro would work, but I haven't actually managed to get it to work. Perhaps this is just a feature request for a more straightforward way to accomplish this with a macro like sync, if one doesn't exist now. – Michael Ohlrogge May 15 '16 at 17:49
  • If I get you correctly, that would mean that each call would have to request-and-fetch synchronously, making it worthless to do it with multiple processes (actually running in single process/thread would be better since you would be not spending time in overheads) – Felipe Lema May 16 '16 at 12:51
  • [`@sync`](http://docs.julialang.org/en/latest/stdlib/parallel/#Base.@sync) __waits__ for the expresion (that being `@async sendTo(...)`, which includes a `@spawnat`) is completed. You're doing the loop synchronously (there are never two workers working at the same time) – Felipe Lema May 17 '16 at 19:57
  • Ok, thank you! I realized that perhaps I shouldn't be asking questions in the comments section (saw this on a Meta post) and thus moved my query to this page: http://stackoverflow.com/questions/37287020/how-and-when-to-use-async-and-sync/37287021#37287021 I'd welcome any comments, corrections, suggestions, etc. you have! – Michael Ohlrogge May 17 '16 at 22:11