朱莉娅:pmap可以修改参数吗?

时间:2016-02-18 16:28:36

标签: parallel-processing julia pmap

我将相同的函数应用于多个独立对象,我想并行执行。问题是函数修改了它的一个参数。这适用于地图但不适用于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:

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返回东西。

1 个答案:

答案 0 :(得分:3)

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

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

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

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

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

也许你可以利用SharedArray来实现你想要的,或重组你的榜样,这样你的最终目标就会更加明确。

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