2016-11-15 12 views
1

私はMATLABのLapackコマンドslasd4を呼び出すためにMEXファイルを構築しようとしています。 mexファイルの構築は成功しますが、コマンドを使用しようとするとMATLABがクラッシュし、メッセージで終了します。アクセス違反の終了slasd4 mex

異常終了:アクセス違反。

誰でもこの問題を解決できますか?私は、MEXファイルを使用するための組み込みアドオンでMATLAB R2016bを使用しています。ここで

は私のMEXファイルである:ここで

#include "mex.h" 
#include "lapack.h" 

void mexFunction(int nlhs,  mxArray *plhs[], 
       int nrhs, const mxArray *prhs[]) 
{ 
    mwSize n, i, info = 0; 
    float *z, *d, *delta, *work, *sigma, rho; 

    /* verify input/output arguments */ 
    if (nrhs > 4) { 
     mexErrMsgTxt("Too many input arguments."); 
    } 
    if (nlhs > 3) { 
     mexErrMsgTxt("Too many output arguments."); 
    } 

    /* dimensions of input matrix */ 
    n = mxGetN(prhs[0]); 

    /* create output matrices */ 
    plhs[0] = mxCreateNumericMatrix(n, 1, mxSINGLE_CLASS, mxREAL); 
    plhs[1] = mxCreateNumericMatrix(n, 1, mxSINGLE_CLASS, mxREAL); 
    plhs[2] = mxCreateNumericMatrix(1, 1, mxSINGLE_CLASS, mxREAL); 

    /* get pointers to data */ 
    i  = (mwSignedIndex) prhs[3]; 

    d  = (float *) mxGetPr(prhs[0]); 
    z  = (float *) mxGetPr(prhs[1]); 
    rho = (float) mxGetScalar(prhs[2]);   

    delta = (float *) mxGetPr(plhs[0]); 
    work = (float *) mxGetPr(plhs[1]); 
    sigma = (float *) mxGetPr(plhs[2]); 

    /* Call Lapack function */ 
    slasd4(&n, &i, d, z, delta, &rho, sigma, work, &info); 

    /* check if call was successful */ 
    if (info < 0) { 
     mexErrMsgTxt("Illegal values in arguments."); 
    } else if (info > 0) { 
     mexErrMsgTxt("Failed to converge."); 
    } 
} 

は簡単なテストの例です:に関連する

[ 0] 0x000000000b8c15b0  C:\Users\Joni\Desktop\NLA\Paper\slasd4.mexw64+00005552 mexfilerequiredapiversion+00000032 
[ 1] 0x000000000b8c1561  C:\Users\Joni\Desktop\NLA\Paper\slasd4.mexw64+00005473 mexFunction+00000305 
[ 2] 0x00000000fc5fc5d1 C:\Program Files\MATLAB\R2016b\bin\win64\libmex.dll+00116177 mexRunMexFile+00000129 
[ 3] 0x00000000fc5fb2e2 C:\Program Files\MATLAB\R2016b\bin\win64\libmex.dll+00111330 mexFeature_mexver+00001794 
[ 4] 0x00000000fc5fa506 C:\Program Files\MATLAB\R2016b\bin\win64\libmex.dll+00107782 mexUnlock+00020182 
+0

'あなたがそれを渡しているという事実はすでに私を奇妙なものにしています... –

+0

また、 'n'は符号なし(' mwSize')、 'i'は署名されています(' mwSignedIndex')、それは奇妙です。さらに、 'mxArrays'へのポインタを' mwSignedIndex'にキャストしてサイズを取得することはできません。 'mxGetN()'を呼び出すことを意味しませんか? –

+0

この種のコンテキストで使用される 'slasd4'のドキュメントにリンクできますか? –

答えて

0

いくつかの問題:

D = [2; 0]; 
z = [1;0]; 
[delta, work, sigma] = slasd4(D,z,-1,1); 

ここでは、障害から始まるスタックトレースですデータ型など。MATLAB提供のライブラリshを使用してBLASおよびLAPACK呼び出しに使用されるすべての整数変数sh ouldは通常、mwSizeではなくmwSignedIndexとして型指定されます。また、渡される変数の基礎となるデータ型がdouble型である場合、そのデータを(float *)をポイントするだけで浮動小数点に変更することはできません。したがって、入力データが正しいクラスであることを確認する必要があります。前までは、あなたはここなど多くの変数クラスとサイズのためよりチェックを入れてしなければならないコード修正のカップルと一緒に、追加のアップフロントをチェックして、いくつかのコードです:

#include "mex.h" 
#include "lapack.h" 

void mexFunction(int nlhs,  mxArray *plhs[], 
       int nrhs, const mxArray *prhs[]) 
{ 
mwSignedIndex n, i, info = 0; /* CHANGED */ 
float *z, *d, *delta, *work, *sigma, rho; 
mxArray *plhs0, *plhs1, *plhs2; /* NEW */ 

/* verify input/output arguments */ 
if (nrhs != 4) { /* CHANGED */ 
    mexErrMsgTxt("Need exactly 4 inputs."); /* CHANGED */ 
} 
if (nlhs > 3) { 
    mexErrMsgTxt("Too many output arguments."); 
} 
/* NEW */ 
if(!mxIsSingle(prhs[0]) || mxIsComplex(prhs[0])) { 
    mexErrMsgTxt("1st argument must be a real single class variable"); 
} 
if(!mxIsSingle(prhs[1]) || mxIsComplex(prhs[1])) { 
    mexErrMsgTxt("2nd argument must be a real single class variable"); 
} 
if(!mxIsNumeric(prhs[2]) || mxIsComplex(prhs[2]) || mxGetNumberOfElements(prhs[2]) != 1) { 
    mexErrMsgTxt("3rd argument must be a real numeric scalar variable"); 
} 
if(!mxIsNumeric(prhs[3]) || mxIsComplex(prhs[3]) || mxGetNumberOfElements(prhs[3]) != 1) { 
    mexErrMsgTxt("4th argument must be a real numeric scalar variable"); 
} 

/* dimensions of input matrix */ 
n = mxGetN(prhs[0]); 

/* create output matrices */ 
plhs0 = mxCreateNumericMatrix(n, 1, mxSINGLE_CLASS, mxREAL); /* CHANGED */ 
plhs1 = mxCreateNumericMatrix(n, 1, mxSINGLE_CLASS, mxREAL); /* CHANGED */ 
plhs2 = mxCreateNumericMatrix(1, 1, mxSINGLE_CLASS, mxREAL); /* CHANGED */ 

/* get pointers to data */ 
i  = (mwSignedIndex) mxGetScalar(prhs[3]); /* CHANGED */ 
d  = (float *) mxGetData(prhs[0]); /* CHANGED */ 
z  = (float *) mxGetData(prhs[1]); /* CHANGED */ 
rho = (float) mxGetScalar(prhs[2]);   

delta = (float *) mxGetData(plhs0); /* CHANGED */ 
work = (float *) mxGetData(plhs1); /* CHANGED */ 
sigma = (float *) mxGetData(plhs2); /* CHANGED */ 

/* Call Lapack function */ 
slasd4(&n, &i, d, z, delta, &rho, sigma, work, &info); 

/* check if call was successful */ 
if (info < 0) { 
    mexErrMsgTxt("Illegal values in arguments."); 
} else if (info > 0) { 
    mexErrMsgTxt("Failed to converge."); 
} 
plhs[0] = plhs0; /* NEW */ 
if(nlhs > 1) plhs[1] = plhs1; /* NEW */ 
if(nlhs > 2) plhs[2] = plhs2; /* NEW */ 
} 

そしてここにはあります実行結果:

>> D = [2; 0]; 
>> z = [1;0]; 
>> [delta, work, sigma] = slasd4(D,z,-1,1) 
??? Error using ==> slasd4 
1st argument must be a real single class variable 

>> [delta, work, sigma] = slasd4(single(D),z,-1,1) 
??? Error using ==> slasd4 
2nd argument must be a real single class variable 

>> [delta, work, sigma] = slasd4(single(D),single(z),-1,1) 
delta = 
    1 
work = 
    1 
sigma = 
    1.7321 

私は、segフォールトを越えるために十分な変更を加えました。私は実際の関数呼び出しについて何もチェックしておらず、あなたが仕事変数の正しい次元を持っているか、変数に適切なデータがあるかどうかを確認しませんでした。

関連する問題