2017-05-09 2 views
2

Ich muss einen Multiprocessing-Pool implementieren, der beliebige Pakete für Berechnungen verwendet. Dazu benutze ich Python und joblib 0.9.0. Dieser Code ist im Grunde die Struktur, die ich möchte.Python Multiprocessing-Pool-Funktion nicht definiert

import numpy as np 
from joblib import pool 

def someComputation(x): 
    return np.interp(x, [-1, 1], [-1, 1]) 

if __name__ == '__main__': 
    some_set_of_numbers = [-1,-0.5,0,0.5,1] 
    the_pool = pool.Pool(processes=2) 
    solutions = [the_pool.apply_async(someComputation, (x,)) for x in some_set_of_numbers] 
    print(solutions[0].get()) 

Auf beide 10 Windows- und Red Hat Enterprise Linux Anaconda 4.3.1 Python 3.6.0 (sowie 3.5 und 3.4 mit virtueller ENVs), erhalte ich, dass 'np' nie in die someComputation übergeben wurde () gibt den Fehler

File "C:\Anaconda3\lib\site-packages\multiprocessing_on_dill\pool.py", line 608, in get 
    raise self._value 
NameError: name 'np' is not defined 

jedoch auf meinem Mac OS X 10.11.6 läuft Python 3.5 und die gleiche JOBLIB, erhalten ich die erwartete Ausgabe von ‚-1‘ mit dem exakt gleichen Code zu erhöhen. This Frage ist im Wesentlichen das Gleiche, aber es ging um Pathos und nicht Joblib. Die allgemeine Antwort war die numpy Import-Anweisung innerhalb der Funktion

from joblib import pool 

def someComputation(x): 
    import numpy as np 
    return np.interp(x, [-1, 1], [-1, 1]) 

if __name__ == '__main__': 
    some_set_of_numbers = [-1,-0.5,0,0.5,1] 
    the_pool = pool.Pool(processes=2) 
    solutions = [the_pool.apply_async(someComputation, (x,)) for x in some_set_of_numbers] 
    print(solutions[0].get()) 

Dies löst das Problem auf den Windows-und Linux-Maschinen gehört, wo sie jetzt Ausgabe ‚-1‘ wie erwartet, aber diese Lösung scheint klobig. Gibt es irgendeinen Grund? warum das erste Bit Code würde auf einem Mac funktionieren, aber nicht Windows oder Linux? Ich muss schließlich diesen Code auf dem Linux-Rechner laufen lassen, also gibt es irgendeine Reparatur, die die Importanweisung nicht innerhalb der Funktion einschließt?

Edit:

Nach ein bisschen weiter zu untersuchen, ich eine alte Abhilfe fand ich vor Jahren gestellt, die aussieht wie das Problem verursacht. In JOBLIB/pool.py änderte I Leitung 44 von

from multiprocessing.pool import Pool 

zu

from multiprocessing_on_dill.pool import Pool 

Beizen von beliebigen Funktionen zu unterstützen. Aus irgendeinem Grund verursacht diese Änderung wirklich das Problem unter Windows und Linux, aber der Mac-Computer läuft gut. Die Verwendung von Multiprocessing anstelle von multiprocessing_on_dill löst das oben genannte Problem, aber der Code funktioniert in den meisten Fällen nicht, da sie nicht gebeizt werden können.

+0

Nicht sicher, ob dies Ihre Frage beantwortet, aber ein besserer Weg, als den Import in die Funktion zu setzen wäre, deklarieren Sie es als 'def someComputation (x, np = np):'. Dies sollte das Modul bei der ersten Interpretation an einen lokalen Namen innerhalb der Funktion binden, so dass die Import-Maschinerie nicht jedes Mal ausgeführt werden muss. –

+0

Das funktioniert gut und ich kann es sicherlich verwenden, bis wir das eigentliche Problem herausfinden. –

Antwort

1

Ich bin mir nicht sicher, was das genaue Problem ist, aber es scheint, dass es ein Problem mit der Übertragung des globalen Bereichs auf die Unterprozesse gibt, die die Aufgabe ausführen. Sie können möglicherweise Namen Fehler vermeiden, indem Sie den Namen np als Funktionsparameter Bindung:

def someComputation(x, np=np): 
    return np.interp(x, [-1, 1], [-1, 1]) 

Dies hat den Vorteil, dass sie einen Aufruf an die Importmaschinerie jedes Mal, wenn die Funktion ausgeführt wird, erforderlich ist. Der Name np wird an die Funktion gebunden, wenn sie beim Laden des Moduls zuerst ausgewertet wird.