背景

在接触深度学习框架及上层程序应用,比如自动驾驶的感知模块,经常会遇到向量、矩阵的运算; 这些场景对计算效率要求比较高,所以一般通过C/C++实现。下面介绍一些常用的第三方库。

具体库

BLAS

BLAS(Basic Linear Algebra Subprograms)是一个向量、矩阵运算的API标准,按功能定义了三个级别的运算:

Level1: 向量与向量运算 $$ \mathbf{y} \gets \alpha \mathbf{x} + \mathbf{y} $$

Level2: 向量与矩阵运算 $$ \mathbf{y} \gets \alpha \mathbf{A}\mathbf{x} + \beta \mathbf{y} $$

Level3: 矩阵与矩阵运算 $$ \mathbf{C} \gets \alpha \mathbf{A}\mathbf{B} + \beta \mathbf{C} $$

实现

各个软硬件厂商有自己的实现,并针对性能做了大幅优化,下面列举一些常见的:

  • Netlib BLAS/CBLAS: 官方实现出自 Netlib,编程语言有Fortran和C两个版本的实现。

  • OpenBLAS: 基于C和Fortran的开源实现,性能比官方实现要好。

  • CuBLAS: NVIDIA CUDA SDK包含了BLAS功能,通过C语言实现能在GPU显卡上运行。

  • MKL: Intel核心数学库,支持Intel系列CPU,支持平台包括Linux, Windows及OS X。

参考链接

  1. Wikipedia BLAS
  2. Netlib BLAS

LAPACK

LAPACK(Linear Algebra Package)是数值线性代数的标准软件库。它提供了 求解线性方程组和线性最小二乘法、特征值问题和奇异值分解的实现;还包括矩阵分解的实现, 例如LU、QR、Cholesky和Schur分解。它的实现依赖于底层的BLAS。

官方或者常规实现一般使用Fortran,如果需要在其他语言使用,可以使用接口binding, 比如Python中的科学计算库SciPy默认使用OpenBlas,也可以选择官方Netlib的LAPACK。

实现
  • Netlib LAPACK: 官方实现出自 Netlib,编程语言为Fortran。

  • Intel MKL: Intel x86 CPU 的数学实现。

  • OpenBLAS: BLAS 和 LAPACK 的开源实现。

  • Eigen: 线性代数的头文件库,包含BLASK和部分LAPACK的实现。

参考链接

  1. Wikipedia LAPACK
  2. Netlib LAPACK
  3. SciPy BLAS/LAPACK

MKL

英特尔oneMKL是一个针对科学、工程和金融应用的优化数学程序库。 核心数学函数包括 BLAS、LAPACK、ScaLAPACK、稀疏求解器、快速傅里叶变换和向量数学。 该库支持 Intel CPU 和 GPU,并且可用于Windows、Linux和macOS 操作系统。 未开源,可以免费使用。

参考链接

  1. Intel oneMKL
  2. Wikipedia MKL

Eigen

Eigen是一个高级 C++ 模板头文件库,用于线性代数、矩阵和向量运算、几何变换、数值求解器和相关算法。 通过使用表达式模版和浮点运算的代价模型,代码库内部实现循环展开和向量化。

从 Eigen 3.3 及更高版本开始,任何F77兼容的BLAS或LAPACK 库都可以用作密集矩阵乘积和密集矩阵分解的后端。 例如,MKL、OpenBLAS、Netlib LAPACK等。

说明:由于BLAS/LAPACK接口偏低层不友好,一般使用的是 Eigen 进行C++功能开发; 特别依赖性能的实现一般直接使用 OpenBLAS或CuBLAS。

参考链接

  1. Eigen using BLAS/LAPACK

其他

除了上面的一些常规库,还有很多优化库,比如SuiteSparse用于稀疏矩阵运算, ceres-solver用于求解非线性优化问题,gtsam 通过因子图优化的方式求解最优问题等等。