在进入 SGEMM 时,参数编号 8 具有非法值
On entry to SGEMM parameter number 8 had an illegal value
我正在尝试探索 cblas 库;所以我尝试使用 Level3 cblas_sgemm 例程进行二维矩阵乘法。
C=(alpha)* A * B + (beta) * C
;; where aplha=1 & beta=0
#define TYPE float
#define A_R 3
#define A_C 2
#define B_R 2
#define B_C 3
int main()
{
TYPE *A=NULL,*B=NULL,*C=NULL;
if(A_C != B_R)
{
printf("\nA(%d,%d) X B(%d,%d) not possible\n",A_R,A_C,B_R,B_C);
exit(1);
}
A=(TYPE*)malloc(A_R*A_C*sizeof(TYPE));
B=(TYPE*)malloc(B_R*B_C*sizeof(TYPE));
C=(TYPE*)malloc(A_R*B_C*sizeof(TYPE));
initM(A,B,C);//initializes matrix
cblas_sgemm(CblasRowMajor, CblasNoTrans,CblasNoTrans,A_R, B_C,A_C, 1.0, A,A_R, B, B_R,0.0, C, A_C);
//multiply(A,B,C);
printf("\n%f\n",C[ (A_R*B_C)-1]);
}
我使用静态库编译我的程序:
gcc mxm_blas.c -L/CBLAS/lib/ -lcblas -L/BLAS/ -lblas -I/CBLAS/include/ -lgfortran
现在 运行 代码,我得到:
On entry to SGEMM parameter number 8 had an illegal value
我觉得麻烦的是数组的声明方式!大多数示例 i have seen 将数组声明为:
float A[100][100],b[100][100],C[100][100];
这是错误原因还是程序错误?通过 sgemm API 进行基于 malloc 的矩阵乘法不可能吗?
更新: initM 初始化矩阵:
void initM(TYPE* A,TYPE* B,TYPE* C)
{
long int i,j;
j=A_R*A_C;
for(i=0;i<j;i++) A[i]=2;
j=B_R*B_C;
for(i=0;i<j;i++) B[i]=3;
j=A_R*B_C;
for(i=0;i<j;i++) C[i]=0;
}
错误消息是由 sgemm
而不是 cblas_sgemm
产生的。 sgemm
的第8个参数是:
SUBROUTINE SGEMM(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
C 函数 cblas_sgemm 只是调用 Fortran 例程 sgemm 的包装器。 Bascally 它将一些从 by value
传递的参数转换为 by reference
。此外,Fortran 例程缺少 "RowMajor" 参数。
由于您使用的是 "RowMajor" 存储,因此您应该使用列数作为矩阵的主要维度。
即使我不能测试,我建议:
cblas_sgemm(CblasRowMajor, CblasNoTrans,CblasNoTrans,A_R, B_C, A_C, 1.0, A, A_C, B, B_C, 0.0, C, B_C);
另外可以参考GSL example.
对ctheo的回答稍作修改:
A[A_R][A_C] X B[B_R][B_C]=C[A_R][B_C] //if (A_C==B_R)
所以,在将最后一个参数设置为 LDC=B_C 时,代码工作正常
cblas_sgemm(CblasRowMajor, CblasNoTrans,CblasNoTrans,A_R, B_C,A_C,1.0, A,A_C, B, B_C,0.0, C, B_C );
我正在尝试探索 cblas 库;所以我尝试使用 Level3 cblas_sgemm 例程进行二维矩阵乘法。
C=(alpha)* A * B + (beta) * C
;; where aplha=1 & beta=0
#define TYPE float
#define A_R 3
#define A_C 2
#define B_R 2
#define B_C 3
int main()
{
TYPE *A=NULL,*B=NULL,*C=NULL;
if(A_C != B_R)
{
printf("\nA(%d,%d) X B(%d,%d) not possible\n",A_R,A_C,B_R,B_C);
exit(1);
}
A=(TYPE*)malloc(A_R*A_C*sizeof(TYPE));
B=(TYPE*)malloc(B_R*B_C*sizeof(TYPE));
C=(TYPE*)malloc(A_R*B_C*sizeof(TYPE));
initM(A,B,C);//initializes matrix
cblas_sgemm(CblasRowMajor, CblasNoTrans,CblasNoTrans,A_R, B_C,A_C, 1.0, A,A_R, B, B_R,0.0, C, A_C);
//multiply(A,B,C);
printf("\n%f\n",C[ (A_R*B_C)-1]);
}
我使用静态库编译我的程序:
gcc mxm_blas.c -L/CBLAS/lib/ -lcblas -L/BLAS/ -lblas -I/CBLAS/include/ -lgfortran
现在 运行 代码,我得到:
On entry to SGEMM parameter number 8 had an illegal value
我觉得麻烦的是数组的声明方式!大多数示例 i have seen 将数组声明为:
float A[100][100],b[100][100],C[100][100];
这是错误原因还是程序错误?通过 sgemm API 进行基于 malloc 的矩阵乘法不可能吗?
更新: initM 初始化矩阵:
void initM(TYPE* A,TYPE* B,TYPE* C)
{
long int i,j;
j=A_R*A_C;
for(i=0;i<j;i++) A[i]=2;
j=B_R*B_C;
for(i=0;i<j;i++) B[i]=3;
j=A_R*B_C;
for(i=0;i<j;i++) C[i]=0;
}
错误消息是由 sgemm
而不是 cblas_sgemm
产生的。 sgemm
的第8个参数是:
SUBROUTINE SGEMM(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
C 函数 cblas_sgemm 只是调用 Fortran 例程 sgemm 的包装器。 Bascally 它将一些从 by value
传递的参数转换为 by reference
。此外,Fortran 例程缺少 "RowMajor" 参数。
由于您使用的是 "RowMajor" 存储,因此您应该使用列数作为矩阵的主要维度。
即使我不能测试,我建议:
cblas_sgemm(CblasRowMajor, CblasNoTrans,CblasNoTrans,A_R, B_C, A_C, 1.0, A, A_C, B, B_C, 0.0, C, B_C);
另外可以参考GSL example.
对ctheo的回答稍作修改:
A[A_R][A_C] X B[B_R][B_C]=C[A_R][B_C] //if (A_C==B_R)
所以,在将最后一个参数设置为 LDC=B_C 时,代码工作正常
cblas_sgemm(CblasRowMajor, CblasNoTrans,CblasNoTrans,A_R, B_C,A_C,1.0, A,A_C, B, B_C,0.0, C, B_C );