Caffe 源码阅读笔记 [基本模块] Syncedmem & Blob
来源:互联网 发布:linux运维工程师薪资 编辑:程序博客网 时间:2024/05/21 14:52
syncedmem
- syncedmem管理一段大小为size的内存。这段内存可以从GPU或者主机内存分配,syncedmem负责GPU和主机内存之间的同步。如果数据是在GPU里而要从主机内存取出,syncedmem会先把数据从GPU内存memcpy到主机内存返回(标记为SYNCED); 相反也是一样。
- 分配/释放内存的方式
- CPU: ptr = malloc(size) / free(ptr)
- GPU: cudaMallocHost(ptr, size) / cudaFreeHost(ptr)
成员变量
void* cpu_ptr_, gpu_ptr_; //数据指针 size_t size_; // SyncedMemory(size_t size) // 状态 { // UNINITIALIZED = 初始值 // HEAD_AT_CPU = 最新数据在主机内存里 // HEAD_AT_GPU = 最新数据在GPU内存里 // SYNCED = 表示主机内存数据和GPU内存的数据是一致的 // } SyncedHead head_; bool cpu_malloc_use_cuda_; bool own_gpu_data_, own_cpu_data_; // true则析构时将内存释放 int gpu_device_; // GPU device id
CPU 相关方法
// 获得主机内存数据inline void SyncedMemory::cpu_data() { switch (head_) { case UNINITIALIZED: 分配内存,head_=HEAD_AT_CPU break; case HEAD_AT_GPU: //数据已经在GPU内存里#ifndef CPU_ONLY // 从GPU内存拷贝回主机内存 caffe_gpu_memcpy(size_, gpu_ptr_, cpu_ptr_); head_ = SYNCED;#end return (const void*)cpu_ptr_;}// 设置主机内存数据void SyncedMemory::set_cpu_data(void* data) { cpu_ptr_ = data; head_ = HEAD_AT_CPU; own_cpu_data_ = false;}
GPU 相关方法
//获得GPU内存数据inline void SyncedMemory::gpu_data() {#ifndef CPU_ONLY switch (head_) { case UNINITIALIZED: 分配内存, head_ = HEAD_AT_GPU; break; case HEAD_AT_CPU: // 从Host内存拷贝到GPU内存 caffe_gpu_memcpy(size_, cpu_ptr_, gpu_ptr_); head_ = SYNCED; break;#end}// 设置GPU内存void SyncedMemory::set_gpu_data(void* data) { gpu_ptr_ = data; head_ = HEAD_AT_GPU; own_gpu_data_ = false;}// 用于在Data Layer异步从内存拷贝到GPUvoid SyncedMemory::async_gpu_push(const cudaStream_t& stream) { CHECK(head_ == HEAD_AT_CPU); // 确认数据已经在主机内存里 // 异步拷贝到GPU内存 CUDA_CHECK(cudaMemcpyAsync(gpu_ptr_, cpu_ptr_, size_, put, stream)); head_ = SYNCED; // 设置同步完毕}
Blob
- Blob是Caffe的Layer之间传输的内部数据单元
- 它存储矩阵data_和 diff_, 由shape_来表示矩阵的各个维度。比如number张图片训练数据可以表示成 number * channels * height * width 的4维矩阵,shape_ = {number, channels, height, width},具体实现上data_和diff_分别是一个大小为number * channels * height * width的一维数组(SyncedMem类型)。
Blob 成员变量
shared_ptr<SyncedMemory> data_; // 数据 shared_ptr<SyncedMemory> diff_; // diff vector<int> shape_; // 维度 int count_; // shape_[0]*shape_[1]*...*shape_[n] int capacity_; // data_和diff_的capacity,只有当count_>capacity_的时候,才重新分配内存
Blob基本方法
// 更改Blob的维度shape_,如果已分配的内存无法存储shape表示的数组,重新分配内存void Reshape(const vector<int>& shape); // 返回data_->xpu_data(), data_->set_xpu_data()void cpu_data(), gpu_data(), set_cpu_data(), set_gpu_data() // cpu_diff(), ...类似// 和别的blob共享data_和diff_,避免拷贝void ShareData(const Blob& other); // ShareDiff// 从ProtoBuf读取Blob和写到ProtoBuf里, toProto可设置是否写diff数据void FromProto/toProto();
Blob矩阵操作
// 更新主机内存或者GPU内存里的数据:data_ := -1*diff_ + data_void Update() { // 由data_.head() == HEAD_AT_CPU 判断数据在哪里, 下面函数类似 caffe_axpy<Dtype>(count_, Dtype(-1), static_cast<const Dtype*>(diff_->cpu_data()), static_cast<Dtype*>(data_->mutable_cpu_data())); OR caffe_gpu_axpy<Dtype>(count_, Dtype(-1), static_cast<const Dtype*>(diff_->gpu_data()), static_cast<Dtype*>(data_->mutable_gpu_data()));}// 计算sum(data_),data_内所有元素之和Dtype asum_data() // 调用caffe_cpu_asum 或 caffe_gpu_asumDtype asum_diff()// 计算sum(data_.*data_),元素平方总和Dtype sumsq_data() // 调用caffe_cpu_dot(count_, data, data)或caffe_gpu_dot(count_, data, data, &sumsq)Dtype sumsq_diff()// data_ := scale_factor * data_void scale_data(Dtype scale_factor) // 调用caffe_scal 或 caffe_gpu_scalvoid scale_diff(Dtype scale_factor)// 根据index访问data_和diff_矩阵元素Dtype data_at(const vector<int>& index)Dtype diff_at(const vector<int>& index)// 计算一个矩阵切片的元素个数,返回所有shape_[i]的乘积(start_axis<=i<end_axis)int count(int start_axis, int end_axis)
0 0
- Caffe 源码阅读笔记 [基本模块] Syncedmem & Blob
- Caffe 源码阅读笔记 [基本模块] Solver
- caffe源码阅读2-syncedmem.hpp+.cpp
- Caffe 源码阅读笔记 [基本模块] Caffe.cpp
- Caffe源码阅读笔记(1):Blob
- Caffe 源码阅读笔记 [基本模块] Layer和LayerFactory
- Caffe 源码阅读笔记 [基本模块] 网络Net
- caffe源码追踪--syncedmem
- caffe源码阅读之Blob
- Caffe源码解析2:SyncedMem
- caffe源码阅读——Blob类
- caffe源码阅读1-blob.hpp
- caffe源码阅读3-blob.cpp
- caffe源码阅读——Blob类
- Caffe源码解读2--syncedmem.hpp
- Caffe源码中syncedmem文件分析
- Caffe源码阅读笔记
- caffe 源码阅读笔记(0):基本概述
- HDU 3709 Balanced Number (数位DP)
- Java的练习4
- 又见神奇的异或。Trie树。今日头条。
- 这个应该是目前最全的Tracking相关的文章了
- UVA 12169
- Caffe 源码阅读笔记 [基本模块] Syncedmem & Blob
- 获取linux下,tcp、udp的系统默认缓存大小和最大值
- 十四、Lua字符串库中的几个重要函数
- 反射获取HashMap内部table字段及其node链表,打印全部数据
- Nginx 与 FPM 的工作机制
- 文章标题 HDU 5113 : Black And White (dfs+剪枝)
- windows禅道环境搭建
- Linux常用的操作指令
- 【LeetCode】210. Course Schedule II (Medium)