我有以下Julia函数,它接受一个输入数组并将其分配给可用的worker。
function DistributeArray(IN::Array,IN_symb::Symbol;mod=Main) # Distributes an array among workers
dim = length(size(IN))
size_per_worker = floor(Int,size(IN,1) / nworkers())
StartIdx = 1
EndIdx = size_per_worker
for (idx, pid) in enumerate(workers())
if idx == nworkers()
EndIdx = size(IN,1)
end
if dim == 3
@spawnat(pid, eval(mod, Expr(:(=), IN_symb, IN[StartIdx:EndIdx,:,:])))
elseif dim == 2
@spawnat(pid, eval(mod, Expr(:(=), IN_symb, IN[StartIdx:EndIdx,:])))
elseif dim == 1
@spawnat(pid, eval(mod, Expr(:(=), IN_symb, IN[StartIdx:EndIdx])))
else
error("Invalid dimensions for input array.")
end
StartIdx = EndIdx + 1
EndIdx = EndIdx + size_per_worker - 1
end
end
我在其他一些函数中调用此函数来分发数组。例如,这是一个测试函数:
function test(IN::Array,IN_symb::Symbol)
DistributeArray(IN,IN_symb)
@everywhere begin
if myid() != 1
println(size(IN))
end
end
end
我希望此功能可以使用' IN'在所有可用的worker中分配并分配它,然后打印分配给每个worker的大小。以下命令集(其中输入的名称与函数内使用的名称匹配)可正常工作:
addprocs(3)
IN = rand(27,33)
IN_symb = :IN
test(IN,IN_symb)
# From worker 2: (9,33)
# From worker 3: (8,33)
# From worker 4: (10,33)
但是,当我更改输入的名称以使它们与函数中使用的名称不同时,我收到错误(在运行follow命令之前启动新的julia会话):
addprocs(3)
a = rand(27,33)
a_symb = :a
test(a,a_symb)
ERROR: On worker 2:
UndefVarError: IN not defined
in eval at ./sysimg.jl:14
in anonymous at multi.jl:1378
in anonymous at multi.jl:907
in run_work_thunk at multi.jl:645
[inlined code] from multi.jl:907
in anonymous at task.jl:63
in remotecall_fetch at multi.jl:731
in remotecall_fetch at multi.jl:734
in anonymous at multi.jl:1380
...and 3 other exceptions.
in sync_end at ./task.jl:413
[inlined code] from multi.jl:1389
in test at none:2
我不明白导致此错误的原因。在我看来,函数没有使用我给他们的输入?
答案 0 :(得分:1)
在您的test()
函数中,您正在运行println(size(IN))
。因此,您正在查找名为IN
的特定对象的每个进程。但是,在第二个示例中,您要命名对象a
而不是IN
(因为您提供的符号是:a
)。您提供给DistributeArray()
函数的符号定义了对象在worker上的名称,因此这是您将来用于引用这些对象的名称。
您可以通过略微修改test()
功能来获得我认为您正在寻找的结果:
function test(IN::Array,IN_symb::Symbol)
DistributeArray(IN,IN_symb)
for (idx, pid) in enumerate(workers())
@spawnat pid println(size(eval(IN_symb)))
end
end
在我看来,@spawnat
有时可以更灵活一些,让您更好地指定您想要评估的表达式。