caffe源代码分析--Blob类代码研究
作者:linger
转自须注明转自:http://blog.csdn.net/lingerlanlan/article/details/24379689
数据成员
shared_ptr<SyncedMemory>data_;//data数据。指向SyncedMemory的智能指针
shared_ptr<SyncedMemory>diff_;//表示“差”。用于更新data_
intnum_;
intchannels_;
intheight_;
intwidth_;
intcount_;
构造函数
Blob():num_(0),channels_(0),height_(0),width_(0),count_(0),data_(),diff_(){}
功能:简单的初始化
explicitBlob(constintnum,constintchannels,constintheight,constintwidth);
功能:调用Reshape函数。初始化数据成员
template<typenameDtype>
Blob<Dtype>::Blob(constintnum,constintchannels,constintheight,
constintwidth)
{
Reshape(num,channels, height, width);
}
析构函数
virtual~Blob(){}
功能:啥都没做?
voidReshape(constintnum,constintheight,
constintwidth,constintchannels);
功能:初始化数据成员,智能指针指向SyncedMemory对象。此时SyncedMemory对象事实上并没有为自己的“数据”申请内存,仅仅是自己“数据”的大小(size)。
template<typenameDtype>
voidBlob<Dtype>::Reshape(constintnum,constintchannels,constintheight,
constintwidth)
{
CHECK_GE(num,0);
CHECK_GE(channels,0);
CHECK_GE(height,0);
CHECK_GE(width,0);
num_=
num;
channels_=
channels;
height_=
height;
width_=
width;
count_=num_*channels_*height_*width_;
if(count_){
data_.reset(newSyncedMemory(count_*sizeof(Dtype)));
diff_.reset(newSyncedMemory(count_*sizeof(Dtype)));
}else{
data_.reset(reinterpret_cast<SyncedMemory*>(NULL));
diff_.reset(reinterpret_cast<SyncedMemory*>(NULL));
}
}
成员訪问函数
功能:就是返回一些成员变量
inlineintnum()const{returnnum_;}
inlineintchannels()const{returnchannels_;}
inlineintheight()const{returnheight_;}
inlineintwidth()const{returnwidth_;}
inlineintcount()const{returncount_;}
inlineintoffset(constintn,constintc
= 0, constinth
= 0,constintw
= 0) const{
return((n
* channels_+ c) *height_+
h) *width_+ w;
//计算偏移量,由于数据在内存是一维数组形式的,所以须要计算偏移量来訪问
}
“数据”指针返回函数
功能:事实上这些函数就是调用SyncedMemory的函数,来返回数据的指针
constDtype*cpu_data()const;
constDtype*gpu_data()const;
constDtype*cpu_diff()const;
constDtype*gpu_diff()const;
Dtype*mutable_cpu_data();
Dtype*mutable_gpu_data();
Dtype*mutable_cpu_diff();
Dtype*mutable_gpu_diff();
inlineDtypedata_at(constintn,constintc,constinth,
constintw)const{
//从cpu訪问数据data
return*(cpu_data()+
offset(n, c, h, w));
}
inlineDtypediff_at(constintn,constintc,constinth,
constintw)const{
//从cpu訪问数据diff
return*(cpu_diff()
+ offset(n, c, h, w));
}
函数voidUpdate()
功能:更新data_的数据,就是减去diff_的数据。
template<typenameDtype>
voidBlob<Dtype>::Update(){
//We
will perform update based on where the data is located.
switch(data_->head()){
caseSyncedMemory::HEAD_AT_CPU:
//perform
computation on CPU
caffe_axpy<Dtype>(count_,Dtype(-1),
reinterpret_cast<constDtype*>(diff_->cpu_data()),
reinterpret_cast<Dtype*>(data_->mutable_cpu_data()));
//在math_functions.cpp能够找到该函数的实现。事实上这函数也是封装了mkl的函数。这里调用是为了实现了两个向量的减法。
break;
caseSyncedMemory::HEAD_AT_GPU:
caseSyncedMemory::SYNCED:
//perform
computation on GPU
caffe_gpu_axpy<Dtype>(count_,Dtype(-1),
reinterpret_cast<constDtype*>(diff_->gpu_data()),
reinterpret_cast<Dtype*>(data_->mutable_gpu_data()));
//在math_functions.cpp能够找到该函数的实现。事实上这函数也是封装了cublas的函数。这里调用是为了实现了两个向量的减法。
break;
default:
LOG(FATAL)<<"Syncedmemnot
initialized.";
}
}
函数voidCopyFrom(constBlob<Dtype>&source,boolcopy_diff
= false,boolreshape
= false);
功能:从source拷贝数据。copy_diff作为标志来区分是拷贝data还是拷贝diff。
template<typenameDtype>
voidBlob<Dtype>::CopyFrom(constBlob&source,boolcopy_diff,boolreshape)
{
if(num_!=
source.num() || channels_!=
source.channels() ||
height_!=
source.height() || width_!=
source.width()) {
if(reshape)
{
Reshape(source.num(),source.channels(), source.height(), source.width());
}else{
LOG(FATAL)<<"Tryingto
copy blobs of different sizes.";
}
}
switch(Caffe::mode()){
caseCaffe::GPU:
if(copy_diff){
CUDA_CHECK(cudaMemcpy(diff_->mutable_gpu_data(),source.gpu_diff(),
sizeof(Dtype)*count_,cudaMemcpyDeviceToDevice));
}else{
CUDA_CHECK(cudaMemcpy(data_->mutable_gpu_data(),source.gpu_data(),
sizeof(Dtype)*count_,cudaMemcpyDeviceToDevice));
}
break;
caseCaffe::CPU:
if(copy_diff){
memcpy(diff_->mutable_cpu_data(),source.cpu_diff(),
sizeof(Dtype)*count_);
}else{
memcpy(data_->mutable_cpu_data(),source.cpu_data(),
sizeof(Dtype)*count_);
}
break;
default:
LOG(FATAL)<<"Unknowncaffemode.";
}
}
函数voidFromProto(constBlobProto&proto);
功能:从proto读数据进来,事实上就是反序列化
template<typenameDtype>
voidBlob<Dtype>::FromProto(constBlobProto&proto){
Reshape(proto.num(),proto.channels(),proto.height(),proto.width());
//copy
data
Dtype*data_vec
= mutable_cpu_data();
for(inti
= 0; i < count_;++i) {
data_vec[i]=proto.data(i);
}
if(proto.diff_size()>
0) {
Dtype*diff_vec
= mutable_cpu_diff();
for(inti
= 0; i < count_;++i) {
diff_vec[i]=proto.diff(i);
}
}
}
函数voidToProto(BlobProto*proto,boolwrite_diff
= false)const;
功能:序列化到proto保存
template<typenameDtype>
voidBlob<Dtype>::ToProto(BlobProto*proto,boolwrite_diff)const{
proto->set_num(num_);
proto->set_channels(channels_);
proto->set_height(height_);
proto->set_width(width_);
proto->clear_data();
proto->clear_diff();
constDtype*data_vec
= cpu_data();
for(inti
= 0; i < count_;++i) {
proto->add_data(data_vec[i]);
}
if(write_diff)
{
constDtype*diff_vec
= cpu_diff();
for(inti
= 0; i < count_;++i) {
proto->add_diff(diff_vec[i]);
}
}
}
caffe源代码分析--Blob类代码研究的更多相关文章
- caffe源代码分析--math_functions.cu代码研究
当中用到一个宏定义CUDA_KERNEL_LOOP 在common.hpp中有. #defineCUDA_KERNEL_LOOP(i,n) \ for(inti = blockIdx.x * bloc ...
- caffe源代码分析--softmax_layer.cpp
caffe源代码分析--softmax_layer.cpp // Copyright 2013 Yangqing Jia // #include <algorithm> #include ...
- Caffe源码-Blob类
Blob类简介 Blob是caffe中的数据传递的一个基本类,网络各层的输入输出数据以及网络层中的可学习参数(learnable parameters,如卷积层的权重和偏置参数)都是Blob类型.Bl ...
- Red5源代码分析 - 关键类及其初始化过程
原文地址:http://semi-sleep.javaeye.com/blog/348768 Red5如何响应rmpt的请求,中间涉及哪些关键类? 响应请求的流程如下: 1.Red5在启动时会调用RT ...
- caffe源代码分析--data_layer.cpp
dataLayer作为整个网络的输入层, 数据从leveldb中取. leveldb的数据是通过图片转换过来的. 网络建立的时候. datalayer主要是负责设置一些參数,比方batchsize.c ...
- ffdshow 源代码分析 8: 视频解码器类(TvideoCodecDec)
===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...
- Media Player Classic - HC 源代码分析 2:核心类 (CMainFrame)(1)
===================================================== Media Player Classic - HC 源代码分析系列文章列表: Media P ...
- Caffe源代码中Solver文件分析
Caffe源代码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/solver.hpp文件 ...
- ffdshow 源代码分析 9: 编解码器有关类的总结
===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...
随机推荐
- Git教程Git多人协作开发
Git可以完成两件事情: 1. 版本控制 2.多人协作开发 如今的项目,规模越来越大,功能越来越多,需要有一个团队进行开发. 如果有多个开发人员共同开发一个项目,如何进行协作的呢. Git提供了一个非 ...
- unity, texture import settings
如果图片带透明通道,则若勾选Alpha Is Transparency,图片会呈现透明的预览效果. 但Alpha Is Transparency勾选与否是否影响shader的输出效果目前我还不太清 ...
- [hihoCoder] 骨牌覆盖问题·一
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 骨牌,一种古老的玩具.今天我们要研究的是骨牌的覆盖问题:我们有一个2xN的长条形棋盘,然后用1x2的骨牌去覆盖整个棋盘.对 ...
- 【Android】20.2 视频播放
分类:C#.Android.VS2015: 创建日期:2016-03-11 一.简介 本节例子和上一节的音频播放例子相似,也是最简单的示例,比如并没有考虑视频播放过程中电话打入的情况,也没有考虑复杂的 ...
- 【Android】3.11 地理编码功能
分类:C#.Android.VS2015.百度地图应用: 创建日期:2016-02-04 一.简介 地理编码指的是将地址信息建立空间坐标关系的过程,提供了地理坐标和地址之间相互转换的能力. 地理编码分 ...
- graal
https://github.com/graalvm/graal-core/blob/master/docs/Publications.md http://stefan-marr.de/downloa ...
- javascript原生bind方法ie低版本兼容详解
上一篇文章讲到了javascript原生的bind方法: http://www.cnblogs.com/liulangmao/p/3451669.html 这篇文章就在理解了原生bind方法的原理以后 ...
- C_文件包含.h文件和包含.c文件总结
很多人对C语言中的 “文件包含”都不陌生了,文件包含处理在程序开发中会给我们的模块化程序设计带来很大的好处,通过文件包含的方法把程序中的各个功能模块联系起来是模块化程序设计中的一种非常有利的手段. 文 ...
- 如何保证RabbitMQ的消息不丢失及其背后的原理
一.消息为什么丢失 RabbitMQ默认情况下的交换机和队列以及消息是非持久化的,也就是说在服务器重启或者宕机恢复后,之前创建的交换机和队列都将不复存在,之前未消费的消息也就消失不见了.原因在于每个队 ...
- u-boot mkconfig文件分析
#!/bin/sh -e #遇到非0返回 就退出脚本 # Script to create header files and links to configure # U-Boot for a spe ...