作者: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类代码研究的更多相关文章

  1. caffe源代码分析--math_functions.cu代码研究

    当中用到一个宏定义CUDA_KERNEL_LOOP 在common.hpp中有. #defineCUDA_KERNEL_LOOP(i,n) \ for(inti = blockIdx.x * bloc ...

  2. caffe源代码分析--softmax_layer.cpp

    caffe源代码分析--softmax_layer.cpp // Copyright 2013 Yangqing Jia // #include <algorithm> #include ...

  3. Caffe源码-Blob类

    Blob类简介 Blob是caffe中的数据传递的一个基本类,网络各层的输入输出数据以及网络层中的可学习参数(learnable parameters,如卷积层的权重和偏置参数)都是Blob类型.Bl ...

  4. Red5源代码分析 - 关键类及其初始化过程

    原文地址:http://semi-sleep.javaeye.com/blog/348768 Red5如何响应rmpt的请求,中间涉及哪些关键类? 响应请求的流程如下: 1.Red5在启动时会调用RT ...

  5. caffe源代码分析--data_layer.cpp

    dataLayer作为整个网络的输入层, 数据从leveldb中取. leveldb的数据是通过图片转换过来的. 网络建立的时候. datalayer主要是负责设置一些參数,比方batchsize.c ...

  6. ffdshow 源代码分析 8: 视频解码器类(TvideoCodecDec)

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

  7. Media Player Classic - HC 源代码分析 2:核心类 (CMainFrame)(1)

    ===================================================== Media Player Classic - HC 源代码分析系列文章列表: Media P ...

  8. Caffe源代码中Solver文件分析

    Caffe源代码(caffe version commit: 09868ac , date: 2015.08.15)中有一些重要的头文件,这里介绍下include/caffe/solver.hpp文件 ...

  9. ffdshow 源代码分析 9: 编解码器有关类的总结

    ===================================================== ffdshow源代码分析系列文章列表: ffdshow 源代码分析 1: 整体结构 ffds ...

随机推荐

  1. java中异常和集合

    1. java中处理错误情况有两种,1  Error,2  Exception error是无法处理的,Exception是可以处理的情况. Exception中又有两种情况,RuntimeExcep ...

  2. OpenGL cullface

    opengl cullface是根据顶点顺逆时针来判断正反面的.而不是根据法线判断的.所以有可能法线是正确的,但cullface效果却是反的.

  3. Redis(一):概述

    1.Redis解释 Redis 是一个基于key-value形式进行存储的内存型数据库. 1.1 数据存储方式为key-value 1.2 数据存储在内存中. 1.2.1 优点:效率高.理论值:每秒1 ...

  4. Java中instanceof关键字的理解

    java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例. 用法: res ...

  5. 解决MAC下xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools)的问题

    将系统升级到了最新10.13.3 macOS High Sierra后,在使用ctags命令时会出现如下问题: xcrun: error: invalid active developer path ...

  6. SQLAlchemy的“缓存”问题导致的BUG

    问题描述: 最近做项目,遇到一个问题,两个项目操作同一个数据库,其中A项目用的pymysql链接操作数据库,B项目用的sqlalchemy,当我请求B项目中的一个接口,会通知A项目操作数据库,然后返回 ...

  7. Ribbon对于SocketTimeOutException重试的坑以及重试代码解析

    背景 本文基于Spring-Cloud, Daltson SR4 微服务一般多实例部署,在发布的时候,我们要做到无感知发布:微服务调用总会通过Ribbon,同时里面会实现一些重试的机制,相关配置是: ...

  8. eclipse ant 的自动部署(autobulid)

    在写项目中,经常需要在 ctrl+s的时候自动编译并且把这个改动的文件copy至某个目录,除了eclipse自带 java脚本的web自动部署到项目中配置的目录下,但是不能随心所欲copy,比如其他文 ...

  9. dp之二维背包poj1837(天平问题 推荐)

    题意:给你c(2<=c<=20)个挂钩,g(2<=g<=20)个砝码,求在将所有砝码(砝码重1~~25)挂到天平(天平长  -15~~15)上,并使得天平平衡的方法数..... ...

  10. R ggplot2 线性回归

    摘自  http://f.dataguru.cn/thread-278300-1-1.html library(ggplot2) x=1:10y=rnorm(10)a=data.frame(x= x, ...