]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - jacinto-ai/caffe-jacinto.git/blobdiff - src/caffe/layers/pooling_layer.cpp
average pooling - fixed point implementation
[jacinto-ai/caffe-jacinto.git] / src / caffe / layers / pooling_layer.cpp
index edeb9112bc59ef18a2f2fc04b48d37d13ec16838..c6f72113087f580c4499883c75f2fbc474560708 100644 (file)
@@ -128,6 +128,10 @@ void PoolingLayer<Ftype, Btype>::Reshape(const vector<Blob*>& bottom,
 template <typename Ftype, typename Btype>
 void PoolingLayer<Ftype, Btype>::Forward_cpu(const vector<Blob*>& bottom,
       const vector<Blob*>& top) {
+  const QuantizationParameter& qparam = this->layer_param_.quantization_param();
+  bool quantize = (qparam.qparam_out_size()>0 && qparam.qparam_out(0).quantize());
+  int qscale_in = (qparam.qparam_in_size()>0? qparam.qparam_in(0).scale_target() : 1);
+
   const Ftype* bottom_data = bottom[0]->cpu_data<Ftype>();
   Ftype* top_data = top[0]->mutable_cpu_data<Ftype>();
   const int top_count = top[0]->count();
@@ -204,13 +208,28 @@ void PoolingLayer<Ftype, Btype>::Forward_cpu(const vector<Blob*>& bottom,
             wstart = max(wstart, 0);
             hend = min(hend, height_);
             wend = min(wend, width_);
-            for (int h = hstart; h < hend; ++h) {
-              for (int w = wstart; w < wend; ++w) {
-                top_data[ph * pooled_width_ + pw] +=
-                    bottom_data[h * width_ + w];
-              }
+
+            if(quantize) {
+                const int qbits = 12;
+                const int qscale = (1<<qbits);
+                const int mult_factor = int(qscale/float(pool_size) + 0.5f);
+
+                for (int h = hstart; h < hend; ++h) {
+                  for (int w = wstart; w < wend; ++w) {
+                    top_data[ph * pooled_width_ + pw] +=
+                        int(bottom_data[h * width_ + w] * qscale_in * mult_factor + 0.5);
+                  }
+                }
+                top_data[ph * pooled_width_ + pw] /= float(qscale_in*qscale);
+            } else {
+                for (int h = hstart; h < hend; ++h) {
+                  for (int w = wstart; w < wend; ++w) {
+                    top_data[ph * pooled_width_ + pw] +=
+                        bottom_data[h * width_ + w];
+                  }
+                }
+                top_data[ph * pooled_width_ + pw] /= pool_size;
             }
-            top_data[ph * pooled_width_ + pw] /= pool_size;
           }
         }
         // compute offset