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文件分析的更多相关文章

  1. Caffe源码中math_functions文件分析

    Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下math_functions文件. 1.      include文件: ...

  2. Caffe源码中syncedmem文件分析

    Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下syncedmem文件. 1.      include文件: (1).& ...

  3. Caffe源码中caffe.proto文件分析

    Caffe源码(caffe version:09868ac , date: 2015.08.15)中有一些重要文件,这里介绍下caffe.proto文件. 在src/caffe/proto目录下有一个 ...

  4. 【神经网络与深度学习】Caffe源码中各种依赖库的作用及简单使用

    1.      Boost库:它是一个可移植.跨平台,提供源代码的C++库,作为标准库的后备. 在Caffe中用到的Boost头文件包括: (1).shared_ptr.hpp:智能指针,使用它可以不 ...

  5. tf源码中的object_detection_tutorial.ipynb文件

    今天看到原来下载的tf源码的目标检测源码中test的代码不知道跑哪儿去了,这里记录一下... Imports import numpy as np import os import six.moves ...

  6. linux源码Makefile的详细分析

    目录 一.概述 1.本文的意义 2.Linux内核Makefile文件组成 二.Linux内核Makefile的“make解析”过程 1 顶层Makefile阶段 1.从总目标uImage说起 2.v ...

  7. caffe源码学习之Proto数据格式【1】

    前言: 由于业务需要,接触caffe已经有接近半年,一直忙着阅读各种论文,重现大大小小的模型. 期间也总结过一些caffe源码学习笔记,断断续续,这次打算系统的记录一下caffe源码学习笔记,巩固一下 ...

  8. 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% ...

  9. caffe源码学习

    本文转载自:https://buptldy.github.io/2016/10/09/2016-10-09-Caffe_Code/ Caffe简介 Caffe作为一个优秀的深度学习框架网上已经有很多内 ...

随机推荐

  1. MySQL主从复制——主库已有数据的解决方案

    在上篇文章中我们介绍了基于Docker的Mysql主从搭建,一主多从的搭建过程就是重复了一主一从的从库配置过程,需要注意的是,要保证主从库my.cnf中server-id的唯一性.搭建完成后,可以在主 ...

  2. 记一款bug管理系统(bugdone.cn)的开发过程(4) - 新增BugTalk功能

    测试人员提出一个Bug,如果开发人员对Bug有疑义,会直接面对面讨论或者通过QQ等线上聊天工具讨论,但过后再去找讨论记录会很麻烦.因此BugDone提出一个全新的概念:将问题的讨论留在问题内.BugD ...

  3. python常用模块之string

    python常用模块string模块,该模块可以帮我们获取字母.数字.特殊符号. import string #打印所有的小写字母 print(string.ascii_lowercase) #打印所 ...

  4. LINUX使用extundelete进行数据恢复

    从删库到跑路不是一句笑话,不小心误删除操作很容易造成整个公司业务崩溃.所以真的误删除了,第一时间就是赶紧停机,不要再进行任何写入操作,把这块磁盘挂载到其他机器进行数据恢复 这里我们介绍一下使用 LIN ...

  5. matlab使用总结2

    1.MATLAB中a./b与a/b的区别以及左除和右除 http://blog.csdn.net/wk119911/article/details/7452411 a=[1 2;3 4]; b=[1 ...

  6. Linux运维之shell脚本基础知识

    1.bash中的算术运算 let运算符 [root@:vg_adn_tidbCkhsTest ~/tidb-bench/sysbench]#echo $i [root@:vg_adn_tidbCkhs ...

  7. 阿里八八Alpha阶段Scrum(8/12)

    今日进度 叶文滔: 已经成功解决兼容性问题,目前正在嵌入多级按钮API,预计明天可以完成 王国超: 今天终于debug了,被卡了几天的fragment嵌套listview终于成功了 俞鋆: 研究了一下 ...

  8. 1.Solr介绍

    转载请出自出处:http://www.cnblogs.com/hd3013779515/ Solr是一个基于Lucene的全文搜索引擎,同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,实现 ...

  9. Concurrent包学习之 BlockingQueue源码学习

    上一篇学习了ExecutorService和其它相关类的源码,本篇要学习的BlockingQueue中的源码,as always,先上类图 其实继承(实现)的层次比较简单,我们只要需要先学习一下Blo ...

  10. 谈谈HTTP

    HTTP又称超文本传输协议,在互联网上广为流传和应用. 今天主要讲这么几个? a.针对HTTP下细分为: HTTP概念.Request和Response详解.Request中GET和POST的区别.说 ...