caffe caffe.cpp 程序入口分析
caffe.cpp 程序入口分析,
(1)main()函数中,输入的train,test,device_query,time。 通过下面两行进入程序。
if (argc == 2) {
return GetBrewFunction(caffe::string(argv[1]))();
return GetBrewFunction(caffe::string(argv[1]))();
(2)GetBrewFunction()函数定义如下,其返回BrewFunction函数指针。
static BrewFunction GetBrewFunction(const caffe::string& name) {
// use map type to check name appears frequency
if (g_brew_map.count(name)) { // 判断输入的是不是g_brew_map中train,test,device_query,time中一个,
return g_brew_map[name]; // 如果是的话,就调用相应的train(),test(),device_query(),time()
// use map type to check name appears frequency
if (g_brew_map.count(name)) { // 判断输入的是不是g_brew_map中train,test,device_query,time中一个,
return g_brew_map[name]; // 如果是的话,就调用相应的train(),test(),device_query(),time()
...
}
(3)g_brew_map实现过程,首先通过 typedef定义函数指针
typedef int (*BrewFunction)();
这个是用typedef定义函数指针方法。这个程序定义一个BrewFunction函数指针类型,
在caffe.cpp 中 BrewFunction 作为GetBrewFunction()函数的返回类型,可以是 train(),test(),device_query(),time() 这四个函数指针的其中一个。在train(),test(),中可以调用solver类的函数,从而进入到net,进入到每一层,运行整个caffe程序。
(4)g_brew_map定义
typedef std::map<caffe::string, BrewFunction> BrewMap;// 因为输入参数可能为train,test,device_query,time,所以定义一个容器类型,
BrewMap g_brew_map;
BrewMap g_brew_map;
(5) g_brew_map 初始化
#define RegisterBrewFunction(func) \
namespace { \
class __Registerer_##func { \
public: /* NOLINT */ \
__Registerer_##func() { \
g_brew_map[#func] = &func; \
} \
}; \
__Registerer_##func g_registerer_##func; \
}
namespace { \
class __Registerer_##func { \
public: /* NOLINT */ \
__Registerer_##func() { \
g_brew_map[#func] = &func; \
} \
}; \
__Registerer_##func g_registerer_##func; \
}
这个作用和#define RegisterBrewFunction(func) g_brew_map[#func]=&func; 这个宏定义功能类似,其中,func可以为:train,test,device_query,time。
综上, caffe中定义了train(),test(),device_query(),time()四种方式。 如果需要,咱们可以增加其他的方式,然后通过RegisterBrewFunction() 函数注册一下即可。