主要函数
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做转置操作(CblasTransCblasNoTrans)
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 intM,
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);
}
template <>
void caffe_cpu_gemv<double>(const CBLAS_TRANSPOSE TransA, const intM,
const int N, const double alpha,const double* A, const double* x,
const double beta, double* y) {
cblas_dgemv(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 = 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 += 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, unsignedint 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, constfloat* X,
constfloat 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= a + - * \ b)
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_log<float>(const int n, const float* a, float* y) {
vsLn(n, a, y);
}
template <>
void caffe_log<double>(const int n, const double* a, double* y) {
vdLn(n, a, y);
}
template <>
void caffe_abs<float>(const int n, const float* a, float* y) {
vsAbs(n, a, y);
}
template <>
void caffe_abs<double>(const int n, const double* a, double* y) {
vdAbs(n, a, y);
}
功能 : 同样是element-wise操作,分别是y= a ^ b, y = a^2,y = exp(a ),y = |a |
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) {
returnboost::math::nextafter<Dtype>(
b,std::numeric_limits<Dtype>::max());
}
功能 : 返回 b 较大方向上可以表示的最接近的数值。
13. caffe_rng_uniform 函数:
template <typename Dtype>
void caffe_rng_uniform(const int n, const Dtype a, const Dtype b, Dtype*r) {
CHECK_GE(n, 0);
CHECK(r);
CHECK_LE(a, b);
boost::uniform_real<Dtype>random_distribution(a, caffe_nextafter<Dtype>(b));
boost::variate_generator<caffe::rng_t*,boost::uniform_real<Dtype> >
variate_generator(caffe_rng(),random_distribution);
for (int i = 0; i < n; ++i) {
r = variate_generator();
}
}
14. caffe_rng_gaussian函数:
template <typename Dtype>
void caffe_rng_gaussian(const int n, const Dtype a,
const Dtype sigma, Dtype* r) {
CHECK_GE(n, 0);
CHECK(r);
CHECK_GT(sigma, 0);
boost::normal_distribution<Dtype> random_distribution(a, sigma);
boost::variate_generator<caffe::rng_t*,boost::normal_distribution<Dtype> >
variate_generator(caffe_rng(),random_distribution);
for (int i = 0; i < n; ++i) {
r = variate_generator();
}
}
15. caffe_rng_bernoulli函数:
template <typename Dtype>
void caffe_rng_bernoulli(const int n, const Dtype p, int* r) {
CHECK_GE(n, 0);
CHECK(r);
CHECK_GE(p, 0);
CHECK_LE(p, 1);
boost::bernoulli_distribution<Dtype> random_distribution(p);
boost::variate_generator<caffe::rng_t*,boost::bernoulli_distribution<Dtype> >
variate_generator(caffe_rng(),random_distribution);
for (int i = 0; i < n; ++i) {
r = variate_generator();
}
}
16.caffe_cpu_strided_dot函数:
template <>
float caffe_cpu_strided_dot<float>(const int n, const float* x,const int incx,
const float* y, const int incy){
return cblas_sdot(n, x, incx, y,incy);
}
功能: 返回 vector X 和 vector Y 的内积。
incx, incy : 步长,即每隔incx 或 incy 个element 进行操作。
17.
template <typename Dtype>
Dtype caffe_cpu_dot(const int n, const Dtype* x, const Dtype* y) {
return caffe_cpu_strided_dot(n, x,1, y, 1);
}
18. 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<double>(const int n, const double alpha, constdouble *x,
double*y) {
cblas_dcopy(n, x, 1, y, 1);
cblas_dscal(n, alpha, y, 1);
}
功能:y = alpha*x