mkl行主序、列主序转换——以cblas_sgemm为例

本文 以mkl中的cblas_sgemm为例演示行主序、列主序调用方式以及相互调用。

cblas_sgemm接口:

void cblas_sgemm (const CBLAS_LAYOUT Layout, const CBLAS_TRANSPOSE transa, const
CBLAS_TRANSPOSE transb, const MKL_INT m, const MKL_INT n, const MKL_INT k, const float
alpha, const float *a, const MKL_INT lda, const float *b, const MKL_INT ldb, const
float beta, float *c, const MKL_INT ldc);

功能描述:

C = alpha*op(A)op(B) + betaC

其中:

op(X)=X或者op(X)=X’;

alpha、beta均为标量;

A、B、C均为矩阵;

op(A)是形状为m x k的矩阵;

op(B)是形状为k x n的矩阵;

C是形状为m x n的矩阵;

输入参数:

layout:

行主序(CblasRowMajor)

列主序(CblasColMajor)

transa:

矩阵A非转置(CblasNoTrans),即op(A)=A

矩阵A转置(CblasTrans),即op(A)=A’

transb:

矩阵B非转置(CblasNoTrans),即op(B)=B

矩阵B转置(CblasTrans),即op(B)=B’

m:

矩阵op(A)与矩阵C的行数

n:

矩阵op(B)与矩阵C的列数

k:

矩阵op(A)的列数与矩阵op(B)的行数

alpha:

标量

a:

transa=CblasNoTranstransa=CblasTrans
Layout=CblasColMajorlda*k的矩阵lda*m的矩阵
Layout=CblasRowMajorlda*m的矩阵lda*k的矩阵

lda:

原矩阵a主行元素数量

transa=CblasNoTranstransa=CblasTrans
Layout=CblasColMajormax(1,m)max(1,k)
Layout=CblasRowMajormax(1,k)max(1,m)

b:

transa=CblasNoTranstransa=CblasTrans
Layout=CblasColMajorldb*n的矩阵ldb*k的矩阵
Layout=CblasRowMajorldb*k的矩阵ldb*n的矩阵

ldb:

原矩阵b主行元素数量

transa=CblasNoTranstransa=CblasTrans
Layout=CblasColMajormax(1,k)max(1,n)
Layout=CblasRowMajormax(1,n)max(1,k)

beta:

标量

C:

Layout=CblasColMajorldc*n的矩阵
Layout=CblasRowMajorldc*m的矩阵

ldc:

Layout=CblasColMajormax(1,m)
Layout=CblasRowMajormax(1,n)

输出参数:

c

调用方法:

行主序

void ABC_row(const CBLAS_TRANSPOSE transa,const CBLAS_TRANSPOSE transb,
const int m, const int n, const int k,
const float alpha, const float* a,
const float* b,
const float beta, float* c)
{
	/*一般都是行主序调用*/
	cblas_sgemm(CblasRowMajor, transa, transb, 
				m, n, k,
				alpha, a,
				/*op(a)为mxk,且为行主序:
					如果矩阵a不用转置,则:op(a)=a,lda为k(原矩阵a(mxk)的每行有k个元素)
					如果矩阵a需要转置,则:op(a)=a',lda为m(原矩阵a(kxm)的每行有m个元素)
				*/
				(CblasNoTrans == transa)?k:m,
				b,
				/*op(b)为kxn,且为行主序:
					如果矩阵b不用转置,则:op(b)=b,ldb为n(原矩阵b(kxn)的每行有n个元素)
					如果矩阵b需要转置,则:op(b)=b',ldb为k(原矩阵b(nxk)的每行有k个元素)
				*/				
				(CblasNoTrans == transb)?n:k,
				beta, c, 
				n); //矩阵c为mxn,且为行主序
}

列主序:

void ABC_col(const CBLAS_TRANSPOSE transa,const CBLAS_TRANSPOSE transb,
const int m, const int n, const int k,
const float alpha, const float* a,
const float* b,
const float beta, float* c)
{
	cblas_sgemm(CblasColMajor, transa, transb, 
				m, n, k,
				alpha, a,
				/*op(a)为mxk,且为列主序:
					如果矩阵a不用转置,则:op(a)=a,lda为m(原矩阵a(mxk)的每列有m个元素)
					如果矩阵a需要转置,则:op(a)=a',lda为k(原矩阵a(kxm)的每列有k个元素)
				*/								
				(CblasNoTrans == transa)?m:k,
				b,
				/*op(b)为kxn,且为列主序:
					如果矩阵b不用转置,则:op(b)=b,ldb为k(原矩阵b(kxn)的每列有k个元素)
					如果矩阵b需要转置,则:op(b)=b',ldb为n(原矩阵b(nxk)的每列有n个元素)
				*/						
				(CblasNoTrans == transb)?k:n,
				beta, c, 
				m);//矩阵c为mxn,且为列主序
}

行主序调用列主序

可以采用该方式统一MKL或openblas与cublas的接口一致性,因为cublas采用的是列主序。

void ABC_row(const CBLAS_TRANSPOSE transa,const CBLAS_TRANSPOSE transb,
const int m, const int n, const int k,
const float alpha, const float* a,
const float* b,
const float beta, float* c)
{
	/* C = alpha * A * B + beta * C --> C' = alpha * B' * A' + beta * C' */
	ABC_col(transb, transa, 
			n, m, k, 
			alpha, b, a, 
			beta, c);
}

列主序调用行主序:

(一般不会这样使用)

void ABC_col(const CBLAS_TRANSPOSE transa,const CBLAS_TRANSPOSE transb,
const int m, const int n, const int k,
const float alpha, const float* a,
const float* b,
const float beta, float* c)
{
	/* C = alpha * A * B + beta * C --> C' = alpha * B' * A' + beta * C' */
	ABC_row(transb, transa, 
			n, m, k, 
			alpha, b, a, 
			beta, c);
}

相关文献

1、OpenBlas官网

2、MKL文档

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
cblas_dgemm是一个基于BLAS(Basic Linear Algebra Subprograms)库的矩阵乘法函数,用于计算两个矩阵的乘积。以下是cblas_dgemm的源代码及解析: ``` void cblas_dgemm( const CBLAS_LAYOUT Layout, const CBLAS_TRANSPOSE TransA, const CBLAS_TRANSPOSE TransB, const MKL_INT M, const MKL_INT N, const MKL_INT K, const double alpha, const double *A, const MKL_INT lda, const double *B, const MKL_INT ldb, const double beta, double *C, const MKL_INT ldc) ``` 参数解析: - Layout:指定矩阵数据的存储格式,可以是CblasRowMajor或CblasColMajor。 - TransA:指定是否需要对矩阵A进行转置操作,可以是CblasNoTrans或CblasTrans。 - TransB:指定是否需要对矩阵B进行转置操作,可以是CblasNoTrans或CblasTrans。 - M:指定矩阵C的行数。 - N:指定矩阵C的列数。 - K:指定矩阵A和矩阵B的公共维数。 - alpha:指定矩阵A与矩阵B的乘积的缩放因子。 - A:指向矩阵A的首地址。 - lda:指定矩阵A的列数。 - B:指向矩阵B的首地址。 - ldb:指定矩阵B的列数。 - beta:指定矩阵C的缩放因子。 - C:指向矩阵C的首地址。 - ldc:指定矩阵C的列数。 cblas_dgemm的实现采用了通用矩阵乘法算法(GEMM),具体实现细节详见BLAS库的文档。通用矩阵乘法算法的核心思想是将矩阵的乘法拆分成多个向量的乘积,以加速计算。在BLAS库中,通用矩阵乘法算法的实现包括了多种优化策略,如缓存优化、向量化优化等,可以在不同架构的计算机上达到较好的性能表现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值