Error calling remotecall_fetch from module


#1

I had similar code working on v0.4, but now fails on v0.5

module TestModule
    export test1, test2, test3
    test1(id) = remotecall_fetch(myid, id)
    test2(id) = remotecall_fetch(()->VERSION, id)
    test3(id) = remotecall_fetch(eval, id, :(Sys.CPU_CORES))
end

using TestModule
addprocs(2)

test1(2)   # works
test2(2)   # error
test3(2)   # error

And here’s the output:

julia> test1(2)
2

julia> test2(2)
ERROR: On worker 2:
UndefVarError: TestModule not defined
 in deserialize at .\serialize.jl:602
 in handle_deserialize at .\serialize.jl:581
 in deserialize at .\serialize.jl:541
 in deserialize_datatype at .\serialize.jl:822
 in handle_deserialize at .\serialize.jl:571
 in deserialize_msg at .\multi.jl:120
 in message_handler_loop at .\multi.jl:1317
 in process_tcp_streams at .\multi.jl:1276
 in #620 at .\event.jl:68
 in #remotecall_fetch#608(::Array{Any,1}, ::Function, ::Function, ::Base.Worker) at .\multi.jl:1070
 in remotecall_fetch(::Function, ::Base.Worker) at .\multi.jl:1062
 in #remotecall_fetch#611(::Array{Any,1}, ::Function, ::Function, ::Int64) at .\multi.jl:1080
 in test2(::Int64) at .\REPL[1]:4

julia> test3(2)
ERROR: On worker 2:
UndefVarError: ##1#2 not defined
 in deserialize_datatype at .\serialize.jl:823
 in handle_deserialize at .\serialize.jl:571
 in deserialize_msg at .\multi.jl:120
 in message_handler_loop at .\multi.jl:1317
 in process_tcp_streams at .\multi.jl:1276
 in #620 at .\event.jl:68
 in #remotecall_fetch#608(::Array{Any,1}, ::Function, ::Function, ::Base.Worker) at .\multi.jl:1070
 in remotecall_fetch(::Function, ::Base.Worker) at .\multi.jl:1062
 in #remotecall_fetch#611(::Array{Any,1}, ::Function, ::Function, ::Int64) at .\multi.jl:1080
 in test3(::Int64) at .\REPL[1]:5

Why is it failing?


#2

The example code gives the same error on 0.4, for the same reason: the code must be loaded on remote workers. A simple fix is:

@everywhere module TestModule
...
end

(note: run @everywhere after addprocs!)

Please see the manual for more options and examples.


#3

Yes, it does give same error on 0.4. I apologise I should have checked first.
In trying to create a minimal working example I’ve obviously removed something relevant.

I have seen @everywhere using Module but for some reason I didn’t need this in my case (on v0.4)
But I did have using Module after addprocs()
Another difference was that Module was defined in a file in LOAD_PATH.

So I’m a bit confused about why it worked on v0.4. I’ll do some more investigating.

To help my understanding, in the example above, why does TestModule need to be loaded on remote workers?
It seems there isn’t anything in TestModule required on remote workers.


#4

Anonymous functions are still referenced by enclosing module – look at @code_lowered test2(2). Likewise for the 3rd one: eval == TestModule.eval.


#5

Thanks! This is very helpful.

For the above, I can do the following using Core.eval and everything works without requiring TestModule on workers.

module TestModule
    export test1, test2, test3
    test1(id) = remotecall_fetch(myid, id)
    test2(id) = remotecall_fetch(Core.eval, id, :VERSION)
    test3(id) = remotecall_fetch(Core.eval, id, Sys, :CPU_CORES)
end

using TestModule
addprocs(2)

test1(2)
test2(2)
test3(2)