多处理并行化距离计算方法



这个问题与我几天前发布的另一个问题有关;我已经阅读了这个关于multiprocessing用实例方法酸洗的问题。问题是,我不知道如何将提供的解决方案应用于我的案例:

def _pickle_method(method):
    # Author: Steven Bethard
    # http://bytes.com/topic/python/answers/552476-why-cant-you-pickle-instancemethods
    func_name = method.im_func.__name__
    obj = method.im_self
    cls = method.im_class
    cls_name = ''
    if func_name.startswith('__') and not func_name.endswith('__'):
        cls_name = cls.__name__.lstrip('_')
    if cls_name:
        func_name = '_' + cls_name + func_name
    return _unpickle_method, (func_name, obj, cls)
def _unpickle_method(func_name, obj, cls):
    # Author: Steven Bethard
    # http://bytes.com/topic/python/answers/552476-why-cant-you-pickle-instancemethods
    for cls in cls.mro():
        try:
            func = cls.__dict__[func_name]
        except KeyError:
            pass
        else:
            break
    return func.__get__(obj, cls)
copy_reg.pickle(types.MethodType, _pickle_method, _unpickle_method)
class Circle(Feature):
# Stuff...
    def __points_distance(self,points):
        xa = n.array([self.xc,self.yc]).reshape((1,2))
        d = n.abs(dist.cdist(points,xa) - self.radius)
        return d
def points_distance(self,points,pool=None):
    if pool:
        return pool.map(self.__points_distance,points)
    else:
        return self.__points_distance(points)

这会在运行以下程序时产生ValueError: XA must be a 2-dimensional array错误:

import tra.features as fts
import numpy as np
import multiprocessing as mp
points = np.random.random(size=(1000,2))
circle_points = np.random.random(size=(3,2))
feature = fts.Circle(circle_points)
pool = mp.Pool()
ds = feature.points_distance(points,pool=pool)

但它(显然(在做时有效

pool = None
ds = feature.points_distance(points,pool=pool)

有线索吗?

这与此不同(我检查了此实现(,因为该方法在实例化Circle类并调用其points_distance方法的另一个类中使用。在任何情况下,另一个区别是points_distance方法使用期望(n,2(形numpy.ndarrayscipy.spatial.distance.cdist。它在使用串行版本时有效,但在并行使用时会引发我提到的异常。我想cPickle传递的论点有一个警告。

我认为这里有很多困惑,所以我不确定我是否理解这个问题。

异常NameError: global name 'pool' is not defined不是由于酸洗问题,而是由于作用域问题。

该方法在其作用域中找不到pool。尝试通过将pool引用传递给该方法来修复它。

其他:

pool = mp.Pool(mp.cpu_count())

cpu_count()调用是多余的,因为池已经产生了与默认情况下的CPU一样多的工作线程。

传递给pool.mappoints数组的形状为(1000,2(。当pool.map将其拆分为points参数传递给__points_distance时,该数组只有形状(2,(。

在调用cdist之前,尝试将points.shape = (1, 2)添加到__points_distance的正文中。

pool变量是在Circle类之外定义的,因此points_distance() will be unable to find池`在其命名空间中:

向Circle或Feature添加一个接受pool的构造函数,并将要使用的池传递给RansacFeature,我假设它会为您实例化Circle

最新更新