在BLAS/LAPACK使用 Eigen
英文原文(Using BLAS/LAPACK from Eigen)
自Eigen 3.3版本以及以后,任何F77兼容的BLAS或LAPACK库都可以用作稠密矩阵乘积和稠密矩阵分解的后端。例如,可以在OSX上使用Intel® MKL,Apple的Accelerate框架,OpenBLAS,Netlib LAPACK等。
请务必查看此页面以进一步讨论关于使用Intel® MKL(也包括VML,PARDISO等)的具体用法。
为了使用外部BLAS和LAPACK库,您必须将自己的应用程序链接到相应的库及其依赖项。对于LAPACK,还必须链接到标准的Lapacke
库,它用作Eigen的C++代码和LAPACK F77接口之间方便的中间层。然后,必须通过定义以下一个或多个宏(在包含任何Eigen头文件之前)来激活它们的使用:
注意:
对于Mac用户,为了使用与
Accelerate
框架一起提供的lapack版本,您还需要lapacke
库。使用MacPorts
很容易实现:sudo port install lapack
然后使用以下链接标志:
-framework Accelerate /opt/local/lib/lapack/liblapacke.dylib
宏 | 描述 |
---|---|
EIGEN_USE_BLAS | 启用外部BLAS级别2和3例程的使用(与任何F77 BLAS接口兼容)。 |
EIGEN_USE_LAPACKE | 启用通过Lapacke C接口到Lapack 的外部Lapack 例程的使用(与任何F77 LAPACK接口兼容)。 |
EIGEN_USE_LAPACKE_STRICT | 与EIGEN_USE_LAPACKE 相同,但数字鲁棒性较低的算法被禁用。这目前仅涉及 JacobiSVD ,否则会被gesvd 替换,后者比Jacobi 旋转不太稳健。 |
在这种情况下,Eigen的一些算法会被隐式地替换为对BLAS或LAPACK例程的调用。这些替换仅适用于使用以下四种标准标量类型之一的动态或足够大的对象:float
、double
、complex<float>
和complex<double>
。对其他标量类型的操作或混合实数和复数的操作将继续使用内置的算法。
可以被替换的Eigen功能的广度如下表所示:
在这些例子中,m1
和m2
是密集矩阵,v1
和v2
是密集向量。
在英特尔® MKL使用 Eigen
英文原文(Using Intel® MKL from Eigen)
自Eigen 3.1版本及以后,用户可以使用Intel®Math Kernel Library(MKL)
如果安装了Intel MKL 10.3
(或更高版本)。
Intel MKL 提供了针对x86兼容架构高度优化的多线程数学例程。Intel MKL
可在Linux
、Mac
和Windows
上使用,适用于Intel64
和IA32
架构。
注意:
Intel® MKL是专有软件,用户需要购买或注册社区(免费)Intel MKL许可证来使用它。此外,用户产品的许可证必须允许链接到专有软件,但不包括任何未经修改的GPL版本。
通过Eigen使用Intel MKL很容易:
- 在包含任何Eigen的头文件之前定义
EIGEN_USE_MKL_ALL
宏。 - 将你的程序链接到MKL库(请参阅MKL链接指南)。
- 在64位系统上,你必须使用LP64接口(而不是ILP64接口)。
在这样做时,一些Eigen的算法会被替换为调用Intel MKL例程,而这种替换仅适用于具有以下四种标准标量类型之一的动态或足够大的对象:float
,double
,complex<float>
和complex<double>
。使用其他标量类型或混合实数和复数的操作仍将使用内置的算法。
此外,您可以选择定义以下一个或多个宏来决定哪些部分将被替换:
宏 | 描述 |
---|---|
EIGEN_USE_BLAS | 启用使用外部BLAS Level 2 和Level 3 例程。 |
EIGEN_USE_LAPACKE | 启用使用Lapacke C接口到Lapack的外部Lapack例程。 |
EIGEN_USE_LAPACKE_STRICT | 与EIGEN_USE_LAPACKE 相同,但将禁用鲁棒性较低的算法。这仅涉及到JacobiSVD ,否则将被gesvd 替换,后者比Jacobi 旋转算法鲁棒性更低。 |
EIGEN_USE_MKL_VML | 启用Intel VML(向量操作)的使用。 |
EIGEN_USE_MKL_ALL | 定义了EIGEN_USE_BLAS 、EIGEN_USE_LAPACKE 和EIGEN_USE_MKL_VML 。 |
EIGEN_USE_BLAS
和EIGEN_USE_LAPACKE*
宏可以与EIGEN_USE_MKL
结合使用,以显式告诉Eigen底层的BLAS/Lapack
实现是Intel MKL
。主要效果是启用MKL
直接调用功能(MKL_DIRECT_CALL
)。这可能有助于提高某些MKL BLAS
(?GEMM
、?GEMV
、?TRSM
、?AXPY
和?DOT
)和LAPACK
(LU
、Cholesky
和QR
)例程对非常小的矩阵的性能。可以通过定义EIGEN_MKL_NO_DIRECT_CALL
来禁用MKL
直接调用。
请注意,BLAS
和LAPACKE
后端可用于任何F77兼容的BLAS
和LAPACK
库。有关详细信息,请参见 此页面。
最后,Intel MKL
附带的PARDISO
稀疏求解器可以通过PardisoSupport
模块的PardisoLU
、PardisoLLT
和PardisoLDLT
类来使用。
下表总结了EIGEN_USE_MKL_VML
覆盖的函数列表:
在这些例子中,v1
和v2
是密集的向量。
链接
- Intel MKL可以在这里购买和下载。
- Intel MKL还捆绑在Intel Composer XE中。
在 CUDA 内核中使用 Eigen
英文原文(Using Eigen in CUDA kernels)
从CUDA 5.5
和Eigen 3.3
开始,可以在CUDA
核函数内使用Eigen的矩阵、向量和数组(fixed size
)。这在处理众多但小型问题时特别有用。默认情况下,当在由nvcc
编译的.cu
文件中包含Eigen头文件时,大多数Eigen的函数和方法都会被设备主机关键字前缀,使它们可从主机和设备代码中调用。这种支持可以通过在包含任何Eigen头文件之前定义EIGEN_NO_CUDA
来禁用。这在仅在主机端使用Eigen的.cu
文件使用时可能有用。但是,在两种情况下,主机的SIMD
矢量化必须在.cu
文件中禁用。因此,强烈建议将所有昂贵的主机计算从.cu
文件恰当地移动到常规的.cpp
文件中。
已知问题:
nvcc
和MS Visual Studio
不兼容(欢迎提交补丁)。nvcc 5.5
与gcc-4.7
(或更高版本)使用标准库<limits>
头文件有问题。为了解决这个问题,您可以在包含任何其他文件之前添加以下内容:
// workaround issue between gcc >= 4.7 and cuda 5.5
#if (defined __GNUC__) && (__GNUC__>4 || __GNUC_MINOR__>=7)
#undef _GLIBCXX_ATOMIC_BUILTINS
#undef _GLIBCXX_USE_INT128
#endif
- 在64位系统上,Eigen默认使用长整型作为索引和大小的类型。在CUDA设备上,默认使用32位整型是有意义的。但是,为了使主机和CUDA代码兼容,Eigen不能自动完成此操作。因此,用户需要在整个代码中(如果没有通过Eigen对象在主机和CUDA代码之间进行交互,则仅在CUDA代码中)定义
EIGEN_DEFAULT_DENSE_INDEX_TYPE
为int
。