diff options
author | Sang-Hoon Park <sang-hoon.park@arm.com> | 2019-09-17 08:59:09 +0100 |
---|---|---|
committer | Georgios Pinitas <georgios.pinitas@arm.com> | 2019-09-30 15:33:01 +0000 |
commit | cecb0a75a9de0a12d30f8fabbe16a656c722afa1 (patch) | |
tree | 9517b7fd1fa31126c5fbd3e66f4fb9c7e0b9af1b | |
parent | 879d1313ba69d9ced8424f54ffeea6a3c60496f0 (diff) | |
download | ComputeLibrary-cecb0a75a9de0a12d30f8fabbe16a656c722afa1.tar.gz |
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>
-rw-r--r-- | arm_compute/core/Window.h | 17 | ||||
-rw-r--r-- | arm_compute/core/Window.inl | 18 | ||||
-rw-r--r-- | arm_compute/core/utils/misc/Utility.h | 16 | ||||
-rw-r--r-- | src/core/CL/ICLKernel.cpp | 2 | ||||
-rw-r--r-- | tests/datasets/ShapeDatasets.h | 12 |
5 files changed, 56 insertions, 9 deletions
diff --git a/arm_compute/core/Window.h b/arm_compute/core/Window.h index a56227996b..be42fe9a87 100644 --- a/arm_compute/core/Window.h +++ b/arm_compute/core/Window.h @@ -48,7 +48,7 @@ public: /** 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 @@ public: */ 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: 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 eeef3df7b0..589d6bfafc 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 @@ inline void Window::set(size_t dimension, const Window::Dimension &dim) _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 @@ inline Window Window::broadcast_if_dimension_le_one(const TensorShape &shape) co { 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 8dd9afd5cd..2325644e72 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 @@ struct index_sequence_generator<0u, S...> : index_sequence<S...> 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 diff --git a/src/core/CL/ICLKernel.cpp b/src/core/CL/ICLKernel.cpp index 2d28a496c9..d81ad46b29 100644 --- a/src/core/CL/ICLKernel.cpp +++ b/src/core/CL/ICLKernel.cpp @@ -98,7 +98,7 @@ void ICLKernel::add_tensor_argument(unsigned &idx, const ICLTensor *tensor, cons for(unsigned int n = 0; n < info->num_dimensions(); ++n) { - offset_first_element += window[n].start() * strides[n]; + offset_first_element += (window.is_broadcasted(n) ? 0 : window[n].start()) * strides[n]; } unsigned int idx_start = idx; diff --git a/tests/datasets/ShapeDatasets.h b/tests/datasets/ShapeDatasets.h index 07ecf45d81..b479eb4953 100644 --- a/tests/datasets/ShapeDatasets.h +++ b/tests/datasets/ShapeDatasets.h @@ -203,7 +203,9 @@ public: TensorShape{ 128U, 1U, 5U, 3U }, TensorShape{ 9U, 9U, 3U, 4U }, TensorShape{ 27U, 13U, 2U, 4U }, - TensorShape{ 1U, 1U, 1U, 5U } + TensorShape{ 1U, 1U, 1U, 5U }, + TensorShape{ 1U, 16U, 10U, 2U, 128U }, + TensorShape{ 1U, 16U, 10U, 2U, 128U } }), ShapeDataset("Shape1", { @@ -212,7 +214,9 @@ public: TensorShape{ 128U, 64U, 1U, 3U }, TensorShape{ 9U, 1U, 3U }, TensorShape{ 1U }, - TensorShape{ 9U, 9U, 3U, 5U } + TensorShape{ 9U, 9U, 3U, 5U }, + TensorShape{ 1U, 1U, 1U, 1U, 128U }, + TensorShape{ 128U } })) { } @@ -686,7 +690,7 @@ public: : ShapeDataset("InputShape", { // Batch size 1 - TensorShape{ 32U, 37U, 3U }, + TensorShape{ 32U, 37U, 3U }, // Batch size 4 TensorShape{ 32U, 37U, 3U, 4U }, }) @@ -702,7 +706,7 @@ public: : ShapeDataset("InputShape", { // Batch size 1 - TensorShape{ 32U, 37U, 3U }, + TensorShape{ 32U, 37U, 3U }, // Batch size 4 TensorShape{ 32U, 37U, 3U, 4U }, // Arbitrary batch size |