我用这个简单的代码做了一个 blas 矩阵/向量产品:
#include "mkl.h"
#include <stdio.h>
int main(){
const int M = 2;
const int N = 3;
double *x = new double[N];
double *A = new double[M*N];
double *b = new double[M];
for (int i = 0; i < M; i++){
b[i] = 0.0; //Not necessary but anyway...
for (int j = 0; j < N; j++){
A[j * M + i] = i + j * 2;
}
}
for (int j = 0; j < N; j++)
x[j] = j*j;
const int incr = 1;
const double alpha = 1.0;
const double beta = 0.0;
const char no = 'N';
dgemv(&no, &M, &N, &alpha, A, &M, x, &incr, &beta, b, &incr );
printf("b = [%e %e]'\n",b[0],b[1]);
delete[] x;
delete[] A;
delete[] b;
}
虽然显示的结果符合预期 ([18, 23]),但英特尔 Inspector在调用 dgemv 时发现 1 个无效内存访问和 2 个无效部分内存访问。无效的内存访问和一次无效的部分内存访问与向量b对应分配的内存有关。第二个无效的部分内存访问与分配给 A 的内存有关。如果我使用静态数组,我不会收到任何错误。
其他 MKL 函数也会发生这种情况,例如 dgesv 或当我尝试使用 cblas_dgemv 时。我使用 Intel Inspector XE 2016 和带有 MKL 顺序的 Intel C++ Compiler 16.0。
我的 dgemv 调用是错误的,还是误报。有人经历过吗?
谢谢
编辑:
正如 Josh Milthorpe 所建议的那样:该错误仅出现在小型数组上,可能是因为 MKL 试图以大块的形式访问内存以提高效率。
我做了几次测试,M 至少需要 20 才不会出错。N 可以是任何正数。我想这不是一个错误,MKL 只是访问为矩阵分配的空间之外的内存,但不会改变或真正使用它。