I'm puzzled by Julia behavior around loading modules when worker processes are used.
I need to use a rather heavy PyPlot module which takes a considerable amount of time to load. This program:
using PyPlot
pygui(true)
println("Loaded")
takes around 11 seconds to load on my laptop:
% time julia test.jl
INFO: Loading help data...
Loaded
julia test.jl 11,10s user 0,18s system 99% cpu 11,323 total
Note the INFO: Loading help data... line. It seems to be emitted by the PyPlot module as it does not appear if I omit using PyPlot line.
However, when I run this program:
using PyPlot
pygui(true)
@everywhere println("Loaded")
I get these results:
% time julia -p 4 test.jl
INFO: Loading help data...
INFO: Loading help data...
INFO: Loading help data...
INFO: Loading help data...
INFO: Loading help data...
Loaded
From worker 2: Loaded
From worker 5: Loaded
From worker 3: Loaded
From worker 4: Loaded
julia -p 4 test.jl 88,94s user 1,19s system 266% cpu 33,865 total
Not only it runs for whopping 33 seconds (three times longer!), but it also seems to load PyPlot module on every worker!
But I was sure that in order for module to be available on each worker, it has to be @everywhered! Indeed, this simple program crashes:
module Example
export x
x = 10
end
using Example
@everywhere println("x: $x")
Invocation:
% julia -p 4 test2.jl
x: 10
exception on 2: exception on exception on exception on 4: 5: 3: ERROR: x not defined
in eval at /usr/bin/../lib/julia/sys.so
ERROR: x not defined
in eval at /usr/bin/../lib/julia/sys.so
ERROR: x not defined
in eval at /usr/bin/../lib/julia/sys.so
ERROR: x not defined
in eval at /usr/bin/../lib/julia/sys.so
So why is PyPlot module loaded on all workers even if I didn't request it?
What's even more interesting, there is a workaround:
using PyPlot
pygui(true)
addprocs(4)
@everywhere println("Loaded")
When I run this program with julia test.jl, I get 15 seconds:
% time julia test.jl
INFO: Loading help data...
Loaded
From worker 2: Loaded
From worker 4: Loaded
From worker 5: Loaded
From worker 3: Loaded
julia test.jl 21,98s user 0,46s system 143% cpu 15,678 total
which is exactly what I'd have expected for the original version ran with julia -p 4 test.jl. But I don't like this workaround because it forces my program to use addprocs().
Is there a way to restrict module loading to the master process when Julia is started with -p X argument?