Numpy:多处理带池的矩阵乘法

Numpy: Multiprocessing a matrix multiplication with pool

我正在尝试计算池的点积

pool = Pool(8)
x = np.array([2,3,1,0])
y = np.array([1,3,1,0])
print np.dot(x,y) #works
print pool.map(np.dot,x,y) #error below

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

也试过

ne.evaluate('dot(x, y)') 


TypeError: 'VariableNode' object is not callable

不幸的是,您尝试做的事情以您尝试做的方式是不可能的,而且以简单的方式也不可能。

更糟糕的是,Python 2.7 的 multiprocessing.pool 文档是完全错误的,本质上是 Pool.map 的谎言:它根本不等同于内置 [=12] =].内置 map 可以采用多个参数迭代器传递给函数,而 Pool.map 不能......这已经知道并且没有在 Pool.map 的文档字符串中修复或记录,因为 at least 2011。当然,在 Python 3 中有一个部分修复与星图...

不过老实说,多处理模块对于加速数字代码并不是很有用。例如,see here 用于长时间讨论许多 numpy 操作在通过多处理完成时 变慢 的情况。

但是,这里还有另一个问题:您不能像这样简单地并行化。 map 采用 lists/iterators 个参数并依次对每个参数应用一个函数。这不会做你想做的事:在这种情况下,尝试 map(np.dot,x,y),并注意你得到的只是作为列表的 x 和 y 的每个元素的乘积,而不是点积。 运行 一个函数并行多次很容易。在单个调用中使该函数并行是很困难的,因为它需要使函数本身并行。在这种情况下,这通常意味着重写函数。

除了 np.dot 实际上已经并行化,如果你有一个带有 blas 或 atlas 的 numpy 版本(试试 np.__config__.show())。在这种情况下,您实际上根本不需要做任何工作:np.dot(x,y) 应该 已经 使用您所有的核心而不做任何工作!

我要注意,这仅限于某些 dtypes;浮动通常是最受支持的。例如,在我的计算机上,请注意 floatint 之间的显着差异:

In [19]: a = np.matrix(np.random.randint(0,10,size=(1000,1000)),dtype='int')

In [20]: b = a.astype('float')

In [23]: %timeit np.dot(a,a)
1 loops, best of 3: 6.91 s per loop

In [24]: %timeit np.dot(b,b)
10 loops, best of 3: 28.1 ms per loop

对于 numexpr(在提问时,向可能不知道的人指出您使用的缩写是很有用的),只有一组非常有限的支持函数;查看文档以获取列表。您收到的错误是因为 dot 不是受支持的函数。由于您正在处理一维数组,并且点的定义非常简单,因此以下内容将起作用:ne.evaluate('sum(x*y)')。但是,我怀疑您是否打算只使用一维数组。

如果你真的想大规模并行处理,我建议使用 IPython,它的 parallel system 与 Python 的多处理不同,它实际上很有用用于数值工作。作为一个额外的好处,它还可以跨计算机并行。然而,这种并行化通常只对每 运行 需要一段时间的事情有用;如果您只想将所有内核用于简单的事情,那么最好希望 numpy 对您要使用的功能具有多处理器支持。