2017-06-20 100 views
2

所以我想帮助另一个SO用户,并且在这个过程中,我无法创建一个Cython程序来执行一些简单的NumPy外部操作,这迫使我使用GIL。这使得使用OpenMP(多核)成为不可能。然后,我遇到了一个有趣的帖子,而您可以从SciPy Fortran库直接导入用NumPy安装的Cython代码(BLAS,LAPACK),在我的情况下是英特尔MKL等效函数。我想要做的是一个简单的向量乘以2个向量1000x1维度的另一个转置,导致1000x1000矩阵。但是我找不到相关的Fortran程序(相当于NumPy乘法),它可以做到这一点。所有的例程似乎都做了矩阵乘法。所以现在在SciPy中很酷的功能是将它添加到您的Cython模块中:import scipy.linalg.cython_blas as blascimport scipy.linalg.cython_lapack as lapack然后理论上我开始使用Fortran库dgemm,通过调用blas.dgemm(options),但它执行的是矩阵乘积而不是元素乘法。有没有人知道Fortan模块可以完成2个1000x1矢量的简单乘法,1个转置,产生一个1000x1000的矩阵?如果你可以添加很好的输入语法。我将C连续内存视图传递给函数,即[:: 1] Cython NumPy向量。在使用NOGIL的Cython中使用Fortran NumPy操作,相当于NumPy乘法的Fortran库是什么?

+0

您可能不需要这样做。您可以将小GIL需要的部分封装在'with gil:'块中。乘法(可能)在内部再次释放GIL,所以如果这是你希望做的事情,可能(可能)大部分与其他代码并行运行。 – DavidW

+0

@DavidW你说得对,我不必这样做,但我想将它添加到我的Cython工具箱中......我一直在使用Python,任何可以加速OpenMP的东西都变得更好。从这个意义上说,将Fortan指针直接指向Scipy和Cython非常有吸引力。 – Matt

回答

3

你所描述的是纯粹的NumPy功能,称为"broadcasting"。这些广播操作使用C(或Cython)代码完成。您可以随时通过Python C API(例如PyNumber_Multiply)访问它们(尽管它们可能不会释放GIL),但Cython中的正常乘法应该委托给该函数,因此您通常不需要调用(或导入)它直接。

BLAS/LAPACK主要用于线性代数的东西,即使您可以“使用”暴露在那里的功能,它也不会与NumPy使用的(通常)相同。

+0

谢谢你的阅读材料。我相信可以使用Hadamard产品完成2个向量的元素乘法,但这仅在MKL中(即,我没有在'scipy.linalg.cython_lapack'文件中看到定义)https://stackoverflow.com/a/29950051/6037118虽然如果您知道任何示例文件以显示如何包含可以启动我的MKL库,那么'vdmul'就是库:https://software.intel.com/zh-cn/mkl-显影剂基准FORTRAN-v-MUL – Matt