2016-10-18 23 views
0

私はPythonでマルチプロセッシングを試みています。私はベクターを追加するコードを書いていますが、関数から出力を得ることができませんでした。 0ではなく、2Pythonマルチプロセッシングデータが正しく出力されない

from multiprocessing import Process 
import numpy as np 

numThreads = 16 
num = 16 

numIter = num/numThreads 

X = np.ones((num, 1)) 
Y = np.ones((num, 1)) 
Z = np.zeros((num, 1)) 

def add(X,Y,Z,j): 
    Z[j] = X[j] + Y[j] 

if __name__ == '__main__': 
    jobs = [] 
    for i in range(numThreads): 
    p = Process(target=add, args=(X, Y, Z, i,)) 
    jobs.append(p) 

    for i in range(numThreads): 
    jobs[i].start() 

    for i in range(numThreads): 
    jobs[i].join() 

    print Z[0] 

編集アウトどの意味、出力Zプリント:clockerのアドバイスを取り、これに私のコードを変更:

import multiprocessing 
import numpy as np 

numThreads = 16 
numRows = 32000 
numCols = 2 
numOut = 3 

stride = numRows/numThreads 

X = np.ones((numRows, numCols)) 
W = np.ones((numCols, numOut)) 
B = np.ones((numRows, numOut)) 
Y = np.ones((numRows, numOut)) 

def conv(idx): 
    Y[idx*stride:idx*stride+stride] = X[idx*stride:idx*stride+stride].dot(W) + B[idx*stride:idx*stride+stride] 

if __name__=='__main__': 
    pool = multiprocessing.Pool(numThreads) 
    pool.map(conv, range(numThreads)) 
    print Y 

と出力ではなくSaxpのYです。

+0

「出力できなかった」とはどういう意味ですか? –

答えて

0

最後の行が[2]の代わりに[0]を返す理由は、各プロセスがそれを変更する前にZの独立したコピーを作成することです(またはZ[j] - これについて完全にはわからないかもしれません)。いずれにしても、別のプロセスを実行すると、元のバージョンは変更されません。

代わりにthreading moduleを使用する場合、最後の行は実際に[2]を期待通りに返しますが、それは複数処理ではありません。

だから、multiprocessing.Poolを代わりに使用します。あなたの実験に完全に従えば、次のことができます:

In [40]: pool = multiprocessing.Pool() 
In [41]: def add_func(j): 
    ....:  return X[j] + Y[j] 
In [42]: pool = multiprocessing.Pool(numThreads) 
In [43]: pool.map(add_func, range(numThreads)) 
Out[43]: 
[array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.]), 
array([ 2.])] 

楽しくお楽しみください!

問題は、conv()関数が値を返さないという問題です。プロセスプールは値を取り出すためにX、B、Wのコピーを取得しますが、conv()内のYは起動される各プロセスに対してローカルです。 Yの新しい計算値を取得するには、このようなものを使用します:

def conv(idx): 
    Ylocal_section = X[idx*stride:idx*stride+stride].dot(W) + B[idx*stride:idx*stride+stride] 
    return Ylocal_section 

results = pool.map(conv, range(numThreads)) # then apply each result to Y 
for idx in range(numThreads): 
    Y[idx*stride:idx*stride+stride] = results[idx] 

を並列には本当に速い複雑得ることができ、この時点で私は、高速な2Dの畳み込みを行うことができ、既存のライブラリを評価します。 numpyおよびscipyライブラリは超効率的で、あなたのニーズをより良く満たすかもしれません。

+0

こんにちは、それほど問題がなければ、マルチプロセッシングがPythonでどのように機能するか説明できますか?でのように、 'range(numThreads) 'を使用すると、いくつかのデータセットでどのようにスケールされますか?私はC++ 11スレッドのような人です。 Pythonの構文はちょっと変わっています。 – ABCD

+0

の範囲(numThreads)は[0,1,2、... numThreads-1]に解決されます。ライン入力 'In [43]'は 'pool.map(add_func、[0,1,2,3、...、15])'と等価です。 map関数はPythonの標準ライブラリに書かれています。それは次のように翻訳されています: 'for i in range(numThreads):add_func(i)' – clocker

+0

こんにちは、私は畳み込みを使うようにデータを変更しました。同じエラーが表示されています。質問に掲載されたコード。 – ABCD

関連する問題