Data Layers Parallel for Multi-GPU
[platform/upstream/caffeonacl.git] / include / caffe / layer.hpp
1 #ifndef CAFFE_LAYER_H_
2 #define CAFFE_LAYER_H_
3
4 #include <boost/thread.hpp>
5 #include <algorithm>
6 #include <string>
7 #include <vector>
8
9 #include "caffe/blob.hpp"
10 #include "caffe/common.hpp"
11 #include "caffe/layer_factory.hpp"
12 #include "caffe/proto/caffe.pb.h"
13 #include "caffe/util/device_alternate.hpp"
14
15 namespace caffe {
16
17 /**
18  * @brief An interface for the units of computation which can be composed into a
19  *        Net.
20  *
21  * Layer%s must implement a Forward function, in which they take their input
22  * (bottom) Blob%s (if any) and compute their output Blob%s (if any).
23  * They may also implement a Backward function, in which they compute the error
24  * gradients with respect to their input Blob%s, given the error gradients with
25  * their output Blob%s.
26  */
27 template <typename Dtype>
28 class Layer {
29  public:
30   /**
31    * You should not implement your own constructor. Any set up code should go
32    * to SetUp(), where the dimensions of the bottom blobs are provided to the
33    * layer.
34    */
35   explicit Layer(const LayerParameter& param)
36     : layer_param_(param) {
37       // Set phase and copy blobs (if there are any).
38       phase_ = param.phase();
39       if (layer_param_.blobs_size() > 0) {
40         blobs_.resize(layer_param_.blobs_size());
41         for (int i = 0; i < layer_param_.blobs_size(); ++i) {
42           blobs_[i].reset(new Blob<Dtype>());
43           blobs_[i]->FromProto(layer_param_.blobs(i));
44         }
45       }
46     }
47   virtual ~Layer() {}
48
49   /**
50    * @brief Implements common layer setup functionality.
51    *
52    * @param bottom the preshaped input blobs
53    * @param top
54    *     the allocated but unshaped output blobs, to be shaped by Reshape
55    *
56    * Checks that the number of bottom and top blobs is correct.
57    * Calls LayerSetUp to do special layer setup for individual layer types,
58    * followed by Reshape to set up sizes of top blobs and internal buffers.
59    * Sets up the loss weight multiplier blobs for any non-zero loss weights.
60    * This method may not be overridden.
61    */
62   void SetUp(const vector<Blob<Dtype>*>& bottom,
63       const vector<Blob<Dtype>*>& top) {
64     CheckBlobCounts(bottom, top);
65     LayerSetUp(bottom, top);
66     Reshape(bottom, top);
67     SetLossWeights(top);
68   }
69
70   /**
71    * @brief Does layer-specific setup: your layer should implement this function
72    *        as well as Reshape.
73    *
74    * @param bottom
75    *     the preshaped input blobs, whose data fields store the input data for
76    *     this layer
77    * @param top
78    *     the allocated but unshaped output blobs
79    *
80    * This method should do one-time layer specific setup. This includes reading
81    * and processing relevent parameters from the <code>layer_param_</code>.
82    * Setting up the shapes of top blobs and internal buffers should be done in
83    * <code>Reshape</code>, which will be called before the forward pass to
84    * adjust the top blob sizes.
85    */
86   virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
87       const vector<Blob<Dtype>*>& top) {}
88
89   /**
90    * @brief Whether a layer should be shared by multiple nets during data
91    *        parallelism. By default, all layers except for data layers should
92    *        not be shared. data layers should be shared to ensure each worker
93    *        solver access data sequentially during data parallelism.
94    */
95   virtual inline bool ShareInParallel() const { return false; }
96
97   /**
98    * @brief Adjust the shapes of top blobs and internal buffers to accommodate
99    *        the shapes of the bottom blobs.
100    *
101    * @param bottom the input blobs, with the requested input shapes
102    * @param top the top blobs, which should be reshaped as needed
103    *
104    * This method should reshape top blobs as needed according to the shapes
105    * of the bottom (input) blobs, as well as reshaping any internal buffers
106    * and making any other necessary adjustments so that the layer can
107    * accommodate the bottom blobs.
108    */
109   virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
110       const vector<Blob<Dtype>*>& top) = 0;
111
112   /**
113    * @brief Given the bottom blobs, compute the top blobs and the loss.
114    *
115    * @param bottom
116    *     the input blobs, whose data fields store the input data for this layer
117    * @param top
118    *     the preshaped output blobs, whose data fields will store this layers'
119    *     outputs
120    * \return The total loss from the layer.
121    *
122    * The Forward wrapper calls the relevant device wrapper function
123    * (Forward_cpu or Forward_gpu) to compute the top blob values given the
124    * bottom blobs.  If the layer has any non-zero loss_weights, the wrapper
125    * then computes and returns the loss.
126    *
127    * Your layer should implement Forward_cpu and (optionally) Forward_gpu.
128    */
129   inline Dtype Forward(const vector<Blob<Dtype>*>& bottom,
130       const vector<Blob<Dtype>*>& top);
131
132   /**
133    * @brief Given the top blob error gradients, compute the bottom blob error
134    *        gradients.
135    *
136    * @param top
137    *     the output blobs, whose diff fields store the gradient of the error
138    *     with respect to themselves
139    * @param propagate_down
140    *     a vector with equal length to bottom, with each index indicating
141    *     whether to propagate the error gradients down to the bottom blob at
142    *     the corresponding index
143    * @param bottom
144    *     the input blobs, whose diff fields will store the gradient of the error
145    *     with respect to themselves after Backward is run
146    *
147    * The Backward wrapper calls the relevant device wrapper function
148    * (Backward_cpu or Backward_gpu) to compute the bottom blob diffs given the
149    * top blob diffs.
150    *
151    * Your layer should implement Backward_cpu and (optionally) Backward_gpu.
152    */
153   inline void Backward(const vector<Blob<Dtype>*>& top,
154       const vector<bool>& propagate_down,
155       const vector<Blob<Dtype>*>& bottom);
156
157   /**
158    * @brief Returns the vector of learnable parameter blobs.
159    */
160   vector<shared_ptr<Blob<Dtype> > >& blobs() {
161     return blobs_;
162   }
163
164   /**
165    * @brief Returns the layer parameter.
166    */
167   const LayerParameter& layer_param() const { return layer_param_; }
168
169   /**
170    * @brief Writes the layer parameter to a protocol buffer
171    */
172   virtual void ToProto(LayerParameter* param, bool write_diff = false);
173
174   /**
175    * @brief Returns the scalar loss associated with a top blob at a given index.
176    */
177   inline Dtype loss(const int top_index) const {
178     return (loss_.size() > top_index) ? loss_[top_index] : Dtype(0);
179   }
180
181   /**
182    * @brief Sets the loss associated with a top blob at a given index.
183    */
184   inline void set_loss(const int top_index, const Dtype value) {
185     if (loss_.size() <= top_index) {
186       loss_.resize(top_index + 1, Dtype(0));
187     }
188     loss_[top_index] = value;
189   }
190
191   /**
192    * @brief Returns the layer type.
193    */
194   virtual inline const char* type() const { return ""; }
195
196   /**
197    * @brief Returns the exact number of bottom blobs required by the layer,
198    *        or -1 if no exact number is required.
199    *
200    * This method should be overridden to return a non-negative value if your
201    * layer expects some exact number of bottom blobs.
202    */
203   virtual inline int ExactNumBottomBlobs() const { return -1; }
204   /**
205    * @brief Returns the minimum number of bottom blobs required by the layer,
206    *        or -1 if no minimum number is required.
207    *
208    * This method should be overridden to return a non-negative value if your
209    * layer expects some minimum number of bottom blobs.
210    */
211   virtual inline int MinBottomBlobs() const { return -1; }
212   /**
213    * @brief Returns the maximum number of bottom blobs required by the layer,
214    *        or -1 if no maximum number is required.
215    *
216    * This method should be overridden to return a non-negative value if your
217    * layer expects some maximum number of bottom blobs.
218    */
219   virtual inline int MaxBottomBlobs() const { return -1; }
220   /**
221    * @brief Returns the exact number of top blobs required by the layer,
222    *        or -1 if no exact number is required.
223    *
224    * This method should be overridden to return a non-negative value if your
225    * layer expects some exact number of top blobs.
226    */
227   virtual inline int ExactNumTopBlobs() const { return -1; }
228   /**
229    * @brief Returns the minimum number of top blobs required by the layer,
230    *        or -1 if no minimum number is required.
231    *
232    * This method should be overridden to return a non-negative value if your
233    * layer expects some minimum number of top blobs.
234    */
235   virtual inline int MinTopBlobs() const { return -1; }
236   /**
237    * @brief Returns the maximum number of top blobs required by the layer,
238    *        or -1 if no maximum number is required.
239    *
240    * This method should be overridden to return a non-negative value if your
241    * layer expects some maximum number of top blobs.
242    */
243   virtual inline int MaxTopBlobs() const { return -1; }
244   /**
245    * @brief Returns true if the layer requires an equal number of bottom and
246    *        top blobs.
247    *
248    * This method should be overridden to return true if your layer expects an
249    * equal number of bottom and top blobs.
250    */
251   virtual inline bool EqualNumBottomTopBlobs() const { return false; }
252
253   /**
254    * @brief Return whether "anonymous" top blobs are created automatically
255    *        by the layer.
256    *
257    * If this method returns true, Net::Init will create enough "anonymous" top
258    * blobs to fulfill the requirement specified by ExactNumTopBlobs() or
259    * MinTopBlobs().
260    */
261   virtual inline bool AutoTopBlobs() const { return false; }
262
263   /**
264    * @brief Return whether to allow force_backward for a given bottom blob
265    *        index.
266    *
267    * If AllowForceBackward(i) == false, we will ignore the force_backward
268    * setting and backpropagate to blob i only if it needs gradient information
269    * (as is done when force_backward == false).
270    */
271   virtual inline bool AllowForceBackward(const int bottom_index) const {
272     return true;
273   }
274
275   /**
276    * @brief Specifies whether the layer should compute gradients w.r.t. a
277    *        parameter at a particular index given by param_id.
278    *
279    * You can safely ignore false values and always compute gradients
280    * for all parameters, but possibly with wasteful computation.
281    */
282   inline bool param_propagate_down(const int param_id) {
283     return (param_propagate_down_.size() > param_id) ?
284         param_propagate_down_[param_id] : false;
285   }
286   /**
287    * @brief Sets whether the layer should compute gradients w.r.t. a
288    *        parameter at a particular index given by param_id.
289    */
290   inline void set_param_propagate_down(const int param_id, const bool value) {
291     if (param_propagate_down_.size() <= param_id) {
292       param_propagate_down_.resize(param_id + 1, true);
293     }
294     param_propagate_down_[param_id] = value;
295   }
296
297
298  protected:
299   /** The protobuf that stores the layer parameters */
300   LayerParameter layer_param_;
301   /** The phase: TRAIN or TEST */
302   Phase phase_;
303   /** The vector that stores the learnable parameters as a set of blobs. */
304   vector<shared_ptr<Blob<Dtype> > > blobs_;
305   /** Vector indicating whether to compute the diff of each param blob. */
306   vector<bool> param_propagate_down_;
307
308   /** The vector that indicates whether each top blob has a non-zero weight in
309    *  the objective function. */
310   vector<Dtype> loss_;
311
312   /** @brief Using the CPU device, compute the layer output. */
313   virtual void Forward_cpu(const vector<Blob<Dtype>*>& bottom,
314       const vector<Blob<Dtype>*>& top) = 0;
315   /**
316    * @brief Using the GPU device, compute the layer output.
317    *        Fall back to Forward_cpu() if unavailable.
318    */
319   virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
320       const vector<Blob<Dtype>*>& top) {
321     // LOG(WARNING) << "Using CPU code as backup.";
322     return Forward_cpu(bottom, top);
323   }
324
325   /**
326    * @brief Using the CPU device, compute the gradients for any parameters and
327    *        for the bottom blobs if propagate_down is true.
328    */
329   virtual void Backward_cpu(const vector<Blob<Dtype>*>& top,
330       const vector<bool>& propagate_down,
331       const vector<Blob<Dtype>*>& bottom) = 0;
332   /**
333    * @brief Using the GPU device, compute the gradients for any parameters and
334    *        for the bottom blobs if propagate_down is true.
335    *        Fall back to Backward_cpu() if unavailable.
336    */
337   virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
338       const vector<bool>& propagate_down,
339       const vector<Blob<Dtype>*>& bottom) {
340     // LOG(WARNING) << "Using CPU code as backup.";
341     Backward_cpu(top, propagate_down, bottom);
342   }
343
344   /**
345    * Called by the parent Layer's SetUp to check that the number of bottom
346    * and top Blobs provided as input match the expected numbers specified by
347    * the {ExactNum,Min,Max}{Bottom,Top}Blobs() functions.
348    */
349   virtual void CheckBlobCounts(const vector<Blob<Dtype>*>& bottom,
350                                const vector<Blob<Dtype>*>& top) {
351     if (ExactNumBottomBlobs() >= 0) {
352       CHECK_EQ(ExactNumBottomBlobs(), bottom.size())
353           << type() << " Layer takes " << ExactNumBottomBlobs()
354           << " bottom blob(s) as input.";
355     }
356     if (MinBottomBlobs() >= 0) {
357       CHECK_LE(MinBottomBlobs(), bottom.size())
358           << type() << " Layer takes at least " << MinBottomBlobs()
359           << " bottom blob(s) as input.";
360     }
361     if (MaxBottomBlobs() >= 0) {
362       CHECK_GE(MaxBottomBlobs(), bottom.size())
363           << type() << " Layer takes at most " << MaxBottomBlobs()
364           << " bottom blob(s) as input.";
365     }
366     if (ExactNumTopBlobs() >= 0) {
367       CHECK_EQ(ExactNumTopBlobs(), top.size())
368           << type() << " Layer produces " << ExactNumTopBlobs()
369           << " top blob(s) as output.";
370     }
371     if (MinTopBlobs() >= 0) {
372       CHECK_LE(MinTopBlobs(), top.size())
373           << type() << " Layer produces at least " << MinTopBlobs()
374           << " top blob(s) as output.";
375     }
376     if (MaxTopBlobs() >= 0) {
377       CHECK_GE(MaxTopBlobs(), top.size())
378           << type() << " Layer produces at most " << MaxTopBlobs()
379           << " top blob(s) as output.";
380     }
381     if (EqualNumBottomTopBlobs()) {
382       CHECK_EQ(bottom.size(), top.size())
383           << type() << " Layer produces one top blob as output for each "
384           << "bottom blob input.";
385     }
386   }
387
388   /**
389    * Called by SetUp to initialize the weights associated with any top blobs in
390    * the loss function. Store non-zero loss weights in the diff blob.
391    */
392   inline void SetLossWeights(const vector<Blob<Dtype>*>& top) {
393     const int num_loss_weights = layer_param_.loss_weight_size();
394     if (num_loss_weights) {
395       CHECK_EQ(top.size(), num_loss_weights) << "loss_weight must be "
396           "unspecified or specified once per top blob.";
397       for (int top_id = 0; top_id < top.size(); ++top_id) {
398         const Dtype loss_weight = layer_param_.loss_weight(top_id);
399         if (loss_weight == Dtype(0)) { continue; }
400         this->set_loss(top_id, loss_weight);
401         const int count = top[top_id]->count();
402         Dtype* loss_multiplier = top[top_id]->mutable_cpu_diff();
403         caffe_set(count, loss_weight, loss_multiplier);
404       }
405     }
406   }
407
408  private:
409   // mutex to lock layer to ensure sequential forward
410   boost::mutex forward_mutex_;
411
412   DISABLE_COPY_AND_ASSIGN(Layer);
413 };  // class Layer
414
415 // Forward and backward wrappers. You should implement the cpu and
416 // gpu specific implementations instead, and should not change these
417 // functions.
418 template <typename Dtype>
419 inline Dtype Layer<Dtype>::Forward(const vector<Blob<Dtype>*>& bottom,
420     const vector<Blob<Dtype>*>& top) {
421   // Lock during forward to ensure sequential forward
422   boost::mutex::scoped_lock lock(forward_mutex_);
423   Dtype loss = 0;
424   Reshape(bottom, top);
425   switch (Caffe::mode()) {
426   case Caffe::CPU:
427     Forward_cpu(bottom, top);
428     for (int top_id = 0; top_id < top.size(); ++top_id) {
429       if (!this->loss(top_id)) { continue; }
430       const int count = top[top_id]->count();
431       const Dtype* data = top[top_id]->cpu_data();
432       const Dtype* loss_weights = top[top_id]->cpu_diff();
433       loss += caffe_cpu_dot(count, data, loss_weights);
434     }
435     break;
436   case Caffe::GPU:
437     Forward_gpu(bottom, top);
438 #ifndef CPU_ONLY
439     for (int top_id = 0; top_id < top.size(); ++top_id) {
440       if (!this->loss(top_id)) { continue; }
441       const int count = top[top_id]->count();
442       const Dtype* data = top[top_id]->gpu_data();
443       const Dtype* loss_weights = top[top_id]->gpu_diff();
444       Dtype blob_loss = 0;
445       caffe_gpu_dot(count, data, loss_weights, &blob_loss);
446       loss += blob_loss;
447     }
448 #endif
449     break;
450   default:
451     LOG(FATAL) << "Unknown caffe mode.";
452   }
453   return loss;
454 }
455
456 template <typename Dtype>
457 inline void Layer<Dtype>::Backward(const vector<Blob<Dtype>*>& top,
458     const vector<bool>& propagate_down,
459     const vector<Blob<Dtype>*>& bottom) {
460   switch (Caffe::mode()) {
461   case Caffe::CPU:
462     Backward_cpu(top, propagate_down, bottom);
463     break;
464   case Caffe::GPU:
465     Backward_gpu(top, propagate_down, bottom);
466     break;
467   default:
468     LOG(FATAL) << "Unknown caffe mode.";
469   }
470 }
471
472 // Serialize LayerParameter to protocol buffer
473 template <typename Dtype>
474 void Layer<Dtype>::ToProto(LayerParameter* param, bool write_diff) {
475   param->Clear();
476   param->CopyFrom(layer_param_);
477   param->clear_blobs();
478   for (int i = 0; i < blobs_.size(); ++i) {
479     blobs_[i]->ToProto(param->add_blobs(), write_diff);
480   }
481 }
482
483 }  // namespace caffe
484
485 #endif  // CAFFE_LAYER_H_