1

Je voudrais utiliser le multitraitement pour générer la matrice de transition d'une chaîne de Markov.Utilisation du multitraitement avec plusieurs valeurs de retour et dictionnaires ordonnés

La fonction generateKeys() génère un dictionnaire avec de nouveaux débits et un dictionnaire avec de nouvelles clés pour chaque état dans l'espace d'état après une transition.

from collections import OrderedDict 

def generateKeys(): 
    idxDict = OrderedDict() 
    rateDict = OrderedDict() 
    for key,state in stateDict.items():    
     newkeys,rates = transitionFunction(state)    
     idxDict[key] = newkeys 
     rateDict[key] = rates 
    return idxDict,rateDict 

La raison d'utiliser OrderedDict est ici que les clés se mélangent avec une dict régulière dans une étape suivante (Dans l'étape suivante, je concaténer les tableaux de numpy dans les dictionnaires et les stocker dans une coo_matrix clairsemée). Comme les clés du dictionnaire sont uniques, il devrait être possible d'exécuter generateKeys() en parallèle et de remplir plus rapidement les deux dictionnaires sur une machine multicœur.

J'ai examiné le paquet multiprocessing et quelques exemples, mais les exemples que j'ai vus étaient pour une seule valeur de retour et sans dictionnaires ordonnés. Je ne comprends pas encore vraiment comment l'appliquer dans mon environnement. Quelqu'un peut-il me montrer comment cela fonctionne?

+0

Si vous avez besoin pour maintenir l'ordre pour 'transitionFunction' appelle, le parallélisme est pas la voie à suivre .. – Cyrbil

+0

@Cyrbil Hmm, vous avez raison. Je vois déjà une solution de contournement pour cela en utilisant des dictionnaires réguliers et le tri par clés. – Forzaa

Répondre

2

Si transitionFunction peut appliquer vos états dans un ordre quelconque:

transitionFunction('A') 
transitionFunction('B') 

# is equivalent to 
transitionFunction('B') 
transitionFunction('A') 

Vous pouvez utiliser:

from multiprocessing import Pool, cpu_count 

p = Pool(cpu_count()) 
results = p.map(transitionFunction, stateDict.values()) 

results auront le même ordre que les valeurs de stateDict, vous pouvez construire votre dict avec:

idxDict = dict(zip(stateDict.keys(), i[0] for i in results)) 
rateDict = dict(zip(stateDict.keys(), i[1] for i in results)) 

Si transitionFunction peut pas appliquer vos états dans l'ordre, alors vous aurez des résultats imprévisibles ...

+0

Merci pour l'aide. Je pense que cela devrait résoudre mon problème. Maintenant, le problème suivant est que je ne peux pas appeler cela depuis une classe: 'p.map (self.transitionFunction, self.stateDict.values ​​())' renvoie l'erreur suivante: 'Can not pickle : recherche d'attribut __builtin __ .instancemethod failed'. – Forzaa

+0

Pour ce problème, reportez-vous au nombreux post le mentionnant déjà: http://stackoverflow.com/search?tab=votes&q=Can%27t%20pickle%20%3Ctype%20%27instancemethod%27%3E – Cyrbil

0

Il semble y avoir une solution pour partager un dictionnaire entre des processus indépendants. Regardez here pour une discription. À mon humble avis, il est le moyen le plus facile de gérer votre problème. Cependant, cette solution ne prend pas en charge OrderedDict. Donc, si vous pouvez trouver un moyen de le faire sans eux, cela fonctionnerait. Peut-être que vous pourriez passer/transformer vous dict ensuite dans la forme désirée.