2016-09-22 2 views
1

Ich versuche, einen multivariaten Fixpunkt-Iterationsalgorithmus mit Multiprocessing zu beschleunigen, aber ich habe Probleme mit gemeinsamen Daten. Mein Lösungsvektor ist eigentlich ein benanntes Wörterbuch und kein Vektor von Zahlen. Jedes Element des Vektors wird tatsächlich unter Verwendung einer anderen Formel berechnet. Auf einem hohen Niveau, ich habe ein Algorithmus wie folgt aus:Python Multiprocessing-Pool mit gemeinsamen Daten

current_estimate = previous_estimate 
while True: 
for state in all_states: 
    current_estimate[state] = state.getValue(previous_estimate) 
if norm(current_estimate, previous_estimate) < tolerance: 
    break 
else: 
    previous_estimate, current_estimate = current_estimate, previous_estimate 

Ich versuche, die for-Schleife Teil mit Multiprocessing parallelisieren. Die Variable previous_estimate ist schreibgeschützt und jeder Prozess muss nur auf ein Element current_estimate schreiben. Mein aktueller Versuch, die for-Schleife Umschreiben ist wie folgt:

# Class and function definitions 
class A(object): 
    def __init__(self,val): 
     self.val = val 

    # representative getValue function 
    def getValue(self, est): 
     return est[self] + self.val 

def worker(state, in_est, out_est): 
    out_est[state] = state.getValue(in_est) 

def worker_star(a_b_c): 
    """ Allow multiple arguments for a pool 
     Taken from http://stackoverflow.com/a/5443941/3865495 
    """ 
    return worker(*a_b_c) 

# Initialize test environment 
manager = Manager() 
estimates = manager.dict() 
all_states = [] 
for i in range(5): 
    a = A(i) 
    all_states.append(a) 
    estimates[a] = 0 

pool = Pool(process = 2) 
prev_est = estimates 
curr_est = estimates 
pool.map(worker_star, itertools.izip(all_states, itertools.repeat(prev_est), itertools.repreat(curr_est))) 

Das Problem, das ich zur Zeit in renne ist, dass die Elemente zum all_states Array hinzugefügt sind nicht die gleichen wie die in die manager.dict() hinzugefügt. Ich bekomme immer key value Fehler beim Versuch, Elemente des Wörterbuchs mit Elementen des Arrays zugreifen. Und beim Debuggen stellte ich fest, dass keines der Elemente gleich ist.

print map(id, estimates.keys()) 
>>> [19558864, 19558928, 19558992, 19559056, 19559120] 
print map(id, all_states) 
>>> [19416144, 19416208, 19416272, 19416336, 19416400] 

Antwort

1

Dies geschieht, weil die Objekte Sie in die estimatesDictProxy nicht wirklich die gleichen Objekte wie jene setzen, die in der regulären dict leben. Der manager.dict()-Aufruf gibt eine DictProxy zurück, die den Zugriff auf eine dict Proxy-Proxy ist, die tatsächlich in einem vollständig separaten Manager-Prozess lebt. Wenn Sie Dinge einfügen, werden sie wirklich kopiert und an einen Remote-Prozess gesendet, was bedeutet, dass sie eine andere Identität haben.

für Elemente in der estimates wird nur den Wert des val
class A(object): 
    def __init__(self,val): 
     self.val = val 

    # representative getValue function 
    def getValue(self, est): 
     return est[self] + self.val 

    def __hash__(self): 
     return hash(self.__key()) 

    def __key(self): 
     return (self.val,) 

    def __eq__(x, y): 
     return x.__key() == y.__key() 

Das bedeutet, die wichtigsten Look-Ups verwenden:

Um dies zu umgehen, können Sie Ihre eigenen __eq__ und __hash__ Funktionen auf A, wie described in this question definieren Attribut, um Identität und Gleichheit einzurichten, anstatt die von Python zugewiesene id.

Verwandte Themen