11#include < vector>
22
33#include " caffe/layers/conv_layer.hpp"
4+ #include " caffe/util/math_functions.hpp"
45
56namespace caffe {
67
@@ -51,10 +52,39 @@ void ConvolutionLayer<Dtype>::compute_output_shape() {
5152template <typename Dtype>
5253void ConvolutionLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
5354 const vector<Blob<Dtype>*>& top) {
55+ // set up quantization parameters: scale + zero_point
56+ const Dtype input_scale = this ->input_scale_ ;
57+ const Dtype output_scale = this ->output_scale_ ;
58+ const Dtype weight_scale = this ->weight_scale_ ;
59+ const Dtype bias_scale = this ->bias_scale_ ;
60+ const int input_zero_point = this ->input_zero_point_ ;
61+ const int output_zero_point = this ->output_zero_point_ ;
62+ const int weight_zero_point = this ->weight_zero_point_ ;
63+ const int bias_zero_point = this ->bias_zero_point_ ;
64+ const Dtype saturate = this ->saturate_ ;
65+ const bool quant_in = (input_scale != Dtype (1.0 ) || input_zero_point != 0 );
66+ const bool quant_out = (output_scale != Dtype (1.0 ) || output_zero_point != 0 );
67+ const bool quant_w = (weight_scale != Dtype (1.0 ) || weight_zero_point != 0 );
68+ const bool quant_b = (this ->bias_term_ && (bias_scale != Dtype (1.0 ) || bias_zero_point != 0 ));
69+ if (quant_w) {
70+ Dtype *qw = this ->blobs_ [0 ]->mutable_cpu_data ();
71+ caffe_cpu_dequantize<Dtype>(this ->blobs_ [0 ]->count (), qw, weight_scale, weight_zero_point);
72+ }
73+ if (quant_b) {
74+ Dtype *qb = this ->blobs_ [1 ]->mutable_cpu_data ();
75+ caffe_cpu_dequantize<Dtype>(this ->blobs_ [1 ]->count (), qb, bias_scale, bias_zero_point);
76+ }
77+
5478 const Dtype* weight = this ->blobs_ [0 ]->cpu_data ();
5579 for (int i = 0 ; i < bottom.size (); ++i) {
80+ if (quant_in) {
81+ Dtype* qin = bottom[i]->mutable_cpu_data ();
82+ caffe_cpu_dequantize<Dtype>(bottom[i]->count (), qin, input_scale, input_zero_point);
83+ }
84+
5685 const Dtype* bottom_data = bottom[i]->cpu_data ();
5786 Dtype* top_data = top[i]->mutable_cpu_data ();
87+
5888 for (int n = 0 ; n < this ->num_ ; ++n) {
5989 this ->forward_cpu_gemm (bottom_data + n * this ->bottom_dim_ , weight,
6090 top_data + n * this ->top_dim_ );
@@ -63,6 +93,33 @@ void ConvolutionLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
6393 this ->forward_cpu_bias (top_data + n * this ->top_dim_ , bias);
6494 }
6595 }
96+
97+ const int count_t = top[i]->count ();
98+ if (quant_out) {
99+ caffe_cpu_quantize<Dtype>(count_t , top_data, output_scale, output_zero_point);
100+ }
101+ if (saturate == ConvolutionParameter_SaturateMethod_Signed)
102+ caffe_cpu_signed_saturate (count_t , top_data);
103+ if (saturate == ConvolutionParameter_SaturateMethod_Unsigned)
104+ caffe_cpu_unsigned_saturate (count_t , top_data);
105+ if (saturate == ConvolutionParameter_SaturateMethod_Signed_8bit)
106+ caffe_cpu_signed_8bit_saturate (count_t , top_data);
107+ if (saturate == ConvolutionParameter_SaturateMethod_Unsigned_8bit)
108+ caffe_cpu_unsigned_8bit_saturate (count_t , top_data);
109+
110+ if (quant_in) { // restore the quantized input blob
111+ Dtype* qin = bottom[i]->mutable_cpu_data ();
112+ caffe_cpu_quantize<Dtype>(bottom[i]->count (), qin, input_scale, input_zero_point);
113+ }
114+ }
115+ // restore quantized weight/bias
116+ if (quant_w) {
117+ Dtype *qw = this ->blobs_ [0 ]->mutable_cpu_data ();
118+ caffe_cpu_quantize<Dtype>(this ->blobs_ [0 ]->count (), qw, weight_scale, weight_zero_point);
119+ }
120+ if (quant_b) {
121+ Dtype *qb = this ->blobs_ [1 ]->mutable_cpu_data ();
122+ caffe_cpu_quantize<Dtype>(this ->blobs_ [1 ]->count (), qb, bias_scale, bias_zero_point);
66123 }
67124}
68125
0 commit comments