[Eigen中文文档] 在 BLAS/LAPACK 、英特尔® MKL 和 CUDA 中使用 Eigen

简介: 自Eigen 3.3版本以及以后,任何F77兼容的BLAS或LAPACK库都可以用作稠密矩阵乘积和稠密矩阵分解的后端。例如,可以在OSX上使用Intel® MKL,Apple的Accelerate框架,OpenBLAS,Netlib LAPACK等。请务必查看此页面以进一步讨论关于使用Intel® MKL(也包括VML,PARDISO等)的具体用法。

文档总目录

在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例程的调用。这些替换仅适用于使用以下四种标准标量类型之一的动态或足够大的对象:floatdoublecomplex<float>complex<double>。对其他标量类型的操作或混合实数和复数的操作将继续使用内置的算法。

可以被替换的Eigen功能的广度如下表所示:

在这里插入图片描述

在这些例子中,m1m2是密集矩阵,v1v2是密集向量。

在英特尔® MKL使用 Eigen

英文原文(Using Intel® MKL from Eigen)

自Eigen 3.1版本及以后,用户可以使用Intel®Math Kernel Library(MKL)如果安装了Intel MKL 10.3(或更高版本)。

Intel MKL 提供了针对x86兼容架构高度优化的多线程数学例程。Intel MKL可在LinuxMacWindows上使用,适用于Intel64IA32架构。

注意:

Intel® MKL是专有软件,用户需要购买或注册社区(免费)Intel MKL许可证来使用它。此外,用户产品的许可证必须允许链接到专有软件,但不包括任何未经修改的GPL版本。

通过Eigen使用Intel MKL很容易:

  1. 在包含任何Eigen的头文件之前定义EIGEN_USE_MKL_ALL宏。
  2. 将你的程序链接到MKL库(请参阅MKL链接指南)。
  3. 在64位系统上,你必须使用LP64接口(而不是ILP64接口)。

在这样做时,一些Eigen的算法会被替换为调用Intel MKL例程,而这种替换仅适用于具有以下四种标准标量类型之一的动态或足够大的对象:floatdoublecomplex<float>complex<double>。使用其他标量类型或混合实数和复数的操作仍将使用内置的算法。

此外,您可以选择定义以下一个或多个宏来决定哪些部分将被替换:

描述
EIGEN_USE_BLAS 启用使用外部BLAS Level 2Level 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_BLASEIGEN_USE_LAPACKEEIGEN_USE_MKL_VML

EIGEN_USE_BLASEIGEN_USE_LAPACKE*宏可以与EIGEN_USE_MKL结合使用,以显式告诉Eigen底层的BLAS/Lapack实现是Intel MKL。主要效果是启用MKL直接调用功能(MKL_DIRECT_CALL)。这可能有助于提高某些MKL BLAS?GEMM?GEMV?TRSM?AXPY?DOT)和LAPACKLUCholeskyQR)例程对非常小的矩阵的性能。可以通过定义EIGEN_MKL_NO_DIRECT_CALL来禁用MKL直接调用。

请注意,BLASLAPACKE后端可用于任何F77兼容的BLASLAPACK库。有关详细信息,请参见 此页面

最后,Intel MKL附带的PARDISO稀疏求解器可以通过PardisoSupport模块的PardisoLUPardisoLLTPardisoLDLT类来使用。

下表总结了EIGEN_USE_MKL_VML覆盖的函数列表:

在这里插入图片描述

在这些例子中,v1v2是密集的向量。

链接

在 CUDA 内核中使用 Eigen

英文原文(Using Eigen in CUDA kernels)

CUDA 5.5Eigen 3.3开始,可以在CUDA核函数内使用Eigen的矩阵、向量和数组(fixed size)。这在处理众多但小型问题时特别有用。默认情况下,当在由nvcc编译的.cu文件中包含Eigen头文件时,大多数Eigen的函数和方法都会被设备主机关键字前缀,使它们可从主机和设备代码中调用。这种支持可以通过在包含任何Eigen头文件之前定义EIGEN_NO_CUDA来禁用。这在仅在主机端使用Eigen的.cu文件使用时可能有用。但是,在两种情况下,主机的SIMD矢量化必须在.cu文件中禁用。因此,强烈建议将所有昂贵的主机计算从.cu文件恰当地移动到常规的.cpp文件中。

已知问题:

  • nvccMS Visual Studio不兼容(欢迎提交补丁)。
  • nvcc 5.5gcc-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_TYPEint
相关文章
|
8月前
|
存储 编译器
|
8月前
|
存储 C语言 C++
|
5月前
|
存储 API 开发工具
AMD 开源 “HIP-RT” 光线追踪库
AMD 开源 “HIP-RT” 光线追踪库
116 0
|
8月前
|
测试技术 API C++
[Eigen中文文档] 扩展/自定义Eigen(一)
在本节中,将介绍如何向MatrixBase添加自定义方法。由于所有表达式和矩阵类型都继承自MatrixBase,因此将方法添加到MatrixBase会立即使其对所有表达式可用!一个典型的用例是,使Eigen与另一个API兼容。
111 0
|
8月前
|
存储 索引
[Eigen中文文档] 扩展/自定义Eigen(三)
本页面针对非常高级的用户,他们不害怕处理一些Eigen的内部细节。在大多数情况下,可以通过使用自定义一元或二元函数避免使用自定义表达式,而极其复杂的矩阵操作可以通过零元函数(nullary-expressions)来实现,如前一页所述。 本页面通过示例介绍了如何在Eigen中实现新的轻量级表达式类型。它由三个部分组成:表达式类型本身、包含有关表达式编译时信息的特性类和评估器类,用于将表达式评估为矩阵。
67 1
|
8月前
|
存储 对象存储 索引
[Eigen中文文档] 扩展/自定义Eigen(二)
CwiseNullaryOp 类的主要目的是定义过程矩阵,例如由Ones()、Zero()、Constant()、Identity()和Random()方法返回的常量或随机矩阵。然而,通过一些想象力,可以用最小的努力实现非常复杂的矩阵操作,因此很少需要实现新的表达式。
69 0
|
8月前
|
存储 编译器 调度
|
8月前
|
安全
[Eigen中文文档] 混叠
在 Eigen 中,混叠是指相同的矩阵(或数组或向量)出现在赋值操作符的左边和右边。如下表达式,mat = 2*mat 或者 mat = mat.transpose()。第一个表达式是没有问题的,但是第二个表达式,会出现不可预料的结果。这一节会解释什么是混叠,以及它的危害与处理方法。
55 0
|
8月前
[Eigen中文文档] 在 CMake 项目中使用 Eigen
Eigen提供了CMake(CMake 3.0或更高版本)支持,使得该库可以轻松地在CMake项目中使用。
209 1
|
8月前
|
并行计算 算法 安全
[Eigen中文文档] Eigen 和多线程
某些 Eigen 算法可以利用硬件中存在的多个内核。
215 0