类方法内的并行循环调用了另一个类方法

时间:2019-06-01 18:40:06

标签: python class serialization pickle python-multiprocessing

这个问题与SO上的these other帖子有关,但是其中建议的解决方案似乎不适用于我的情况。简而言之,我的问题可以通过以下示例进行说明。我有一个Algebra类,其中的方法triPower旨在为固定(a+b+c)**n的许多n值计算三项式的幂,即a, b, c。为此,我想创建一个方法_triPower(a,b,c,n)并通过pool.map()将其传递给我的functools.partial(_triPower,...)函数,在此我修复a, b, c并保留n为唯一方法参数,因为我使用的是Python 2.7,并且map模块的multiprocessing只需要一个参数函数(否则请参阅this post)。代码如下:

from __future__ import division
import numpy as np
import functools as fntls
import multiprocessing as mp
import multiprocessing.pool as mppl

# A couple of classes introduced to allow multiple processes to have their own daemons (parallelization)
class NoDaemonProcess(mp.Process):
   # make 'daemon' attribute always return False
   def _get_daemon(self):
      return False
   def _set_daemon(self, value):
      pass
   daemon = property(_get_daemon, _set_daemon)

# We sub-class multiprocessing.pool.Pool instead of multiprocessing.Pool
# because the latter is only a wrapper function, not a proper class.
class MyPool(mppl.Pool):
    Process = NoDaemonProcess

# Sample class where I want a method to run a parallel loop
class Algebra(object):
    def __init__(self,offset):
        self.offset = offset

    def trinomial(self,a,b,c):
        return a+b+c

    def _triPower(self,a,b,c,n):
    """This is the method that I want to run in parallel from the next method"""
        return self.offset + self.trinomial(a,b,c)**n

    def triPower(self,n):
        pls = MyPool(4)
        vals = pls.map(fntls.partial(self._triPower,a=1.,b=0.,c=1.),n)
        print vals

# Testing
if __name__ == "__main__":
    A = Algebra(0.)
    A.triPower(np.arange(0.,10.,0.01))

以上操作无效,并产生错误(如this post所预期):

cPickle.PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed

因此,在同一篇文章之后,我尝试将_triPower定义为全局函数,即

def _triPower(alg,a,b,c,n):
"""This is the method that I want to run in parallel from the next method"""
    return alg.trinomial(a,b,c)**n 

,然后根据以下条件编辑Algebra.triPower(...)

    def triPower(self,n):
    pls = MyPool(4)
    vals = pls.map(fntls.partial(_triPower, alg=self, a=1., b=0., c=1.), n)
    print vals 

而后者却给出了一些奇怪的TypeError,例如:

TypeError: _triPower() got multiple values for keyword argument 'alg' 

另一方面,关于尝试使方法像VeryPicklableObject中那样由this other post进行序列化的建议似乎也行不通,并且该软件包目前已失效(截至05/2019)。那么我在做错什么,如何使我的计算并行运行?

0 个答案:

没有答案