diff options
Diffstat (limited to 'tests/validation')
-rw-r--r-- | tests/validation/CL/Im2Col.cpp | 80 | ||||
-rw-r--r-- | tests/validation/NEON/Im2Col.cpp | 9 | ||||
-rw-r--r-- | tests/validation/fixtures/Im2ColFixture.h | 10 | ||||
-rw-r--r-- | tests/validation/reference/Im2Col.cpp | 45 | ||||
-rw-r--r-- | tests/validation/reference/Im2Col.h | 3 |
5 files changed, 111 insertions, 36 deletions
diff --git a/tests/validation/CL/Im2Col.cpp b/tests/validation/CL/Im2Col.cpp index e8019cca92..cf7c79ad72 100644 --- a/tests/validation/CL/Im2Col.cpp +++ b/tests/validation/CL/Im2Col.cpp @@ -53,9 +53,14 @@ const auto conv_filter_sizes = framework::dataset::make("KernelDims", { Size2D(3 const auto padstrides = framework::dataset::make("PadStride", { PadStrideInfo(1U, 1U, 0U, 0U), PadStrideInfo(1U, 1U, 1U, 1U), PadStrideInfo(2U, 2U, 0U, 2U) }); -const auto conv_args = combine(combine(combine(conv_filter_sizes, padstrides), - framework::dataset::make("QuantizationInfo", QuantizationInfo(0.5f, 10))), - framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })); +const auto conv_args = combine(combine(combine(combine(conv_filter_sizes, padstrides), + framework::dataset::make("QuantizationInfo", QuantizationInfo(0.5f, 10))), + framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })), + framework::dataset::make("NumGroups", { 1 })); +const auto grouped_args = combine(combine(combine(combine(conv_filter_sizes, padstrides), + framework::dataset::make("QuantizationInfo", QuantizationInfo(0.5f, 10))), + framework::dataset::make("DataLayout", { DataLayout::NCHW })), + framework::dataset::make("NumGroups", { 2, 3, 4 })); } // namespace TEST_SUITE(CL) @@ -96,7 +101,6 @@ FIXTURE_DATA_TEST_CASE(RunSmall, CLIm2ColFixture<float>, framework::DatasetMode: // Validate output validate(CLAccessor(_target), _reference); } -TEST_SUITE_END() FIXTURE_DATA_TEST_CASE(RunLarge, CLIm2ColFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::LargeShapes(), framework::dataset::make("DataType", DataType::F32)), conv_args), @@ -105,8 +109,7 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLIm2ColFixture<float>, framework::DatasetMode: // Validate output validate(CLAccessor(_target), _reference); } - -#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC +TEST_SUITE_END() TEST_SUITE(FP16) FIXTURE_DATA_TEST_CASE(RunSmall, CLIm2ColFixture<half>, framework::DatasetMode::ALL, combine(combine(combine(datasets::SmallShapes(), framework::dataset::make("DataType", DataType::F16)), @@ -124,9 +127,6 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLIm2ColFixture<half>, framework::DatasetMode:: validate(CLAccessor(_target), _reference); } TEST_SUITE_END() - -#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */ - TEST_SUITE_END() TEST_SUITE(QASYMM8) @@ -146,6 +146,68 @@ FIXTURE_DATA_TEST_CASE(RunLarge, CLIm2ColFixture<uint8_t>, framework::DatasetMod } TEST_SUITE_END() +TEST_SUITE(Grouped) +TEST_SUITE(FP32) +FIXTURE_DATA_TEST_CASE(RunSmall, CLIm2ColFixture<float>, framework::DatasetMode::ALL, combine(combine(combine(datasets::GroupedIm2ColSmallShapes(), framework::dataset::make("DataType", + DataType::F32)), + grouped_args), + framework::dataset::make("ChannelsFirstOutputNHWC", true))) +{ + // Validate output + validate(CLAccessor(_target), _reference); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLIm2ColFixture<float>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::GroupedIm2ColLargeShapes(), framework::dataset::make("DataType", + DataType::F32)), + grouped_args), + framework::dataset::make("ChannelsFirstOutputNHWC", true))) +{ + // Validate output + validate(CLAccessor(_target), _reference); +} +TEST_SUITE_END() + +TEST_SUITE(FP16) +FIXTURE_DATA_TEST_CASE(RunSmall, CLIm2ColFixture<half>, framework::DatasetMode::ALL, combine(combine(combine(datasets::GroupedIm2ColSmallShapes(), framework::dataset::make("DataType", + DataType::F16)), + grouped_args), + framework::dataset::make("ChannelsFirstOutputNHWC", true))) +{ + // Validate output + validate(CLAccessor(_target), _reference); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLIm2ColFixture<half>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::GroupedIm2ColLargeShapes(), framework::dataset::make("DataType", + DataType::F16)), + grouped_args), + framework::dataset::make("ChannelsFirstOutputNHWC", true))) +{ + // Validate output + validate(CLAccessor(_target), _reference); +} +TEST_SUITE_END() + +TEST_SUITE(QASYMM8) +FIXTURE_DATA_TEST_CASE(RunSmall, CLIm2ColFixture<uint8_t>, framework::DatasetMode::ALL, combine(combine(combine(datasets::GroupedIm2ColSmallShapes(), framework::dataset::make("DataType", + DataType::QASYMM8)), + grouped_args), + framework::dataset::make("ChannelsFirstOutputNHWC", true))) +{ + // Validate output + validate(CLAccessor(_target), _reference); +} + +FIXTURE_DATA_TEST_CASE(RunLarge, CLIm2ColFixture<uint8_t>, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::GroupedIm2ColLargeShapes(), framework::dataset::make("DataType", + DataType::QASYMM8)), + grouped_args), + framework::dataset::make("ChannelsFirstOutputNHWC", true))) +{ + // Validate output + validate(CLAccessor(_target), _reference); +} +TEST_SUITE_END() +TEST_SUITE_END() + TEST_SUITE_END() TEST_SUITE_END() } // namespace validation diff --git a/tests/validation/NEON/Im2Col.cpp b/tests/validation/NEON/Im2Col.cpp index f011ebe935..0ea68bf49d 100644 --- a/tests/validation/NEON/Im2Col.cpp +++ b/tests/validation/NEON/Im2Col.cpp @@ -40,9 +40,10 @@ namespace validation namespace { const auto conv_filter_sizes = framework::dataset::make("KernelDims", { Size2D(3U, 3U), Size2D(3U, 1U), Size2D(1U, 5U), Size2D(5U, 5U), Size2D(7U, 7U) }); -const auto conv_args = combine(combine(combine(conv_filter_sizes, framework::dataset::make("PadStride", { PadStrideInfo(1U, 1U, 0U, 0U), PadStrideInfo(1U, 1U, 1U, 1U), PadStrideInfo(2U, 2U, 0U, 2U) })), - framework::dataset::make("QuantizationInfo", QuantizationInfo(0.5f, 10))), - framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })); +const auto conv_args = combine(combine(combine(combine(conv_filter_sizes, framework::dataset::make("PadStride", { PadStrideInfo(1U, 1U, 0U, 0U), PadStrideInfo(1U, 1U, 1U, 1U), PadStrideInfo(2U, 2U, 0U, 2U) })), + framework::dataset::make("QuantizationInfo", QuantizationInfo(0.5f, 10))), + framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })), + framework::dataset::make("NumGroups", { 1 })); } // namespace TEST_SUITE(NEON) TEST_SUITE(Im2Col) @@ -66,7 +67,7 @@ DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip( framework::dataset::make("Expected", { false, false, false, false, true })), input_info, output_info, has_bias, expected) { - bool status = bool(NEIm2Col::validate(&input_info, &output_info, Size2D(3U, 3U), PadStrideInfo(), has_bias, false, false)); + bool status = bool(NEIm2Col::validate(&input_info, &output_info, Size2D(3U, 3U), PadStrideInfo(), has_bias)); ARM_COMPUTE_EXPECT(status == expected, framework::LogLevel::ERRORS); } // clang-format on diff --git a/tests/validation/fixtures/Im2ColFixture.h b/tests/validation/fixtures/Im2ColFixture.h index da2576b37c..b5e83a9872 100644 --- a/tests/validation/fixtures/Im2ColFixture.h +++ b/tests/validation/fixtures/Im2ColFixture.h @@ -50,13 +50,14 @@ class Im2ColValidationFixture : public framework::Fixture public: template <typename...> void setup(TensorShape input_shape, DataType data_type, const Size2D &kernel_dims, const PadStrideInfo &conv_info, const QuantizationInfo &quant_info, const DataLayout &data_layout, - bool channels_first_output_nhwc) + unsigned int num_groups, bool channels_first_output_nhwc) { _kernel_dims = kernel_dims; _conv_info = conv_info; _quant_info = quant_info; _data_layout = data_layout; _has_bias = data_type != DataType::QASYMM8; + _num_groups = num_groups; if(_data_layout == DataLayout::NHWC) { @@ -66,7 +67,7 @@ public: TensorInfo input_info(input_shape, 1, data_type); input_info.set_data_layout(_data_layout); - const TensorShape output_shape = compute_im2col_conv_shape(&input_info, _kernel_dims, _conv_info, _has_bias, Size2D(1U, 1U), batch_size_on_z); + const TensorShape output_shape = compute_im2col_conv_shape(&input_info, _kernel_dims, _conv_info, _has_bias, Size2D(1U, 1U), batch_size_on_z && _num_groups == 1, _num_groups); _target = compute_target(input_shape, output_shape, data_type); compute_reference(input_shape, output_shape, data_type, channels_first_output_nhwc); @@ -87,7 +88,7 @@ protected: // Create and configure function FunctionType im2col_func; - im2col_func.configure(&src, &dst, _kernel_dims, _conv_info, _has_bias); + im2col_func.configure(&src, &dst, _kernel_dims, _conv_info, _has_bias, Size2D(1U, 1U), _num_groups); ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS); @@ -117,7 +118,7 @@ protected: // Fill reference fill(src); - reference::im2col<T>(src, _reference, _kernel_dims, _conv_info, _has_bias, channels_first_output_nhwc); + reference::im2col<T>(src, _reference, _kernel_dims, _conv_info, _has_bias, _num_groups, channels_first_output_nhwc); } TensorType _target{}; SimpleTensor<T> _reference{}; @@ -126,6 +127,7 @@ protected: DataLayout _data_layout{}; QuantizationInfo _quant_info{}; bool _has_bias{}; + unsigned int _num_groups{}; }; } // namespace validation } // namespace test diff --git a/tests/validation/reference/Im2Col.cpp b/tests/validation/reference/Im2Col.cpp index 2459499474..0c41d88f3e 100644 --- a/tests/validation/reference/Im2Col.cpp +++ b/tests/validation/reference/Im2Col.cpp @@ -36,7 +36,7 @@ namespace validation namespace reference { template <typename T> -void im2col_nchw(const SimpleTensor<T> &src, SimpleTensor<T> &dst, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias) +void im2col_nchw(const SimpleTensor<T> &src, SimpleTensor<T> &dst, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, unsigned int num_groups) { ARM_COMPUTE_ERROR_ON(src.data_layout() != DataLayout::NCHW); const int stride_x = conv_info.stride().first; @@ -58,26 +58,32 @@ void im2col_nchw(const SimpleTensor<T> &src, SimpleTensor<T> &dst, const Size2D for(int b = 0; b < batches; ++b) { - for(int yo = 0; yo < dst_height; ++yo) + for(int g = 0; g < static_cast<int>(num_groups); ++g) { - // Compute input spatial coordinates - const int xi = (yo % convolved_dims.first) * stride_x; - const int yi = (yo / convolved_dims.first) * stride_y; + const int first_group_ch = g * (src_channels / num_groups); + const int last_group_ch = (g + 1) * (src_channels / num_groups); - for(int ci = 0; ci < src_channels; ++ci) + for(int yo = 0; yo < dst_height; ++yo) { - for(int yk = 0; yk < kernel_height; ++yk) + // Compute input spatial coordinates + const int xi = (yo % convolved_dims.first) * stride_x; + const int yi = (yo / convolved_dims.first) * stride_y; + + for(int ci = first_group_ch; ci < last_group_ch; ++ci) { - for(int xk = 0; xk < kernel_width; ++xk) + for(int yk = 0; yk < kernel_height; ++yk) { - dst[dst_idx++] = tensor_elem_at(src, Coordinates(xi + xk - pad_x, yi + yk - pad_y, ci, b), BorderMode::CONSTANT, static_cast<T>(pad_val)); + for(int xk = 0; xk < kernel_width; ++xk) + { + dst[dst_idx++] = tensor_elem_at(src, Coordinates(xi + xk - pad_x, yi + yk - pad_y, ci, b), BorderMode::CONSTANT, static_cast<T>(pad_val)); + } } } - } - if(has_bias) - { - dst[dst_idx++] = static_cast<T>(1); + if(has_bias) + { + dst[dst_idx++] = static_cast<T>(1); + } } } } @@ -179,13 +185,13 @@ void im2col_nhwc_channel_first(const SimpleTensor<T> &src, SimpleTensor<T> &dst, } template <typename T> -void im2col(const SimpleTensor<T> &src, SimpleTensor<T> &dst, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, bool channels_first_output_nhwc) +void im2col(const SimpleTensor<T> &src, SimpleTensor<T> &dst, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, const unsigned int num_groups, bool channels_first_output_nhwc) { switch(src.data_layout()) { case DataLayout::NCHW: { - im2col_nchw(src, dst, kernel_dims, conv_info, has_bias); + im2col_nchw(src, dst, kernel_dims, conv_info, has_bias, num_groups); break; } case DataLayout::NHWC: @@ -208,9 +214,12 @@ void im2col(const SimpleTensor<T> &src, SimpleTensor<T> &dst, const Size2D &kern } } -template void im2col(const SimpleTensor<uint8_t> &src, SimpleTensor<uint8_t> &dst, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, bool channels_first_output_nhwc); -template void im2col(const SimpleTensor<half> &src, SimpleTensor<half> &dst, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, bool channels_first_output_nhwc); -template void im2col(const SimpleTensor<float> &src, SimpleTensor<float> &dst, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, bool channels_first_output_nhwc); +template void im2col(const SimpleTensor<uint8_t> &src, SimpleTensor<uint8_t> &dst, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, unsigned int num_groups, + bool channels_first_output_nhwc); +template void im2col(const SimpleTensor<half> &src, SimpleTensor<half> &dst, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, unsigned int num_groups, + bool channels_first_output_nhwc); +template void im2col(const SimpleTensor<float> &src, SimpleTensor<float> &dst, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, unsigned int num_groups, + bool channels_first_output_nhwc); } // namespace reference } // namespace validation } // namespace test diff --git a/tests/validation/reference/Im2Col.h b/tests/validation/reference/Im2Col.h index b1ebaf25da..84ee237453 100644 --- a/tests/validation/reference/Im2Col.h +++ b/tests/validation/reference/Im2Col.h @@ -35,7 +35,8 @@ namespace validation namespace reference { template <typename T> -void im2col(const SimpleTensor<T> &src, SimpleTensor<T> &dst, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, bool channels_first_output_nhwc = false); +void im2col(const SimpleTensor<T> &src, SimpleTensor<T> &dst, const Size2D &kernel_dims, const PadStrideInfo &conv_info, bool has_bias, const unsigned int num_groups, + bool channels_first_output_nhwc = false); } // namespace reference } // namespace validation } // namespace test |