I have a bunch of functions within a module. I want to make a function that uses various other functions within that module in parallel. The solution that works in the REPL is to addprocs for the number of cores I have and then use @everywhere using ModuleName. Within ModuleName however that does not work because there is an error "syntax: “toplevel” expression not a top level. A minimal working example is:
function do_manythings(Y::Array, num_cores::Integer)
@everywhere using ModuleName
squares = @distributed (vcat) for y in Y
export do_something, do_manythings
Potentially there is an issue that the compiler would like to see ModuleName in compiling this code but doesn’t have it yet (but I don’t really know how compilers work…).
What is the proper way to use the functions of a module within that same module? I would ideally like to do it so that a user of ModuleName specifies how many cores he/she has to use but does not have to know or do anything else to get it to run in parallel.
You can use @everywhere @eval Mod1 using Mod2 to evaluate using Mod2 in Mod1’s namespace on the remote worker. Note @eval ModuleName expr can generally be used to evaluate anything into another module.
Not sure I understand exactly what you mean, but basically its the same thing as how you can’t just put using Foo inside the body of a function. But you can @eval using Foo inside a function to execute that statement in the toplevel scope of the current module.
As I just learned trying to answer this, looks like @everywhere is smart and will look through your expression, grab any import or using statements, and do those first on the master process, before sending the statement to workers. But what happens when it does using Foo on the master is special, and described here, especially the very last sentence. Basically you precompile Foo (if necessary) on the master process, load it on the master, then load it on the workers (which will use the compile cache). In your case you will then also execute using Foo on the workers, which will just bring Foo into scope and be instantaneous as Foo was already loaded.