繁体   English   中英

在Python中实现大型ndarray乘法的最快方法

[英]Fastest way to implement large ndarray multiplication in Python

我目前正在研究耦合HMM的Python实现,它涉及元素乘法,点积和维数(50,50,40,40,40)和维数(40,40,40)的ndarray之和。 ,40)。 也就是说,非常大......第二个ndarray或多或少稀疏,约有70%的零。

我一直在使用numpy.einsum,它给了我相当慢的结果(算法运行大约需要3小时)。 现在的问题是我需要为我的HMM优化一些参数,这意味着我必须至少进行10000次运行,因此我需要一个至少1000倍的速度增加才能保持合理。

我一直在寻找在Python中进行大型数组操作的最佳方法,现在我已经完全迷失了所有我读过的内容。 所以我有几个问题。 在问他们之前,我只想说明我在带有OSX,intel处理器和nvidia GPU的机器上使用最后一个带有Python 3的anaconda发行版。 此外,我相信我可以压扁我的ndarray以简化我的问题到一个简单的矩阵矩阵问题。

1)似乎BLAS / MKL库可以提供相当好的增加。 当使用带有OSX的Ananaconda时,似乎MKL本身与Python链接。 因此,直到现在我一直在使用MKL而不知道吗? NP。 config .show()给了我这样的东西:

openblas_lapack_info:
  NOT AVAILABLE
blas_opt_info:
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['//anaconda/include']
    libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['//anaconda/lib']
lapack_opt_info:
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['//anaconda/include']
    libraries = ['mkl_lapack95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['//anaconda/lib']
lapack_mkl_info:
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['//anaconda/include']
    libraries = ['mkl_lapack95_lp64', 'mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['//anaconda/lib']
blas_mkl_info:
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['//anaconda/include']
    libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['//anaconda/lib']
mkl_info:
    define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
    include_dirs = ['//anaconda/include']
    libraries = ['mkl_intel_lp64', 'mkl_intel_thread', 'mkl_core', 'iomp5', 'pthread']
    library_dirs = ['//anaconda/lib']

这真的能提高einsum功能的速度吗? 如果没有,我怎样才能设法从Python访问MKL的gemm函数?

2)这些Python库中的任何一个对我的问题是否有用:Theanos,Numba,Cupy? 或者只是简单的Anaconda Accelerate? 来自Anaconda Accelerate的cuBlas会对我来说是最好的选择吗(即我愿意使用单一或半浮动精度)?

3)在C或C ++中重新编码我的算法会有用吗?

4)我尝试使用稀疏矩阵(scipy.sparse.csc_matrix)实现我的算法,但它使我的程序慢了很多。 这是可以预料的还是我弄错了?

我知道这提出了很多问题,但这是我第一次遇到这种问题而互联网并不是那么明确......

非常感谢!

好吧,因为我在最后几天花了很多时间来调查我的问题,我或许可以给像我这样迷失的人一些答案。 所以:

1)是的,默认情况下,MKL本身安装了anaconda(虽然情况并非如此)。 但是,np.einsum并没有从中获益,因为它没有使用BLAS优化的dot numpy函数。 因此,尝试从mkl手动访问gemm函数是没用的(即使由于库anaconda加速,这实际上非常容易)。 使用np.tensordot,np.multiply和其他方法重写np.einsum的操作更容易。

2)我没有时间去探索我询问过的所有库,但是一个数字的Theanos操作显然不比简单的np.tensordot快。 同样,几年前情况并非如此,因为np.tensordot操作没有将BLAS用于多维数组。 关于所有cuda库,看起来它们与MKL相比实际上并不那么好,除非你有一个非常强大的CGU(参见https://larsjuhljensen.wordpress.com/2011/01/28/commentary- the-gpu-computing-fallacy /

3)将用MKL优化的一些Python代码重写为C ++并没有太大的增加(参见基准测试(使用BLAS的python与c ++)和(numpy)

4)仍然不知道为什么我的稀疏矩阵实现比密集矩阵慢。 我做错了很可能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM