多进程并行距离计算方法
Parallelize distance calculation method with multiprocessing
此问题与 I posted days ago; I've read this question 有关 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)
有什么线索吗?
这与 (I checked this 实现不同)因为该方法在另一个 class 中使用,它实例化 Circle
class 并调用它的 points_distance
方法.在任何情况下,另一个区别是 points_distance
方法使用 scipy.spatial.distance.cdist
期望 (n,2)-shaped numpy.ndarray
。它在使用串行版本时有效,但在并行使用时引发我提到的异常。我想有一个关于 cPickle 传递参数的警告。
我觉得这里有点混乱,所以我不确定我是否理解这个问题。
异常 NameError: global name 'pool' is not defined
不是由于酸洗问题,而是由于范围问题。
该方法在其范围内找不到 pool
。尝试通过将 pool
引用传递给该方法来修复它。
其他:
pool = mp.Pool(mp.cpu_count())
cpu_count()
调用是多余的,因为默认情况下池已经产生了与您拥有的 CPU 一样多的工作线程。
您传递给 pool.map
的 points
数组的形状为 (1000, 2)。当 pool.map
拆分它作为 points
参数传递给 __points_distance
时, 那个 数组只有形状 (2,)。
尝试在调用 cdist
之前将 points.shape = (1, 2)
添加到 __points_distance
的正文中。
pool
变量在 Circle
class 之外定义,因此 points_distance() will be unable to find
pool` 在其命名空间中:
向接受 pool
的 Circle 或 Feature 添加一个构造函数,并将您要使用的池传递给 RansacFeature
,我假设它会为您实例化 Circle
。
此问题与 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
class 并调用它的 points_distance
方法.在任何情况下,另一个区别是 points_distance
方法使用 scipy.spatial.distance.cdist
期望 (n,2)-shaped numpy.ndarray
。它在使用串行版本时有效,但在并行使用时引发我提到的异常。我想有一个关于 cPickle 传递参数的警告。
我觉得这里有点混乱,所以我不确定我是否理解这个问题。
异常 NameError: global name 'pool' is not defined
不是由于酸洗问题,而是由于范围问题。
该方法在其范围内找不到 pool
。尝试通过将 pool
引用传递给该方法来修复它。
其他:
pool = mp.Pool(mp.cpu_count())
cpu_count()
调用是多余的,因为默认情况下池已经产生了与您拥有的 CPU 一样多的工作线程。
您传递给 pool.map
的 points
数组的形状为 (1000, 2)。当 pool.map
拆分它作为 points
参数传递给 __points_distance
时, 那个 数组只有形状 (2,)。
尝试在调用 cdist
之前将 points.shape = (1, 2)
添加到 __points_distance
的正文中。
pool
变量在 Circle
class 之外定义,因此 points_distance() will be unable to find
pool` 在其命名空间中:
向接受 pool
的 Circle 或 Feature 添加一个构造函数,并将您要使用的池传递给 RansacFeature
,我假设它会为您实例化 Circle
。