caffe 源码解读 Part1
1. 基础知识
- inline
C++关键字,在函数声明或定义中函数返回类型前加上关键字inline,即可以把函数指定为在计算机科学中,内联函数(有时称作在线函数或编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展);也就是说建议编译器将指定的函数体插入并取代每一处调用该函数的地方(上下文),从而节省了每次调用函数带来的额外时间开支。但在选择使用内联函数时,必须在程序占用空间和程序执行效率之间进行权衡,因为过多的比较复杂的函数进行内联扩展将带来很大的存储资源开支。另外还需要特别注意的是对递归函数的内联扩展可能引起部分编译器的无穷编译。。关键字inline必须与函数定义放在一起才能使函数成为内联,仅仅将inline放在函数声明前面不起任何作用。inline是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。
内联函数:在计算机科学中,内联函数(有时称作在线函数或编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展);也就是说建议编译器将指定的函数体插入并取代每一处调用该函数的地方(上下文),从而节省了每次调用函数带来的额外时间开支。但在选择使用内联函数时,必须在程序占用空间和程序执行效率之间进行权衡,因为过多的比较复杂的函数进行内联扩展将带来很大的存储资源开支。另外还需要特别注意的是对递归函数的内联扩展可能引起部分编译器的无穷编译。
- CHECK
#define CHECK_EQ(val1, val2) CHECK_OP(_EQ, ==,val1, val2) //相当于assert(val1 == val2) release下可用,如果检测为true,则返回NULL,否则就会返回一个有明确提示信息的字符串指针,并输出该信息,然后是程序宕掉。以下同理
#define CHECK_NE(val1, val2) CHECK_OP(_NE, !=,val1, val2) //相当于assert(val1 != val2)
#define CHECK_LE(val1, val2) CHECK_OP(_LE, <=,val1, val2) //相当于assert(val1 <= val2)
#define CHECK_LT(val1, val2) CHECK_OP(_LT, < ,val1, val2) // 相当于assert(val1 < val2)
#define CHECK_GE(val1, val2) CHECK_OP(_GE, >=,val1, val2) //相当于assert(val1 >= val2)
//CHECK(...)相当于assert ...
2.主要变量
shared_ptr<SyncedMemory> data_;
shared_ptr<SyncedMemory> diff_;
shared_ptr<SyncedMemory> shape_data_;
vector<int> shape_;
int count_;
int capacity_;
BLob只是一个基本的数据结构,因此内部的变量相对较少,首先是data_指针,指针类型是shared_ptr,属于boost库的一个智能指针,这一部分主要用来申请内存存储data,data主要是正向传播的时候用的。同理,diff_主要用来存储偏差,update data,shape_data和shape_都是存储Blob的形状,一个是老版本一个是新版本。count表示Blob中的元素个数,也就是个数* 通道数 * 高度 *宽度,capacity表示当前的元素个数,因为Blob可能会reshape。
3. 函数
- LegacyShape
//返回指定维度的值
inline int LegacyShape(int index) const {
CHECK_LE(num_axes(), 4)//判断维度是否小于等于4
<< "Cannot use legacy accessors on Blobs with > 4 axes.";
CHECK_LT(index, 4);//inde < 4
CHECK_GE(index, -4);//index >= -4
if (index >= num_axes() || index < -num_axes()) {
// Axis is out of range, but still in [0, 3] (or [-4, -1] for reverse
// indexing) -- this special case simulates the one-padding used to fill
// extraneous axes of legacy blobs.
return 1;
}
return shape(index);//返回这个维度的值
}
- num(), channels(), height(), width()
//分别返回N, C, H, W
inline int num() const {
return LegacyShape(0);
}
inline int channels() const {
return LegacyShape(1);
}
inline int height() const {
return LegacyShape(2);
}
inline int width() const {
return LegacyShape(3);
}
- data and diff
cpu_data()
mutable_cup_data()
cpu_diff()
mutable_cup_diff()
gpu_data()
mutable_gpu_data()
gpu_diff()
mutable_gpu_data()
//读数据的时候要加cpu_data(),写数据的时候加mutable_cpu_data()
if (dist_matrix.cpu_data()[anc * nums + neg] > dist_matrix.cpu_data()[anc * nums + pos])
correct_rank_count += Dtype(1);
dist_matrix.mutable_cpu_data()[j * nums + i] = dist_matrix.mutable_cpu_data()[i * nums + j];
- caffe_
reference: https://blog.csdn.net/seven_first/article/details/47378697
/*****************************************************************
*name: caffe_scal
*function: X = alpha * X
*N: X中element的个数
*****************************************************************/
template <>
void caffe_scal<float>(const int N, const float alpha, float *X) {
cblas_sscal(N, alpha, X, 1);
}
/*****************************************************************
*这四个函数分别实现element-wise的加减乘除(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_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);
}
/*****************************************************************
功能: 返回 vector X 和 vector Y 的内积。
incx, incy : 步长,即每隔incx 或 incy 个element 进行操作。
*****************************************************************/
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);
}
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);
}
/*****************************************************************
功能: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);
}