Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
153 lines (135 sloc) 5.48 KB
/**
* @brief A layer factory that allows one to register layers.
* During runtime, registered layers can be called by passing a LayerParameter
* protobuffer to the CreateLayer function:
*
* LayerRegistry<Dtype>::CreateLayer(param);
*
* There are two ways to register a layer. Assuming that we have a layer like:
*
* template <typename Dtype>
* class MyAwesomeLayer : public Layer<Dtype> {
* // your implementations
* };
*
* and its type is its C++ class name, but without the "Layer" at the end
* ("MyAwesomeLayer" -> "MyAwesome").
*
* If the layer is going to be created simply by its constructor, in your c++
* file, add the following line:
*
* REGISTER_LAYER_CLASS(MyAwesome);
*
* Or, if the layer is going to be created by another creator function, in the
* format of:
*
* template <typename Dtype>
* Layer<Dtype*> GetMyAwesomeLayer(const LayerParameter& param) {
* // your implementation
* }
*
* (for example, when your layer has multiple backends, see GetConvolutionLayer
* for a use case), then you can register the creator function instead, like
*
* REGISTER_LAYER_CREATOR(MyAwesome, GetMyAwesomeLayer)
*
* Note that each layer type should only be registered once.
*/
#ifndef CAFFE_LAYER_FACTORY_H_
#define CAFFE_LAYER_FACTORY_H_
#include <map>
#include <string>
#include <vector>
#include "caffe/common.hpp"
#include "caffe/layer.hpp"
#include "caffe/proto/caffe.pb.h"
namespace caffe {
template <typename Dtype>
class Layer;
// 注册类,将每个layer的type(string)和对应的creator(函数指针)成对放入map中
template <typename Dtype>
class LayerRegistry {
public:
// 维护一个CreatroRegistry list,保存每个layer的函数句柄
typedef shared_ptr<Layer<Dtype> > (*Creator)(const LayerParameter&);
typedef std::map<string, Creator> CreatorRegistry;
// 创建注册表
static CreatorRegistry& Registry() {
// map实例, 仅第一次调用时new,其他时候直接return
static CreatorRegistry* g_registry_ = new CreatorRegistry();
return *g_registry_;
}
// Adds a creator.
// 向registry 列表中添加一组<type, creatro>
static void AddCreator(const string& type, Creator creator) {
CreatorRegistry& registry = Registry();
CHECK_EQ(registry.count(type), 0)
<< "Layer type " << type << " already registered.";
registry[type] = creator;
}
// Get a layer using a LayerParameter.
// 在net.cpp的Init函数中被调用。根据参数prototxt文件中layer相关参数创建layer的实例
static shared_ptr<Layer<Dtype> > CreateLayer(const LayerParameter& param) {
if (Caffe::root_solver()) {
LOG(INFO) << "Creating layer " << param.name();
}
const string& type = param.type(); // 获取layer的type
CreatorRegistry& registry = Registry(); // 获取注册表指针
// 是否找到给定type的creator,没有则报错
CHECK_EQ(registry.count(type), 1) << "Unknown layer type: " << type
<< " (known types: " << LayerTypeListString() << ")";
return registry[type](param); // 有则根据layer的type,调用相应的creator函数
}
// 得到注册表中所有layer的type名
static vector<string> LayerTypeList() {
CreatorRegistry& registry = Registry();
vector<string> layer_types;
for (typename CreatorRegistry::iterator iter = registry.begin();
iter != registry.end(); ++iter) {
layer_types.push_back(iter->first);
}
return layer_types;
}
private:
// Layer registry should never be instantiated - everything is done with its
// static variables.
// 私有构造函数,禁止实例化. 因为所有功能都由静态函数完成,所以不需要实例化
LayerRegistry() {}
// 没啥好说的,将LayerTypeList的所有成员用逗号串联成一个字符串
static string LayerTypeListString() {
vector<string> layer_types = LayerTypeList();
string layer_types_str;
for (vector<string>::iterator iter = layer_types.begin();
iter != layer_types.end(); ++iter) {
if (iter != layer_types.begin()) {
layer_types_str += ", ";
}
layer_types_str += *iter;
}
return layer_types_str;
}
};
// 仅有一个构造函数的LayerRegisterer类,用于注册layer
template <typename Dtype>
class LayerRegisterer {
public:
LayerRegisterer(const string& type,
shared_ptr<Layer<Dtype> > (*creator)(const LayerParameter&)) {
// LOG(INFO) << "Registering layer type: " << type;
LayerRegistry<Dtype>::AddCreator(type, creator);
}
};
// 通过宏注册layer,调用上面的LayerRegisterer类的构造函数
#define REGISTER_LAYER_CREATOR(type, creator) \
static LayerRegisterer<float> g_creator_f_##type(#type, creator<float>); \
static LayerRegisterer<double> g_creator_d_##type(#type, creator<double>) \
// 在每个xx_layer.cpp文件的末尾处被调用, 为每个type生成creator方法,并注册到LayerRegister中
#define REGISTER_LAYER_CLASS(type) \
template <typename Dtype> \
shared_ptr<Layer<Dtype> > Creator_##type##Layer(const LayerParameter& param) \
{ \
return shared_ptr<Layer<Dtype> >(new type##Layer<Dtype>(param)); \
} \
REGISTER_LAYER_CREATOR(type, Creator_##type##Layer)
} // namespace caffe
#endif // CAFFE_LAYER_FACTORY_H_
You can’t perform that action at this time.