aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSang-Hoon Park <sang-hoon.park@arm.com>2021-04-13 20:21:11 +0100
committerGeorgios Pinitas <georgios.pinitas@arm.com>2021-04-19 07:31:51 +0000
commitfe56edb4fd7a620fea4b6002d87a9763bdf8791a (patch)
tree62615f99b01b5c5811eb92c77cc729bbf7bd3d9a
parent9a81cd82a8102ee0bd69bfe4939d5c867aed15e9 (diff)
downloadComputeLibrary-fe56edb4fd7a620fea4b6002d87a9763bdf8791a.tar.gz
Add padding consideration to pooling index computation
Fix the pooling kernel which has been missing consideration of left padding, which can be implictly added by external kernels. Additionally, tests for FP16 have been added for the logic. Resolves: COMPMID-4363 Change-Id: I5655991cb80f749fb1ae9bbd3918b436a078f5d1 Signed-off-by: Sang-Hoon Park <sang-hoon.park@arm.com> Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/5421 Tested-by: Arm Jenkins <bsgcomp@arm.com> Reviewed-by: Michele Di Giorgio <michele.digiorgio@arm.com> Reviewed-by: Giorgio Arena <giorgio.arena@arm.com> Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
-rw-r--r--src/core/cpu/kernels/pooling/neon/fp16.cpp20
-rw-r--r--src/core/cpu/kernels/pooling/neon/fp32.cpp20
-rw-r--r--tests/validation/NEON/PoolingLayer.cpp57
-rw-r--r--tests/validation/fixtures/PoolingLayerFixture.h3
4 files changed, 57 insertions, 43 deletions
diff --git a/src/core/cpu/kernels/pooling/neon/fp16.cpp b/src/core/cpu/kernels/pooling/neon/fp16.cpp
index 1ecceafe86..0aae7b8a57 100644
--- a/src/core/cpu/kernels/pooling/neon/fp16.cpp
+++ b/src/core/cpu/kernels/pooling/neon/fp16.cpp
@@ -57,9 +57,11 @@ void pooling2_f16_maxpool_indices(const ITensor *src, ITensor *dst0, ITensor *ds
int pool_stride_y = 0;
std::tie(pool_stride_x, pool_stride_y) = pool_info.pad_stride_info.stride();
- const int pad_right = src->info()->padding().right;
- const int in_stride_y = static_cast<int>(src->info()->strides_in_bytes().y());
- const int in_stride_z = static_cast<int>(src->info()->strides_in_bytes().z());
+ const int pad_right = src->info()->padding().right;
+ const int pad_left = src->info()->padding().left;
+ const int pad_horizontal = pad_right + pad_left;
+ const int in_stride_y = static_cast<int>(src->info()->strides_in_bytes().y());
+ const int in_stride_z = static_cast<int>(src->info()->strides_in_bytes().z());
execute_window_loop(window_out, [&](const Coordinates & id)
{
@@ -95,9 +97,9 @@ void pooling2_f16_maxpool_indices(const ITensor *src, ITensor *dst0, ITensor *ds
const uint32_t offset_base = offset_no_padding<float16_t>(in.offset(), id, *src->info(), pool_stride_x, pool_stride_y, DataLayout::NHWC);
const uint32_t offset_x0 = (uint32_t)offset_base / sizeof(float16_t) + x_off;
- const uint32_t offset_x1 = (uint32_t)offset_x0 + in_stride_y / sizeof(float16_t) - pad_right;
- const uint32_t offset_x2 = (uint32_t)offset_x0 + in_stride_z / sizeof(float16_t) - pad_right * src->info()->tensor_shape()[1];
- const uint32_t offset_x3 = (uint32_t)offset_x2 + in_stride_y / sizeof(float16_t) - pad_right;
+ const uint32_t offset_x1 = (uint32_t)offset_x0 + in_stride_y / sizeof(float16_t) - pad_horizontal;
+ const uint32_t offset_x2 = (uint32_t)offset_x0 + in_stride_z / sizeof(float16_t) - pad_horizontal * src->info()->tensor_shape()[1];
+ const uint32_t offset_x3 = (uint32_t)offset_x2 + in_stride_y / sizeof(float16_t) - pad_horizontal;
const uint32x4_t voffset_x0_0 = { offset_x0, offset_x0 + 1, offset_x0 + 2, offset_x0 + 3 };
const uint32x4_t voffset_x0_1 = { offset_x0 + 4, offset_x0 + 5, offset_x0 + 6, offset_x0 + 7 };
const uint16x8_t voffset_x0 = vcombine_u16(vmovn_u32(voffset_x0_0), vmovn_u32(voffset_x0_1));
@@ -134,9 +136,9 @@ void pooling2_f16_maxpool_indices(const ITensor *src, ITensor *dst0, ITensor *ds
const uint32_t offset_base = offset_no_padding<float16_t>(in.offset(), id, *src->info(), pool_stride_x, pool_stride_y, DataLayout::NHWC);
const uint32_t offset_x0 = (uint32_t)offset_base / sizeof(float16_t) + x_off;
- const uint32_t offset_x1 = (uint32_t)offset_x0 + in_stride_y / sizeof(float16_t) - pad_right;
- const uint32_t offset_x2 = (uint32_t)offset_x0 + in_stride_z / sizeof(float16_t) - pad_right * src->info()->tensor_shape()[1];
- const uint32_t offset_x3 = (uint32_t)offset_x2 + in_stride_y / sizeof(float16_t) - pad_right;
+ const uint32_t offset_x1 = (uint32_t)offset_x0 + in_stride_y / sizeof(float16_t) - pad_horizontal;
+ const uint32_t offset_x2 = (uint32_t)offset_x0 + in_stride_z / sizeof(float16_t) - pad_horizontal * src->info()->tensor_shape()[1];
+ const uint32_t offset_x3 = (uint32_t)offset_x2 + in_stride_y / sizeof(float16_t) - pad_horizontal;
const uint32_t tmp_idx0 = (x0 >= x1) ? offset_x0 : offset_x1;
const uint32_t tmp_idx1 = (x2 >= x3) ? offset_x2 : offset_x3;
const uint32_t tmp_idx2 = (std::max(x0, x1) >= std::max(x2, x3)) ? tmp_idx0 : tmp_idx1;
diff --git a/src/core/cpu/kernels/pooling/neon/fp32.cpp b/src/core/cpu/kernels/pooling/neon/fp32.cpp
index a2bd4a6bb3..4e41fdec7f 100644
--- a/src/core/cpu/kernels/pooling/neon/fp32.cpp
+++ b/src/core/cpu/kernels/pooling/neon/fp32.cpp
@@ -58,9 +58,11 @@ void pooling2_f32_maxpool_indices(const ITensor *src, ITensor *dst0, ITensor *ds
float32x4_t vres;
float res;
- const int pad_right = src->info()->padding().right;
- const int in_stride_y = static_cast<int>(src->info()->strides_in_bytes().y());
- const int in_stride_z = static_cast<int>(src->info()->strides_in_bytes().z());
+ const int pad_right = src->info()->padding().right;
+ const int pad_left = src->info()->padding().left;
+ const int pad_horizontal = pad_right + pad_left;
+ const int in_stride_y = static_cast<int>(src->info()->strides_in_bytes().y());
+ const int in_stride_z = static_cast<int>(src->info()->strides_in_bytes().z());
execute_window_loop(window_out, [&](const Coordinates & id)
{
@@ -97,9 +99,9 @@ void pooling2_f32_maxpool_indices(const ITensor *src, ITensor *dst0, ITensor *ds
const uint32_t offset_base = offset_no_padding<float>(in.offset(), id, *src->info(), pool_stride_x, pool_stride_y, DataLayout::NHWC);
const uint32_t offset_x0 = (uint32_t)offset_base / sizeof(float) + x_off;
- const uint32_t offset_x1 = (uint32_t)offset_x0 + in_stride_y / sizeof(float) - pad_right;
- const uint32_t offset_x2 = (uint32_t)offset_x0 + in_stride_z / sizeof(float) - pad_right * src->info()->tensor_shape()[1];
- const uint32_t offset_x3 = (uint32_t)offset_x2 + in_stride_y / sizeof(float) - pad_right;
+ const uint32_t offset_x1 = (uint32_t)offset_x0 + in_stride_y / sizeof(float) - pad_horizontal;
+ const uint32_t offset_x2 = (uint32_t)offset_x0 + in_stride_z / sizeof(float) - pad_horizontal * src->info()->tensor_shape()[1];
+ const uint32_t offset_x3 = (uint32_t)offset_x2 + in_stride_y / sizeof(float) - pad_horizontal;
const uint32x4_t voffset_x0 = { offset_x0, offset_x0 + 1, offset_x0 + 2, offset_x0 + 3 };
const uint32x4_t voffset_x1 = { offset_x1, offset_x1 + 1, offset_x1 + 2, offset_x1 + 3 };
const uint32x4_t voffset_x2 = { offset_x2, offset_x2 + 1, offset_x2 + 2, offset_x2 + 3 };
@@ -126,9 +128,9 @@ void pooling2_f32_maxpool_indices(const ITensor *src, ITensor *dst0, ITensor *ds
const uint32_t offset_base = offset_no_padding<float>(in.offset(), id, *src->info(), pool_stride_x, pool_stride_y, DataLayout::NHWC);
const uint32_t offset_x0 = (uint32_t)offset_base / sizeof(float) + x_off;
- const uint32_t offset_x1 = (uint32_t)offset_x0 + in_stride_y / sizeof(float) - pad_right;
- const uint32_t offset_x2 = (uint32_t)offset_x0 + in_stride_z / sizeof(float) - pad_right * src->info()->tensor_shape()[1];
- const uint32_t offset_x3 = (uint32_t)offset_x2 + in_stride_y / sizeof(float) - pad_right;
+ const uint32_t offset_x1 = (uint32_t)offset_x0 + in_stride_y / sizeof(float) - pad_horizontal;
+ const uint32_t offset_x2 = (uint32_t)offset_x0 + in_stride_z / sizeof(float) - pad_horizontal * src->info()->tensor_shape()[1];
+ const uint32_t offset_x3 = (uint32_t)offset_x2 + in_stride_y / sizeof(float) - pad_horizontal;
const uint32_t tmp_idx0 = (x0 >= x1) ? offset_x0 : offset_x1;
const uint32_t tmp_idx1 = (x2 >= x3) ? offset_x2 : offset_x3;
const uint32_t tmp_idx2 = (std::max(x0, x1) >= std::max(x2, x3)) ? tmp_idx0 : tmp_idx1;
diff --git a/tests/validation/NEON/PoolingLayer.cpp b/tests/validation/NEON/PoolingLayer.cpp
index 9a6af49836..acc9c3e516 100644
--- a/tests/validation/NEON/PoolingLayer.cpp
+++ b/tests/validation/NEON/PoolingLayer.cpp
@@ -168,12 +168,12 @@ FIXTURE_DATA_TEST_CASE(RunSmall, NEPoolingLayerFixture<float>, framework::Datase
validate(Accessor(_target), _reference, tolerance_f32);
}
FIXTURE_DATA_TEST_CASE(RunMixedDataLayout, NEPoolingLayerMixedDataLayoutFixture<float>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(),
- combine(combine(combine(combine(datasets::PoolingTypes(),
- framework::dataset::make("PoolingSize", { Size2D(2, 2) })),
- framework::dataset::make("PadStride", { PadStrideInfo(2, 1, 0, 0) })),
- framework::dataset::make("ExcludePadding", { false })),
- framework::dataset::make("DataType", DataType::F32))),
- pool_data_layout_dataset))
+ combine(combine(combine(combine(datasets::PoolingTypes(),
+ framework::dataset::make("PoolingSize", { Size2D(2, 2) })),
+ framework::dataset::make("PadStride", { PadStrideInfo(2, 1, 0, 0) })),
+ framework::dataset::make("ExcludePadding", { false })),
+ framework::dataset::make("DataType", DataType::F32))),
+ pool_data_layout_dataset))
{
// Validate output
validate(Accessor(_target), _reference, tolerance_f32);
@@ -190,6 +190,17 @@ TEST_SUITE_END() // FP32
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
TEST_SUITE(FP16)
+FIXTURE_DATA_TEST_CASE(RunIndices, NEPoolingLayerIndicesFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), combine(PoolingLayerIndicesDatasetFPSmall,
+ framework::dataset::make("DataType",
+ DataType::F16))),
+ framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })
+
+ ))
+{
+ // Validate output
+ validate(Accessor(_target), _reference, tolerance_f16);
+ validate(Accessor(_target_indices), _ref_indices);
+}
FIXTURE_DATA_TEST_CASE(RunSmall, NEPoolingLayerFixture<half>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), combine(PoolingLayerDatasetFPSmall,
framework::dataset::make("DataType", DataType::F16))),
pool_data_layout_dataset))
@@ -237,14 +248,14 @@ FIXTURE_DATA_TEST_CASE(RunSmall, NEPoolingLayerQuantizedFixture<uint8_t>, framew
validate(Accessor(_target), _reference, tolerance_qasymm8);
}
FIXTURE_DATA_TEST_CASE(RunMixedDataLayout, NEPoolingLayerQuantizedMixedDataLayoutFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallShapes(),
- combine(combine(combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }),
- framework::dataset::make("PoolingSize", { Size2D(2, 2) })),
- framework::dataset::make("PadStride", { PadStrideInfo(1, 2, 1, 1) })),
- framework::dataset::make("ExcludePadding", { true })),
- framework::dataset::make("DataType", DataType::QASYMM8))),
- framework::dataset::make("DataLayout", { DataLayout::NHWC, DataLayout::NCHW })),
- framework::dataset::make("InputQuantInfo", { QuantizationInfo(1.f / 255.f, 10) })),
- framework::dataset::make("OutputQuantInfo", { QuantizationInfo(1.f / 255.f, 5) })))
+ combine(combine(combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }),
+ framework::dataset::make("PoolingSize", { Size2D(2, 2) })),
+ framework::dataset::make("PadStride", { PadStrideInfo(1, 2, 1, 1) })),
+ framework::dataset::make("ExcludePadding", { true })),
+ framework::dataset::make("DataType", DataType::QASYMM8))),
+ framework::dataset::make("DataLayout", { DataLayout::NHWC, DataLayout::NCHW })),
+ framework::dataset::make("InputQuantInfo", { QuantizationInfo(1.f / 255.f, 10) })),
+ framework::dataset::make("OutputQuantInfo", { QuantizationInfo(1.f / 255.f, 5) })))
{
// Validate output
validate(Accessor(_target), _reference, tolerance_qasymm8);
@@ -254,7 +265,7 @@ TEST_SUITE(QASYMM8_SIGNED)
FIXTURE_DATA_TEST_CASE(RunSmall, NEPoolingLayerQuantizedFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallShapes(),
combine(PoolingLayerDatasetQASYMM8Small,
framework::dataset::make("DataType", DataType::QASYMM8_SIGNED))),
- framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })),
+ framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })),
qasymm8_signed_in_qinfo_dataset),
qasymm8_signed_in_qinfo_dataset))
{
@@ -262,14 +273,14 @@ FIXTURE_DATA_TEST_CASE(RunSmall, NEPoolingLayerQuantizedFixture<int8_t>, framewo
validate(Accessor(_target), _reference, tolerance_qasymm8_s);
}
FIXTURE_DATA_TEST_CASE(RunMixedDataLayout, NEPoolingLayerQuantizedMixedDataLayoutFixture<int8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallShapes(),
- combine(combine(combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }),
- framework::dataset::make("PoolingSize", { Size2D(2, 2) })),
- framework::dataset::make("PadStride", { PadStrideInfo(1, 2, 1, 1) })),
- framework::dataset::make("ExcludePadding", { true })),
- framework::dataset::make("DataType", DataType::QASYMM8_SIGNED))),
- framework::dataset::make("DataLayout", { DataLayout::NHWC, DataLayout::NCHW })),
- framework::dataset::make("InputQuantInfo", { QuantizationInfo(1.f / 127.f, -10) })),
- framework::dataset::make("OutputQuantInfo", { QuantizationInfo(1.f / 127.f, -10) })))
+ combine(combine(combine(combine(framework::dataset::make("PoolingType", { PoolingType::MAX, PoolingType::AVG }),
+ framework::dataset::make("PoolingSize", { Size2D(2, 2) })),
+ framework::dataset::make("PadStride", { PadStrideInfo(1, 2, 1, 1) })),
+ framework::dataset::make("ExcludePadding", { true })),
+ framework::dataset::make("DataType", DataType::QASYMM8_SIGNED))),
+ framework::dataset::make("DataLayout", { DataLayout::NHWC, DataLayout::NCHW })),
+ framework::dataset::make("InputQuantInfo", { QuantizationInfo(1.f / 127.f, -10) })),
+ framework::dataset::make("OutputQuantInfo", { QuantizationInfo(1.f / 127.f, -10) })))
{
// Validate output
validate(Accessor(_target), _reference, tolerance_qasymm8_s);
diff --git a/tests/validation/fixtures/PoolingLayerFixture.h b/tests/validation/fixtures/PoolingLayerFixture.h
index 66e09d5bdb..74ba3b3431 100644
--- a/tests/validation/fixtures/PoolingLayerFixture.h
+++ b/tests/validation/fixtures/PoolingLayerFixture.h
@@ -114,8 +114,7 @@ protected:
ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
ARM_COMPUTE_EXPECT(_target_indices.info()->is_resizable(), framework::LogLevel::ERRORS);
- // TODO: uncomment after COMPMID-4363
- // add_padding_x({ &src, &dst, &_target_indices }, data_layout);
+ add_padding_x({ &src, &dst, &_target_indices }, data_layout);
// Allocate tensors
src.allocator()->allocate();