1

我将相同的功能应用于多个独立的对象,我想并行执行。问题是函数修改了它的一个参数。这适用于地图,但不适用于 pmap。这是一个最小的可重现示例:

@everywhere function testmod!(a,μ)
    for i=1:length(a)
        a[i]=i*μ
    end
    b=copy(a)
    return b
end

myarrays=[zeros(Float64,10) for i=1:10]
pmap((a1,a2)->testmod!(a1,a2),myarrays,[i for i=1:10])

这个玩具函数修改了输入数组 a 的元素。我将比较map和pmap的结果:

地图

julia> myarrays=[zeros(Float64,10) for i=1:10]
10-element Array{Array{Float64,1},1}:
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]

julia> map((a1,a2)->testmod!(a1,a2),myarrays,[i for i=1:10])
10-element Array{Array{Float64,1},1}:
 [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0]          
 [2.0,4.0,6.0,8.0,10.0,12.0,14.0,16.0,18.0,20.0]     
 [3.0,6.0,9.0,12.0,15.0,18.0,21.0,24.0,27.0,30.0]    
 [4.0,8.0,12.0,16.0,20.0,24.0,28.0,32.0,36.0,40.0]   
 [5.0,10.0,15.0,20.0,25.0,30.0,35.0,40.0,45.0,50.0]  
 [6.0,12.0,18.0,24.0,30.0,36.0,42.0,48.0,54.0,60.0]  
 [7.0,14.0,21.0,28.0,35.0,42.0,49.0,56.0,63.0,70.0]  
 [8.0,16.0,24.0,32.0,40.0,48.0,56.0,64.0,72.0,80.0]  
 [9.0,18.0,27.0,36.0,45.0,54.0,63.0,72.0,81.0,90.0]  
 [10.0,20.0,30.0,40.0,50.0,60.0,70.0,80.0,90.0,100.0]

julia> myarrays
10-element Array{Array{Float64,1},1}:
 [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0]          
 [2.0,4.0,6.0,8.0,10.0,12.0,14.0,16.0,18.0,20.0]     
 [3.0,6.0,9.0,12.0,15.0,18.0,21.0,24.0,27.0,30.0]    
 [4.0,8.0,12.0,16.0,20.0,24.0,28.0,32.0,36.0,40.0]   
 [5.0,10.0,15.0,20.0,25.0,30.0,35.0,40.0,45.0,50.0]  
 [6.0,12.0,18.0,24.0,30.0,36.0,42.0,48.0,54.0,60.0]  
 [7.0,14.0,21.0,28.0,35.0,42.0,49.0,56.0,63.0,70.0]  
 [8.0,16.0,24.0,32.0,40.0,48.0,56.0,64.0,72.0,80.0]  
 [9.0,18.0,27.0,36.0,45.0,54.0,63.0,72.0,81.0,90.0]  
 [10.0,20.0,30.0,40.0,50.0,60.0,70.0,80.0,90.0,100.0]

这可以按需要工作。对比pmap:

地图

julia> myarrays=[zeros(Float64,10) for i=1:10]
10-element Array{Array{Float64,1},1}:
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]

julia> pmap((a1,a2)->testmod!(a1,a2),myarrays,[i for i=1:10])
10-element Array{Any,1}:
 [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0]          
 [2.0,4.0,6.0,8.0,10.0,12.0,14.0,16.0,18.0,20.0]     
 [3.0,6.0,9.0,12.0,15.0,18.0,21.0,24.0,27.0,30.0]    
 [4.0,8.0,12.0,16.0,20.0,24.0,28.0,32.0,36.0,40.0]   
 [5.0,10.0,15.0,20.0,25.0,30.0,35.0,40.0,45.0,50.0]  
 [6.0,12.0,18.0,24.0,30.0,36.0,42.0,48.0,54.0,60.0]  
 [7.0,14.0,21.0,28.0,35.0,42.0,49.0,56.0,63.0,70.0]  
 [8.0,16.0,24.0,32.0,40.0,48.0,56.0,64.0,72.0,80.0]  
 [9.0,18.0,27.0,36.0,45.0,54.0,63.0,72.0,81.0,90.0]  
 [10.0,20.0,30.0,40.0,50.0,60.0,70.0,80.0,90.0,100.0]

julia> myarrays
10-element Array{Array{Float64,1},1}:
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]
 [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0]

显然 myarray 没有被修改。有什么方法可以用 pmap 实现这一点,或者你只能用 pmap 返回东西。

4

1 回答 1

3

首先是没有必要做(a1,a2)->testmod!(a1,a2),你可以通过testmod!

IE。pmap(testmod!,myarrays,[i for i=1:10])

其次,在这两种情况下都不使用返回值。您只是在第一个 ( map) 示例中修改了数组。在pmap示例中,必须将数组复制到每个工作进程,因此它只在工作进程本身上被修改。

重要的是mapor pmap(以及使用它们的预期方式)是每个函数返回的值(这是相同的)。

myarray如果您没有任何工作进程,您可能会注意到使用 pmap 时会发生变化。这是因为数组没有复制到任何地方,所有修改都是在本地完成的。

也许您可以使用 aSharedArray来实现您想要的,或者重组您的示例,以便您的最终目标更加清晰。

tl;dr -- pmap 可以修改它的参数,但结果可能不是你所期望的。

于 2016-02-18T20:07:00.977 回答