2017-06-24 90 views
0

我的多處理需求非常簡單:我在機器學習中工作,有時需要評估多個數據集中的算法或數據集中的多個算法等。我只需要用一些參數運行一個函數並獲得一個數字。Julia等效於Python多處理.Pool.map

我不需要RPC,共享數據,什麼都沒有。

在朱莉婭,我得到一個錯誤與下面的代碼:

type Model 
    param 
end 

# 1. I have several algorithms/models 
models = [Model(i) for i in 1:50] 

# 2. I have one dataset 
X = rand(50, 5) 

# 3. I want to paralelize this function 
@everywhere function transform(m) 
    sum(X .* m.param) 
end 

addprocs(3) 
println(pmap(transform, models)) 

我不斷收到錯誤,比如,

ERROR: LoadError: On worker 2: 
UndefVarError: #transform not defined 

此外,有沒有辦法避免放置@everywhere到處?我能否告訴所有變量應在創建時複製到工作人員中(如Python multiprocessing中所做的那樣)?

我的典型代碼看起來顯然比這更復雜,模型包含幾個文件。

以供參考,這是我會在Python做:

import numpy as np 
import time 

# 1. I have several algorithms/models 
class Model: 
    def __init__(self, param): 
     self.param = param 
models = [Model(i) for i in range(1,51)] 

# 2. I have one dataset 
X = np.random.random((50, 5)) 

# 3. I want to paralelize this function 
def transform(m): 
    return np.sum(X * m.param) 

import multiprocessing 
pool = multiprocessing.Pool(4) 
print(pool.map(transform, models)) 

回答

3

核心問題是你需要添加你試圖對他們的定義的東西之前的過程。 addprocs應該始終是你在using之前做的第一件事(見下文)。 這就是爲什麼當您啓動茱莉亞時,通常會使用-p標誌。 或與---machinefile <file>with a -L <file>

@everywhere執行當前存在的所有進程上的代碼。 即在@everywhere之後添加的進程沒有在其上執行代碼。

此外,你錯過了一些@everywheres。

addprocs(3) 

@everywhere type Model 
    param 
end 

# 1. I have several algorithms/models 
models = [Model(i) for i in 1:50] 

# 2. I have one dataset 
@everywhere X = rand(50, 5) 

# 3. I want to paralelize this function 
@everywhere function transform(m) 
    sum(X .* m.param) 
end 

println(pmap(transform, models)) 

替代用更少的@everywhere秒。

使用塊發送的碼一整塊@everywhere

addprocs(3) 
@everywhere begin 
    type Model 
     param 
    end 

    X = rand(50, 5) 

    function transform(m) 
     sum(X .* m.param) 
    end 
end 

models = [Model(i) for i in 1:50] 

println(pmap(transform, models)) 

使用局部變量

局部變量(包括函數),按要求發送。 雖然這對類型沒有幫助。

addprocs(3) 

@everywhere type Model 
    param 
end 

function main() 
    X = rand(50, 5) 

    models = [Model(i) for i in 1:50] 

    function transform(m) 
     sum(X .* m.param) 
    end 

    println(pmap(transform, models)) 
end 

main() 

使用模塊

當你using Foo模塊Foo被加載上的所有進程。 但沒有納入範圍。 這有點奇怪,反直覺。 這麼多以至於我無法想象它的一個工作示例。 但其他人可能。

+0

「@everywhere X = rand(50,5)」不會在每個進程上產生唯一的數據集嗎? – rickhg12hs

+0

這個答案比我討價還價的要多。謝謝!我的困惑是認爲'addprocs()'會使用'fork()',它將淺色內存狀態複製到子進程。對於簡單的東西,我做簡單的POSIX範例很好。我會嘗試將我的代碼更改爲Julia的方法並回復給您。 –

+0

@ rickhg12hs從我的測試中,你是對的。這對我來說不是一個大問題,因爲我的數據集不是隨機生成的。與此同時,他們需要時間來加載......我想我會想要使用'SharedArray'或使用「我不喜歡的」局部變量,這是因爲對於我所做的工作,腳本/全局變量最好的工作。 –