下一篇:从零开始的 Rust 语言 blas 库之预备篇(2)—— blas 矩阵格式详解
文章部分参考:https://blog.csdn.net/hehe199807/article/details/108365427
最近想着自己即将要踏入深度学习的领域发展,不能够只知其用法却不知道底层。
许多深度学习的模型,底层本质都是矩阵运算,于是突发奇想,打算自己移植一个线性代数库。凭借着之前的并行计算的基础,我选中了 blas 库,也是顺应了时代。
至于开发语言,我选中了 Rust 语言。一部分原因是我曾经参与过 rcore 项目,另一方面是 Rust 语言最近开始被 linux 社区接受了,我想也是时候支持这门新生语言了。
项目取名为 roblas,含义为 rust-only blas,项目地址为:https://github.com/rust-family/roblas
此处基本参考:https://blog.csdn.net/hehe199807/article/details/108365427
BLAS 库,即 Basic Linear Algrbra Subprograms,是进行向量和矩阵等基本线性代数操作的事实上的数值库。这些程序最早在 1979 年发布,是 LAPACK(Linear Algebra PACKage) 的一部分,便于建立功能更强的数值程序包。BLAS库在高性能计算中被广泛应用,由此衍生出大量优化版本,如 Intel MKL,AMD 的 ACML,ATLAS 等。在 cuda 计算领域,也有实现了相应接口的 cublas 库存在。
BLAS 中对每个函数的功能定义见官方:http://netlib.org/blas/blasqr.pdf。BLAS 函数名中的前缀 “x
” 表示参数和返回值的类型:
其中混合精度由 S,D,C,Z 组成,最左边表示返回值类型,其余为参数类型。如 DROTMG 表示的是双精度的平面转换,SSCAL 表示的则是单精度的向量缩放。
此处有一个解释较好的回答:https://zhuanlan.zhihu.com/p/104287878。
在 BLAS2 和 BLAS3 的函数中,有以下重要的参数:
正如之前所说,BLAS 只是一组向量和矩阵运行的接口规范,也可以称为API规范。Netlib 用 fortran 实现了 BLAS 的这些 API 接口,得到的库也叫做 BLAS。Netlib只是一般性地实现了基本功能,并没有对运算做过多的优化。
LAPACK (linear algebra package),是著名的线性代数库,也是 Netlib 用 fortran 语言编写的。其底层是 BLAS,在此基础上定义了很多矩阵和向量高级运算的函数,如矩阵分解、求逆和求奇异值等。该库的运行效率比 BLAS 库高。
从某个角度讲,LAPACK 也可以称作是一组科学计算(矩阵运算)的接口规范。Netlib 实现了这一组规范的功能,得到的这个库叫做 LAPACK 库。
前面 BLAS 和 LAPACK 的实现均是用的 Fortran 语言。为了方便 c 程序的调用,Netlib 开发了 CBLAS 和 CLAPACK。其本质是在 BLAS 和 LAPACK 的基础上,增加了 c 的调用方式。
再有了接口规范之后,其他的组织、个人和公司,就可以根据此规范,实现自己的科学计算库。
开源社区实现的科学计算(矩阵计算)库中,比较著名的两个就是 atlas 和 OpenBLAS。它们都实现了 BLAS 的全部功能,以及 LAPACK 的部分功能,并且他们都对计算过程进行了优化。
下面是一些相关链接:
目前的计划,是依照 netlib 的 cblas 库进行初版 roblas 的实现,即函数名需要遵守 c 规范,可能考虑后续与 c 进行链接测试。
netlib 中关于 blas 的使用文档非常的粪坑,因此在此找到了两个较好的文档:
https://www.hpc.nec/documents/sdk/SDK_NLC/UsersGuide/blas/f/en/index.html
https://spec.oneapi.com/versions/0.7/elements/oneMKL/source/domains/blas/blas.html#onemkl-blas
平台相关的优化,预计在明年再实现,主要涉及到多线程以及 SIMD 优化。Rust 的多线程支持已经基本完善,x86/x64 的 SIMD 支持也已经到位,理论上可以实现。
码字不易,且看且珍惜~