1. 程式人生 > >Caffe math_functions

Caffe math_functions

主要函式

math_function 定義了caffe 中用到的一些矩陣操作和數值計算的一些函式,這裡以float型別為例做簡單的分析

1. caffe_cpu_gemm 函式:

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);

}

功能: C=alpha*A*B+beta*C

A,B,C 是輸入矩陣(一維陣列格式)

CblasRowMajor :資料是行主序的(二維資料也是用一維陣列儲存的)

TransA, TransB:是否要對A和B做轉置操作(CblasTrans CblasNoTrans)

M: A、C 的行數

N: B、C 的列數

K: A 的列數, B 的行數

lda : A的列數(不做轉置)行數(做轉置)

ldb: B的列數(不做轉置)行數(做轉置)

2. caffe_cpu_gemv 函式:

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);

}

功能: y=alpha*A*x+beta*y

其中X和Y是向量,A 是矩陣

M:A 的行數

N:A 的列數

cblas_sgemv 中的 引數1 表示對X和Y的每個元素都進行操作

3.caffe_axpy 函式:

template <>void caffe_axpy<float>(const int N, const float alpha, const float* X,float* Y) {

    cblas_saxpy(N, alpha, X, 1, Y, 1);

}

功能: Y=alpha*X+Y

N:為X和Y中element的個數

4.caffe_set 函式:

template <typename Dtype>void caffe_set(const int N, const Dtype alpha, Dtype* Y) {

    if (alpha == 0) {

        memset(Y, 0, sizeof(Dtype) * N); // NOLINT(caffe/alt_fn)

        return;

    }

    for (int i = 0; i < N; ++i) {

        Y[i] = alpha;

    }

}

功能:用常數 alpha 對 Y 進行初始化

函式 void *memset(void *buffer, char c, unsigned count) 一般為新申請的記憶體做初始化,功能是將buffer所指向記憶體中的每個位元組的內容全部設定為c指定的ASCII值, count為塊的大小

5.caffe_add_scalar 函式:

template <>void caffe_add_scalar(const int N, const float alpha, float* Y) {

    for (int i = 0; i < N; ++i) {

        Y[i] += alpha;

    }

}

功能: 給 Y 的每個 element 加上常數 alpha

6.caffe_copy 函式:

template <typename Dtype>void caffe_copy(const int N, const Dtype* X, Dtype* Y) {

    if (X != Y) {

        if (Caffe::mode() == Caffe::GPU) {

            #ifndef CPU_ONLY

                // NOLINT_NEXT_LINE(caffe/alt_fn)

                CUDA_CHECK(cudaMemcpy(Y, X, sizeof(Dtype) * N, cudaMemcpyDefault));

            #else

                NO_GPU;

            #endif

        } else {

            memcpy(Y, X, sizeof(Dtype) * N); // NOLINT(caffe/alt_fn)

        }

    }

}

函式 void *memcpy(void *dest, void *src, unsigned int count) 把src所指向的記憶體區域 copy到dest所指向的記憶體區域, count為塊的大小

7.caffe_scal 函式:

template <>void caffe_scal<float>(const int N, const float alpha, float *X) {

    cblas_sscal(N, alpha, X, 1);

}

功能:X = alpha*X

N: X中element的個數

8.caffeine_cup_axpby 函式:

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);

}

功能:Y= alpha*X+beta*Y

9.caffe_add、 caffe_sub、 caffe_mul、 caffe_div 函式:

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

    vsAdd(n, a, b, y);

}

template <>void caffe_sub<float>(const int n, const float* a, const float* b,float* y) {

    vsSub(n, a, b, y);

}

template <>void caffe_mul<float>(const int n, const float* a, const float* b,float* y) {

    vsMul(n, a, b, y);

}

template <>void caffe_div<float>(const int n, const float* a, const float* b,float* y) {

    vsDiv(n, a, b, y);

}

功能:這四個函式分別實現element-wise的加減乘除(y[i] = a[i] + - * \ b[i])

10.caffe_powx、 caffe_sqr、 caffe_exp、 caffe_abs 函式:

template <>void caffe_powx<float>(const int n, const float* a, const float b,float* y) {

    vsPowx(n, a, b, y);

}

template <>void caffe_sqr<float>(const int n, const float* a, float* y) {

    vsSqr(n, a, y);

}

template <>void caffe_exp<float>(const int n, const float* a, float* y) {

    vsExp(n, a, y);

}

template <>void caffe_abs<float>(const int n, const float* a, float* y) {

    vsAbs(n, a, y);

}

功能 : 同樣是element-wise操作,分別是y[i] = a[i] ^ b, y[i] = a[i]^2,y[i] = exp(a[i] ),y[i] = |a[i] |

11.int caffe_rng_rand 函式:

unsigned int caffe_rng_rand() {

    return (*caffe_rng())();

}

功能:返回一個隨機數

12.caffe_nextafer 函式:

template <typename Dtype>Dtype caffe_nextafter(const Dtype b) {

    return boost::math::nextafter<Dtype>(b, std::numeric_limits<Dtype>::max());

}

功能 : 返回 b 最大方向上可以表示的最接近的數值。

13.caffe_cpu_strided_dot 函式:

template <>double caffe_cpu_strided_dot<double>(const int n, const double* x,const int incx, const double* y, const int incy) {

    return cblas_ddot(n, x, incx, y, incy);

}

功能: 返回 vector X 和 vector Y 的內積。

incx, incy : 步長,即每隔incx 或 incy 個element 進行操作。

14.caffe_cpu_hamming_distance 函式:

template <>int caffe_cpu_hamming_distance<float>(const int n, const float* x,const float* y) {

    int dist = 0;

    for (int i = 0; i < n; ++i) {

        dist += __builtin_popcount(static_cast<uint32_t>(x[i]) ^

        static_cast<uint32_t>(y[i]));

    }

    return dist;

}

功能:返回 x 和 y 之間的海明距離。(兩個等長字串之間的海明距離是兩個字串對應位置的不同字元的個數。)

15. caffe_cpu_asum 函式:

template <>float caffe_cpu_asum<float>(const int n, const float* x) {

    return cblas_sasum(n, x, 1);

}

功能:計算 vector x 的所有element的絕對值之和。

16.caffe_cpu_scale 函式:

template <>void caffe_cpu_scale<float>(const int n, const float alpha, const float *x,float* y) {

    cblas_scopy(n, x, 1, y, 1);

    cblas_sscal(n, alpha, y, 1);

}

功能:y = alpha*x