dgemv produces only zero vectors as results

1 回表示 (過去 30 日間)
Nikolaos
Nikolaos 2020 年 1 月 19 日
コメント済み: James Tursa 2020 年 1 月 20 日
Hello, I am trying to link this simple matlab script
A = [2 3; -1 4];
B = [5; 3];
C = zeros(2, 1);
alpha = 1;
beta = 1;
C = mv_mult(A, B, alpha, beta)
with the following mexFunction
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "blas.h"
#include "mex.h"
#include "matrix.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
/* pointers to input & output matrices*/
double *A, *v, *Y, *a, *b;
ptrdiff_t rows_A, cols_A;
ptrdiff_t rows_v, cols_v;
// create input matrix (A)
A = mxGetDoubles(prhs[0]);
rows_A = mxGetM(prhs[0]);
cols_A = mxGetN(prhs[0]);
// create input vector (v)
v = mxGetDoubles(prhs[1]);
rows_v = mxGetM(prhs[1]);
cols_v = 1;
// parse scalars (a, b)
a = mxGetDoubles(prhs[2]);
b = mxGetDoubles(prhs[3]);
// create output matrix (Y)
plhs[0] = mxCreateDoubleMatrix(rows_A, cols_v, mxREAL);
Y = mxGetPr(plhs[0]);
printf("A[0]: %lf\n", A[0]);
printf("A[1]: %lf\n", A[1]);
// compute mm multiplication using blas2 operations
char chn = 'N';
const long int i_one = 1;
dgemv_(&chn, &rows_A, &cols_A,
a, A, &cols_v,
v, &i_one,
b, Y, &i_one);
}
The function compiles without errors nor warnings but matlab replies with [0 0]' instead of [19 7]'. I can't understand why though. Note that I am trying to use blas2 operations only.
  1 件のコメント
Walter Roberson
Walter Roberson 2020 年 1 月 19 日
https://www.mathworks.com/matlabcentral/answers/390546-wrong-result-when-calling-cblas-dgemv-function-in-a-mex-file might help

サインインしてコメントする。

採用された回答

James Tursa
James Tursa 2020 年 1 月 20 日
編集済み: James Tursa 2020 年 1 月 20 日
Two things:
1) All of the integers that you are passing into BLAS/LAPACK functions should be the same. Why are you using ptrdiff_t and long int? Make them the same. What that needs to be depends on the version of MATLAB you are running, but based on the fact you are calling mxGetDoubles it indicates a later version, so use ptrdiff_t for that i_one. Or use the supplied mwSignedIndex macro.
2) You have an incorrect argument for the leading dimension of A, LDA. You have &cols_v when it should be &rows_A:
dgemv_(&chn, &rows_A, &cols_A,
a, A, &rows_A, // <-- changed
v, &i_one,
b, Y, &i_one);
  2 件のコメント
Nikolaos
Nikolaos 2020 年 1 月 20 日
2) Was the problem, I fixed it last night after a few hours.
1) I used long int because gcc gave me warnings with plain integer, and once the warning was gone I thought it was ok. It still works though, even with mixed long int/ptrdiff_t. As for the reason I used both, it's because I am a beginner in matlab (an experience of a few days), so I tried copy-pasting some code from blas-3 dgemm in order to make it blas2-dgemv.
Thank you for your help!!
James Tursa
James Tursa 2020 年 1 月 20 日
You can find several online links that describe the interface to the BLAS/LAPACK routines. You can generally trust them as far as the order and meaning of the arguments, and where the floating point doubles or singles are. But you cannot trust them for what integer size to use in the arguments. The integer size needed will entirely depend on your particular setup and which BLAS/LAPACK libraries you are linking to. So you need to know that detail about the libraries to know what is correct. For the MATLAB supplied BLAS/LAPACK libraries, I think you are always safe to use their supplied mwSignedIndex macro, which would be translated into 32-bit integers or 64-bit integers appropriate for the system. In any event, regardless of the particular libraries involved, all of the integer arguments should always be defined the same way.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeLogical についてさらに検索

タグ

製品


リリース

R2019b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by