COMPMID-2637 [CL] fix broadcast pixel-wise multiplication with 5D tensors

Broadcast pixel-wise multiplication with 5D tensors is fixed
by adding information whether a dimension has been broadcasted
to compute correct start offset when adding 3D tensor argument.
The testcase that failed is added to the validation test suite.

Change-Id: I320876f507012c27b39daae1316f9b69138ed204
Signed-off-by: Sang-Hoon Park <sang-hoon.park@arm.com>
Reviewed-on: https://review.mlplatform.org/c/1994
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
Reviewed-by: Georgios Pinitas <georgios.pinitas@arm.com>
diff --git a/arm_compute/core/Window.h b/arm_compute/core/Window.h
index a562279..be42fe9 100644
--- a/arm_compute/core/Window.h
+++ b/arm_compute/core/Window.h
@@ -48,7 +48,7 @@
 
     /** Default constructor: create a window containing a single element. */
     constexpr Window()
-        : _dims()
+        : _dims(), _is_broadcasted(utility::generate_array<bool, Coordinates::num_max_dimensions, false>::value)
     {
     }
     /** Copy constructor
@@ -170,6 +170,20 @@
      */
     void set(size_t dimension, const Dimension &dim);
 
+    /** Set the dimension as broadcasted dimension
+     *
+     * @param[in] dimension The dimension to set
+     */
+    void set_broadcasted(size_t dimension);
+
+    /** Return whether a dimension has been broadcasted
+     *
+     * @param[in] dimension The requested dimension
+     *
+     * @return true if the dimension has been broadcasted
+     */
+    bool is_broadcasted(size_t dimension) const;
+
     /** Use the tensor's dimensions to fill the window dimensions.
      *
      * @param[in] shape           @ref TensorShape to copy the dimensions from.
@@ -419,6 +433,7 @@
 
 private:
     std::array<Dimension, Coordinates::num_max_dimensions> _dims;
+    std::array<bool, Coordinates::num_max_dimensions>      _is_broadcasted;
 };
 } // namespace arm_compute
 #include "Window.inl"
diff --git a/arm_compute/core/Window.inl b/arm_compute/core/Window.inl
index eeef3df..589d6bf 100644
--- a/arm_compute/core/Window.inl
+++ b/arm_compute/core/Window.inl
@@ -24,11 +24,12 @@
 namespace arm_compute
 {
 inline Window::Window(const Window &src)
-    : _dims()
+    : _dims(), _is_broadcasted(utility::generate_array<bool, Coordinates::num_max_dimensions, false>::value)
 {
     for(size_t i = 0; i < Coordinates::num_max_dimensions; ++i)
     {
         set(i, src[i]);
+        _is_broadcasted[i] = src.is_broadcasted(i);
     }
 }
 
@@ -51,6 +52,19 @@
     _dims[dimension] = dim;
 }
 
+inline void Window::set_broadcasted(size_t dimension)
+{
+    ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions);
+    set(dimension, Dimension(0, 0, 0));
+    _is_broadcasted[dimension] = true;
+}
+
+inline bool Window::is_broadcasted(size_t dimension) const
+{
+    ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions);
+    return _is_broadcasted[dimension];
+}
+
 inline Window Window::collapse_if_possible(const Window &full_window, const size_t first,
                                            const size_t last, bool *has_collapsed) const
 {
@@ -110,7 +124,7 @@
     {
         if(shape[d] <= 1)
         {
-            broadcastWin.set(d, Dimension(0, 0, 0));
+            broadcastWin.set_broadcasted(d);
         }
     }
     return broadcastWin;
diff --git a/arm_compute/core/utils/misc/Utility.h b/arm_compute/core/utils/misc/Utility.h
index 8dd9afd..2325644 100644
--- a/arm_compute/core/utils/misc/Utility.h
+++ b/arm_compute/core/utils/misc/Utility.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 ARM Limited.
+ * Copyright (c) 2017-2019 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -53,6 +53,20 @@
 
 template <std::size_t N>
 using index_sequence_t = typename index_sequence_generator<N>::type;
+
+template <typename T, std::size_t N, T val, T... vals>
+struct generate_array : generate_array < T, N - 1, val, val, vals... >
+{
+};
+
+template <typename T, T val, T... vals>
+struct generate_array<T, 0, val, vals...>
+{
+    static constexpr std::array<T, sizeof...(vals)> value{ vals... };
+};
+
+template <typename T, T val, T... vals>
+constexpr std::array<T, sizeof...(vals)> generate_array<T, 0, val, vals...>::value;
 /** @endcond */
 
 namespace detail