aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgios Pinitas <georgios.pinitas@arm.com>2019-12-12 18:23:13 +0000
committerGeorgios Pinitas <georgios.pinitas@arm.com>2020-02-12 13:50:24 +0000
commit80838f166ee1d6eb152dc85f21642157b80301c0 (patch)
tree99cd7e0d85de12f1f9201ab76cc43b38af262884
parent9bd49f979907fdef82a50f64a486c5d69df7ae39 (diff)
downloadComputeLibrary-80838f166ee1d6eb152dc85f21642157b80301c0.tar.gz
COMPMID-2819: Avoid overflows in pooling shape calculation
Pooling shape calculator was performing operations in the unsigned domain leading to overflows in irregular shapes. Thus, we perform all operations in the signed domain and we get the maximum between the given shape and 1, returning always a valid tensor. Signed-off-by: Georgios Pinitas <georgios.pinitas@arm.com> Change-Id: Ia95d7e54929c8bc29e99dc80a61065e403b29a94 Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/2467 Tested-by: Arm Jenkins <bsgcomp@arm.com> Reviewed-by: Giorgio Arena <giorgio.arena@arm.com> Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
-rw-r--r--arm_compute/core/Utils.h4
-rw-r--r--src/core/Utils.cpp34
-rw-r--r--tests/datasets/PoolingLayerDataset.h1
3 files changed, 22 insertions, 17 deletions
diff --git a/arm_compute/core/Utils.h b/arm_compute/core/Utils.h
index a2c18bb205..22a1e7064d 100644
--- a/arm_compute/core/Utils.h
+++ b/arm_compute/core/Utils.h
@@ -943,8 +943,8 @@ std::pair<unsigned int, unsigned int> deconvolution_output_dimensions(unsigned i
*
* @return A pair with the new width in the first position and the new height in the second.
*/
-std::pair<unsigned int, unsigned int> scaled_dimensions(unsigned int width, unsigned int height,
- unsigned int kernel_width, unsigned int kernel_height,
+std::pair<unsigned int, unsigned int> scaled_dimensions(int width, int height,
+ int kernel_width, int kernel_height,
const PadStrideInfo &pad_stride_info,
const Size2D &dilation = Size2D(1U, 1U));
diff --git a/src/core/Utils.cpp b/src/core/Utils.cpp
index f930804ce3..59dc3652fa 100644
--- a/src/core/Utils.cpp
+++ b/src/core/Utils.cpp
@@ -399,34 +399,38 @@ std::pair<unsigned int, unsigned int> arm_compute::deconvolution_output_dimensio
return std::make_pair<unsigned int, unsigned int>(w, h);
}
-std::pair<unsigned int, unsigned int> arm_compute::scaled_dimensions(unsigned int width, unsigned int height,
- unsigned int kernel_width, unsigned int kernel_height,
+std::pair<unsigned int, unsigned int> arm_compute::scaled_dimensions(int width, int height,
+ int kernel_width, int kernel_height,
const PadStrideInfo &pad_stride_info,
const Size2D &dilation)
{
- const unsigned int pad_left = pad_stride_info.pad_left();
- const unsigned int pad_top = pad_stride_info.pad_top();
- const unsigned int pad_right = pad_stride_info.pad_right();
- const unsigned int pad_bottom = pad_stride_info.pad_bottom();
- const unsigned int stride_x = pad_stride_info.stride().first;
- const unsigned int stride_y = pad_stride_info.stride().second;
- unsigned int w = 0;
- unsigned int h = 0;
+ const int dilation_x = dilation.x();
+ const int dilation_y = dilation.y();
+ const int pad_left = pad_stride_info.pad_left();
+ const int pad_top = pad_stride_info.pad_top();
+ const int pad_right = pad_stride_info.pad_right();
+ const int pad_bottom = pad_stride_info.pad_bottom();
+ const int stride_x = pad_stride_info.stride().first;
+ const int stride_y = pad_stride_info.stride().second;
+ int w = 0;
+ int h = 0;
switch(pad_stride_info.round())
{
case DimensionRoundingType::FLOOR:
- w = static_cast<unsigned int>(std::floor((static_cast<float>(width + pad_left + pad_right - (dilation.x() * (kernel_width - 1) + 1)) / stride_x) + 1));
- h = static_cast<unsigned int>(std::floor((static_cast<float>(height + pad_top + pad_bottom - (dilation.y() * (kernel_height - 1) + 1)) / stride_y) + 1));
+ w = static_cast<int>(std::floor((static_cast<float>(width + pad_left + pad_right - (dilation_x * (kernel_width - 1) + 1)) / stride_x) + 1));
+ h = static_cast<int>(std::floor((static_cast<float>(height + pad_top + pad_bottom - (dilation_y * (kernel_height - 1) + 1)) / stride_y) + 1));
break;
case DimensionRoundingType::CEIL:
- w = static_cast<unsigned int>(std::ceil((static_cast<float>(width + pad_left + pad_right - (dilation.x() * (kernel_width - 1) + 1)) / stride_x) + 1));
- h = static_cast<unsigned int>(std::ceil((static_cast<float>(height + pad_top + pad_bottom - (dilation.y() * (kernel_height - 1) + 1)) / stride_y) + 1));
+ w = static_cast<int>(std::ceil((static_cast<float>(width + pad_left + pad_right - (dilation_x * (kernel_width - 1) + 1)) / stride_x) + 1));
+ h = static_cast<int>(std::ceil((static_cast<float>(height + pad_top + pad_bottom - (dilation_y * (kernel_height - 1) + 1)) / stride_y) + 1));
break;
default:
ARM_COMPUTE_ERROR("Unsupported rounding type");
}
- return std::make_pair(w, h);
+ w = std::max(1, w);
+ h = std::max(1, h);
+ return std::make_pair(static_cast<unsigned int>(w), static_cast<unsigned int>(h));
}
bool arm_compute::needs_serialized_reduction(ReductionOperation op, DataType dt, unsigned int axis)
diff --git a/tests/datasets/PoolingLayerDataset.h b/tests/datasets/PoolingLayerDataset.h
index 56fcdc3d0f..943279ee46 100644
--- a/tests/datasets/PoolingLayerDataset.h
+++ b/tests/datasets/PoolingLayerDataset.h
@@ -106,6 +106,7 @@ public:
PoolingLayerDatasetSpecial()
{
// Special cases
+ add_config(TensorShape(2U, 3U, 4U, 1U), PoolingLayerInfo(PoolingType::AVG, Size2D(3, 3), DataLayout::NCHW, PadStrideInfo(3, 3, 0, 0), true));
add_config(TensorShape(60U, 52U, 3U, 2U), PoolingLayerInfo(PoolingType::AVG, Size2D(100, 100), DataLayout::NCHW, PadStrideInfo(5, 5, 50, 50), true));
// Asymmetric padding
add_config(TensorShape(112U, 112U, 32U), PoolingLayerInfo(PoolingType::MAX, 3, DataLayout::NCHW, PadStrideInfo(2, 2, 0, 1, 0, 1, DimensionRoundingType::FLOOR)));