LayerRegistry uses shared_ptr instead of raw pointers
authorJonathan L Long <jonlong@cs.berkeley.edu>
Tue, 17 Feb 2015 03:18:15 +0000 (19:18 -0800)
committerJonathan L Long <jonlong@cs.berkeley.edu>
Tue, 17 Feb 2015 06:46:13 +0000 (22:46 -0800)
Sometimes it's useful for CreateLayer to return a Layer already in use
by another object (e.g., by a Python wrapper). With raw pointers, there
is no way to properly share owership.

include/caffe/layer_factory.hpp
src/caffe/layer_factory.cpp
src/caffe/layers/softmax_loss_layer.cpp
src/caffe/net.cpp
src/caffe/test/test_layer_factory.cpp
src/caffe/test/test_upgrade_proto.cpp

index ede5d1f..2fcd938 100644 (file)
@@ -53,7 +53,7 @@ class Layer;
 template <typename Dtype>
 class LayerRegistry {
  public:
-  typedef Layer<Dtype>* (*Creator)(const LayerParameter&);
+  typedef shared_ptr<Layer<Dtype> > (*Creator)(const LayerParameter&);
   typedef std::map<string, Creator> CreatorRegistry;
 
   static CreatorRegistry& Registry() {
@@ -70,7 +70,7 @@ class LayerRegistry {
   }
 
   // Get a layer using a LayerParameter.
-  static Layer<Dtype>* CreateLayer(const LayerParameter& param) {
+  static shared_ptr<Layer<Dtype> > CreateLayer(const LayerParameter& param) {
     LOG(INFO) << "Creating layer " << param.name();
     const string& type = param.type();
     CreatorRegistry& registry = Registry();
@@ -103,7 +103,7 @@ template <typename Dtype>
 class LayerRegisterer {
  public:
   LayerRegisterer(const string& type,
-                  Layer<Dtype>* (*creator)(const LayerParameter&)) {
+                  shared_ptr<Layer<Dtype> > (*creator)(const LayerParameter&)) {
     // LOG(INFO) << "Registering layer type: " << type;
     LayerRegistry<Dtype>::AddCreator(type, creator);
   }
@@ -116,8 +116,9 @@ class LayerRegisterer {
 
 #define REGISTER_LAYER_CLASS(type)                                             \
   template <typename Dtype>                                                    \
-  Layer<Dtype>* Creator_##type##Layer(const LayerParameter& param) {           \
-    return new type##Layer<Dtype>(param);                                      \
+  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)
 
index c3fd1f3..a27c4ca 100644 (file)
@@ -9,7 +9,7 @@ namespace caffe {
 
 // Get convolution layer according to engine.
 template <typename Dtype>
-Layer<Dtype>* GetConvolutionLayer(
+shared_ptr<Layer<Dtype> > GetConvolutionLayer(
     const LayerParameter& param) {
   ConvolutionParameter_Engine engine = param.convolution_param().engine();
   if (engine == ConvolutionParameter_Engine_DEFAULT) {
@@ -19,10 +19,10 @@ Layer<Dtype>* GetConvolutionLayer(
 #endif
   }
   if (engine == ConvolutionParameter_Engine_CAFFE) {
-    return new ConvolutionLayer<Dtype>(param);
+    return shared_ptr<Layer<Dtype> >(new ConvolutionLayer<Dtype>(param));
 #ifdef USE_CUDNN
   } else if (engine == ConvolutionParameter_Engine_CUDNN) {
-    return new CuDNNConvolutionLayer<Dtype>(param);
+    return shared_ptr<Layer<Dtype> >(new CuDNNConvolutionLayer<Dtype>(param));
 #endif
   } else {
     LOG(FATAL) << "Layer " << param.name() << " has unknown engine.";
@@ -33,7 +33,7 @@ REGISTER_LAYER_CREATOR(Convolution, GetConvolutionLayer);
 
 // Get pooling layer according to engine.
 template <typename Dtype>
-Layer<Dtype>* GetPoolingLayer(const LayerParameter& param) {
+shared_ptr<Layer<Dtype> > GetPoolingLayer(const LayerParameter& param) {
   PoolingParameter_Engine engine = param.pooling_param().engine();
   if (engine == PoolingParameter_Engine_DEFAULT) {
     engine = PoolingParameter_Engine_CAFFE;
@@ -42,7 +42,7 @@ Layer<Dtype>* GetPoolingLayer(const LayerParameter& param) {
 #endif
   }
   if (engine == PoolingParameter_Engine_CAFFE) {
-    return new PoolingLayer<Dtype>(param);
+    return shared_ptr<Layer<Dtype> >(new PoolingLayer<Dtype>(param));
 #ifdef USE_CUDNN
   } else if (engine == PoolingParameter_Engine_CUDNN) {
     PoolingParameter p_param = param.pooling_param();
@@ -50,9 +50,9 @@ Layer<Dtype>* GetPoolingLayer(const LayerParameter& param) {
         param.top_size() > 1) {
       LOG(INFO) << "CUDNN does not support padding or multiple tops. "
                 << "Using Caffe's own pooling layer.";
-      return new PoolingLayer<Dtype>(param);
+      return shared_ptr<Layer<Dtype> >(new PoolingLayer<Dtype>(param));
     }
-    return new CuDNNPoolingLayer<Dtype>(param);
+    return shared_ptr<Layer<Dtype> >(new CuDNNPoolingLayer<Dtype>(param));
 #endif
   } else {
     LOG(FATAL) << "Layer " << param.name() << " has unknown engine.";
@@ -63,7 +63,7 @@ REGISTER_LAYER_CREATOR(Pooling, GetPoolingLayer);
 
 // Get relu layer according to engine.
 template <typename Dtype>
-Layer<Dtype>* GetReLULayer(const LayerParameter& param) {
+shared_ptr<Layer<Dtype> > GetReLULayer(const LayerParameter& param) {
   ReLUParameter_Engine engine = param.relu_param().engine();
   if (engine == ReLUParameter_Engine_DEFAULT) {
     engine = ReLUParameter_Engine_CAFFE;
@@ -72,10 +72,10 @@ Layer<Dtype>* GetReLULayer(const LayerParameter& param) {
 #endif
   }
   if (engine == ReLUParameter_Engine_CAFFE) {
-    return new ReLULayer<Dtype>(param);
+    return shared_ptr<Layer<Dtype> >(new ReLULayer<Dtype>(param));
 #ifdef USE_CUDNN
   } else if (engine == ReLUParameter_Engine_CUDNN) {
-    return new CuDNNReLULayer<Dtype>(param);
+    return shared_ptr<Layer<Dtype> >(new CuDNNReLULayer<Dtype>(param));
 #endif
   } else {
     LOG(FATAL) << "Layer " << param.name() << " has unknown engine.";
@@ -86,7 +86,7 @@ REGISTER_LAYER_CREATOR(ReLU, GetReLULayer);
 
 // Get sigmoid layer according to engine.
 template <typename Dtype>
-Layer<Dtype>* GetSigmoidLayer(const LayerParameter& param) {
+shared_ptr<Layer<Dtype> > GetSigmoidLayer(const LayerParameter& param) {
   SigmoidParameter_Engine engine = param.sigmoid_param().engine();
   if (engine == SigmoidParameter_Engine_DEFAULT) {
     engine = SigmoidParameter_Engine_CAFFE;
@@ -95,10 +95,10 @@ Layer<Dtype>* GetSigmoidLayer(const LayerParameter& param) {
 #endif
   }
   if (engine == SigmoidParameter_Engine_CAFFE) {
-    return new SigmoidLayer<Dtype>(param);
+    return shared_ptr<Layer<Dtype> >(new SigmoidLayer<Dtype>(param));
 #ifdef USE_CUDNN
   } else if (engine == SigmoidParameter_Engine_CUDNN) {
-    return new CuDNNSigmoidLayer<Dtype>(param);
+    return shared_ptr<Layer<Dtype> >(new CuDNNSigmoidLayer<Dtype>(param));
 #endif
   } else {
     LOG(FATAL) << "Layer " << param.name() << " has unknown engine.";
@@ -109,7 +109,7 @@ REGISTER_LAYER_CREATOR(Sigmoid, GetSigmoidLayer);
 
 // Get softmax layer according to engine.
 template <typename Dtype>
-Layer<Dtype>* GetSoftmaxLayer(const LayerParameter& param) {
+shared_ptr<Layer<Dtype> > GetSoftmaxLayer(const LayerParameter& param) {
   SoftmaxParameter_Engine engine = param.softmax_param().engine();
   if (engine == SoftmaxParameter_Engine_DEFAULT) {
     engine = SoftmaxParameter_Engine_CAFFE;
@@ -118,10 +118,10 @@ Layer<Dtype>* GetSoftmaxLayer(const LayerParameter& param) {
 #endif
   }
   if (engine == SoftmaxParameter_Engine_CAFFE) {
-    return new SoftmaxLayer<Dtype>(param);
+    return shared_ptr<Layer<Dtype> >(new SoftmaxLayer<Dtype>(param));
 #ifdef USE_CUDNN
   } else if (engine == SoftmaxParameter_Engine_CUDNN) {
-    return new CuDNNSoftmaxLayer<Dtype>(param);
+    return shared_ptr<Layer<Dtype> >(new CuDNNSoftmaxLayer<Dtype>(param));
 #endif
   } else {
     LOG(FATAL) << "Layer " << param.name() << " has unknown engine.";
@@ -132,7 +132,7 @@ REGISTER_LAYER_CREATOR(Softmax, GetSoftmaxLayer);
 
 // Get tanh layer according to engine.
 template <typename Dtype>
-Layer<Dtype>* GetTanHLayer(const LayerParameter& param) {
+shared_ptr<Layer<Dtype> > GetTanHLayer(const LayerParameter& param) {
   TanHParameter_Engine engine = param.tanh_param().engine();
   if (engine == TanHParameter_Engine_DEFAULT) {
     engine = TanHParameter_Engine_CAFFE;
@@ -141,10 +141,10 @@ Layer<Dtype>* GetTanHLayer(const LayerParameter& param) {
 #endif
   }
   if (engine == TanHParameter_Engine_CAFFE) {
-    return new TanHLayer<Dtype>(param);
+    return shared_ptr<Layer<Dtype> >(new TanHLayer<Dtype>(param));
 #ifdef USE_CUDNN
   } else if (engine == TanHParameter_Engine_CUDNN) {
-    return new CuDNNTanHLayer<Dtype>(param);
+    return shared_ptr<Layer<Dtype> >(new CuDNNTanHLayer<Dtype>(param));
 #endif
   } else {
     LOG(FATAL) << "Layer " << param.name() << " has unknown engine.";
index 8f6a4ef..0c9ba2c 100644 (file)
@@ -15,7 +15,7 @@ void SoftmaxWithLossLayer<Dtype>::LayerSetUp(
   LossLayer<Dtype>::LayerSetUp(bottom, top);
   LayerParameter softmax_param(this->layer_param_);
   softmax_param.set_type("Softmax");
-  softmax_layer_.reset(LayerRegistry<Dtype>::CreateLayer(softmax_param));
+  softmax_layer_ = LayerRegistry<Dtype>::CreateLayer(softmax_param);
   softmax_bottom_vec_.clear();
   softmax_bottom_vec_.push_back(bottom[0]);
   softmax_top_vec_.clear();
index b3e1194..2e44911 100644 (file)
@@ -63,8 +63,7 @@ void Net<Dtype>::Init(const NetParameter& in_param) {
   bottom_need_backward_.resize(param.layer_size());
   for (int layer_id = 0; layer_id < param.layer_size(); ++layer_id) {
     const LayerParameter& layer_param = param.layer(layer_id);
-    layers_.push_back(shared_ptr<Layer<Dtype> >(
-          LayerRegistry<Dtype>::CreateLayer(layer_param)));
+    layers_.push_back(LayerRegistry<Dtype>::CreateLayer(layer_param));
     layer_names_.push_back(layer_param.name());
     LOG(INFO) << "Creating Layer " << layer_param.name();
     bool need_backward = false;
index 3ad635a..7a6401c 100644 (file)
@@ -25,7 +25,7 @@ TYPED_TEST(LayerFactoryTest, TestCreateLayer) {
   for (typename LayerRegistry<Dtype>::CreatorRegistry::iterator iter =
        registry.begin(); iter != registry.end(); ++iter) {
     layer_param.set_type(iter->first);
-    layer.reset(LayerRegistry<Dtype>::CreateLayer(layer_param));
+    layer = LayerRegistry<Dtype>::CreateLayer(layer_param);
     EXPECT_EQ(iter->first, layer->type());
   }
 }
index 7094055..eec6276 100644 (file)
@@ -2901,7 +2901,7 @@ TEST_F(NetUpgradeTest, TestUpgradeV1LayerType) {
       continue;  // Empty string isn't actually a valid layer type.
     }
     layer_param.set_type(v2_layer_type);
-    layer.reset(LayerRegistry<float>::CreateLayer(layer_param));
+    layer = LayerRegistry<float>::CreateLayer(layer_param);
     EXPECT_EQ(v2_layer_type, layer->type());
   }
 }