caffe源码分析-SyncedMemory

本文主要分析caffeBlob内存管理类SyncedMemory,主要内容包括:

  1. SyncedMemoryBlob的关系

  2. SyncedMemory中的方法,如内存的分配、释放

  3. SyncedMemory中内存的申请,是在数据访问时才分配而不是立马分配(通过enum SyncedHead状态实现)


SyncedMemoryBlob的关系

Blob中的主要数据成员如下,实际是在SyncedMemory上做了一层包装:

template<typename Dtype>
class Blob{    
   protected:
        shared_ptr<SyncedMemory> data_; //存储前向传递数据
        shared_ptr<SyncedMemory> diff_; //存储反向传递梯度
        vector<int> shape_;  //参数维度
        int count_; //Blob存储的元素个数(shape_所有元素乘积)
        int capacity_;//当前Blob的元素个数(控制动态分配)
};

SyncedMemory

SyncedMemory 的主要数据成员如下:

class SyncedMemory {
   private:
        void* cpu_ptr_;//内存指针
        void* gpu_ptr_;//显存指针
        size_t size_;  //数据大小
        SyncedHead head_;//当前数据状态
        bool own_cpu_data_;
        bool cpu_malloc_use_cuda_;
        bool own_gpu_data_;
        int gpu_device_;
};
  1. SyncedMemory屏蔽了代码对不同硬件设备的内存分配的感知,同时隐藏了CPU和GPU之间的同步过程。

  2. SyncedMemory采用“lazy”的模式,就是内存的实际申请时机是在第一次使用时进行的(通过枚举状态)。

首先看如下两个函数cpu_data, gpu_data获取cpu,gpu数据指针:

const void* SyncedMemory::cpu_data() {
    to_cpu();   // 首先完成数据同步,第一次访问时会申请存储空间
    return (const void*)cpu_ptr_;
}
const void* SyncedMemory::gpu_data() {
    #ifndef CPU_ONLY
            to_gpu();
            return (const void*)gpu_ptr_;
    #else
            NO_GPU;
      return NULL;
    #endif
    return nullptr;
}

以cpu_data为例, 如果数据尚未分配(通过如下枚举判断),则分配数据,如果已经分配则什么也不做:

enum SyncedHead { UNINITIALIZED, HEAD_AT_CPU, HEAD_AT_GPU, SYNCED };

inline void SyncedMemory::to_cpu() {
    switch (head_) {
        case UNINITIALIZED://数据尚未分配
            CaffeMallocHost(&cpu_ptr_, size_, &cpu_malloc_use_cuda_);
            caffe_memset(size_, 0, cpu_ptr_);
            head_ = HEAD_AT_CPU;//更新枚举状态
            own_cpu_data_ = true;
            break;
        case HEAD_AT_GPU:
#ifndef CPU_ONLY
//     ........
            ;
#else
            NO_GPU;
#endif
            break;
        case HEAD_AT_CPU:
        case SYNCED:
            break;
    }
}

SyncedMemory有如下接口,获取cpu中的数据指针(gpu同理):

//获取CPU数据指针,不能改变数据内容
const void* cpu_data();
//获取CPU数据指针,可以改变数据内容
void* mutable_cpu_data();

Blob中调用:

// 调用SyncedMemory的数据访问函数cpu_data(),并返回内存指针
template <typename Dtype>
const Dtype* Blob<Dtype>::cpu_data() const {
    CHECK(data_);
    return (const Dtype*)data_->cpu_data();
}
template <typename Dtype>
Dtype* Blob<Dtype>::mutable_cpu_data() {
    CHECK(data_);
    return static_cast<Dtype*>(data_->mutable_cpu_data());
}

内存分配与释放

内存分配与释放由两个(不属于SyncedMemory类)的内联函数完成. 代码简单直观: 如果是CPU模式, 那么调用malloc和free来申请/释放内存, 否则调用CUDA的cudaMallocHost和cudaFreeHost来申请/释放显存.

inline void CaffeMallocHost(void** ptr, size_t size, bool* use_cuda) {
    *ptr = malloc(size);
    *use_cuda = false;
    CHECK(*ptr) << "host allocation of size " << size << " failed";
}

inline void CaffeFreeHost(void* ptr, bool use_cuda) {
    free(ptr);
}

caffe系列源码分析介绍

本系列深度学习框架caffe 源码分析主要内容如下:

1. caffe源码分析-cmake 工程构建:

caffe源码分析-cmake 工程构建主要内容:

自己从头构建一遍工程,这样能让我更好的了解大型的项目的构建。当然原始的caffe的构建感觉还是比较复杂(主要是cmake),我这里仅仅使用cmake构建,而且简化点,当然最重要的是支持CLion直接运行调试(如果需要这个工程可以评论留下你的邮箱,我给你发送过去)。

这里写图片描述

2. caffe的数据内存分配类SyncedMemory, 以及类Blob数据传输的媒介.

主要内容:
caffe源码分析-SyncedMemory
caffe源码分析-Blob
其中Blob分析给出了其直接与opencv的图片相互转化以及操作,可以使得我们更好的理解Blob.

3. caffe layer的源码分析,包括从整体上说明了layer类别以及其proto定义与核心函数.

内容如下:
caffe源码分析-layer
caffe源码分析-ReLULayer
caffe源码分析-inner_product_layer
caffe源码分析-layer_factory

首先分析了最简单的layer Relu,然后在是inner_product_layer全连接层, 最后是layer_factorycaffe中 以此工厂模式create各种Layer.

4. 数据输入层,主要是多线程+BlockingQueue的方式读取数据训练:

内容如下:
caffe源码分析-BlockingQueue
caffe源码分析-InternalThread
caffe源码分析-DataReader

5. IO处理例如读取proto文件转化为网络,以及网络参数的序列化

内容如下:
caffe源码分析-DataTransformer
caffe源码分析-db, io

6. 最后给出了使用纯C++结合多层感知机网络训练mnist的示例

内容如下:

caffe c++示例(mnist 多层感知机c++训练,测试)

类似与caffe一样按照layer、solver、loss、net等模块构建的神经网络实现可以见下面这篇blog,相信看懂了这个python的代码理解caffe框架会更简单点.

神经网络python实现


最后如果需要cmake + CLion直接运行调试caffe的代码工程,可以评论留下你的邮箱,我给你发送过去.

参考:
https://www.jianshu.com/p/2e99bb0421c5
https://www.jianshu.com/p/b105578b214b

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 安装caffe-ssd-gpu在ubuntu18.04的步骤如下: 1. 安装CUDA:从Nvidia官网下载合适的CUDA安装包,按照官方文档的指引进行安装。 2. 安装依赖:运行以下命令安装所需依赖库: ``` sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev \ libopencv-dev libhdf5-serial-dev protobuf-compiler \ libgflags-dev libgoogle-glog-dev liblmdb-dev libboost-all-dev ``` 3. 下载caffe-ssd-gpu源码并编译:从Github上下载caffe-ssd-gpu的源码,按照官方文档指引进行编译。编译时需要指定编译选项为GPU模式。 4. 运行测试:安装完成后,运行测试脚本,确保安装配置成功。 以上为简要步骤,具体操作请参考对应文档和官方指引。 ### 回答2: Ubuntu18.04是目前比较常见的Linux操作系统之一,而CAFFE-SSD-GPU是深度学习的一个工具。下面是安装caffe-ssd-gpu的步骤: 1. 安装CUDA和cuDNN 首先,您需要安装CUDA和cuDNN,这是运行深度学习框架所需的必备组件。下载安装CUDA和cuDNN之前,您需要查看您的图形卡的型号,以便选择正确的CUDA版本和cuDNN版本。 在下载和安装CUDA和cuDNN之前,您需要在NVIDIA的开发者网站上注册自己,并下载适用于您机器的CUDA和cuDNN版本。此外,您还需要在命令行界面中设置以下环境变量: export PATH=/usr/local/cuda-8.0/bin:$PATH export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64:$LD_LIBRARY_PATH 2. 安装依赖项 在安装caffe之前,需要安装一些依赖项。您可以使用以下命令将这些依赖项安装到您的Ubuntu系统上: sudo apt-get update sudo apt-get install -y libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libboost-all-dev libhdf5-serial-dev protobuf-compiler gfortran libjpeg62 libfreeimage-dev libatlas-base-dev git python-dev python-pip libgoogle-glog-dev libbz2-dev libxml2-dev libxslt-dev libffi-dev libssl-dev libgflags-dev liblmdb-dev python-yaml python-numpy python-scipy 3. 下载和安装CAFFE 现在,您需要在您的系统上下载和安装CAFFE。从github上获取caffesource代码并进行安装: git clone https://github.com/weiliu89/caffe.git cd caffe git checkout ssd 4. 编译和安装CAFFE 使用以下命令编译和安装caffe: cp Makefile.config.example Makefile.config make all -j $(($(nproc) + 1)) make pycaffe 执行该命令后,您需要等待一段时间才能完成CAFFE的编译。如果出现任何编译错误,请检查您的CUDA和cuDNN版本是否正确,并重新安装依赖项。 5. 使用CAFFE-SSD-GPU 现在,您已经成功地在Ubuntu18.04操作系统上安装并编译了CAFFE-SSD-GPU,您可以开始使用该工具来执行深度学习任务了。 总结 安装CAFFE-SSD-GPU需要充分理解linux的命令行操作。需要先确认CUDA和cuDNN已经安装,并正确设置环境变量。然后需要下载和安装CAFFE, 并最后编译和安装CAFFE。在安装过程中如果存在问题,可以查看错误日志,重新检查步骤。如果对命令行操作不熟悉,则先学习linux基础操作。 ### 回答3: caffe-ssd-gpu是一种基于caffe框架的用于实现目标检测的神经网络模型,在Ubuntu18.04系统中安装caffe-ssd-gpu需要进行以下步骤: 1. 安装CUDA CUDA是NVIDIA公司推出的用于高性能计算的并行计算平台和编程模型,是使用GPU进行深度学习任务所必需的。在Ubuntu18.04上安装CUDA需要首先确认自己的显卡型号,并选择合适的CUDA版本进行安装。可以在NVIDIA官网上下载相应的CUDA安装包,也可以通过命令行方式进行安装。在安装过程中注意要按照提示完成相应的配置和设置。 2. 安装cuDNN cuDNN是用于深度神经网络的GPU加速库,也是必需的组件之一。在安装过程中同样需要确认CUDA的版本和自己的显卡型号,并下载相应的cuDNN安装包进行安装。 3. 安装依赖包 在安装caffe-ssd-gpu前需要先安装几个依赖包,包括protobuf、opencv、boost等。可以通过命令行方式进行安装,例如: ``` sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libboost-all-dev libhdf5-serial-dev libgflags-dev libgoogle-glog-dev liblmdb-dev ``` 4. 下载caffe-ssd-gpu源码 可以在GitHub上找到caffe-ssd-gpu的源码,下载后解压到自己想要的目录下。 5. 编译和安装caffe-ssd-gpu 进入caffe-ssd-gpu源码目录下,执行以下命令: ``` cd caffe-ssd-gpu mkdir build cd build cmake .. make all -j8 make install ``` 其中,make all -j8表示使用8个线程进行编译,提高编译速度。make install表示安装编译好的caffe-ssd-gpu库文件和可执行文件。 6. 测试安装是否成功 可以尝试运行caffe-ssd-gpu自带的测试程序,检查安装是否成功。在源码目录下执行以下命令: ``` ./build/tools/caffe time --model=models/VGGNet/VOC0712/SSD_300x300_ft/deploy.prototxt --gpu=0 ``` 这条命令会测试caffe-ssd-gpu在GPU上执行推断的速度,如果没有问题,则说明安装成功。 需要注意的是,在安装过程中可能会遇到各种问题,例如依赖包的版本不兼容、CUDA和cuDNN的配置出错等等。这时候需要耐心调试错误,逐个解决问题,才能确保caffe-ssd-gpu能够正常运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值