OpenBLAS sgemm,有特殊要求吗?有时候我会难受

时间:2019-02-13 08:38:38

标签: c blas openblas

我的标题中的某处有此声明:

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;在生产代码中似乎没有发生。

1 个答案:

答案 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实现上,而是会以调用它的方式来实现。