Numpy:使用池多处理矩阵乘法

时间:2015-03-17 02:30:17

标签: python numpy 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

1 个答案:

答案 0 :(得分:3)

遗憾的是,您尝试做的事情是不可能的,并且也不可能以简单的方式实现。

更糟糕的是,Python 2.7的multiprocessing.pool文档完全错误,基本上属于Pool.map:它完全不等同于内置map。内置map可以将多个参数迭代器传递给函数,而Pool.map不能...这已知并且未在Pool.map的文档字符串中修复或记录,因为{ {3}}。当然,在Python 3中有一个部分解决方案,使用starmap ...

老实说,多处理模块对于加速数字代码并不是非常有用。例如,at least 2011用于长时间讨论通过多处理完成许多numpy操作较慢的情况。

然而,这里还有另一个问题:你不能简单地像这样并行化。 map获取参数的列表/迭代器,并依次将函数应用于每个参数。这不会做你想做的事情:在这种情况下,试试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不是受支持的功能。由于您正在处理1D数组,并且dot的定义非常简单,因此以下内容将起作用:ne.evaluate('sum(x*y)')。但是,我怀疑你是否计划仅使用1D阵列。

如果你真的想大规模并行化,我建议使用IPython,它的see here与Python的多处理不同,它实际上对数值工作很有用。作为额外的奖励,它还可以跨计算机并行化。但是,这种并行化通常仅适用于每次运行需要一段时间的事情;如果你只想将所有内核用于简单的事情,那么最好是希望numpy对你想要使用的函数提供多处理器支持。