What exactly does @spawnat capture?

From the documents, I get the impression that the following statement

@spawnat 2 f(a, b)

will run if f is defined on the remote processes. @spawnat will capture the variable a and b automatically. However, this function/function arguments distinction seems rather weird to me. What will happen if a is also a function?

One example I am trying to play with is

using Distributed

@everywhere function do_work(f, jobs, results)
    while true
        x = take!(jobs)
        put!(results, f(x))

function parallel_sum(f, xs)
    s = 0.0
    njobs = length(xs)
    jobs = RemoteChannel(()->Channel{Float64}(njobs))
    results = RemoteChannel(()->Channel{Float64}(njobs))
    for i = 1:njobs
        put!(jobs, xs[i])
    for p in workers()
        @spawnat p do_work(f, jobs, results)
    finished_jobs = 0
    while finished_jobs < njobs
        s += take!(results)
        finished_jobs += 1
    return s

f(x) = exp(x)
xs = collect(1:10)
parallel_sum(f, xs)

I expect f to be sent to the remote process automatically, but it doesn’t. So what exactly does the document mean by “Create a closure around an expression and run the closure asynchronously on process p”?

1 Like