Caffe源码中syncedmem文件分析
Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下syncedmem文件。
1. include文件:
(1)、<caffe/common.hpp>:此文件的介绍可以参考:http://blog.csdn.net/fengbingchun/article/details/54955236 ;
(2)、<caffe/util/math_functions.hpp>:此文件的介绍可以参考: http://blog.csdn.net/fengbingchun/article/details/56280708 ;
2. 内联函数CaffeMallocHost/CaffeFreeHost:
(1)、CaffeMallocHost:CPU模式下,通过调用C语言的malloc函数分配内存;
(2)、CaffeFreeHost:CPU模式下,通过调用C语言的free函数释放内存;
3. 类SyncedMemory:在主机(CPU)和设备(GPU)之间管理内存分配和数据同步,封装CPU和GPU之间数据交互操作。
<caffe/syncedmem.hpp>文件的详细介绍如下:
#ifndef CAFFE_SYNCEDMEM_HPP_ #define CAFFE_SYNCEDMEM_HPP_ #include <cstdlib> #include "caffe/common.hpp" #include "caffe/util/math_functions.hpp" namespace caffe { // If CUDA is available and in GPU mode, host memory will be allocated pinned, // using cudaMallocHost. It avoids dynamic pinning for transfers (DMA). // The improvement in performance seems negligible in the single GPU case, // but might be more significant for parallel training. Most importantly, // it improved stability for large models on many GPUs. // CPU模式下,通过调用C语言的malloc函数分配内存 inline void CaffeMallocHost(void** ptr, size_t size) { #ifndef CPU_ONLY if (Caffe::mode() == Caffe::GPU) { CUDA_CHECK(cudaMallocHost(ptr, size)); return; } #endif *ptr = malloc(size); CHECK(*ptr) << "host allocation of size " << size << " failed"; } // CPU模式下,通过调用C语言的free函数释放内存 inline void CaffeFreeHost(void* ptr) { #ifndef CPU_ONLY if (Caffe::mode() == Caffe::GPU) { CUDA_CHECK(cudaFreeHost(ptr)); return; } #endif free(ptr); } /** * @brief Manages memory allocation and synchronization between the host (CPU) * and device (GPU). * * TODO(dox): more thorough description. */ // 在主机(Host/CPU)和设备(Device/GPU)之间管理内存分配和数据同步,封装CPU和GPU之间数据交互操作 class SyncedMemory { public: // 默认构造函数,简单初始化,数据状态置为UNINITIALIZED SyncedMemory() : cpu_ptr_(NULL), gpu_ptr_(NULL), size_(0), head_(UNINITIALIZED), own_cpu_data_(false), own_gpu_data_(false), gpu_device_(-1) {} // 带size参数的显示构造函数,并未分配内存,数据状态置为UNINITIALIZED explicit SyncedMemory(size_t size) : cpu_ptr_(NULL), gpu_ptr_(NULL), size_(size), head_(UNINITIALIZED), own_cpu_data_(false), own_gpu_data_(false), gpu_device_(-1) {} // 析构函数,CPU模式下,当cpu_ptr_非空并且own_cpu_data_为true时,仅会调用CaffeFreeHost函数释放内存 ~SyncedMemory(); // 获取CPU数据指针,数据不可更改,内部会调用to_cpu函数,在CPU模式下,数据状态为HEAD_AT_CPU,在GPU模式下,数据状态置为SYNCED const void* cpu_data(); // 调用CaffeFreeHost释放内存,如果own_cpu_data_为非空,则调用CaffeFreeHost释放内存,并修改CPU数据指针使其指向data,并置own_cpu_data_为false,数据状态置为HEAD_AT_CPU void set_cpu_data(void* data); // 获取GPU数据指针,数据不可更改,在GPU模式下,数据状态为HEAD_AT_GPU,在CPU模式下,数据状态置为SYNCED const void* gpu_data(); // 在GPU模式下,内部会调用to_gpu函数,如果own_gpu_data_为非空,调用cudaFree释放显存,并修改GPU数据指针使其指向data,并置own_gpu_data_为false,在GPU模式下,数据状态置为HEAD_AT_GPU void set_gpu_data(void* data); // 获取CPU数据指针,数据可更改,内部会调用to_cpu函数,数据状态置为HEAD_AT_CPU void* mutable_cpu_data(); // 获取GPU数据指针,数据可更改,在GPU模式下,内部会调用to_gpu函数,数据状态置为HEAD_AT_GPU void* mutable_gpu_data(); // SyncedHead为枚举类型,数据存放的位置,包括四种数据状态,依次为未初始化、在CPU、在GPU、已同步 enum SyncedHead { UNINITIALIZED, HEAD_AT_CPU, HEAD_AT_GPU, SYNCED }; // 返回数据状态,即数据存放的位置 SyncedHead head() { return head_; } // 返回数据大小(字节) size_t size() { return size_; } #ifndef CPU_ONLY // 异步推送数据从CPU到GPU,并置数据状态为SYNCED void async_gpu_push(const cudaStream_t& stream); #endif private: // 把数据存放到CPU上, // 如果数据状态为UNINITIALIZED,则调用CaffeMallocHost分配内存,并初始化数据内容为0,置own_cpu_data_为true,置数据状态为HEAD_AT_CPU, // 如果数据状态为HEAD_AT_GPU,如果在GPU模式下,如果cpu_ptr_为空,则调用CaffeMallocHost分配内存,并置own_cpu_data_为true,然后则将显存数据拷贝到内存(数据同步),并将数据状态置为SYNCED // 其它数据状态不作任何操作 void to_cpu(); // 把数据存放到GPU上,仅在GPU模式作操作,在CPU模式下不作任何操作, // 如果数据状态为UNINITIALIZED,则调用cudaMalloc分配显存,并初始化数据内容为0,置数据状态为HEAD_AT_GPU,并置own_gpu_data_为true // 如果数据状态为HEAD_AT_CPU,如果gpu_ptr_为空,则调用cudaMalloc分配显存,并置own_gpu_data_为true,然后将内存数据拷贝到显存(数据同步),并将数据状态置为SYNCED // 其它数据状态不作任何操作 void to_gpu(); // 指向CPU的数据指针 void* cpu_ptr_; // 指向GPU的数据指针 void* gpu_ptr_; // 数据大小(字节) size_t size_; // 数据状态,当前数据存放的位置 SyncedHead head_; // 是否通过SyncedMemory类分配了CPU内存 bool own_cpu_data_; // 是否通过SyncedMemory类分配了GPU显存 bool own_gpu_data_; // 设备编号 int gpu_device_; // 禁止使用SyncedMemory类的拷贝和赋值操作 DISABLE_COPY_AND_ASSIGN(SyncedMemory); }; // class SyncedMemory } // namespace caffe #endif // CAFFE_SYNCEDMEM_HPP_
测试代码如下:
int test_caffe_syncedmem() { caffe::SyncedMemory mem(10); caffe::SyncedMemory* p_mem = new caffe::SyncedMemory(10 * sizeof(float)); if (mem.head() != caffe::SyncedMemory::UNINITIALIZED || mem.size() != 10 || p_mem->size() != 10 * sizeof(float) || mem.cpu_data() == nullptr || mem.mutable_cpu_data() == nullptr || mem.head() != caffe::SyncedMemory::HEAD_AT_CPU) { fprintf(stderr, "Error\n"); return -1; } fprintf(stderr, "p_mem size: %d\n", p_mem->size()); fprintf(stderr, "mem size: %d\n", mem.size()); void* cpu_data = mem.mutable_cpu_data(); if (mem.head() != caffe::SyncedMemory::HEAD_AT_CPU) { fprintf(stderr, "Error\n"); return -1; } caffe::caffe_memset(mem.size(), 1, cpu_data); for (int i = 0; i < mem.size(); ++i) { if ((static_cast<char*>(cpu_data))[i] != 1) { fprintf(stderr, "Error\n"); return -1; } } cpu_data = mem.mutable_cpu_data(); if (mem.head() != caffe::SyncedMemory::HEAD_AT_CPU) { fprintf(stderr, "Error\n"); return -1; } caffe::caffe_memset(mem.size(), 2, cpu_data); for (int i = 0; i < mem.size(); ++i) { if ((static_cast<char*>(cpu_data))[i] != 2) { fprintf(stderr, "Error\n"); return -1; } } delete p_mem; return 0; }
测试结果如下:
GitHub:https://github.com/fengbingchun/Caffe_Test
Caffe源码中syncedmem文件分析的更多相关文章
- Caffe源码中common文件分析
Caffe源码(caffe version:09868ac , date: 2015.08.15)中的一些重要头文件如caffe.hpp.blob.hpp等或者外部调用Caffe库使用时,一般都会in ...
- Caffe源码中math_functions文件分析
Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下math_functions文件. 1. include文件: ...
- Caffe源码中caffe.proto文件分析
Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下caffe.proto文件. 在src/caffe/proto目录下有一个 ...
- 【神经网络与深度学习】Caffe源码中各种依赖库的作用及简单使用
1. Boost库:它是一个可移植.跨平台,提供源代码的C++库,作为标准库的后备. 在Caffe中用到的Boost头文件包括: (1).shared_ptr.hpp:智能指针,使用它可以不 ...
- tf源码中的object_detection_tutorial.ipynb文件
今天看到原来下载的tf源码的目标检测源码中test的代码不知道跑哪儿去了,这里记录一下... Imports import numpy as np import os import six.moves ...
- caffe源码阅读
参考网址:https://www.cnblogs.com/louyihang-loves-baiyan/p/5149628.html 1.caffe代码层次熟悉blob,layer,net,solve ...
- caffe源码整个训练过程
Caffe源码 Blob protected: shared_ptr<SyncedMemory> data_; shared_ptr<SyncedMemory> diff_; ...
- caffe源码学习
本文转载自:https://buptldy.github.io/2016/10/09/2016-10-09-Caffe_Code/ Caffe简介 Caffe作为一个优秀的深度学习框架网上已经有很多内 ...
- Caffe源码-SyncedMemory类
SyncedMemory类简介 最近在阅读caffe源码,代码来自BVLC/caffe,基本是参照网络上比较推荐的 Blob-->Layer-->Net-->Solver 的顺序来分 ...
随机推荐
- 微信小程序-06-详解介绍.js 逻辑层文件-注册页面
上一篇介绍的是 app.js 逻辑层文件中注册程序,对应的每个分页面都会有的 js 文件中 page() 函数注册页面 微信小程序-06-详解介绍.js 逻辑层文件-注册页面 宝典官方文档: http ...
- 修复cocos2dx的Label,WP8下不能换行的问题
注:2014年12月23日有内存/性能优化更新,内容在下面分割线后 搞了几个小时,这个头疼的问题,我给出代码吧. 找到 libcocos2d/platform/winrt/CCFreeTypeFont ...
- The ADB instructions
adb kill-server 杀死adb服务. adb start-server 开启adb服务. adb install xxx.apk 安装应用. adb uninstall 应用的包名.卸载应 ...
- 3.网络编程-tcp的服务器简单实现
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2019/1/13 22:03 # @Author : ChenAdong # @ema ...
- weblogic系列漏洞整理 -- 3. weblogic 后台提权
目录 三. weblogic 后台提权 0. 思路分析 1. 利用过程 2. 提示和技巧 一.weblogic安装 http://www.cnblogs.com/0x4D75/p/8916428.ht ...
- python常用模块json
python jons模块 json模块 主要是解决数据格式的转换问题,比如python接收到json对象需要转换为python对象,供python处理,亦或者python数据需要发送到其给其他客户端 ...
- 使用 WebStorm IDE 调试 Pomelo 应用程序
使用得心应手的IDE来开发应用程序,可以使我们的工作事半功倍.而调试则更可以让我们准确的定位BUG,发现问题.本文讲述如何使用 WebStorm 这个怪兽级JavaScript IDE来调试 Chat ...
- gnome extensions 推荐 (fedora 28 常用gnome 插件备份)
当我们进行重新安装系统(fedora 28)的时候,需要初始安装一些 gnome 插件,来进行完善我们的使用. 首先我们应该进行安装 gnome-tweak 工具来进行定制化系统. tweak 可以进 ...
- linux 系统中用root切换到普通用户时显示的异常如-bash-4.1$
解决办法: 其实就是普通用户的家目录缺少配置文件导致: [root@xxx ~]# su - oldboy -bash-4.1$ 原因是普通用户的家目录下缺少文件: [root@xxx ~]# ls ...
- ccf题库中2015年12月2号消除类游戏
题目如下: 问题描述 消除类游戏是深受大众欢迎的一种游戏,游戏在一个包含有n行m列的游戏棋盘上进行,棋盘的每一行每一列的方格上放着一个有颜色的棋子,当一行或一列上有连续三个或更多的相同颜色的棋子时,这 ...