Thank you very much! You are correct, indeed the matrices created by @spawant are never used by pmap. Furthermore, and this is something I was missing before, both @everywhere, @spawnat and sendto from ParallelDataTransfer.jl, when called from inside a function, define A not in the function local scope, but in Main.
This example shows this. I defined a module:
module run_h
using Distributed, Random, LinearAlgebra, ParallelDataTransfer
export run_h_check
function h!(mat, x)
println("Matrix inside pmap ", myid(), " A=", mat)
return eigvals(rand!(MersenneTwister(x), mat))
end
function run_h_check(n, iter)
A = zeros(n, n) # initialized A
println("original A")
println(A)
sendto(workers(), A = A) # make A available to other processes, this actually exports A to Main
@everywhere workers() A[1, 1] = myid()
println("Check that A was modified in the workers")
@everywhere workers() println(A)
println("Pmap...")
return pmap(x->h!(A, x), iter)
end
end
And then I run fro IJulia:
using Distributed
addprocs(4)
@everywhere include("run_h.jl")
@everywhere using .run_h
run_h_check(2, 1:5)
which returns:
original A
[0.0 0.0; 0.0 0.0]
Check that A was modified in the workers
From worker 3: [3.0 0.0; 0.0 0.0]
From worker 5: [5.0 0.0; 0.0 0.0]
From worker 2: [2.0 0.0; 0.0 0.0]
From worker 4: [4.0 0.0; 0.0 0.0]
Pmap...
From worker 4: Matrix inside pmap 4 A=[0.0 0.0; 0.0 0.0]
From worker 5: Matrix inside pmap 5 A=[0.0 0.0; 0.0 0.0]
From worker 3: Matrix inside pmap 3 A=[0.0 0.0; 0.0 0.0]
From worker 2: Matrix inside pmap 2 A=[0.0 0.0; 0.0 0.0]
From worker 4: Matrix inside pmap 4 A=[0.0 0.0; 0.0 0.0]
5-element Array{Array{Float64,1},1}:
[0.470351, -0.226408]
[0.191387, 0.994748]
[-0.00607352, 1.78786]
[-0.102802, 1.71222]
[0.191155, 1.22056]
Indeed, inside the pmap, only the original A=[0.0 0.0; 0.0 0.0] is used. I can then check that sendto
actually moved the matrix A to Main. If I run:
@everywhere workers() println(Main.A)
I get:
From worker 4: A= [4.0 0.0; 0.0 0.0]
From worker 2: A= [2.0 0.0; 0.0 0.0]
From worker 3: A= [3.0 0.0; 0.0 0.0]
From worker 5: A= [5.0 0.0; 0.0 0.0]
But if I simply run:
println(Main.A)
, I obtain the error UndefVarError: A not defined
, since A
was not exported to Main of process 1.
I wasn’t expecting for the matrix A to be automatially made available to all processes in pmap. This is probably the same behaviour that is discussed in @everywhere and pmap inside of a function?
Once again, thank you very much tanhevg! This was really useful!