2011-01-13 7 views
35

Ich bin auf der Suche nach einer endgültigen Antwort auf MATLAB Parfor für Python (Scipy, Numpy).Parfor für Python

Gibt es eine ähnliche Lösung wie Parfor? Wenn nicht, was ist die Komplikation für die Erstellung eines?

UPDATE: Hier ist eine typische numerische Berechnung Code, den ich beschleunigen muss

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) 

Ein Beispiel für eine schwere Berechnungsfunktion bildet:

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] 

Antwort

16

Es gibt viele Python frameworks for parallel computing. Der eine, den ich am meisten mag, ist IPython, aber ich weiß nicht viel über die anderen. In IPython wäre ein Analog zu Parfor client.MultiEngineClient.map() oder einige der anderen Konstrukte in the documentation on quick and easy parallelism.

+1

+1 Ich wusste nicht über Client.MultiEngineClient, obwohl ich IPython verwenden. Danke für den Steuer! –

+0

Es ist mir nicht klar, ob ich einen Code mit IPython parallelen Computer-Framework im Skript-Modus beschleunigt, d. H. Nicht durch ipython läuft. –

+0

@Dat Chu: Natürlich können Sie. Schreiben Sie einfach die Befehle, die Sie an der Eingabeaufforderung eingeben würden, in eine Datei und führen Sie sie mit Python aus. (Ist es das, wonach du fragst?) –

3

ich immer Parallel Python verwendet habe, aber es ist nicht ein vollständiges Analog, da ich glaube, dass es typischerweise separate Prozesse verwendet, die auf bestimmten Betriebssystemen teuer sein können. Dennoch, wenn der Körper Ihrer Schleifen klobig genug ist, dann ist dies egal und kann tatsächlich einige Vorteile haben.

25

Die in Python integrierte wäre multiprocessing Dokumente sind here. Ich benutze immer multiprocessing.Pool mit so vielen Arbeitern wie Prozessoren. Wann immer ich eine for-loop-ähnliche Struktur brauche, verwende ich Pool.imap

Solange der Körper Ihrer Funktion nicht von einer vorherigen Iteration abhängt, dann sollten Sie fast lineare Beschleunigung haben. Dies erfordert auch, dass Ihre Ein- und Ausgänge pickle -fähig sind, aber dies ist ziemlich einfach für Standardtypen zu gewährleisten.

UPDATE: Einige Code für Ihre aktualisierte Funktion nur um zu zeigen, wie einfach es ist:

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

Sie sollten 'output [ind]' durch 'output.flat [ind]' ersetzen, damit der Code funktioniert. ('output' ist ein zweidimensionales Array und würde zwei Indizes benötigen.) –

+0

@Sven: Danke ... das kommt von einem Wechsel zwischen Matlab und Python die ganze Zeit. – JudoWill

2

Jupyter Notebook

ein Beispiel zu sehen, betrachten Sie die Gleichwertigkeit dieser Matlab-Code schreiben wollen in 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') 

Die Art, wie man dies in Python vor allem in jupyter Notebook schreiben kann. Sie haben eine Funktion im Arbeitsverzeichnis erstellen (Ich nannte es FunForParFor.py), das folgende

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

Dann muss ich meine Jupyter Notebook gehen und schreiben Sie den folgenden Code

import multiprocessing 
import FunForParFor 

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

Dies hat hat für mich gearbeitet! Ich wollte es hier nur teilen, um Ihnen ein besonderes Beispiel zu geben.

Verwandte Themen