2017-07-03 3 views
1

Pythonから呼び出されたときにクラッシュする理由を理解できません。インテルMKLのvdMul関数https://software.intel.com/en-us/mkl-developer-reference-c-v-mulを呼び出すのはシンプルなCythonコードです。私はディレクトリにMKLからすべてのDLLをコピーして、さまざまな部分を書き直そうとしましたが、コンパイルは正常ですがクラッシュしています。ここに投稿すると、おそらくC++での作業経験が豊富な人に明らかなエラーが発生したようです。 PYXコードは次のとおりです。CythonがvdMulを使って要素ごとの乗算でMKLをクラッシュさせる

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

あなたは何をしたいですか? vdMultの意味を理解すると、結果はout[i]=a[i]*b[i]のn次元ベクトルになります。従って

  1. 出力は、サイズ1000のフラットな配列にする必要があります。
  2. min(Ashape0,Bshape0)の代わりにAshape0*Bshape0を渡すと、プログラムが境界外の配列にアクセスしようとすると、セグメンテーション違反が発生します。

あなたのコードは次のようになります。

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); 
+0

は、私は最大(Ashape0、Bshape0)を通過し、それがうまく働きました。ベクトル乗算であるため、等価である必要があるため、Ashape0またはBshape0のいずれかにする必要があります。 MKLはまだNumPyよりも2倍遅いですが、理由は分かりませんが...ありがとうございます! – Matt

+0

関数を明確にするためには(少なくとも私は考えましたが)これは別の方法で生成していますが、要素の賢明な乗算でした – Matt

+0

MKL関数が要素の賢明なベクトルの乗算を行うのはどうですか?あなたの応答で推測すると、私は間違ったものを意図せず使用していました。 – Matt

関連する問題