caffe中各種cblas的函式使用總結

時光碎了天發表於2020-04-04
轉自:http://www.cnblogs.com/huashiyiqike/p/3886670.html 和http://blog.sina.com.cn/s/blog_4a03c0100101ethf.html
Y=alpha * X +beta*Y 
template <>
void caffe_cpu_axpby<float>(const int N, const float alpha, const float* X,
                            const float beta, float* Y) {
  cblas_saxpby(N, alpha, X, 1, beta, Y, 1);
}

template <>
void caffe_cpu_axpby<double>(const int N, const double alpha, const double* X,
                             const double beta, double* Y) {
  cblas_daxpby(N, alpha, X, 1, beta, Y, 1);
}
cblas_dscal(N, beta, Y, incY);  Y=Y*beta 
cblas_daxpy(N, alpha, X, incX, Y, incY);  Y= (alpha * X) + Y)



Y=alpha * X + Y 
template <>
void caffe_axpy<float>(const int N, const float alpha, const float* X,
    float* Y) { cblas_saxpy(N, alpha, X, 1, Y, 1); }

template <>
void caffe_axpy<double>(const int N, const double alpha, const double* X,
    double* Y) { cblas_daxpy(N, alpha, X, 1, Y, 1); }


DEFINE_VSL_BINARY_FUNC(Add, y[i] = a[i] + b[i]);
DEFINE_VSL_BINARY_FUNC(Sub, y[i] = a[i] - b[i]);
DEFINE_VSL_BINARY_FUNC(Mul, y[i] = a[i] * b[i]);
DEFINE_VSL_BINARY_FUNC(Div, y[i] = a[i] / b[i]);

template <>
void caffe_add<float>(const int n, const float* a, const float* b,
float* y) {
vsAdd(n, a, b, y);
}

template <>
void caffe_add<double>(const int n, const double* a, const double* b,
double* y) {
vdAdd(n, a, b, y);
}



y=x;
template <>
void caffe_copy<float>(const int N, const float* X, float* Y) {
  cblas_scopy(N, X, 1, Y, 1);
}

template <>
void caffe_copy<double>(const int N, const double* X, double* Y) {
  cblas_dcopy(N, X, 1, Y, 1);
}

template <>
void caffe_gpu_copy<float>(const int N, const float* X, float* Y) {
  CUBLAS_CHECK(cublasScopy(Caffe::cublas_handle(), N, X, 1, Y, 1));
}

template <>
void caffe_gpu_copy<double>(const int N, const double* X, double* Y) {
  CUBLAS_CHECK(cublasDcopy(Caffe::cublas_handle(), N, X, 1, Y, 1));
}


Computes alpha*x*y' + A.
cblas_sger
Multiplies vector X by the transform of vector Y, then adds matrix A (single precison).

Multiplies vector X by the transform of vector Y, then adds matrix A (single precison).
void cblas_sger (
const enum CBLAS_ORDER Order,
const int M,
const int N,
const float alpha,
const float *X,
const int incX,
const float *Y,
const int incY,
float *A,
const int lda
);

Y(vetor)←αAX + βY

This function multiplies A * X (after transposing A, if needed) and multiplies the resulting matrix by alpha. It then multiplies vector Y by beta. It stores the sum of these two products in vector Y.

template <>
void caffe_cpu_gemv<float>(const CBLAS_TRANSPOSE TransA, const int M,
    const int N, const float alpha, const float* A, const float* x,
    const float beta, float* y) {
  cblas_sgemv(CblasRowMajor, TransA, M, N, alpha, A, N, x, 1, beta, y, 1);
}



C(matrix)←αAB + βC
template<typename T>
void gpu_multmat(T* A, T* B, T* C, int M,int K,int N){
     const T alpha = 1,beta=0;
     caffe_gpu_gemm(CblasNoTrans,CblasNoTrans,M,N,K,alpha,A,B,beta,C);
}
template<>
void caffe_cpu_gemm<float>(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) {
  int lda = (TransA == CblasNoTrans) ? K : M;
  int ldb = (TransB == CblasNoTrans) ? N : K;
  cblas_sgemm(CblasRowMajor, TransA, TransB, M, N, K, alpha, A, lda, B,
      ldb, beta, C, N);
}



A=M*N  B=M*K
C=A'*B   N M K
template<typename T>
void cpu_multTmat(T* A, T* B, T* C, int M,int K,int N){
     const T alpha = 1,beta=0;
     caffe_cpu_gemm(CblasTrans,CblasNoTrans,M,N,K,alpha,A,B,beta,C);
    // cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, M, N, K, alpha, A, M, B,    K, beta, C, M);
}
A=M*N B=N*K
C=A*B   M N K


template<typename T>
void cpu_multmat(T* A, T* B, T* C, int M,int K,int N){
     const T alpha = 1,beta=0;
     caffe_cpu_gemm(CblasNoTrans,CblasNoTrans,M,N,K,alpha,A,B,beta,C);
    // cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, M, N, K, alpha, A, M, B,    K, beta, C, M);
}

計算矩陣乘法的函式之一是 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 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的資料

const int lda, const int ldb, const int ldc,在BLAS的文件裡,這三個引數分別為ABC的行數,但是實際使用發現,在CBLAS裡應該是列數。

相關文章