Parallel processing Julia:在worker之间分发数组时,函数内部的变量名需要与函数外部的名称匹配吗?
我有下面的Julia函数,它接受一个输入数组,并将其分配给可用的workerParallel processing Julia:在worker之间分发数组时,函数内部的变量名需要与函数外部的名称匹配吗?,parallel-processing,julia,symbols,Parallel Processing,Julia,Symbols,我有下面的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 EndId
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
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
我希望此函数获取“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)
但是,当我更改输入的名称,使其与函数中使用的名称不同时,会出现错误(在运行以下命令之前启动新的julia会话):
我不明白是什么导致了这个错误。在我看来,函数没有使用我给它们的输入?在函数
test()
中,您正在运行println(size(In))
。因此,您正在查看中名为的特定对象的每个进程。但是,在第二个示例中,您将对象命名为a
,而不是中的(因为您提供的符号是:a
)。您提供给distributarray()
函数的符号定义了对象将在worker上具有的名称,因此您将来将使用该名称来引用这些对象
不过,只要稍微修改一下test()
函数,就可以获得我认为您想要的结果:
function test(IN::Array,IN_symb::Symbol)
DistributeArray(IN,IN_symb)
@everywhere begin
if myid() != 1
println(size(IN))
end
end
end
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
有时可以更灵活一些,让您更好地指定希望它计算的表达式。@user6443519我承认,整个distributarray()
函数相当粗糙。有可能有更好的出路,我只是不知道。如果没有,我希望有。但是,这已经足够让我勉强维持我所需要的了。我打算写一些关于这方面的东西,在GitHub页面上为Julia查询人们,因为他们往往知识渊博。不过我还没找到时间。如果您愿意,您也可以尝试这样做。@user6443519当然,用于在工作人员之间移动数据的整个基础结构(如所述)非常粗糙,distributarray()
函数实际上并不比这更复杂,因为它在很大程度上基于这些原则。所以,在我的一小部分辩护中,这可能有点骇人,但似乎现在朱莉娅的很多类似的东西都是骇人的。