aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/NEON/kernels/NEConvolutionKernel.cpp8
-rw-r--r--src/runtime/CL/functions/CLConvolution.cpp5
-rw-r--r--src/runtime/NEON/functions/NEConvolution.cpp5
-rw-r--r--tests/validation/CL/Convolution.cpp220
-rw-r--r--tests/validation/NEON/Convolution.cpp239
-rw-r--r--tests/validation/Validation.cpp10
-rw-r--r--tests/validation/Validation.h8
-rw-r--r--tests/validation/fixtures/ConvolutionFixture.h130
-rw-r--r--tests/validation/reference/Convolution.cpp8
-rw-r--r--tests/validation/reference/Convolution.h4
10 files changed, 393 insertions, 244 deletions
diff --git a/src/core/NEON/kernels/NEConvolutionKernel.cpp b/src/core/NEON/kernels/NEConvolutionKernel.cpp
index 3a4884eb21..7468f58ca5 100644
--- a/src/core/NEON/kernels/NEConvolutionKernel.cpp
+++ b/src/core/NEON/kernels/NEConvolutionKernel.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017 ARM Limited.
+ * Copyright (c) 2016, 2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -1522,13 +1522,13 @@ void NEConvolutionRectangleKernel::run(const Window &window, const ThreadInfo &i
};
// Run appropriate function
- switch(_output->info()->format())
+ switch(_output->info()->data_type())
{
- case Format::U8:
+ case DataType::U8:
ARM_COMPUTE_ERROR_ON(_func_idx >= func_table_u8.size());
(this->*func_table_u8[_func_idx])(window);
break;
- case Format::S16:
+ case DataType::S16:
ARM_COMPUTE_ERROR_ON(_func_idx >= func_table_s16.size());
(this->*func_table_s16[_func_idx])(window);
break;
diff --git a/src/runtime/CL/functions/CLConvolution.cpp b/src/runtime/CL/functions/CLConvolution.cpp
index a9b086773c..0131801679 100644
--- a/src/runtime/CL/functions/CLConvolution.cpp
+++ b/src/runtime/CL/functions/CLConvolution.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017 ARM Limited.
+ * Copyright (c) 2016, 2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -53,7 +53,8 @@ CLConvolutionSquare<matrix_size>::CLConvolutionSquare(std::shared_ptr<IMemoryMan
}
template <unsigned int matrix_size>
-void CLConvolutionSquare<matrix_size>::configure(ICLTensor *input, ICLTensor *output, const int16_t *conv, uint32_t scale, BorderMode border_mode, uint8_t constant_border_value)
+void CLConvolutionSquare<matrix_size>::configure(ICLTensor *input, ICLTensor *output, const int16_t *conv, uint32_t scale, BorderMode border_mode,
+ uint8_t constant_border_value)
{
ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::U8);
ARM_COMPUTE_ERROR_ON(conv == nullptr);
diff --git a/src/runtime/NEON/functions/NEConvolution.cpp b/src/runtime/NEON/functions/NEConvolution.cpp
index f10ffa6d14..b84dfd344c 100644
--- a/src/runtime/NEON/functions/NEConvolution.cpp
+++ b/src/runtime/NEON/functions/NEConvolution.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2017 ARM Limited.
+ * Copyright (c) 2016, 2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -54,7 +54,8 @@ NEConvolutionSquare<matrix_size>::NEConvolutionSquare(std::shared_ptr<IMemoryMan
}
template <unsigned int matrix_size>
-void NEConvolutionSquare<matrix_size>::configure(ITensor *input, ITensor *output, const int16_t *conv, uint32_t scale, BorderMode border_mode, uint8_t constant_border_value)
+void NEConvolutionSquare<matrix_size>::configure(ITensor *input, ITensor *output, const int16_t *conv, uint32_t scale, BorderMode border_mode,
+ uint8_t constant_border_value)
{
ARM_COMPUTE_ERROR_ON(conv == nullptr);
ARM_COMPUTE_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::U8);
diff --git a/tests/validation/CL/Convolution.cpp b/tests/validation/CL/Convolution.cpp
index c836edabb8..d6405474e3 100644
--- a/tests/validation/CL/Convolution.cpp
+++ b/tests/validation/CL/Convolution.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017, 2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -43,30 +43,17 @@ namespace validation
{
namespace
{
-/* Convolution3x3 */
-constexpr unsigned int filter_size_3x3 = 3; /* Size of the kernel/filter in number of elements. */
-constexpr BorderSize border_size_3x3(filter_size_3x3 / 2); /* Border size of the kernel/filter around its central element. */
-
-/* Convolution5x5 */
-constexpr unsigned int filter_size_5x5 = 5; /* Size of the kernel/filter in number of elements. */
-constexpr BorderSize border_size_5x5(filter_size_5x5 / 2); /* Border size of the kernel/filter around its central element. */
-
-/* Convolution7x7 */
-constexpr unsigned int filter_size_7x7 = 7; /* Size of the kernel/filter in number of elements. */
-constexpr BorderSize border_size_7x7(filter_size_7x7 / 2); /* Border size of the kernel/filter around its central element. */
-
-/* Convolution9x9 */
-constexpr unsigned int filter_size_9x9 = 9; /* Size of the kernel/filter in number of elements. */
-constexpr BorderSize border_size_9x9(filter_size_9x9 / 2); /* Border size of the kernel/filter around its central element. */
} // namespace
TEST_SUITE(CL)
TEST_SUITE(CustomConvolution)
+TEST_SUITE(CustomConvolutionSquare)
TEST_SUITE(CustomConvolution3x3)
-DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
- datasets::BorderModes()),
- shape, data_type, border_mode)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 3 })),
+ shape, data_type, border_mode, filter_size)
{
// Create tensors
CLTensor src = create_tensor<CLTensor>(shape, data_type);
@@ -75,20 +62,15 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
// Create conv matrix
int16_t conv[9];
- // Generate random scale value between 0 and 255.
- std::mt19937 gen(library->seed());
- std::uniform_int_distribution<uint8_t> distribution(0, 255);
- const uint32_t scale = distribution(gen);
-
ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
// Create and configure function
CLConvolution3x3 convolution;
- convolution.configure(&src, &dst, conv, scale, border_mode);
+ convolution.configure(&src, &dst, conv, 0, border_mode);
// Validate valid region
- const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size_3x3);
+ const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_size / 2));
validate(dst.info()->valid_region(), dst_valid_region);
// Validate padding
@@ -108,29 +90,33 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
}
template <typename T>
-using CLConvolutionFixture = ConvolutionValidationFixture<CLTensor, CLAccessor, CLConvolution3x3, T, filter_size_3x3>;
+using CLConvolutionFixture = ConvolutionSquareValidationFixture<CLTensor, CLAccessor, CLConvolution3x3, T>;
-FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 3 })))
{
// Validate output
- validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_3x3));
+ validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)));
}
-FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 3 })))
{
// Validate output
- validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_3x3));
+ validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)));
}
TEST_SUITE_END() /* Custom_Convolution 3x3 */
TEST_SUITE(CustomConvolution5x5)
-DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
- datasets::BorderModes()),
- shape, data_type, border_mode)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 5 })),
+ shape, data_type, border_mode, filter_size)
{
// Create tensors
CLTensor src = create_tensor<CLTensor>(shape, data_type);
@@ -139,20 +125,15 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
// Create conv matrix
int16_t conv[25];
- // Generate random scale value between 0 and 255.
- std::mt19937 gen(library->seed());
- std::uniform_int_distribution<uint8_t> distribution(0, 255);
- const uint32_t scale = distribution(gen);
-
ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
// Create and configure function
CLConvolution5x5 convolution;
- convolution.configure(&src, &dst, conv, scale, border_mode);
+ convolution.configure(&src, &dst, conv, 0, border_mode);
// Validate valid region
- const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size_5x5);
+ const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_size / 2));
validate(dst.info()->valid_region(), dst_valid_region);
// Validate padding
@@ -172,29 +153,31 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
}
template <typename T>
-using CLConvolutionFixture = ConvolutionValidationFixture<CLTensor, CLAccessor, CLConvolution5x5, T, filter_size_5x5>;
-
-FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+using CLConvolutionFixture = ConvolutionSquareValidationFixture<CLTensor, CLAccessor, CLConvolution5x5, T>;
+FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 5 })))
{
// Validate output
- validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_5x5));
+ validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)));
}
-FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 5 })))
{
// Validate output
- validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_5x5));
+ validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)));
}
TEST_SUITE_END() /* Custom Convolution 5x5 */
TEST_SUITE(CustomConvolution7x7)
-DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
- datasets::BorderModes()),
- shape, data_type, border_mode)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 7 })),
+ shape, data_type, border_mode, filter_size)
{
// Create tensors
CLTensor src = create_tensor<CLTensor>(shape, data_type);
@@ -203,20 +186,15 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
// Create conv matrix
int16_t conv[49];
- // Generate random scale value between 0 and 255.
- std::mt19937 gen(library->seed());
- std::uniform_int_distribution<uint8_t> distribution(0, 255);
- const uint32_t scale = distribution(gen);
-
ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
// Create and configure function
CLConvolution7x7 convolution;
- convolution.configure(&src, &dst, conv, scale, border_mode);
+ convolution.configure(&src, &dst, conv, 0, border_mode);
// Validate valid region
- const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size_7x7);
+ const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_size / 2));
validate(dst.info()->valid_region(), dst_valid_region);
// Validate padding
@@ -236,29 +214,32 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
}
template <typename T>
-using CLConvolutionFixture = ConvolutionValidationFixture<CLTensor, CLAccessor, CLConvolution7x7, T, filter_size_7x7>;
+using CLConvolutionFixture = ConvolutionSquareValidationFixture<CLTensor, CLAccessor, CLConvolution7x7, T>;
-FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 7 })))
{
// Validate output
- validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_7x7));
+ validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)));
}
-FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 7 })))
{
// Validate output
- validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_7x7));
+ validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)));
}
TEST_SUITE_END() /* Custom Convolution 7x7 */
TEST_SUITE(CustomConvolution9x9)
-DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
- datasets::BorderModes()),
- shape, data_type, border_mode)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 9 })),
+ shape, data_type, border_mode, filter_size)
{
// Create tensors
CLTensor src = create_tensor<CLTensor>(shape, data_type);
@@ -267,20 +248,15 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
// Create conv matrix
int16_t conv[81];
- // Generate random scale value between 0 and 255.
- std::mt19937 gen(library->seed());
- std::uniform_int_distribution<uint8_t> distribution(0, 255);
- const uint32_t scale = distribution(gen);
-
ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
// Create and configure function
CLConvolution9x9 convolution;
- convolution.configure(&src, &dst, conv, scale, border_mode);
+ convolution.configure(&src, &dst, conv, 0, border_mode);
// Validate valid region
- const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size_9x9);
+ const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_size / 2));
validate(dst.info()->valid_region(), dst_valid_region);
// Validate padding
@@ -300,24 +276,98 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
}
template <typename T>
-using CLConvolutionFixture = ConvolutionValidationFixture<CLTensor, CLAccessor, CLConvolution9x9, T, filter_size_9x9>;
+using CLConvolutionFixture = ConvolutionSquareValidationFixture<CLTensor, CLAccessor, CLConvolution9x9, T>;
-FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 9 })))
{
// Validate output
- validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_9x9));
+ validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)));
}
-FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 9 })))
{
// Validate output
- validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_9x9));
+ validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)));
}
TEST_SUITE_END() /* Custom Convolution 9x9 */
+TEST_SUITE_END() /* Custom Convolution Square */
+
+TEST_SUITE(CustomConvolutionRectangle)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType",
+ DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_width", { 3, 5, 7, 9 })),
+ framework::dataset::make("filter_height", { 3, 5, 7, 9 })),
+ shape, data_type, border_mode, filter_width, filter_height)
+{
+ // Create tensors
+ CLTensor src = create_tensor<CLTensor>(shape, data_type);
+ CLTensor dst = create_tensor<CLTensor>(shape, data_type);
+
+ // Create conv matrix
+ int16_t conv[filter_width * filter_height];
+
+ ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+ // Create and configure function
+ CLConvolutionRectangle convolution;
+ convolution.configure(&src, &dst, conv, filter_width, filter_height, 1, border_mode);
+
+ // Validate valid region
+ const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_height / 2, filter_width / 2));
+ validate(dst.info()->valid_region(), dst_valid_region);
+
+ // Validate padding
+ PaddingCalculator calculator(shape.x(), 8);
+ calculator.set_border_size(filter_width / 2);
+ calculator.set_border_mode(border_mode);
+
+ const PaddingSize dst_padding = calculator.required_padding();
+
+ calculator.set_accessed_elements(16);
+ calculator.set_access_offset(-(filter_width / 2));
+
+ const PaddingSize width_padding = calculator.required_padding();
+
+ calculator.set_border_size(filter_height / 2);
+ calculator.set_access_offset(-(filter_height / 2));
+ const PaddingSize height_padding = calculator.required_padding();
+
+ validate(src.info()->padding(), width_padding, height_padding);
+ validate(dst.info()->padding(), dst_padding);
+}
+
+template <typename T>
+using CLConvolutionFixture = ConvolutionRectangleValidationFixture<CLTensor, CLAccessor, CLConvolutionRectangle, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, CLConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+ DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_width", { 3, 5, 7, 9 })),
+ framework::dataset::make("filter_height", { 3, 5, 7, 9 })))
+{
+ // Validate output
+ validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)));
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, CLConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+ DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_width", { 3, 5, 7, 9 })),
+ framework::dataset::make("filter_height", { 3, 5, 7, 9 })))
+{
+ // Validate output
+ validate(CLAccessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)));
+}
+TEST_SUITE_END() /* Custom Convolution Rectangle */
TEST_SUITE_END()
TEST_SUITE_END()
} // namespace validation
diff --git a/tests/validation/NEON/Convolution.cpp b/tests/validation/NEON/Convolution.cpp
index 0fb61dcf0e..5af803010b 100644
--- a/tests/validation/NEON/Convolution.cpp
+++ b/tests/validation/NEON/Convolution.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017, 2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -49,47 +49,17 @@ namespace
* while reference performs direct division with scale.
*/
constexpr AbsoluteTolerance<uint8_t> tolerance_u8(1);
-
-/* Convolution3x3 */
-constexpr unsigned int filter_size_3x3 = 3; /* Size of the kernel/filter in number of elements. */
-constexpr BorderSize border_size_3x3(filter_size_3x3 / 2); /* Border size of the kernel/filter around its central element. */
-
-/* Convolution5x5 */
-constexpr unsigned int filter_size_5x5 = 5; /* Size of the kernel/filter in number of elements. */
-constexpr BorderSize border_size_5x5(filter_size_5x5 / 2); /* Border size of the kernel/filter around its central element. */
-
-/* Convolution7x7 */
-constexpr unsigned int filter_size_7x7 = 7; /* Size of the kernel/filter in number of elements. */
-constexpr BorderSize border_size_7x7(filter_size_7x7 / 2); /* Border size of the kernel/filter around its central element. */
-
-/* Convolutionx */
-constexpr unsigned int filter_size_9x9 = 9; /* Size of the kernel/filter in number of elements. */
-constexpr BorderSize border_size_9x9(filter_size_9x9 / 2); /* Border size of the kernel/filter around its central element. */
-
-/** Create conv matrix with filter size, and fill them with random value
- *
- * @param[in/out] conv Convolution matrix to be filled with random int16_t
- * @param[in] filter_size Filter Size.
- */
-void create_conv(int16_t *conv, const unsigned int filter_size)
-{
- std::mt19937 gen(library->seed());
- std::uniform_int_distribution<int16_t> distribution_int16(-32768, 32767);
-
- for(unsigned int i = 0; i < filter_size * filter_size; ++i)
- {
- conv[i] = distribution_int16(gen);
- }
-}
} // namespace
TEST_SUITE(NEON)
TEST_SUITE(CustomConvolution)
+TEST_SUITE(CustomConvolutionSuqare)
TEST_SUITE(CustomConvolution3x3)
-DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
- datasets::BorderModes()),
- shape, data_type, border_mode)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 3 })),
+ shape, data_type, border_mode, filter_size)
{
// Create tensors
Tensor src = create_tensor<Tensor>(shape, data_type);
@@ -97,22 +67,16 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
// Create conv matrix
int16_t conv[9];
- create_conv(conv, filter_size_3x3);
-
- // Generate random scale value between 0 and 255.
- std::mt19937 gen(library->seed());
- std::uniform_int_distribution<uint8_t> distribution(0, 255);
- uint32_t scale = distribution(gen);
ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
// Create and configure function
NEConvolution3x3 convolution;
- convolution.configure(&src, &dst, conv, scale, border_mode);
+ convolution.configure(&src, &dst, conv, 0, border_mode);
// Validate valid region
- const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size_3x3);
+ const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_size / 2));
validate(dst.info()->valid_region(), dst_valid_region);
// Validate padding
@@ -132,29 +96,32 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
}
template <typename T>
-using NEConvolutionFixture = ConvolutionValidationFixture<Tensor, Accessor, NEConvolution3x3, T, filter_size_3x3>;
+using NEConvolutionFixture = ConvolutionSquareValidationFixture<Tensor, Accessor, NEConvolution3x3, T>;
-FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 3 })))
{
// Validate output
- validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_3x3), tolerance_u8);
+ validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
}
-FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 3 })))
{
// Validate output
- validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_3x3), tolerance_u8);
+ validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
}
TEST_SUITE_END() /* Custom Convolution3x3 */
TEST_SUITE(CustomConvolution5x5)
-DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
- datasets::BorderModes()),
- shape, data_type, border_mode)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 5 })),
+ shape, data_type, border_mode, filter_size)
{
// Create tensors
Tensor src = create_tensor<Tensor>(shape, data_type);
@@ -162,22 +129,16 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
// Create conv matrix
int16_t conv[25];
- create_conv(conv, filter_size_5x5);
-
- // Generate random scale value between 0 and 255.
- std::mt19937 gen(library->seed());
- std::uniform_int_distribution<uint8_t> distribution(0, 255);
- uint32_t scale = distribution(gen);
ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
// Create and configure function
NEConvolution5x5 convolution;
- convolution.configure(&src, &dst, conv, scale, border_mode);
+ convolution.configure(&src, &dst, conv, 0, border_mode);
// Validate valid region
- const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size_5x5);
+ const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_size / 2));
validate(dst.info()->valid_region(), dst_valid_region);
// Validate padding
@@ -197,29 +158,32 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
}
template <typename T>
-using NEConvolutionFixture = ConvolutionValidationFixture<Tensor, Accessor, NEConvolution5x5, T, filter_size_5x5>;
+using NEConvolutionFixture = ConvolutionSquareValidationFixture<Tensor, Accessor, NEConvolution5x5, T>;
-FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 5 })))
{
// Validate output
- validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_5x5), tolerance_u8);
+ validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
}
-FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 5 })))
{
// Validate output
- validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_5x5), tolerance_u8);
+ validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
}
TEST_SUITE_END() /* Custom Convolution 5x5 */
TEST_SUITE(CustomConvolution7x7)
-DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
- datasets::BorderModes()),
- shape, data_type, border_mode)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 7 })),
+ shape, data_type, border_mode, filter_size)
{
// Create tensors
Tensor src = create_tensor<Tensor>(shape, data_type);
@@ -227,22 +191,16 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
// Create conv matrix
int16_t conv[49];
- create_conv(conv, filter_size_7x7);
-
- // Generate random scale value between 0 and 255.
- std::mt19937 gen(library->seed());
- std::uniform_int_distribution<uint8_t> distribution(0, 255);
- uint32_t scale = distribution(gen);
ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
// Create and configure function
NEConvolution7x7 convolution;
- convolution.configure(&src, &dst, conv, scale, border_mode);
+ convolution.configure(&src, &dst, conv, 0, border_mode);
// Validate valid region
- const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size_7x7);
+ const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_size / 2));
validate(dst.info()->valid_region(), dst_valid_region);
// Validate padding
@@ -262,29 +220,32 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
}
template <typename T>
-using NEConvolutionFixture = ConvolutionValidationFixture<Tensor, Accessor, NEConvolution7x7, T, filter_size_7x7>;
+using NEConvolutionFixture = ConvolutionSquareValidationFixture<Tensor, Accessor, NEConvolution7x7, T>;
-FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 7 })))
{
// Validate output
- validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_7x7), tolerance_u8);
+ validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
}
-FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 7 })))
{
// Validate output
- validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_7x7), tolerance_u8);
+ validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
}
TEST_SUITE_END() /* Custom Convolution 7x7 */
TEST_SUITE(CustomConvolution9x9)
-DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
- datasets::BorderModes()),
- shape, data_type, border_mode)
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType", DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 9 })),
+ shape, data_type, border_mode, filter_size)
{
// Create tensors
Tensor src = create_tensor<Tensor>(shape, data_type);
@@ -292,22 +253,16 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
// Create conv matrix
int16_t conv[81];
- create_conv(conv, filter_size_9x9);
-
- // Generate random scale value between 0 and 255.
- std::mt19937 gen(library->seed());
- std::uniform_int_distribution<uint8_t> distribution(0, 255);
- uint32_t scale = distribution(gen);
ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
// Create and configure function
NEConvolution9x9 convolution;
- convolution.configure(&src, &dst, conv, scale, border_mode);
+ convolution.configure(&src, &dst, conv, 0, border_mode);
// Validate valid region
- const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), border_size_9x9);
+ const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_size / 2));
validate(dst.info()->valid_region(), dst_valid_region);
// Validate padding
@@ -327,24 +282,98 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(conca
}
template <typename T>
-using NEConvolutionFixture = ConvolutionValidationFixture<Tensor, Accessor, NEConvolution9x9, T, filter_size_9x9>;
+using NEConvolutionFixture = ConvolutionSquareValidationFixture<Tensor, Accessor, NEConvolution9x9, T>;
-FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 9 })))
{
// Validate output
- validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_9x9), tolerance_u8);
+ validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
}
-FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
DataType::U8)),
- datasets::BorderModes()))
+ datasets::BorderModes()),
+ framework::dataset::make("filter_size", { 9 })))
{
// Validate output
- validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), border_size_9x9), tolerance_u8);
+ validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
}
TEST_SUITE_END() /* Custom Convolution 9x9 */
+TEST_SUITE_END() /* Custom Convolution Square */
+
+TEST_SUITE(CustomConvolutionRectangle)
+
+DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(combine(combine(combine(concat(datasets::SmallShapes(), datasets::LargeShapes()), framework::dataset::make("DataType",
+ DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_width", { 3, 5, 7, 9 })),
+ framework::dataset::make("filter_height", { 3, 5, 7, 9 })),
+ shape, data_type, border_mode, filter_width, filter_height)
+{
+ // Create tensors
+ Tensor src = create_tensor<Tensor>(shape, data_type);
+ Tensor dst = create_tensor<Tensor>(shape, data_type);
+
+ // Create conv matrix
+ int16_t conv[filter_width * filter_height];
+
+ ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+ // Create and configure function
+ NEConvolutionRectangle convolution;
+ convolution.configure(&src, &dst, conv, filter_width, filter_height, 1, border_mode);
+
+ // Validate valid region
+ const ValidRegion dst_valid_region = shape_to_valid_region(shape, (border_mode == BorderMode::UNDEFINED), BorderSize(filter_height / 2, filter_width / 2));
+ validate(dst.info()->valid_region(), dst_valid_region);
+
+ // Validate padding
+ PaddingCalculator calculator(shape.x(), 8);
+ calculator.set_border_size(filter_width / 2);
+ calculator.set_border_mode(border_mode);
+
+ const PaddingSize dst_padding = calculator.required_padding();
+
+ calculator.set_accessed_elements(16);
+ calculator.set_access_offset(-(filter_width / 2));
+
+ const PaddingSize width_padding = calculator.required_padding();
+
+ calculator.set_border_size(filter_height / 2);
+ calculator.set_access_offset(-(filter_height / 2));
+ const PaddingSize height_padding = calculator.required_padding();
+
+ validate(src.info()->padding(), width_padding, height_padding);
+ validate(dst.info()->padding(), dst_padding);
+}
+
+template <typename T>
+using NEConvolutionFixture = ConvolutionRectangleValidationFixture<Tensor, Accessor, NEConvolutionRectangle, T>;
+
+FIXTURE_DATA_TEST_CASE(RunSmall, NEConvolutionFixture<uint8_t>, framework::DatasetMode::PRECOMMIT, combine(combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType",
+ DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_width", { 3, 5, 7, 9 })),
+ framework::dataset::make("filter_height", { 3, 5, 7, 9 })))
+{
+ // Validate output
+ validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
+}
+
+FIXTURE_DATA_TEST_CASE(RunLarge, NEConvolutionFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType",
+ DataType::U8)),
+ datasets::BorderModes()),
+ framework::dataset::make("filter_width", { 3, 5, 7, 9 })),
+ framework::dataset::make("filter_height", { 3, 5, 7, 9 })))
+{
+ // Validate output
+ validate(Accessor(_target), _reference, shape_to_valid_region(_reference.shape(), (_border_mode == BorderMode::UNDEFINED), BorderSize(_height / 2, _width / 2)), tolerance_u8);
+}
+TEST_SUITE_END()
TEST_SUITE_END()
TEST_SUITE_END()
} // namespace validation
diff --git a/tests/validation/Validation.cpp b/tests/validation/Validation.cpp
index ebca1936e7..d01ac12f97 100644
--- a/tests/validation/Validation.cpp
+++ b/tests/validation/Validation.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017, 2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -170,6 +170,14 @@ void validate(const arm_compute::PaddingSize &padding, const arm_compute::Paddin
ARM_COMPUTE_EXPECT_EQUAL(padding.left, reference.left, framework::LogLevel::ERRORS);
}
+void validate(const arm_compute::PaddingSize &padding, const arm_compute::PaddingSize &width_reference, const arm_compute::PaddingSize &height_reference)
+{
+ ARM_COMPUTE_EXPECT_EQUAL(padding.top, height_reference.top, framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT_EQUAL(padding.right, width_reference.right, framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT_EQUAL(padding.bottom, height_reference.bottom, framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT_EQUAL(padding.left, width_reference.left, framework::LogLevel::ERRORS);
+}
+
void validate(const IAccessor &tensor, const void *reference_value)
{
ARM_COMPUTE_ASSERT(reference_value != nullptr);
diff --git a/tests/validation/Validation.h b/tests/validation/Validation.h
index 1f81d38acd..b12d7de97a 100644
--- a/tests/validation/Validation.h
+++ b/tests/validation/Validation.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017, 2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -163,6 +163,12 @@ void validate(const arm_compute::ValidRegion &region, const arm_compute::ValidRe
*/
void validate(const arm_compute::PaddingSize &padding, const arm_compute::PaddingSize &reference);
+/** Validate padding.
+ *
+ * Padding on all sides has to be the same.
+ */
+void validate(const arm_compute::PaddingSize &padding, const arm_compute::PaddingSize &width_reference, const arm_compute::PaddingSize &height_reference);
+
/** Validate tensors.
*
* - Dimensionality has to be the same.
diff --git a/tests/validation/fixtures/ConvolutionFixture.h b/tests/validation/fixtures/ConvolutionFixture.h
index 8bf6ea26a8..114d38a21a 100644
--- a/tests/validation/fixtures/ConvolutionFixture.h
+++ b/tests/validation/fixtures/ConvolutionFixture.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017, 2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -41,44 +41,40 @@ namespace test
{
namespace validation
{
-template <typename TensorType, typename AccessorType, typename FunctionType, typename T, const unsigned int filter_size>
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
class ConvolutionValidationFixture : public framework::Fixture
{
-public:
+protected:
template <typename...>
- void setup(TensorShape shape, DataType data_type, BorderMode border_mode)
+ void setup(TensorShape shape, DataType data_type, BorderMode border_mode, const unsigned int width, const unsigned int height)
{
std::mt19937 gen(library->seed());
std::uniform_int_distribution<uint8_t> distribution(0, 255);
const uint8_t constant_border_value = distribution(gen);
- // Generate random scale value between 0 and 255.
- const uint32_t scale = distribution(gen);
+ // Generate random scale value between 1 and 255.
+ std::uniform_int_distribution<uint8_t> distribution_scale(1, 255);
+ const uint32_t scale = distribution_scale(gen);
- switch(filter_size)
- {
- case 3:
- case 5:
- case 7:
- case 9:
- int16_t conv[filter_size * filter_size];
- create_conv(conv);
-
- _target = compute_target(shape, data_type, conv, scale, border_mode, constant_border_value);
- _reference = compute_reference(shape, data_type, conv, scale, border_mode, constant_border_value);
- break;
- default:
- ARM_COMPUTE_ERROR("Filter Size Not Supported");
- }
+ ARM_COMPUTE_ERROR_ON(3 != width && 5 != width && 7 != width && 9 != width);
+ ARM_COMPUTE_ERROR_ON(3 != height && 5 != height && 7 != height && 9 != height);
+
+ int16_t conv[width * height];
+ create_conv(conv);
+
+ _width = width;
+ _height = height;
+ _target = compute_target(shape, data_type, conv, scale, border_mode, constant_border_value);
+ _reference = compute_reference(shape, data_type, conv, scale, border_mode, constant_border_value);
}
-protected:
- void create_conv(int16_t *conv)
+ void
+ create_conv(int16_t *conv)
{
std::mt19937 gen(library->seed());
std::uniform_int_distribution<int16_t> distribution_int16(-32768, 32767);
- for(unsigned int i = 0; i < filter_size * filter_size; ++i)
+ for(unsigned int i = 0; i < _width * _height; ++i)
{
conv[i] = distribution_int16(gen);
}
@@ -90,6 +86,40 @@ protected:
library->fill_tensor_uniform(tensor, i);
}
+ SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type, const int16_t *conv, uint32_t scale, BorderMode border_mode, uint8_t constant_border_value)
+ {
+ ARM_COMPUTE_ERROR_ON(data_type != DataType::U8);
+
+ // Create reference
+ SimpleTensor<T> src{ shape, data_type };
+
+ // Fill reference
+ fill(src, 0);
+
+ // Compute reference
+ return reference::convolution<T>(src, conv, scale, border_mode, constant_border_value, _width, _height);
+ }
+
+ virtual TensorType compute_target(const TensorShape &shape, DataType data_type, const int16_t *conv, uint32_t scale, BorderMode border_mode, uint8_t constant_border_value) = 0;
+
+ BorderMode _border_mode{};
+ TensorType _target{};
+ SimpleTensor<T> _reference{};
+ unsigned int _width{};
+ unsigned int _height{};
+};
+
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ConvolutionSquareValidationFixture : public ConvolutionValidationFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+ template <typename...>
+ void setup(TensorShape shape, DataType data_type, BorderMode border_mode, const unsigned int width)
+ {
+ ConvolutionValidationFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, border_mode, width, width);
+ }
+
+protected:
TensorType compute_target(const TensorShape &shape, DataType data_type, const int16_t *conv, uint32_t scale, BorderMode border_mode, uint8_t constant_border_value)
{
// Create tensors
@@ -111,32 +141,56 @@ protected:
ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
// Fill tensors
- fill(AccessorType(src), 0);
- fill(AccessorType(dst), 1);
+ this->fill(AccessorType(src), 0);
+ this->fill(AccessorType(dst), 1);
// Compute function
convolution.run();
return dst;
}
+};
- SimpleTensor<T> compute_reference(const TensorShape &shape, DataType data_type, const int16_t *conv, uint32_t scale, BorderMode border_mode, uint8_t constant_border_value)
+template <typename TensorType, typename AccessorType, typename FunctionType, typename T>
+class ConvolutionRectangleValidationFixture : public ConvolutionValidationFixture<TensorType, AccessorType, FunctionType, T>
+{
+public:
+ template <typename...>
+ void setup(TensorShape shape, DataType data_type, BorderMode border_mode, const unsigned int width, const unsigned int height)
{
- ARM_COMPUTE_ERROR_ON(data_type != DataType::U8);
+ ConvolutionValidationFixture<TensorType, AccessorType, FunctionType, T>::setup(shape, data_type, border_mode, width, height);
+ }
- // Create reference
- SimpleTensor<T> src{ shape, data_type };
+protected:
+ TensorType compute_target(const TensorShape &shape, DataType data_type, const int16_t *conv, uint32_t scale, BorderMode border_mode, uint8_t constant_border_value)
+ {
+ // Create tensors
+ TensorType src = create_tensor<TensorType>(shape, data_type);
+ TensorType dst = create_tensor<TensorType>(shape, data_type);
- // Fill reference
- fill(src, 0);
+ // Create and configure function
+ FunctionType convolution;
+ convolution.configure(&src, &dst, conv, this->_width, this->_height, scale, border_mode, constant_border_value);
- // Compute reference
- return reference::convolution<T>(src, conv, scale, border_mode, constant_border_value, filter_size);
- }
+ ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS);
- BorderMode _border_mode{};
- TensorType _target{};
- SimpleTensor<T> _reference{};
+ // Allocate tensors
+ src.allocator()->allocate();
+ dst.allocator()->allocate();
+
+ ARM_COMPUTE_EXPECT(!src.info()->is_resizable(), framework::LogLevel::ERRORS);
+ ARM_COMPUTE_EXPECT(!dst.info()->is_resizable(), framework::LogLevel::ERRORS);
+
+ // Fill tensors
+ this->fill(AccessorType(src), 0);
+ this->fill(AccessorType(dst), 1);
+
+ // Compute function
+ convolution.run();
+
+ return dst;
+ }
};
} // namespace validation
} // namespace test
diff --git a/tests/validation/reference/Convolution.cpp b/tests/validation/reference/Convolution.cpp
index 84be858cfc..777e2df400 100644
--- a/tests/validation/reference/Convolution.cpp
+++ b/tests/validation/reference/Convolution.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017, 2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -35,7 +35,7 @@ namespace validation
namespace reference
{
template <typename T>
-SimpleTensor<T> convolution(const SimpleTensor<T> &src, const int16_t *conv, uint32_t scale, BorderMode border_mode, T constant_border_value, const unsigned int filter_size)
+SimpleTensor<T> convolution(const SimpleTensor<T> &src, const int16_t *conv, uint32_t scale, BorderMode border_mode, T constant_border_value, const unsigned int width, const unsigned int height)
{
SimpleTensor<T> dst(src.shape(), src.data_type());
SimpleTensor<int32_t> sum(src.shape(), src.data_type());
@@ -43,7 +43,7 @@ SimpleTensor<T> convolution(const SimpleTensor<T> &src, const int16_t *conv, uin
for(int element_idx = 0; element_idx < src.num_elements(); ++element_idx)
{
const Coordinates id = index2coord(src.shape(), element_idx);
- apply_2d_spatial_filter(id, src, sum, TensorShape(filter_size, filter_size), conv, 1, border_mode, constant_border_value);
+ apply_2d_spatial_filter(id, src, sum, TensorShape(width, height), conv, 1, border_mode, constant_border_value);
if(tensor_elem_at<int32_t>(sum, id, border_mode, constant_border_value) < 0)
{
@@ -63,7 +63,7 @@ SimpleTensor<T> convolution(const SimpleTensor<T> &src, const int16_t *conv, uin
}
template SimpleTensor<uint8_t> convolution(const SimpleTensor<uint8_t> &src, const int16_t *conv, uint32_t scale, BorderMode border_mode, uint8_t constant_border_value,
- const unsigned int filter_size);
+ const unsigned int widht, const unsigned int height);
} // namespace reference
} // namespace validation
} // namespace test
diff --git a/tests/validation/reference/Convolution.h b/tests/validation/reference/Convolution.h
index bdaac28ae6..ea9f4e444b 100644
--- a/tests/validation/reference/Convolution.h
+++ b/tests/validation/reference/Convolution.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017, 2018 ARM Limited.
*
* SPDX-License-Identifier: MIT
*
@@ -35,7 +35,7 @@ namespace validation
namespace reference
{
template <typename T>
-SimpleTensor<T> convolution(const SimpleTensor<T> &src, const int16_t *conv, uint32_t scale, BorderMode border_mode, T constant_border_value, const unsigned int filter_size);
+SimpleTensor<T> convolution(const SimpleTensor<T> &src, const int16_t *conv, uint32_t scale, BorderMode border_mode, T constant_border_value, const unsigned int width, const unsigned int height);
} // namespace reference
} // namespace validation
} // namespace test