本文 以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=CblasNoTrans |
transa=CblasTrans |
Layout=CblasColMajor |
lda*k的矩阵 |
lda*m的矩阵 |
Layout=CblasRowMajor |
lda*m的矩阵 |
lda*k的矩阵 |
lda:
原矩阵a主行元素数量
|
transa=CblasNoTrans |
transa=CblasTrans |
Layout=CblasColMajor |
max(1,m) |
max(1,k) |
Layout=CblasRowMajor |
max(1,k) |
max(1,m) |
b:
|
transa=CblasNoTrans |
transa=CblasTrans |
Layout=CblasColMajor |
ldb*n的矩阵 |
ldb*k的矩阵 |
Layout=CblasRowMajor |
ldb*k的矩阵 |
ldb*n的矩阵 |
ldb:
原矩阵b主行元素数量
|
transa=CblasNoTrans |
transa=CblasTrans |
Layout=CblasColMajor |
max(1,k) |
max(1,n) |
Layout=CblasRowMajor |
max(1,n) |
max(1,k) |
beta:
标量
C:
Layout=CblasColMajor |
ldc*n的矩阵 |
Layout=CblasRowMajor |
ldc*m的矩阵 |
ldc:
Layout=CblasColMajor |
max(1,m) |
Layout=CblasRowMajor |
max(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,
(CblasNoTrans == transa)?k:m,
b,
(CblasNoTrans == transb)?n:k,
beta, c,
n);
}
列主序:
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,
(CblasNoTrans == transa)?m:k,
b,
(CblasNoTrans == transb)?k:n,
beta, c,
m);
}
行主序调用列主序:
可以采用该方式统一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)
{
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)
{
ABC_row(transb, transa,
n, m, k,
alpha, b, a,
beta, c);
}
相关文献
1、OpenBlas官网
2、MKL文档