COMPMID-1621 Deconvolution wrong output calculation

Change-Id: Ida71312bcf6dbd854f2ab1efc65f74910c79e152
Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/151510
Tested-by: bsgcomp <bsgcomp@arm.com>
Reviewed-by: Michele DiGiorgio <michele.digiorgio@arm.com>
diff --git a/tests/validation/reference/DeconvolutionLayer.cpp b/tests/validation/reference/DeconvolutionLayer.cpp
index ba28b46..5ca3b44 100644
--- a/tests/validation/reference/DeconvolutionLayer.cpp
+++ b/tests/validation/reference/DeconvolutionLayer.cpp
@@ -38,11 +38,23 @@
                                     const PadStrideInfo &info, const std::pair<unsigned int, unsigned int> &a)
 {
     // Create reference
-    const int   stride_x     = info.stride().first;
-    const int   stride_y     = info.stride().second;
+    const int stride_x           = info.stride().first;
+    const int stride_y           = info.stride().second;
+    const int weights_width      = weights.shape().x();
+    const int weights_height     = weights.shape().y();
+    const int weights_upper_dims = weights.shape().total_size() / (weights_width * weights_height);
+
+    // Find the upsampled dimensions
+    unsigned int out_x = (src.shape().x() - 1) * stride_x + a.first + 1;
+    unsigned int out_y = (src.shape().y() - 1) * stride_y + a.second + 1;
+
+    // Find the padding needed for the convolution with stride 1 in order to match output shape
+    unsigned int padx = output_shape.x() - (out_x - weights_width + 1);
+    unsigned int pady = output_shape.y() - (out_y - weights_height + 1);
+    out_x += padx;
+    out_y += pady;
+
     TensorShape scaled_shape = src.shape();
-    int         out_x        = src.shape().x() + (src.shape().x() - 1) * (stride_x - 1) + a.first + 2 * info.pad().first;
-    int         out_y        = src.shape().y() + (src.shape().y() - 1) * (stride_y - 1) + a.second + 2 * info.pad().second;
     scaled_shape.set(0, out_x);
     scaled_shape.set(1, out_y);
     SimpleTensor<T> scaled{ scaled_shape, src.data_type(), 1, src.quantization_info() };
@@ -69,14 +81,28 @@
         std::fill_n(scaled.data(), scaled.num_elements(), T(0));
     }
 
+    // Flip weights by 180 degrees
+    SimpleTensor<T> weights_flipped{ weights.shape(), weights.data_type(), 1, weights.quantization_info() };
+    for(int ud = 0; ud < weights_upper_dims; ++ud)
+    {
+        const int offset = ud * weights_width * weights_height;
+        for(int y = 0; y < weights_height; ++y)
+        {
+            for(int x = 0; x < weights_width; ++x)
+            {
+                weights_flipped[offset + (weights_height - 1 - y) * weights_width + (weights_width - 1 - x)] = weights[offset + y * weights_width + x];
+            }
+        }
+    }
+
     for(int slice = 0; slice < num_2d_slices; ++slice)
     {
         const int offset_slice_in  = slice * width_in * height_in;
         const int offset_slice_out = slice * width_scaled * height_scaled;
-        const int start_x          = info.pad().first;
-        const int start_y          = ay + info.pad().second;
-        const int end_y            = height_scaled - info.pad().second;
-        const int end_x            = width_scaled - ax - info.pad().first;
+        const int start_x          = padx / 2;
+        const int start_y          = ay + pady / 2;
+        const int end_y            = height_scaled - pady / 2;
+        const int end_x            = width_scaled - ax - padx / 2;
 
         for(int yi = start_y, in_y = 0; yi < end_y; yi += stride_y, in_y++)
         {
@@ -90,7 +116,7 @@
     }
 
     const PadStrideInfo conv_info(1, 1, 0, 0, 0, 0, DimensionRoundingType::CEIL);
-    return convolution_layer(scaled, weights, bias, output_shape, conv_info);
+    return convolution_layer(scaled, weights_flipped, bias, output_shape, conv_info);
 }
 
 template SimpleTensor<uint8_t> deconvolution_layer(const SimpleTensor<uint8_t> &src, const SimpleTensor<uint8_t> &weights, const SimpleTensor<int32_t> &bias, const TensorShape &output_shape,