Define a function on a remote process only

I am trying to run a job on a remote process. But the job function will not be run on the main process, so I try to avoid defining it on main process. However, it seems impossible to define a function on a child process if it is not defined on main process first. I am wondering if it is intentional and why.

A minimum example is

using Distributed

pid = addprocs(1)[1]

ex = :(
    function foo()
        println("HI from foo!")
    end
)
# Everything will be fine if I call `eval(ex)` here
Distributed.remotecall_eval(Main, pid, ex)

An error is thrown: LoadError: UndefVarError: #foo not defined

If I call eval(ex) as stated in the comment, it will define the function on main process and works just like @everywhere. I understand that it is recommended way, but I do want to know why the example does not work.

The example is tested on Julia 1.6, windows 10.

The error stems from the fact that defining a function also gives a return value which is the function itself:

julia> function foo()
           println("HI from foo!")
       end
foo (generic function with 1 method)

so when you evaluate the function definition on the remote, it defines the function just fine, but then the return value tries to get sent back to the master process, which fails since foo isn’t defined there. You can just suppress the return value and do something like:

@everywhere pid begin
    function foo()
        println("HI from foo!")
    end
    nothing
end

(note also the @everywhere macro takes an optional pid argument so you can use the macro form)

1 Like

Many thanks!

1 Like