泛化到多个 BLAS/LAPACK 库

Generalizing to multiple BLAS/LAPACK Libraries

我正在用 C++ 开发一个线性代数工具,它在很大程度上依赖于矩阵乘法和分解(如 LU、SVD),并且旨在应用于大型矩阵。我使用英特尔 MKL 开发它以获得最佳性能,但我不想发布只有英特尔 MKL 的版本,因为我认为它不适用于没有英特尔或不想安装 MKL 的人。相反,我应该发布一个更通用的代码,它不是英特尔 MKL-specific,而是允许用户指定他们想要使用的 BLAS 和 LAPACK 实现(例如 OpenBLAS 或 ATLAS)。

虽然函数原型在不同的实现中似乎是相同的,但有几个(帮助程序?)函数和类型是特定于英特尔 MKL 的。比如有我用的MKL_INT类型,还有mkl_malloc. This article建议用宏重新定义类型,这也是我的第一个想法。我想我也会有 headers 的宏。

我认为编写代码的标准是使其与 BLAS/LAPACK 实现无关,我想知道是否有比依赖宏更简洁的方法——特别是因为后者需要重新编译代码才能切换,这 对于我使用过的其他工具。

大多数依赖 BLAS/LAPACK 调用的科学代码是 implementation-agnostic。他们通常要求图书馆只是 link 适当编辑。

您评论说函数原型在不同的实现中是相同的。这允许您只在某些 myblas.hmylapack.h headers 中使用原型,然后 link 您想要使用的任何库。

听起来您最关心的是您用于 MKL 的 implementation-specific 东西。解决方案就是不要使用这些东西。例如,像 MKL_INT 这样的 MKL 类型并不特殊。它们是 C 数据类型,已被定义为允许在 MKL 提供的 LP32/LP64/ILP64 库之间进行泛化。参见 this table

此外,mkl_malloc 之类的内容并不特别。它是在 C 标准具有 thread-safe 对齐分配之前引入的。事实上,这就是 mkl_malloc 的全部内容。因此,只需使用 aligned_alloc,或者如果您不想提交 C11,请使用 _mm_mallocmemalign 等...

另一方面,MKL 确实为 BLAS/LAPACK 提供了一些未标准化的有用扩展(例如换位)。但是,这种类型的东西通常很容易通过特殊情况 BLAS/LAPACK 调用来实现,或者很容易自己实现。如果您选择使用 MKL,它也有内部线程,但是,许多 BLAS/LAPACK 库都提供此功能。