设为首页 加入收藏

TOP

CBLAS编译安装与使用举例(一)
2015-02-13 18:23:29 来源: 作者: 【 】 浏览:85
Tags:CBLAS 编译 安装 使用 举例

在Github上看到有人用BLAS library优化自己的源码,对此产生了强烈兴趣。


准备自己动手实践一下,网上搜索了一大堆编译安装BLAS教程的资料,没一个靠谱的,编译过程中遇到一堆的问题。因为自己没有root权限,所以只能在home目录中本地编译使用cblas,然后本地链接编译得到的库文件到应用程序。


最后自己凭着直觉连蒙带猜,终于把BLAS与CBLAS装上,并投入到实例中优化运行应用程序。填补了很多Linux知识。?


首先要解释一下BLAS,CBLAS与LAPAXK之间的区别与联系。


CBLAS只是BLAS的C语言版本,所以CBLAS安装需要先装BLAS


1. 编译blas,进入BLAS目录执行下面的命令


? ? gfortran -c? -O3? ? *.f? ? ? ? ? ? ? ? # 编译所有的 .f 文件,生成 .o文件?
? ? ar rv libblas.a? ? ? *.o? ? ? ? ? ? ? ? # 链接所有的 .o文件,生成 .a 文件?


2. 编译cblas,进入CBLAS目录,首先根据自己的操作系统平台,将某个Makefiel.XXX复制为Makefile.in,XXX表示操作系统。如果是Linux,那么就将Makefile.LINUX 复制为 Makefile.in。


? ? cp ../BLAS/libblas.a? testing? # 将上一步编译成功的 libblas.a 复制到 CBLAS目录下的testing子目录?
? ? make? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # 编译所有的目录?


此时会在CBLAS安装目录下的lib目录中产生一个静态链接库文件cblas_LINUX.a,这个库文件和上面得到的libblas.a文件就是我们所需要的。另外还需要的就是CBLAS/include中的cblas.h头文件。将三个文件全部拷贝到,你需调用的应用程序源码目录中。


?


到此BLAS和CBLAS的安装任务完成,可以看出,这里安装的实际含义是编译得到两个库文件和一个头文件,再将这三个文件放置到gcc的搜索路径中去(例如可以在拷贝到/esr/local/lib,或在/usr/local/lib下做一个快捷链接,也可直接像我上面那样复制的)。


cd /usr/local/lib
ln -s? ./CBLAS/lib/cblas_LINUX.a? ./libcblas.a


CBLAS/BLAS分为3个level,level1是用于向量的计算,level2是用于向量和矩阵之间的计算,level3是矩阵之间的计算。比如计算矩阵的乘法就是属于level3,这里就用矩阵乘法来学习使用CBLAS。


计算矩阵乘法的函数之一是 cblas_sgemm,使用单精度实数,另外还有对应双精度实数,单精度复数和双精度复数的函数。在此以 cblas_sgemm为例。


函数定义为:


void cblas_sgemm ( const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const enum CBLAS_TRANSPOSE TransB, const int M, const int N,


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const int K, const float alpha, const float *A,


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const int lda, const float *B, const int ldb,


? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? const float beta, float *C, const int ldc? )


此函数计算的是 C = alpha*op( A )*op( B ) + beta*C,


const enum CBLAS_ORDER Order,这是指的数据的存储形式,在CBLAS的函数中无论一维还是二维数据都是用一维数组存储,这就要涉及是行主序还是列主序,在C语言中数组是用行主序,fortran中是列主序。我还是习惯于是用行主序,所以这个参数是用CblasRowMajor,如果是列主序的话就是CblasColMajor。


?


const enum CBLAS_TRANSPOSE TransA和 const enum CBLAS_TRANSPOSE TransB,这两个参数影响的是op( A )和op( B),可选参数为CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113,其中TransA = CblasNoTrans, op( A ) = A,TransA = CblasTrans, op( A ) = A',TransA = CblasConjTrans, op( A ) = A'。 TransB类似。


const int M,矩阵A的行,矩阵C的行
const int N,矩阵B的列,矩阵C的列
const int K,矩阵A的列,矩阵B的行
const float alpha, const float beta,计算公式中的两个参数值,如果只是计算C=A*B,则alpha=1,beta=0


const float *A, const float *B, const float *C,矩阵ABC的数据


计算两个简单矩阵的乘法。
A:
1,2,3
4,5,6
7,8,9
8,7,6
B:
5,4
3,2
1,0


// 因为程序是C++,而CBLAS是C语言写的,所以在此处用extern关键字
extern"C"
{
? ? #include"cblas.h"? ? ? // 由于cblas.h文件已经拷贝到工作目录中,只需用双引号
}
#include
using namespace std;
int main(void) {
? ? const enum CBLAS_ORDER Order=CblasRowMajor;
? ? const enum CBLAS_TRANSPOSE TransA=CblasNoTrans;
? ? const enum CBLAS_TRANSPOSE TransB=CblasNoTrans;
? ? const int M=4;//A的行数,C的行数
? ? const int N=2;//B的列数,C的列数
? ? const int K=3;//A的列数,B的行数
? ? const float alpha=1;
? ? const float beta=0;
? ? const int lda=K;//A的列
? ? const int ldb=N;//B的列
? ? const int ldc=N;//C的列
? ? const float A[K*M]={1,2,3,4,5,6,7,8,9,8,7,6};
? ? const float B[K*N]={5,4,3,2,1,0};
? ? float C[M*N];
?
? ? cblas_sgemm(Order, TransA, TransB, M, N, K, alpha, A, lda, B, ldb, beta, C, ldc);
? ?
? ? for(int i=0;i? ? {
? ? ? for(int j=0;j? ? ? {
? ? ? ? ? cout<? ? ? }
? ? ? cout<? ? }
?
? ? return EXIT_SUCCESS;
}


在编译的时候需要带上cblas_LINUX.a和libblas.a?


比如:g++ main.cpp cblas_LINUX.a libblas.a -o main


如果是写成Makefile文件,则修改变量OBJS = main.o cblas_LINUX.a libblas.a


当然,这里假定是这两个.a文件是放在可以直接访问的位置,

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇Linux下测试程序运行时间 下一篇Python open() 函数 文件处理

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: