OpenBLAS学习一:源码架构解析&GEMM分析

1. 什么是OpenBLAS

1.1. BLAS

BLAS (basic linear algebra subprogram) 是线性数学的基本计算,包括标量,矢量,矩阵之间的计算,分别称为Level1~3的操作。
由于level3的操作复杂度较高,于是产生了针对不同平台做优化的BLAS实现,包括 AMD Core Math Library (ACML), Arm Performance Libraries, ATLAS, Intel Math Kernel Library (MKL), 及我们要介绍的 OpenBLAS。

另外还要介绍一下 LAPACK,LAPACK是high-level的线性计算库,比如求解特征值,奇异值分解等。也是 OpenBLAS 支持的功能。

OpenBLAS
OpenBLAS 简单说就是 BLAS+LAPACK 在多种CPU上的重新实现。使用 C,Fortran 语言。OpenBLAS不支持GPU。
OpenBLAS 是gotoBLAS的一个分支,gotoBLAS在2008年开始停止更新。
这篇文章仅关注 BLAS 的实现,LAPACK 不在本文的考虑范围内,OpenBLAS 支持 Fortran 和 C 两个版本,我们关注C版本,对应头文件为 cblas.h
下面提到的 OpenBLAS 都是指其中的 CBLAS 部分。

1.2. 功能

包括level 1, 2, 3,分别指矢量和矢量,矢量和矩阵,矩阵和矩阵间的计算,对应的复杂度分别是 O ( n ) , O ( n 2 ) , O ( n 3 ) O(n), O(n^2), O(n^3) O(n),O(n2),O(n3)。很多科学计算,以及当下热门的深度学习的核心运算 CONV, FC 等都可以转化成矩阵乘法。
自然 level3 的性能是大家关注的重点。

1.3. 使用

1.3.1. 编译

包括 make, cmake 两套编译系统,都可以编译。
make直接在 TOP_DIR 下 make 即可,cmake 编译则按如下方式执行

cd cmake
cmake ..          # 生成相应的源码和makefile
cmake --build ..  # 编译生成库,生成的库文件在 `lib/` 下

OpenBLAS 默认会读取 CPU 配置,其型号(如 x86_64,HASWELL) core_num 会被读取作为默认配置。我的设备直接 make 的编译结果如下,库文件在 TOP_DIR 下。

 OpenBLAS build complete. (BLAS CBLAS LAPACK LAPACKE)

  OS               ... Linux             
  Architecture     ... x86_64               
  BINARY           ... 64bit                 
  C compiler       ... GCC  (cmd & version : cc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0)
  Library Name     ... libopenblas_haswellp-r0.3.13.dev.a (Multi-threading; Max num-threads is 16)

To install the library, you can run "make PREFIX=/path/to/your/installation install".

libopenblas_haswellp-r0.3.13.dev.a 表示多线程并行版本。

1.3.2. 调用

CBLAS调用方式如下。
以 gemm (generic matrix multiply)为例,实现的功能为
C = α A ∗ B + β C C = \alpha A * B + \beta C C=αAB+βC
A , B , C A, B, C A,B,C都是矩阵,维度分别是 M × K , K × N , M × N M\times K, K\times N, M\times N M×K,K×N,M×N

接口如下,其中 order 表示数据排布方式,包括 row-majorcol-major 两种方式,分别表示以行/列方向连续排布数据。lda 即矩阵A 的 leading dimension,以 row-major 为例,lda = K

#include "cblas.h"
int main()
{
   
    double A[6] = {
   1.0,2.0,1.0,-3.0,4.0,-1.0};         
    double B[6] = {
   1.0,2.0,1.0,-3.0,4.0,-1.0};  
    double C[9] = {
   .5,.5,.5,.5,.5,.5,.5,.5,.5}; 
    // dgemm C 版本接口
    
  • 20
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值