3

非常に時間がかかる numpy プログラムを作成しました。プロファイリングを行った後、ほとんどの時間が に費やされていることがわかりましたnumpy.einsum

numpy.einsumnumpy は LAPACK または BLAS のラッパーですが、のパフォーマンスが LAPACK または BLAS の対応するものに匹敵するかどうかはわかりません。

では、Fortran や C に切り替えると、パフォーマンスが大幅に向上しますか?

4

1 に答える 1

3

BLAS で指定されたプリミティブ操作に対してのみ、BLAS を使用した Numpy ラップ。これには、、、、( dot1.10の新機能)、およびそれに依存する関数 (など) が含まれます。一方、BLAS にフォールバックできる操作に対してのみ BLAS を呼び出します (Numpy 1.14.0 以降)。innerproductvdotmatmultensordoteinsum

問題がいくつかの BLAS 操作に分解できる場合は、最初に Numpy 自体でそれを試すことをお勧めします。間にいくつかの一時的な配列が必要になる場合があります (BLAS を使用する C/FORTRAN を作成する場合でも同様です)。out=関数のパラメーターを使用すると、特定の配列作成オーバーヘッドを排除できます。

しかし、ほとんどの場合einsum、BLAS では表現できないため、使用しています。簡単な例を見てください:

a = np.arange(60.).reshape(3,4,5)
b = np.arange(24.).reshape(4,3,2)
c = np.einsum('ijk,jil->kl', a, b)

上記をプリミティブ操作で表現するには、最初の 2 つの軸を で交換し、最初のb2 つの次元に対して要素単位の乗算を行い、次にそれらを合計する必要がkありlます。

c2 = np.ndarray((5, 2))
b2 = np.swapaxes(b, 0, 1)
def manualeinsum(c2, a, b):
    ny, nx = c2.shape
    for k in range(ny):
        for l in range(nx):
            c2[k, l] = np.sum(a[..., k]*b2[...,l])
manualeinsum(c2, a, b2)

それをBLASすることはできません。更新: 上記の問題は、BLAS を使用して高速化できる行列乗算として表すことができます。@ali_m のコメントを参照してください。配列が十分に大きい場合は、BLAS アプローチの方が高速です。

一方、einsumそれ自体は C で書かれており、指定されたインデックスに対して次元固有の反復子を作成し、SSE 用に最適化されていることに注意してください。

于 2016-02-19T16:11:00.100 に答える