Cython调用MKL通过vdMul崩溃元素乘法

时间:2017-07-03 20:32:01

标签: c++ cython intel-mkl

我无法弄清楚为什么在从Python调用时会崩溃。这只是一个简单的Cython代码,可以调用英特尔MKL的vdMul函数https://software.intel.com/en-us/mkl-developer-reference-c-v-mul。我已经尝试将每个DLL从MKL复制到目录并重写不同的部分,但它仍然崩溃,虽然编译很好。在这里发帖,因为我可能对在C ++中工作经验丰富的人犯了一个明显的错误。这是PYX代码:

import numpy as np
cimport numpy as np
cimport cython
from cython cimport view

cdef extern from "mkl.h" nogil:
    double* vect_mult "vdMul"(int n,
                          double *a, 
                          double *b,
                          double *y) 

@cython.boundscheck(False)
@cython.wraparound(False)
@cython.cdivision(True)
cpdef mult(double[::1] A, double[::1] B, double[:,::1] output):
    cdef int Ashape0=A.shape[0], Bshape0=B.shape[0]
    cdef int N = Ashape0*Bshape0
    with nogil:
        vect_mult(N, &A[0], &B[0], &output[0,0])

#test script
from cyblas import mult
import numpy as np
a=np.random.randn(1000)
b=np.random.randn(1000)
output = np.zeros((a.shape[0],b.shape[0]))
mult(a,b,output)

1 个答案:

答案 0 :(得分:1)

我不确定,你想做什么。据我了解vdMult的含义:其结果是带有out[i]=a[i]*b[i]的n维向量。所以

  1. 输出应为大小为1000的平面数组。
  2. 传递Ashape0*Bshape0而不是min(Ashape0,Bshape0),因为程序尝试访问数组越界,因此会出现分段错误。
  3. 你的代码应该是这样的:

    cpdef mult(double[::1] A, double[::1] B, double[::1] output):
        cdef int N = A.shape[0]#assuming all vectors have the same size
        with nogil:
            vect_mult(N, &A[0], &B[0], &output[0,0])
    

    编辑: vdMult执行逐点乘法。我假设您要做的是计算out=a*b^t,即out[i][j]=a[i]*b[j]

    所以这是一个常见的矩阵乘法,您可以使用cblas_dgemm。在您的情况下,调用将是(n - 向量a中的元素数量,m - b中的元素数量):

    cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, 
                    n, m, 1, 1.0, A, 1, B, m, 0.0, C, m);