BLAS
简介
BLAS
全称是Basic Linear Algebra Subprograms
是规定了一套低级的执行常见线性代数操作的规范。其实现经常针对特殊的机器进行优化,比较著名的·BLAS库有
ACML, ATLAS, MKL, OpenBLAS。许多常见的数值软件均采用兼容
BLAS规范的实现库来进行线性代数计算,比如
Matlab, Numpy, Mathematica`。
其中,Level 1 BLAS
主要提供向量操作
Level 2 BLAS
提供矩阵向量操作(gemv)
而
Level 3 BLAS
则提供广义矩阵乘积操作(gemm)
GEMM
在深度学习中是十分重要的,全连接层以及卷积层基本上都是通过GEMM
来实现的,而网络中大约90%的运算都是在这两层中。而一个良好的GEMM
的实现可以充分利用系统的多级存储结构和程序执行的局部性来充分加速运算。
gemm
接口解析
gemm
的函数接口如下图所示,darknet
中也采用了类似的接口设计。
其中,
A,B,C
分别是MxK, KxN, MxN
的矩阵,TRANSA, TRANSB, TRANSC
表示是否使用对应矩阵的转置,ALPHA, BETA
为对应的系数。而LDA, LDB, LDC
表示对应矩阵的leading dimension
,即第一维度的大小。根据我的理解(结合darknet
的源码),是因为在内存中是连续存放的,而这个leading dimension
的量是用来定义元素的位置的,即add(A[i, j])=A+i*lda+j
。其中sgemm
中的s
表示是单精度的运算,类似的,还有dgemm
。
BLAS sgemm()的实现
* Form C := alpha*A**T*B**T + beta*C
*
DO 200 J = 1,N
DO 190 I = 1,M
TEMP = ZERO
DO 180 L = 1,K
TEMP = TEMP + A(L,I)*B(J,L)
180 CONTINUE
IF (BETA.EQ.ZERO) THEN
C(I,J) = ALPHA*TEMP
ELSE
C(I,J) = ALPHA*TEMP + BETA*C(I,J)
END IF
190 CONTINUE
200 CONTINUE
上述代码是Fortran
语言,三篇有关于BLAS
的论文也都是用的Fortran
语言写的,在官网上也提供C
的接口,但是是直接调用的Fortran
编写的程序。
参考文献
- Basic Linear Algebra Subprograms-WikiPeia
- Dongarra J J, Croz J D, Hammarling S, et al. A set of level 3 basic linear algebra subprograms[J]. Acm Transactions on Mathematical Software, 1990, 16(1):1-17.
- Why gemm is at the heart of deep learning
- sgemm 官方文档