caffe源码追踪--syncedmem

2023-11-06

首先来看看caffe/include/caffe/syncedmem.hpp

#ifndef CAFFE_SYNCEDMEM_HPP_
#define CAFFE_SYNCEDMEM_HPP_

#include <cstdlib>

#include "caffe/common.hpp"
namespace caffe {
inline void CaffeMallocHost(void** ptr, size_t size, bool* use_cuda) {//分配内存
#ifndef CPU_ONLY
  if (Caffe::mode() == Caffe::GPU) {
    CUDA_CHECK(cudaMallocHost(ptr, size));
    *use_cuda = true;
    return;
  }
#endif
  *ptr = malloc(size);//分配size大小的内存块
  *use_cuda = false;
  CHECK(*ptr) << "host allocation of size " << size << " failed";//分配失败则报错
}
inline void CaffeFreeHost(void* ptr, bool use_cuda) {//释放内存
#ifndef CPU_ONLY
  if (use_cuda) {
    CUDA_CHECK(cudaFreeHost(ptr));
    return;
  }
#endif
  free(ptr);
}
class SyncedMemory {//SyncedMemory类相关的操作,具体见cpp
 public:
  SyncedMemory()//构造函数
      : cpu_ptr_(NULL), gpu_ptr_(NULL), size_(0), head_(UNINITIALIZED),
        own_cpu_data_(false), cpu_malloc_use_cuda_(false), own_gpu_data_(false),
        gpu_device_(-1) {}
  explicit SyncedMemory(size_t size)
      : cpu_ptr_(NULL), gpu_ptr_(NULL), size_(size), head_(UNINITIALIZED),
        own_cpu_data_(false), cpu_malloc_use_cuda_(false), own_gpu_data_(false),
        gpu_device_(-1) {}
  ~SyncedMemory();
  const void* cpu_data();
  void set_cpu_data(void* data);
  const void* gpu_data();
  void set_gpu_data(void* data);
  void* mutable_cpu_data();
  void* mutable_gpu_data();
  enum SyncedHead { UNINITIALIZED, HEAD_AT_CPU, HEAD_AT_GPU, SYNCED };//head的四个状态
  SyncedHead head() { return head_; }
  size_t size() { return size_; }
#ifndef CPU_ONLY
  void async_gpu_push(const cudaStream_t& stream);
#endif
 private:
  void to_cpu();
  void to_gpu();
  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_;
  DISABLE_COPY_AND_ASSIGN(SyncedMemory);
};  // class SyncedMemory

}  // namespace caffe

#endif  // CAFFE_SYNCEDMEM_HPP_

重点看一下cpp文件caffe/src/caffe/syncedmem.cpp

#include "caffe/common.hpp"
#include "caffe/syncedmem.hpp"
#include "caffe/util/math_functions.hpp"

namespace caffe {

SyncedMemory::~SyncedMemory() {//析构函数,如果指针没有释放,则释放
  if (cpu_ptr_ && own_cpu_data_) {
    CaffeFreeHost(cpu_ptr_, cpu_malloc_use_cuda_);
  }
#ifndef CPU_ONLY
  if (gpu_ptr_ && own_gpu_data_) {
    int initial_device;
    cudaGetDevice(&initial_device);
    if (gpu_device_ != -1) {
      CUDA_CHECK(cudaSetDevice(gpu_device_));
    }
    CUDA_CHECK(cudaFree(gpu_ptr_));
    cudaSetDevice(initial_device);
  }
#endif  // CPU_ONLY
}
inline void SyncedMemory::to_cpu() {//gpu与cpu同步
  switch (head_) {//根据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://若是在gpu,则同步CPU与gpu
#ifndef CPU_ONLY
    if (cpu_ptr_ == NULL) {
      CaffeMallocHost(&cpu_ptr_, size_, &cpu_malloc_use_cuda_);
      own_cpu_data_ = true;
    }
    caffe_gpu_memcpy(size_, gpu_ptr_, cpu_ptr_);
    head_ = SYNCED;
#else
    NO_GPU;
#endif
    break;
  case HEAD_AT_CPU:
  case SYNCED:
    break;
  }
}

inline void SyncedMemory::to_gpu() {//CPU与gpu同步
#ifndef CPU_ONLY
  switch (head_) {
  case UNINITIALIZED:
    CUDA_CHECK(cudaGetDevice(&gpu_device_));
    CUDA_CHECK(cudaMalloc(&gpu_ptr_, size_));
    caffe_gpu_memset(size_, 0, gpu_ptr_);
    head_ = HEAD_AT_GPU;
    own_gpu_data_ = true;
    break;
  case HEAD_AT_CPU:
    if (gpu_ptr_ == NULL) {
      CUDA_CHECK(cudaGetDevice(&gpu_device_));
      CUDA_CHECK(cudaMalloc(&gpu_ptr_, size_));
      own_gpu_data_ = true;
    }
    caffe_gpu_memcpy(size_, cpu_ptr_, gpu_ptr_);
    head_ = SYNCED;
    break;
  case HEAD_AT_GPU:
  case SYNCED:
    break;
  }
#else
  NO_GPU;
#endif
}
const void* SyncedMemory::cpu_data() {//获取cpu中数据指针
  to_cpu();
  return (const void*)cpu_ptr_;
}
void SyncedMemory::set_cpu_data(void* data) {//将 cpu_ptr_指向data所指数据,并释放原有数据
  CHECK(data);
  if (own_cpu_data_) {
    CaffeFreeHost(cpu_ptr_, cpu_malloc_use_cuda_);
  }
  cpu_ptr_ = data;
  head_ = HEAD_AT_CPU;
  own_cpu_data_ = false;
}
const void* SyncedMemory::gpu_data() {//获取gpu数据指针
#ifndef CPU_ONLY
  to_gpu();
  return (const void*)gpu_ptr_;
#else
  NO_GPU;
  return NULL;
#endif
}
void SyncedMemory::set_gpu_data(void* data) {//将 gpu_ptr_指向data所指数据,并释放原有数据
#ifndef CPU_ONLY
  CHECK(data);
  if (own_gpu_data_) {
    int initial_device;
    cudaGetDevice(&initial_device);
    if (gpu_device_ != -1) {
      CUDA_CHECK(cudaSetDevice(gpu_device_));
    }
    CUDA_CHECK(cudaFree(gpu_ptr_));
    cudaSetDevice(initial_device);
  }
  gpu_ptr_ = data;
  head_ = HEAD_AT_GPU;
  own_gpu_data_ = false;
#else
  NO_GPU;
#endif
}
void* SyncedMemory::mutable_cpu_data() {
  to_cpu();
  head_ = HEAD_AT_CPU;
  return cpu_ptr_;
}
void* SyncedMemory::mutable_gpu_data() {
#ifndef CPU_ONLY
  to_gpu();
  head_ = HEAD_AT_GPU;
  return gpu_ptr_;
#else
  NO_GPU;
  return NULL;
#endif
}
#ifndef CPU_ONLY
void SyncedMemory::async_gpu_push(const cudaStream_t& stream) {
  CHECK(head_ == HEAD_AT_CPU);
  if (gpu_ptr_ == NULL) {
    CUDA_CHECK(cudaGetDevice(&gpu_device_));
    CUDA_CHECK(cudaMalloc(&gpu_ptr_, size_));
    own_gpu_data_ = true;
  }
  const cudaMemcpyKind put = cudaMemcpyHostToDevice;
  CUDA_CHECK(cudaMemcpyAsync(gpu_ptr_, cpu_ptr_, size_, put, stream));
  head_ = SYNCED;
}
#endif
}  // namespace caffe
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

caffe源码追踪--syncedmem 的相关文章

随机推荐

  • Zotero自定义模板

    Zotero可以很方便给word插上参考文献 这样妈妈也在不用担心引用顺序了 那么问题来了 你引用一个参考文献 其显示的格式最终该是怎样的 比如杂志要加 J 后缀 等等 所以我们需要自定义Zotero的引用模板 模版库 https www
  • Golang 实现一个简单的 http 代理

    本文详细介绍了Golang 实现 http 代理的实现 在实际业务中有需求的同学可以学起来了 代理是网络中的一项重要的功能 其功能就是代理网络用户去取得网络信息 形象的说 它是网络信息的中转站 对于客户端来说 代理扮演的是服务器的角色 接收
  • 02_End-to-End Machine Learning Project_02_stats.sem_Cross_Validation_Grid_Randomized_Ensemble_ Pipel

    02 End to End Machine Learning Project https blog csdn net Linli522362242 article details 103387527 Here are the main st
  • div p、div>p、div+p、div~p、div.a 、p,span的用法和区别

    div p div gt p div p div p div a 的用法和区别 div p 将所有 div 标签里面的 p 标签选中 子标签和孙子辈标签 p div p span Hello World span p span Study
  • 【Apache Spark 】第 4 章Spark SQL 和 DataFrames:内置数据源简介

    大家好 我是Sonhhxg 柒 希望你看完之后 能对你有所帮助 不足请指正 共同学习交流 个人主页 Sonhhxg 柒的博客 CSDN博客 欢迎各位 点赞 收藏 留言 系列专栏 机器学习 ML 自然语言处理 NLP 深度学习 DL fore
  • 深度学习之图像的数据增强

    在图像的深度学习中 为了丰富图像训练集 更好的提取图像特征 泛化模型 防止模型过拟合 一般都会对数据图像进行数据增强 数据增强 常用的方式 就是旋转图像 剪切图像 改变图像色差 扭曲图像特征 改变图像尺寸大小 增强图像噪音 一般使用高斯噪音
  • 【计算机网络】RPC框架简介

    文章目录 RPC框架 RPC简介 什么是 RPC RPC原理 RPC 解决了什么问题 常见的 RPC 框架 HTTP和RPC比较 RPC框架 参考文档 RPC框架 RPC简介 什么是 RPC RPC Remote Procedure Cal
  • Python 打印网页为图片(基于edge)

    首先 如果你还没有安装Edge WebDriver 可以前往此处下载 https developer microsoft com en us microsoft edge tools webdriver 使用Chrome的话一样的下载 但是
  • linux基础(超级详细小白入门篇)

    1 基础介绍 1 1 unix 与 linux 区别 1 2 内核 Ubuntu 主要界面视图 因为窗口也是需要消耗资源的 CentOS 主要运用在服务器 linux启动时我们会看到许多启动信息 Linux 系统的启动过程并不是大家想象中的
  • 渗透初识之DVWA靶场搭建及使用(详细图文)

    目录 环境搭建 一 下载DVWA 二 安装DVWA 三 DVWA 使用 环境搭建 我将环境搭在win7 漏洞环境建议还是在虚拟机上搭建 一 下载DVWA 下载地址 Buy Steroids Online UK Anabolic Steroi
  • shell 学习记录(一)-Orange Pi Linux 5.4 SDK启动脚本build.sh

    前言 完全shell菜鸟 以Orange Pi Linux 5 4 SDK编译启动脚本build sh学习shell 对不懂的语法 命令记录 一 获取当前文件夹绝对路径 SRC dirname realpath BASH SOURCE 0
  • 带你玩转Visual Studio

    带你玩转Visual Studio 带你新建一个工程 工程目录下各文件的含义 解决方案与工程 在这之前先了解一个概念 解决方案与工程 解决方案 Solution 一个大型项目的整体的工作环境 工程 Project 一个解决方案下的一个子工程
  • 小程序中如何将页面生成图片?

    记一次开发一款小程序遇到的需求 根据用户填写的商品信息 生成一张可分享的购买海报 简单的看了一下小程序的canvas组件 是可以满足这个需求的实现 所以就开始规划 组织代码了 1 小程序组件 canvas 是可以实现的 这里我就不多说了 但
  • 英语怎么学

    我是怎么从零开始学英语的 哈哈哈 在很多人眼里 英语难 和我以前的认为一样 其实英语是最好学的一个语言 很有规则 远比我们的母语中文好学 多数不要一年 就能够过关了 但要友技巧 很多人一定会认为我晕了头 不要急 等我说完了 你再说这话也不迟
  • MySQL 利用UDF执行命令

    UDF即User Defined Functions lib mysqludf sys 在github的介绍 A UDF library with functions to interact with the operating syste
  • Openwrt-搭建一个Git服务器

    简介 对于Git文件的管理 一直是一个比较困扰的问题 目前是流行的Github是一个不错的选择 但是默认是开源的 如果是一些不愿共享出来的文件代码 我们最好是搭建一个自己的服务器 在git官方网站有git服务器的搭建方法 今天 我要说的是在
  • PYQT5表格及样式设置方法

    PYQT5遇到的问题和解决 1 给table添加样式 table 透明度设置 构造一个含图片的label 再用setCellWidget把label插入单元格 1 给table添加样式 1 qApp setStyleSheet font s
  • 《因果学习周刊》第6期:因果推荐系统

    No 06 智源社区 因果学习组 因 果 学 习 研究 观点 资源 活动 关于周刊 因果学习作为人工智能领域研究热点之一 其研究进展与成果也引发了众多关注 为帮助研究与工程人员了解该领域的相关进展和资讯 智源社区结合领域内容 撰写了第6期
  • 【GeekUninstaller】卸载程序

    软件介绍 删除不了的文件 或者软件可以下载试试不需要安装 文章目录 前言 一 如何下载 二 使用步骤 1 安装完之后自动打开 前言 GeekUninstallers是一款高效 快速 小巧 免费的软件卸载与清理工具 旨在帮助用户删除系统上安装
  • caffe源码追踪--syncedmem

    首先来看看caffe include caffe syncedmem hpp ifndef CAFFE SYNCEDMEM HPP define CAFFE SYNCEDMEM HPP include