Publishing 2019 R1 content
[platform/upstream/dldt.git] / inference-engine / thirdparty / mkl-dnn / tests / gtests / test_convolution_dw_conv_common.hpp
index 7f3537b..4c8445b 100644 (file)
@@ -25,7 +25,7 @@ template <typename data_t_src, typename data_t_wei,
           typename data_t_acc, typename data_t_dst>
 void compute_ref_conv_fwd(const mkldnn_convolution_desc_t &conv_desc,
         const memory &src, const memory &weights, const memory &bias, const memory &dst,
-        bool with_relu, float eltwise_alpha)
+        bool with_relu, float eltwise_alpha, const float* depthwise_weights)
 {
     int MB = conv_desc.src_desc.dims[0];
     int G = conv_desc.weights_desc.ndims == 5 ? conv_desc.weights_desc.dims[0] : 1;
@@ -47,7 +47,7 @@ void compute_ref_conv_fwd(const mkldnn_convolution_desc_t &conv_desc,
 
     data_t_src *src_data = (data_t_src *)src.get_data_handle();
     data_t_wei *weights_data = (data_t_wei *)weights.get_data_handle();
-    data_t_dst *bias_data = (data_t_dst *)bias.get_data_handle();
+    float *bias_data = (float *)bias.get_data_handle();
     data_t_dst *dst_data = (data_t_dst *)dst.get_data_handle();
 
     const memory::desc src_d = src.get_primitive_desc().desc();
@@ -82,8 +82,6 @@ void compute_ref_conv_fwd(const mkldnn_convolution_desc_t &conv_desc,
                         a += src_data[map_index(src_d, iidx)]
                              * weights_data[map_index(
                                 weights_d, widx)];
-
-
                     }
                 }
             }
@@ -92,11 +90,19 @@ void compute_ref_conv_fwd(const mkldnn_convolution_desc_t &conv_desc,
 
             a_fp += bias_data[G > 1 ? g : oc];
 
+            if (depthwise_weights)
+                a_fp *= depthwise_weights[G > 1 ? g : oc];
+
             if (with_relu) {
                 a_fp = (a_fp > 0) ? a_fp : eltwise_alpha * a_fp;
             }
 
-            dst_data[map_index(dst_d, oidx)] = (data_t_dst) a_fp;
+            using D = memory::data_type;
+            if (data_traits<data_t_dst>::data_type != D::f32){
+               a_fp = nearbyintf(a_fp);
+            }
+
+            dst_data[map_index(dst_d, oidx)] = (data_t_dst)a_fp;
         }
     );
 }
@@ -115,7 +121,9 @@ protected:
         memory::data_type data_type_src = data_traits<data_t_src>::data_type;
         memory::data_type data_type_dst = data_traits<data_t_dst>::data_type;
         memory::data_type data_type_wei = data_traits<data_t_wei>::data_type;
-        memory::data_type data_type_bia = data_traits<data_t_wei>::data_type;
+        memory::data_type data_type_bia = data_traits<float>::data_type;
+
+        bool is_int8 = data_type_src == mkldnn_u8 || data_type_src == mkldnn_s8;
 
         test_convolution_dw_conv_sizes_t cd = p.sizes;
 
@@ -125,7 +133,7 @@ protected:
         int conv2_oh = (conv1_oh - ((cd.conv2_kh - 1) + 1) + 2 * cd.conv2_padh) / cd.conv2_strh + 1;
         int conv2_ow = (conv1_ow - ((cd.conv2_kw - 1) + 1) + 2 * cd.conv2_padw) / cd.conv2_strw + 1;
 
-        std::vector<int> conv1_padR = { cd.conv1_padh, cd.conv1_padw };
+        std::vector<ptrdiff_t> conv1_padR = { cd.conv1_padh, cd.conv1_padw };
         conv1_padR[0] += conv2_oh - conv1_oh;
         conv1_padR[1] += conv2_ow - conv1_ow;
 
@@ -159,27 +167,62 @@ protected:
         auto conv2_dst = memory({conv2_dst_desc, eng});
 
         fill_data<data_t_src>(conv1_src.get_primitive_desc().get_size()
-                / sizeof(data_t_src), (data_t_src *)conv1_src.get_data_handle(), 1., true);
+                / sizeof(data_t_src), (data_t_src *)conv1_src.get_data_handle(), (data_t_src)1, (data_t_src)1);
         fill_data<data_t_wei>(
                 conv1_weights.get_primitive_desc().get_size()
-                / sizeof(data_t_wei),(data_t_wei *)conv1_weights.get_data_handle(), 1., true);
-        fill_data<data_t_wei>(
+                / sizeof(data_t_wei),(data_t_wei *)conv1_weights.get_data_handle(), (data_t_wei)1, (data_t_wei)1);
+        fill_data<float>(
                 conv1_bias.get_primitive_desc().get_size()
-                / sizeof(data_t_wei),(data_t_wei *)conv1_bias.get_data_handle(), 1., true);
+                / sizeof(float),(float *)conv1_bias.get_data_handle(), 1., true);
         fill_data<data_t_wei>(
                 conv2_weights.get_primitive_desc().get_size()
-                / sizeof(data_t_wei),(data_t_wei *)conv2_weights.get_data_handle(), 1., true);
-        fill_data<data_t_wei>(
+                / sizeof(data_t_wei),(data_t_wei *)conv2_weights.get_data_handle(), (data_t_wei)1, (data_t_wei)1);
+        fill_data<float>(
                 conv2_bias.get_primitive_desc().get_size()
-                / sizeof(data_t_wei),(data_t_wei *)conv2_bias.get_data_handle(), 1., true);
+                / sizeof(float),(float *)conv2_bias.get_data_handle(), 1., true);
+
+//        auto conv1_depthwise_weights_desc = create_md({ cd.conv2_oc }, mkldnn::memory::data_type::f32, memory::x);
+//        auto conv1_depthwise_weights = memory({conv1_depthwise_weights_desc, eng});
+        std::vector<float> conv1_depthwise_weights;
+        conv1_depthwise_weights.resize(cd.conv1_oc);
+        fill_data<float>(conv1_depthwise_weights.size(), &conv1_depthwise_weights[0], 1.f / ((float)cd.ic), 1.f / ((float)cd.ic * cd.conv1_kh * cd.conv1_kw));
+
+        std::vector<float> conv2_depthwise_weights;
+        conv2_depthwise_weights.resize(cd.conv1_oc);
+        fill_data<float>(conv2_depthwise_weights.size(), &conv2_depthwise_weights[0], 1.f / ((float)cd.conv2_oc), 1.f / ((float)cd.conv2_oc * cd.conv2_kh * cd.conv2_kw));
+
+        std::vector<float> conv2_depthwise_bias;
+        conv2_depthwise_bias.resize(cd.conv1_oc);
+//        fill_data<float>(conv2_depthwise_bias.size(), &conv2_depthwise_bias[0], 1., true);
+        memset(&conv2_depthwise_bias[0], 0, conv2_depthwise_bias.size() * sizeof(float));
+
+//        auto conv2_depthwise_weights_desc = create_md({ cd.conv2_oc }, mkldnn::memory::data_type::f32, memory::x);
+//        auto conv2_depthwise_bias_desc = create_md({ cd.conv2_oc }, mkldnn::memory::data_type::f32, memory::x);
+//
+//        auto conv2_depthwise_weights = memory({conv2_depthwise_weights_desc, eng});
+//        auto conv2_depthwise_bias = memory({conv2_depthwise_bias_desc, eng});
+
+//        fill_data<float>(conv2_depthwise_weights.get_primitive_desc().get_size() / sizeof(float),
+//                         (float *)conv2_depthwise_weights.get_data_handle(), 1., true);
+//        memset((float*)conv2_depthwise_bias.get_data_handle(), 0, conv2_depthwise_bias.get_primitive_desc().get_size());
 
         mkldnn::post_ops conv1_post_ops;
         conv1_post_ops.append_eltwise(1.0, mkldnn::algorithm::eltwise_relu, 0.0f, 0.0f);
         conv1_post_ops.append_dw_conv(conv1_oh, conv1_ow, cd.conv2_kh, cd.conv2_kw, cd.conv2_strh, cd.conv2_strw,
                                       static_cast<const float*>(conv2_weights.get_data_handle()),
                                       static_cast<const float*>(conv2_bias.get_data_handle()));
+
+        if (is_int8)
+            conv1_post_ops.append_depthwise(depthwise_scale_shift, &conv2_depthwise_weights[0], &conv2_depthwise_bias[0]);
+
         conv1_post_ops.append_eltwise(1.0, mkldnn::algorithm::eltwise_relu, 0.0f, 0.0f);
         mkldnn::primitive_attr conv1_attr;
+
+        if (is_int8) {
+            conv1_attr.set_int_output_round_mode(mkldnn::round_nearest);
+            conv1_attr.set_output_scales(1 << 1 /*through C dim*/, conv1_depthwise_weights);
+        }
+
         conv1_attr.set_post_ops(conv1_post_ops);
 
         auto conv1_primitive_desc = convolution_forward::primitive_desc(conv1_desc, conv1_attr, eng);
@@ -197,8 +240,14 @@ protected:
 
         auto conv1_dst_ref = memory({conv1_dst_desc_ref, eng});
         auto conv2_dst_ref = memory({conv2_dst_desc, eng});
-        compute_ref_conv_fwd<data_t_src, data_t_wei, data_t_acc, data_t_dst>(conv1_desc_ref.data, conv1_src, conv1_weights, conv1_bias, conv1_dst_ref, true, 0.0f);
-        compute_ref_conv_fwd<data_t_dst, data_t_wei, data_t_acc, data_t_dst>(conv2_desc.data, conv1_dst_ref, conv2_weights, conv2_bias, conv2_dst_ref, true, 0.0f);
+
+        auto conv1_depthwise_weights_data = is_int8 ? &conv1_depthwise_weights[0] : nullptr;
+        auto conv2_depthwise_weights_data = is_int8 ? &conv2_depthwise_weights[0] : nullptr;
+
+        compute_ref_conv_fwd<data_t_src, data_t_wei, data_t_acc, data_t_dst>(conv1_desc_ref.data,
+                conv1_src, conv1_weights, conv1_bias, conv1_dst_ref, true, 0.0f, conv1_depthwise_weights_data);
+        compute_ref_conv_fwd<data_t_dst, data_t_wei, data_t_acc, data_t_dst>(conv2_desc.data,
+                conv1_dst_ref, conv2_weights, conv2_bias, conv2_dst_ref, true, 0.0f, conv2_depthwise_weights_data);
 
         compare_data<data_t_dst>(conv2_dst_ref, conv2_dst);
     }