2015-03-18 3 views
1

Я пытаюсь распараллелить код с помощью методов класса с помощью многопроцессорной обработки. Базовая структура выглядит следующим образом:Python: (Pathos) Многопроцессорные методы против класса

# from multiprocessing import Pool 
from pathos.multiprocessing import ProcessingPool as Pool 

class myclass(object): 
    def __init__(self): 
     #some code 
    def mymethod(self): 
     #more code 
     return another_instance_of_myclass 



def myfunc(myinstance,args): 
    #some code 
    test=myinstance.mymethod() 
    #more code 
    return myresult #not an instance,just a number 

p=Pool() 

result = p.map(myfunc,listwithdata) 

После этого не удалось с нормальным многопроцессорной, я стало известно о проблемах с соленья и многопроцессорных, поэтому я попытался решить эту проблему с multiprocessing.pathos. Тем не менее, я до сих пор получаю

PicklingError: Can't pickle <type 'SwigPyObject'>: it's not found as__builtin__.SwigPyObjec 

вместе с множеством ошибок с pickle.py. Помимо этой практической проблемы, я не совсем понимаю, почему ничего, кроме конечного результата myfunc, вообще не маринуют.

+0

Кажется, что 'dill' не работает с Swig из коробки. См. [Этот вопрос] (http://stackoverflow.com/questions/9310053/how-to-make-my-swig-extension-module-work-with-pickle), который имеет решение для создания объектов Swig. Возможно, вы сможете использовать его. – dano

+0

Должен признаться, мне даже понадобился момент, чтобы узнать, откуда идет объект SwigPy (я сам не определял его). Оказывается, один из модулей, которые я использую, в свою очередь, использует числовые библиотеки, написанные на C. Копаем все это выглядит тяжело, но я попробую. – user4319496

ответ

0

Для многопроцессорной сериализации необходима межпроцессная связь. Для этой цели Pickle выполняет плохую работу, вместо этого устанавливайте dill. Детали (с хорошим примером Star Trek) можно найти здесь: http://matthewrocklin.com/blog/work/2013/12/05/Parallelism-and-Serialization/

+0

Спасибо за ссылку. По крайней мере, с примером «Звездного пути» я понимаю, почему методы нужно мариновать. Но в приведенном выше примере я уже использую pathos.multiprocessing, и все еще не удается. – user4319496

+0

@barrios: Я автор 'patos' и' dill'. OP правильный. 'pathos' использует' dill' из коробки. –

+0

извините, не знаю, знаю. – barrios

1

pathos использует dill и dill упорядочивает классы иначе, чем pickle модуль питона делает. pickle сериализует классы по ссылке. dill (по умолчанию) сериализует классы напрямую и только необязательно по ссылке.

>>> import dill 
>>> 
>>> class Foo(object): 
... def __init__(self, x): 
...  self.x = x 
... def bar(self, y): 
...  return self.x + y * z 
... z = 1 
... 
>>> f = Foo(2) 
>>> 
>>> dill.dumps(f) # the dill default, explicitly serialize a class 
'\x80\x02cdill.dill\n_create_type\nq\x00(cdill.dill\n_load_type\nq\x01U\x08TypeTypeq\x02\x85q\x03Rq\x04U\x03Fooq\x05h\x01U\nObjectTypeq\x06\x85q\x07Rq\x08\x85q\t}q\n(U\r__slotnames__q\x0b]q\x0cU\n__module__q\rU\x08__main__q\x0eU\x03barq\x0fcdill.dill\n_create_function\nq\x10(cdill.dill\n_unmarshal\nq\x11Uyc\x02\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00C\x00\x00\x00s\x0f\x00\x00\x00|\x00\x00j\x00\x00|\x01\x00t\x01\x00\x14\x17S(\x01\x00\x00\x00N(\x02\x00\x00\x00t\x01\x00\x00\x00xt\x01\x00\x00\x00z(\x02\x00\x00\x00t\x04\x00\x00\x00selft\x01\x00\x00\x00y(\x00\x00\x00\x00(\x00\x00\x00\x00s\x07\x00\x00\x00<stdin>t\x03\x00\x00\x00bar\x04\x00\x00\x00s\x02\x00\x00\x00\x00\x01q\x12\x85q\x13Rq\x14c__builtin__\n__main__\nh\x0fNN}q\x15tq\x16Rq\x17U\x01zq\x18K\x01U\x07__doc__q\x19NU\x08__init__q\x1ah\x10(h\x11Uuc\x02\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00C\x00\x00\x00s\r\x00\x00\x00|\x01\x00|\x00\x00_\x00\x00d\x00\x00S(\x01\x00\x00\x00N(\x01\x00\x00\x00t\x01\x00\x00\x00x(\x02\x00\x00\x00t\x04\x00\x00\x00selfR\x00\x00\x00\x00(\x00\x00\x00\x00(\x00\x00\x00\x00s\x07\x00\x00\x00<stdin>t\x08\x00\x00\x00__init__\x02\x00\x00\x00s\x02\x00\x00\x00\x00\x01q\x1b\x85q\x1cRq\x1dc__builtin__\n__main__\nh\x1aNN}q\x1etq\x1fRq utq!Rq")\x81q#}q$U\x01xq%K\x02sb.' 
>>> dill.dumps(f, byref=True) # the pickle default, serialize by reference 
'\x80\x02c__main__\nFoo\nq\x00)\x81q\x01}q\x02U\x01xq\x03K\x02sb.' 

Не сериализуется по ссылке гораздо более гибко. Однако в редких случаях лучше работать со ссылками (как это бывает, когда травление чего-то построено на SwigPyObject).

Я имею в виду (для ~ 2 лет), чтобы выставить флаг byref на номер dump звонок внутри pathos, но еще не сделали этого. Это должно быть довольно простое редактирование. Я только что добавил билет, чтобы сделать это: https://github.com/uqfoundation/pathos/issues/58. В то время как я нахожусь в нем, также должно быть легко открыть замену функций dump и load, которые pathos использует ... таким образом, вы можете использовать настроенные сериализаторы (т. Е. Расширять те, которые dill предоставляет или использовать какой-либо другой сериализатор).

+0

Отлично! Регулярно проверяйте свой билет и, конечно же, попробуйте его, как только будет сделано редактирование. – user4319496

Смежные вопросы