Parallel processing Julia:在worker之间分发数组时,函数内部的变量名需要与函数外部的名称匹配吗?

Parallel 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

我有下面的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
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()
函数实际上并不比这更复杂,因为它在很大程度上基于这些原则。所以,在我的一小部分辩护中,这可能有点骇人,但似乎现在朱莉娅的很多类似的东西都是骇人的。