我已经编译了numpy 1.6.2和scipy与MKL希望有更好的性能。 目前我有一个严重依赖于np.einsum()的代码,我被告知einsum对MKL不好,因为几乎没有矢量化。 =( 所以我想用np.dot()和切片来重写我的一些代码,只是为了能够获得一些多核速度。 我非常喜欢np.einsum()的简单性,可读性很好。 无论如何,例如,我有一个多维矩阵乘法形式:
np.einsum('mi,mnijqk->njqk',A,B)
那么如何在np.dot()高效的MKL操作中转换这样的东西,或者其他3,4和5维数组乘法呢?
我会提供更多信息: 我正在计算这个等式:
为此,我使用代码:
np.einsum('mn,mni,nij,nik,mi->njk',a,np.exp(b[:,:,np.newaxis]*U[np.newaxis,:,:]),P,P,X)
这不是那么快,在cython中编码的同样的事情要快5倍:
#STACKOVERFLOW QUESTION:
from __future__ import division
import numpy as np
cimport numpy as np
cimport cython
cdef extern from "math.h":
double exp(double x)
DTYPE = np.float
ctypedef np.float_t DTYPE_t
@cython.boundscheck(False) # turn of bounds-checking for entire function
def cython_DX_h(np.ndarray[DTYPE_t, ndim=3] P, np.ndarray[DTYPE_t, ndim=1] a, np.ndarray[DTYPE_t, ndim=1] b, np.ndarray[DTYPE_t, ndim=2] U, np.ndarray[DTYPE_t, ndim=2] X, int I, int M):
assert P.dtype == DTYPE and a.dtype == DTYPE and b.dtype == DTYPE and U.dtype == DTYPE and X.dtype == DTYPE
cdef np.ndarray[DTYPE_t,ndim=3] DX_h=np.zeros((N,I,I),dtype=DTYPE)
cdef unsigned int j,n,k,m,i
for n in range(N):
for j in range(I):
for k in range(I):
aux=0
for m in range(N):
for i in range(I):
aux+=a[m,n]*exp(b[m,n]*U[n,i])*P[n,i,j]*P[n,i,k]*X[m,i]
DX_h[n,j,k]=aux
return DX_h
有没有办法在纯Python中用cython的性能来做到这一点? (我还没弄清楚如何对这个方程进行推理) 在这个cython代码中,Haven能够做一些prange,很多gil和nogil错误。
答案 0 :(得分:4)
或者,您可以使用numpy.tensordot()
:
np.tensordot(A, B, axes=[[0, 1], [0, 2]])
也会使用多个核心,例如numpy.dot()
。