2016-08-10 5 views
1

j'ai un objet pythonobjets python diffusion à l'aide mpi4py

<GlobalParams.GlobalParams object at 0x7f8efe809080> 

qui contient divers tableaux numpy, les valeurs des paramètres etc. que j'utilise dans diverses fonctions d'appel comme par exemple:

myParams = GlobalParams(input_script) #reads in various parameters from an input script and assigns these to myParams 
myParams.data #calls the data array from myParams 

I Je suis en train de paralléliser mon code et j'aimerais diffuser l'objet myParams afin qu'il soit disponible pour les autres processus fils. Je l'ai fait précédemment pour les tableaux individuels numpy, les valeurs, etc., sous la forme:

points = comm.bcast(points, root = 0) 

Cependant, je ne veux pas avoir à le faire individuellement pour tout le contenu de myParams. Je voudrais diffuser l'objet dans son intégralité afin qu'il puisse être consulté sur d'autres cœurs. J'ai essayé l'évidence:

myParams = comm.bcast(myParams, root=0) 

mais renvoie l'erreur:

myParams = comm.bcast(myParams, root=0) 
    File "MPI/Comm.pyx", line 1276, in mpi4py.MPI.Comm.bcast (src/mpi4py.MPI.c:108819) 
    File "MPI/msgpickle.pxi", line 612, in mpi4py.MPI.PyMPI_bcast (src/mpi4py.MPI.c:47005) 
    File "MPI/msgpickle.pxi", line 112, in mpi4py.MPI.Pickle.dump (src/mpi4py.MPI.c:40704) 
TypeError: cannot serialize '_io.TextIOWrapper' object 

Quelle est la bonne façon de partager cet objet avec les autres noyaux? C'est probablement une exigence courante dans python, mais je ne trouve aucune documentation à ce sujet. La plupart des exemples concernent la diffusion d'une seule variable/matrice.

Répondre

0

Cela ne ressemble pas à un problème MPI; cela ressemble à un problème avec la sérialisation des objets pour la diffusion, qui utilise en interne le module Pickle.

Spécifiquement dans ce cas, il ne peut pas sérialiser un _io.TextIOWrapper - donc je suggère de traquer là où dans votre classe c'est utilisé. Une fois que vous avez déterminé quels champs ne peuvent pas être sérialisés, vous pouvez les supprimer, les diffuser, puis les réassembler sur chaque rang, en utilisant une méthode que vous devez concevoir vous-même (recreateUnpicklableThing() dans l'exemple ci-dessous) . Vous pouvez le faire en ajoutant ces méthodes à votre classe pour Pickle appeler avant et après la diffusion:

def __getstate__(self): 
    members = self.__dict__.copy() 
    # remove things that can't be pickled, using its name 
    del members['someUnpicklableThing'] 
    return members 

def __setstate__(self, members): 
    self.__dict__.update(members) 
    # On unpickle, manually recreate the things that you couldn't pickle 
    # (this method recreates self.someUnpickleableThing using some metadata 
    # carefully chosen by you that Pickle can serialise). 
    self.recreateUnpicklableThing(self.dataForSettingUpSometing) 

Voir ici pour en savoir plus sur la façon dont ces méthodes fonctionnent https://docs.python.org/2/library/pickle.html