我的标题中的某处有此声明:
typedef float real;
typedef int integer;
extern "C" {
extern int sgemm_(char *transa, char *transb,
integer *m, integer *n, integer *k,
const real *alpha,
const real *a, integer *lda,
const real *b, integer *ldb,
const real *beta,
real *c, integer *ldc);
}
然后,我链接到OpenBLAS库(或可选地其他BLAS库,例如MKL)。然后,我直接在C ++代码中调用sgemm_
。 (该代码原则上应可与任何BLAS库一起使用。)
我不确定这是否是个坏主意。还是我应该照顾的。例如。我需要特殊的对齐方式吗?还是在多线程环境中需要注意?
(例如,我在看一下OpenBLAS代码(特别是SGEMM
内核),并且看起来它具有特殊的对齐要求(但也许我错了)。
似乎大多数情况下都可以正常工作。除了某些情况(对于某些复杂的测试用例,在某些情况下(不确定地,也许是10%的用例),我的结果是nan
;在生产代码中似乎没有发生。
答案 0 :(得分:0)
从C ++调用BLAS不会有任何问题。 OpenBLAS是一个使用广泛的库,预计不会出现这样的基本问题。
BLAS本质上是一个Fortran库,因此必须记住,它对二维矩阵使用Fortran存储格式。这意味着矩阵是内存的单个块,按列主顺序存储二维矩阵。
您不能使用二维动态分配的数组(即double **a;
),因为分配的内存将被碎片化。另外,如果您使用二维静态数组(即double a[5][4]
),则应记住,在C / C ++中,存储顺序是以行为主的。在这种情况下,您仍然可以使用BLAS,但必须考虑矩阵已转置。
我建议使用单指针向量(double *a;
)并手动访问矩阵元素(a[i+j*m]
)。
OpenBLAS具有多线程支持。在编译时,您可以定义是否使用线程或OpenMP或不使用。
就您得到的错误而言,我建议检查您的内存,因为这种行为通常是基于内存错误。无论如何,我都不希望错误发生在sgemm
实现上,而是会以调用它的方式来实现。