Caffe源码中common文件分析
Caffe源码(caffe version:09868ac , date: 2015.08.15)中的一些重要头文件如caffe.hpp、blob.hpp等或者外部调用Caffe库使用时,一般都会include<caffe/common.hpp>文件,下面分析此文件的内容:
1. include的文件:
boost中的智能指针头文件<boost/shared_ptr.hpp>,作用类似于C++11中的模板类shared_ptr,通过引用计数方式自动释放所指的对象,不用显示执行delete,关于C++11中shared_ptr的使用可以参考http://blog.csdn.net/fengbingchun/article/details/52202007 .
在Caffe中,封装boost的智能指针using boost::shared_ptr,不使用C++11中的shared_ptr。
GFlags库的<gflags/gflags.h>,它是google的一个开源的处理命令行参数的库,其使用可以参考 http://blog.csdn.net/fengbingchun/article/details/48768039 。
GLog库的<glog/logging.h>,它是google的一个开源的日志库,其使用可以参考 http://blog.csdn.net/fengbingchun/article/details/48768039 。
一些系统头文件,如<climits>、<cmath>、<utility>等。
< caffe/util/device_alternate.hpp >文件。
2. caffe/util/device_alternate.hpp文件:
定义了一些在CPU或GPU+CPU模式下使用的宏和函数。
在CPU模式下(通过#ifdef CPU_ONLY)定义了四个宏用于提示在CPU模式下如果调用GPU函数给出error信息:
#define NO_GPU #define STUB_GPU(classname) #define STUB_GPU_FORWARD(classname, funcname) #define STUB_GPU_BACKWARD(classname, funcname)
在GPU+CPU模式下定义了五个cuda宏、三个函数和一个常量:
#define CUDA_CHECK(condition) #define CUBLAS_CHECK(condition) #define CURAND_CHECK(condition) #define CUDA_KERNEL_LOOP #define CUDA_POST_KERNEL_CHECK const char* cublasGetErrorString(cublasStatus_t error); const char* curandGetErrorString(curandStatus_t error); inline int CAFFE_GET_BLOCKS(const int N); const int CAFFE_CUDA_NUM_THREADS;
3. common.hpp文件中定义的宏:
#define DISABLE_COPY_AND_ASSIGN(classname) #define INSTANTIATE_CLASS(classname) #define INSTANTIATE_LAYER_GPU_FORWARD #define INSTANTIATE_LAYER_GPU_BACKWARD #define INSTANTIATE_LAYER_GPU_FUNCS #define NOT_IMPLEMENTED
其中宏DISABLE_COPY_AND_ASSIGN的作用是禁用指定类的拷贝和赋值操作;宏NOT_IMPLEMENTED的作用是标记没有实现的代码,并给出fatal log;宏INSTANTIATE_CLASS的作用是用于实例化指定的模板类(类模板显示实例化);剩余的三个宏的作用是用于GPU模式下实例化指定的模板类的函数(GPU forward/backward,类似于函数模板显示实例化)。
关于模板显示实例化的介绍可以参考:http://blog.csdn.net/fengbingchun/article/details/51339659
4. GlobalInit函数:
全局初始化函数,用于初始化google开源库gflags(gflags::ParseCommandLineFlags)和glog(google::InitGoogleLogging)。
5. Caffe类:
(1)、采用单例模式(singleton)实现,封装了boost和cuda的一些操作,提供了一套统一的接口,关于单例模式的内容可以参考: http://blog.csdn.net/fengbingchun/article/details/22584107 。
(2)、内部定义了嵌套类RNG,RNG类内部又定义了私有嵌套类Generator,Generator类用于产生随机数.RNG类为随机数生成器,隐藏了boost和CUDA的rng实现,对外提供了一套统一的RNG类。
(3)、构造函数为private,防止直接通过构造函数创建对象,也可防止重复实例化。
(4)、禁止执行拷贝和赋值操作。
(5)、通过Get方法来创建或获取实例。
(6)、枚举类型Brew,指定运行模式:CPU、GPU。
以下是common文件的测试代码:
int test_caffe_common()
{
// 1. test macro NOT_IMPLEMENTED
//NOT_IMPLEMENTED; // error, fatal log
// 2. test global initialization function GlobalInit
int argc = 2;
char** argv = nullptr;
argv = new char*[2];
#ifdef _DEBUG
argv[0] = "E:/GitCode/Caffe_Test/lib/dbg/x64_vc12/Caffe_Test.exe";
#else
argv[0] = "E:/GitCode/Caffe_Test/lib/rel/x64_vc12/Caffe_Test.exe";
#endif
argv[1] = "caffe_test";
caffe::GlobalInit(&argc, &argv);
delete[] argv;
// 3. test caffe class
// caffe::Caffe caffe_; // error, can't create Caffe object directly
// verify Caffe is a singleton class
caffe::Caffe& caffe1 = caffe::Caffe::Get();
caffe::Caffe& caffe2 = caffe::Caffe::Get();
fprintf(stderr, "caffe1 addr: %p\n", &caffe1);
fprintf(stderr, "caffe2 addr: %p\n", &caffe2);
auto addr_caffe1 = std::addressof(caffe1);
auto addr_caffe2 = std::addressof(caffe2);
if (addr_caffe1 != addr_caffe2) {
fprintf(stderr, "caffe1 and caffe2 addr are different: caffe1 addr: %p, caffe2 addr: %p\n", &caffe1, &caffe2);
return -1;
}
// get run mode: CPU or GPU
caffe::Caffe::Brew run_mode = caffe1.mode();
fprintf(stderr, "0: CPU, 1: GPU, run_mode: %d\n", run_mode);
// set solver_count
caffe::Caffe::set_solver_count(5);
// get solver_count
int solver_count = caffe::Caffe::solver_count();
fprintf(stderr, "solver count: %d\n", solver_count);
// set root_solver
caffe::Caffe::set_root_solver(false);
// get root_solver
bool root_solver = caffe::Caffe::root_solver();
fprintf(stderr, "root solver: %d\n", root_solver);
// set device
// caffe::Caffe::SetDevice(2); // error, fatal log: Cannot use GPU in CPU-only Caffe: check mode.
// device query
// caffe::Caffe::DeviceQuery(); // error, fatal log: Cannot use GPU in CPU-only Caffe: check mode.
// RNG: generate random number
caffe::SyncedMemory data_a(10 * sizeof(int));
caffe::Caffe::set_random_seed(8888);
caffe::caffe_rng_bernoulli(10, 0.5, static_cast<int*>(data_a.mutable_cpu_data()));
caffe::SyncedMemory data_b(10 * sizeof(int));
caffe::Caffe::set_random_seed(8888);
caffe::caffe_rng_bernoulli(10, 0.5, static_cast<int*>(data_b.mutable_cpu_data()));
for (int i = 0; i < 10; ++i) {
fprintf(stderr, "%d, %d\n", static_cast<const int*>(data_a.cpu_data())[i], static_cast<const int*>(data_b.cpu_data())[i]);
if (static_cast<const int*>(data_a.cpu_data())[i] != static_cast<const int*>(data_b.cpu_data())[i]) {
fprintf(stderr, "same seed should be generate same random number\n");
return - 1;
}
}
// set run mode
caffe::Caffe::set_mode(caffe::Caffe::GPU);
run_mode = caffe1.mode();
fprintf(stderr, "0: CPU, 1: GPU, run_mode: %d\n", run_mode);
return 0;
}
执行结果如下图:
GitHub:https://github.com/fengbingchun/Caffe_Test
Caffe源码中common文件分析的更多相关文章
- Caffe源码中math_functions文件分析
Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下math_functions文件. 1. include文件: ...
- Caffe源码中syncedmem文件分析
Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下syncedmem文件. 1. include文件: (1).& ...
- 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 ...
- linux源码Makefile的详细分析
目录 一.概述 1.本文的意义 2.Linux内核Makefile文件组成 二.Linux内核Makefile的“make解析”过程 1 顶层Makefile阶段 1.从总目标uImage说起 2.v ...
- caffe源码学习之Proto数据格式【1】
前言: 由于业务需要,接触caffe已经有接近半年,一直忙着阅读各种论文,重现大大小小的模型. 期间也总结过一些caffe源码学习笔记,断断续续,这次打算系统的记录一下caffe源码学习笔记,巩固一下 ...
- Android系统篇之—-编写系统服务并且将其编译到系统源码中【转】
本文转载自:http://www.wjdiankong.cn/android%E7%B3%BB%E7%BB%9F%E7%AF%87%E4%B9%8B-%E7%BC%96%E5%86%99%E7%B3% ...
- caffe源码学习
本文转载自:https://buptldy.github.io/2016/10/09/2016-10-09-Caffe_Code/ Caffe简介 Caffe作为一个优秀的深度学习框架网上已经有很多内 ...
随机推荐
- fiddler常见的应用场景
在移动互联网时代,作为软件测试工程师,fiddler绝对是值得掌握并添加进技术栈里的工具之一. 那么,fiddler在日常的测试工作中,一般都有哪些常见的应用场景呢? 根据以往工作经验,大概有如下4类 ...
- 负载均衡(Load Balancing)学习笔记(二)
概述 文章负载均衡(Load Balancing)学习笔记(一) 讲述了负载均衡的一般性原理,本文继续介绍常见的实现负载均衡的方法. HTTP重定向 HTTP重定向服务器是一台普通的Web服务器,用户 ...
- SQL Server 高并发Insert数据解析,实践
在现实的生产环境中,有可能遇到高并发insert的应用.在此应用时由于堆表(Heap)和聚集表的结构不同导致在高并发的情形下insert效率不尽相同.接下来我会简单的以测试用例来简要说明.并举例说明如 ...
- Spring Cloud 子项目介绍
Spring Cloud由以下子项目组成. Spring Cloud Config 配置中心——利用git来集中管理程序的配置. 项目地址:https://spring.io/projects/spr ...
- Mybatis 学习笔记
可学习渠道 MYBATIS 入门教程 1. Mybatis 介绍 Mybatis 是 sqlmap 技术,对 JDBC 进行封装,将大量的 SQL 语句外部化. 平时我们都用JDBC访问数据库,除了 ...
- 【转】Java学习---集合框架那些事
[原文]https://www.toutiao.com/i6593220692525711885/ Arraylist 与 LinkedList 异同 1. 是否保证线程安全: ArrayList 和 ...
- js 排序,去重
前几天 有一个需求要做一个 勾选的按钮 ,用的前端框架时 extjs . 需求是这样的:选择数据后点击勾选 会把数据 放到一个全局变量里,然后点击另外一个提交按钮 弹出一个窗口 加载这些已经勾选的 ...
- SQLServer 删除表中的重复数据
create table Student( ID varchar(10) not null, Name varchar(10) not null, ); insert in ...
- 写博的第一天 0x00
作为一个大学生,我觉得自己除了睡觉,打游戏,吃饭更应该做点有意义的事情,作为计算机专业的学生,更应该勤奋点,主动去学习.已经要大三了,我认识到这个暑假我必须学点什么了,为了更好的学习,我决定学语言的同 ...
- [Python]运算符的优先级顺序
运算符 描述 ** 指数 (最高优先级) ~ + - 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) * / % // 乘,除,取模和取整除 + - 加法减法 >> & ...