2011-01-13 13 views
35

私はPython(Scipy、Numpy)用のMATLABのparforに対する決定的な答えを探しています。Parfor for Python

parforに似たソリューションはありますか?そうでない場合、それを作成するための合併症は何ですか?

UPDATE:ここで私は

import numpy as np 

N = 2000 
output = np.zeros([N,N]) 
for i in range(N): 
    for j in range(N): 
     output[i,j] = HeavyComputationThatIsThreadSafe(i,j) 

に重い演算機能の一例をスピードアップする必要がある典型的な数値計算コードは次のとおりです。

import scipy.optimize 

def HeavyComputationThatIsThreadSafe(i,j): 
    n = i * j 

    return scipy.optimize.anneal(lambda x: np.sum((x-np.arange(n)**2)), np.random.random((n,1)))[0][0,0] 

答えて

16

Python frameworks for parallel computingが多数あります。私が一番気に入ったのはIPythonですが、他の人たちについてはあまりよく分かりません。 IPythonでは、parforの1つのアナログはclient.MultiEngineClient.map()であるか、the documentation on quick and easy parallelismの他の構文のいくつかです。

+1

+1私はIPythonを使用していますが、client.MultiEngineClientについて知りませんでした。操縦してくれてありがとう! –

+0

IPython並列計算フレームワークでスピードアップしたコードをスクリプトモードで実行できるかどうかはわかりません。つまり、ipythonを実行していません。 –

+0

@Dat Chu:もちろん可能です。プロンプトで入力するコマンドをPythonで実行するファイルに書きます。 (これはあなたが求めているものですか?) –

3

私はいつもParallel Pythonを使用しましたが、そうではありません私はそれが典型的に特定のオペレーティングシステムでは高価になる可能性のある別々のプロセスを使用すると信じて以来、完全なアナログです。それでも、あなたのループの本体がちょっとちょっと面白ければ、これは問題ではなく、実際にはいくつかの利点があります。

25

pythonに組み込まれているものは、multiprocessingの文書はhereです。私は常にmultiprocessing.Poolをプロセッサーと同じ数のワーカーに使用します。そして、私が使用するforループのような構造をする必要があるときはいつでも、Pool.imap

あなたの関数の本体が以前の反復に依存していない限り、ほぼ直線的なスピードアップが必要です。これにはまた、入力と出力がpickle可能である必要がありますが、これは標準タイプに対してはかなり簡単です。

UPDATE:あなたの更新機能のためのいくつかのコードは、ちょうどそれがいかに簡単かを示すために :例を表示するには

from multiprocessing import Pool 
from itertools import product 

output = np.zeros((N,N)) 
pool = Pool() #defaults to number of available CPU's 
chunksize = 20 #this may take some guessing ... take a look at the docs to decide 
for ind, res in enumerate(pool.imap(Fun, product(xrange(N), xrange(N))), chunksize): 
    output.flat[ind] = res 
+0

'output [ind]'を 'output.flat [ind]'に置き換えてコードを動作させるべきです。 ( 'output'は2次元配列で2つのインデックスが必要です) –

+0

@Sven:ありがと... matlabとpythonの間の切り替えが常にあります。 – JudoWill

2

Jupyterノート

あなたは、このMATLABコードの等価性を書きたい考えますPythonで

matlabpool open 4 
parfor n=0:9 
    for i=1:10000 
     for j=1:10000 
      s=j*i 
     end 
    end 
    n 
end 
disp('done') 

これはPythonで、特にjupyterノートで書くかもしれません。あなたは、作業ディレクトリ内の関数を作成する必要があります(私はFunForParFor.pyそれを呼ばれる)は、次の

def func(n): 
    for i in range(10000): 
     for j in range(10000): 
      s=j*i 
    print(n) 

を持っていたそれから私は、これは持っている

import multiprocessing 
import FunForParFor 

if __name__ == '__main__': 
    pool = multiprocessing.Pool(processes=4) 
    pool.map(FunForParFor.func, range(10)) 
    pool.close() 
    pool.join() 
    print('done') 

を私Jupyterノートブックに移動し、次のコードを記述します私のために働いた!私はちょうどあなたに特定の例を与えるためにここでそれを共有したいと思った。