From 678d83a5c3ec1b19ddb9df07a990262ce4bd65e1 Mon Sep 17 00:00:00 2001 From: Manuel Bottini Date: Mon, 7 Jan 2019 16:05:36 +0000 Subject: COMPMID-1838: Add 4D softmax support for NEON and achieve parity with CL Change-Id: I15c4a747cde2536b1caba2baf4ded9ca76e6dae2 Signed-off-by: Manuel Bottini Reviewed-on: https://review.mlplatform.org/487 Tested-by: Arm Jenkins Reviewed-by: VidhyaSudhan Loganathan --- tests/validation/NEON/SoftmaxLayer.cpp | 159 ++++++++++++++++++++++----------- 1 file changed, 109 insertions(+), 50 deletions(-) (limited to 'tests') diff --git a/tests/validation/NEON/SoftmaxLayer.cpp b/tests/validation/NEON/SoftmaxLayer.cpp index 21c77e7059..8f91b51d9a 100644 --- a/tests/validation/NEON/SoftmaxLayer.cpp +++ b/tests/validation/NEON/SoftmaxLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018 ARM Limited. + * Copyright (c) 2017-2019 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -44,10 +44,7 @@ namespace { /** Tolerance for float operations */ constexpr AbsoluteTolerance tolerance_f32(0.000001f); -#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC -constexpr RelativeTolerance rel_tolerance_f16(0.1f); -constexpr AbsoluteTolerance abs_tolerance_f16(0.01f); -#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC*/ +RelativeTolerance tolerance_f16(half(0.2)); /** Tolerance for quantized operations */ constexpr AbsoluteTolerance tolerance_qasymm8(1); @@ -65,11 +62,13 @@ const auto CNNDataTypes = framework::dataset::make("DataType", TEST_SUITE(NEON) TEST_SUITE(SoftmaxLayer) -DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::SoftmaxLayerSmallShapes(), datasets::SoftmaxLayerLargeShapes()), CNNDataTypes), shape, data_type) +DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datasets::Small2DShapes(), datasets::Medium2DShapes()), CNNDataTypes), shape, data_type) { + const QuantizationInfo quantization_info = is_data_type_quantized_asymmetric(data_type) ? QuantizationInfo(1.f / 255.f, 0) : QuantizationInfo(); + // Create tensors - Tensor src = create_tensor(shape, data_type, 1); - Tensor dst = create_tensor(shape, data_type, 1); + Tensor src = create_tensor(shape, data_type, 1, quantization_info); + Tensor dst = create_tensor(shape, data_type, 1, QuantizationInfo(1.f / 256.f, 0)); ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(dst.info()->is_resizable(), framework::LogLevel::ERRORS); @@ -83,31 +82,67 @@ DATA_TEST_CASE(Configuration, framework::DatasetMode::ALL, combine(concat(datase validate(src.info()->valid_region(), valid_region); validate(dst.info()->valid_region(), valid_region); - // Validate padding - const int step = 16 / data_size_from_type(data_type); - const PaddingSize padding = PaddingCalculator(shape.x(), step).required_padding(); - validate(src.info()->padding(), padding); - validate(dst.info()->padding(), PaddingSize()); + // NESoftmaxLayer configures the paddings only in the 2D case + if(shape.num_dimensions() <= 2) + { + // Validate padding + const int step = 16 / data_size_from_type(data_type); + const PaddingSize padding = PaddingCalculator(shape.x(), step).required_padding(); + validate(src.info()->padding(), padding); + validate(dst.info()->padding(), PaddingSize()); + } } // *INDENT-OFF* // clang-format off -DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip( - framework::dataset::make("InputInfo", { TensorInfo(TensorShape(27U, 13U), 1, DataType::F32), // Mismatching data types - TensorInfo(TensorShape(27U, 13U), 1, DataType::F32), // Mismatching shapes - TensorInfo(TensorShape(32U, 16U, 2U), 1, DataType::F32), // Invalid input dimensionality - TensorInfo(TensorShape(32U, 16U), 1, DataType::F32), - }), - framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(27U, 13U), 1, DataType::F16), - TensorInfo(TensorShape(27U, 11U), 1, DataType::F32), - TensorInfo(TensorShape(27U, 11U), 1, DataType::F32), - TensorInfo(TensorShape(32U, 16U), 1, DataType::F32), - })), - framework::dataset::make("Expected", { false, false, false, true })), - input_info, output_info, expected) -{ - bool is_valid = bool(NESoftmaxLayer::validate(&input_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false))); - ARM_COMPUTE_EXPECT(is_valid == expected, framework::LogLevel::ERRORS); +DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip( + framework::dataset::make("InputInfo", { TensorInfo(TensorShape(27U, 13U), 1, DataType::F32), // Mismatching data types + TensorInfo(TensorShape(27U, 13U), 1, DataType::F32), // Mismatching shapes + TensorInfo(TensorShape(27U, 13U), 1, DataType::QASYMM8, // Invalid output quantization info + QuantizationInfo(1.f/256, 12)), + TensorInfo(TensorShape(27U, 13U), 1, DataType::F32), // Window shrink + TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32),// Invalid input dimensionality + TensorInfo(TensorShape(32U, 13U), 1, DataType::F32), + TensorInfo(TensorShape(32U, 13U), 1, DataType::QASYMM8, + QuantizationInfo(1.f/256, 12)), + TensorInfo(TensorShape(32U, 13U), 1, DataType::QASYMM8, //Invalid axis value + QuantizationInfo(1.f/256, 12)), + }), + framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(27U, 13U), 1, DataType::F16), + TensorInfo(TensorShape(27U, 11U), 1, DataType::F32), + TensorInfo(TensorShape(27U, 13U), 1, DataType::QASYMM8, + QuantizationInfo(1.f/256, 12)), + TensorInfo(TensorShape(27U, 13U), 1, DataType::F32), + TensorInfo(TensorShape(27U, 13U, 2U), 1, DataType::F32), + TensorInfo(TensorShape(32U, 13U), 1, DataType::F32), + TensorInfo(TensorShape(32U, 13U), 1, DataType::QASYMM8, + QuantizationInfo(1.f/256, 0)), + TensorInfo(TensorShape(32U, 13U), 1, DataType::QASYMM8, + QuantizationInfo(1.f/256, 0)), + })), + framework::dataset::make("beta", { 1.0, + 2.0, + 1.0, + 2.0, + 1.0, + 2.0, + 1.0, + 2.0, + 1.0, + })), + framework::dataset::make("axis", { 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0, + })), + framework::dataset::make("Expected", { false, false, false, false, false, true, true, false })), + input_info, output_info, beta, axis, expected) +{ + ARM_COMPUTE_EXPECT(bool(NESoftmaxLayer::validate(&input_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), beta, axis)) == expected, framework::LogLevel::ERRORS); } // clang-format on // *INDENT-ON* @@ -118,13 +153,21 @@ using NESoftmaxLayerFixture = SoftmaxValidationFixture, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SoftmaxLayerSmallShapes(), +FIXTURE_DATA_TEST_CASE(RunSmall, NESoftmaxLayerFixture, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::Small4DShapes(), framework::dataset::make("DataType", DataType::F16)), framework::dataset::make("Beta", { 1.0f, 2.0f })), framework::dataset::make("Axis", { 1 }))) { // Validate output - validate(Accessor(_target), _reference, rel_tolerance_f16, 0.f, abs_tolerance_f16); + validate(Accessor(_target), _reference, tolerance_f16); +} +FIXTURE_DATA_TEST_CASE(RunSmall4D, NESoftmaxLayerFixture, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::Small4DShapes(), + framework::dataset::make("DataType", DataType::F32)), + framework::dataset::make("Beta", { 1.0f, 2.0f })), + framework::dataset::make("Axis", { 1, 2, 3 }))) +{ + // Validate output + validate(Accessor(_target), _reference, tolerance_f32); } FIXTURE_DATA_TEST_CASE(RunLarge, NESoftmaxLayerFixture, framework::DatasetMode::NIGHTLY, combine(combine(combine(datasets::SoftmaxLayerLargeShapes(), framework::dataset::make("DataType", DataType::F16)), @@ -132,16 +175,24 @@ FIXTURE_DATA_TEST_CASE(RunLarge, NESoftmaxLayerFixture, framework::Dataset framework::dataset::make("Axis", { 1 }))) { // Validate output - validate(Accessor(_target), _reference, rel_tolerance_f16, 0.f, abs_tolerance_f16); + validate(Accessor(_target), _reference, tolerance_f16); } -TEST_SUITE_END() -#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */ +TEST_SUITE_END() //FP16 +#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */ TEST_SUITE(FP32) -FIXTURE_DATA_TEST_CASE(RunSmall, NESoftmaxLayerFixture, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SoftmaxLayerSmallShapes(), - framework::dataset::make("DataType", DataType::F32)), - framework::dataset::make("Beta", { 1.0f, 2.0f })), - framework::dataset::make("Axis", { 1 }))) +FIXTURE_DATA_TEST_CASE(RunSmall2D, NESoftmaxLayerFixture, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SoftmaxLayerSmallShapes(), + framework::dataset::make("DataType", DataType::F32)), + framework::dataset::make("Beta", { 1.0f, 2.0f })), + framework::dataset::make("Axis", { 1 }))) +{ + // Validate output + validate(Accessor(_target), _reference, tolerance_f32); +} +FIXTURE_DATA_TEST_CASE(RunSmall4D, NESoftmaxLayerFixture, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::Small4DShapes(), + framework::dataset::make("DataType", DataType::F32)), + framework::dataset::make("Beta", { 1.0f, 2.0f })), + framework::dataset::make("Axis", { 1, 2, 3 }))) { // Validate output validate(Accessor(_target), _reference, tolerance_f32); @@ -154,19 +205,28 @@ FIXTURE_DATA_TEST_CASE(RunLarge, NESoftmaxLayerFixture, framework::Datase // Validate output validate(Accessor(_target), _reference, tolerance_f32); } -TEST_SUITE_END() -TEST_SUITE_END() +TEST_SUITE_END() //FP32 +TEST_SUITE_END() //Float template using NESoftmaxLayerQuantizedFixture = SoftmaxValidationQuantizedFixture; TEST_SUITE(Quantized) TEST_SUITE(QASYMM8) -FIXTURE_DATA_TEST_CASE(RunSmall, NESoftmaxLayerQuantizedFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SoftmaxLayerSmallShapes(), - framework::dataset::make("DataType", DataType::QASYMM8)), - combine(framework::dataset::make("QuantizationInfo", { QuantizationInfo(0.5f, -10) }), - framework::dataset::make("Beta", { 1.0f, 2.f }))), - framework::dataset::make("Axis", { 1 }))) +FIXTURE_DATA_TEST_CASE(RunSmall2D, NESoftmaxLayerQuantizedFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SoftmaxLayerSmallShapes(), + framework::dataset::make("DataType", DataType::QASYMM8)), + combine(framework::dataset::make("QuantizationInfo", { QuantizationInfo(0.5f, -10) }), + framework::dataset::make("Beta", { 1.0f, 2.f }))), + framework::dataset::make("Axis", { 1 }))) +{ + // Validate output + validate(Accessor(_target), _reference, tolerance_qasymm8); +} +FIXTURE_DATA_TEST_CASE(RunSmall4D, NESoftmaxLayerQuantizedFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::Small4DShapes(), + framework::dataset::make("DataType", DataType::QASYMM8)), + combine(framework::dataset::make("QuantizationInfo", { QuantizationInfo(0.5f, -10) }), + framework::dataset::make("Beta", { 1.0f, 2.f }))), + framework::dataset::make("Axis", { 1, 2, 3 }))) { // Validate output validate(Accessor(_target), _reference, tolerance_qasymm8); @@ -180,12 +240,11 @@ FIXTURE_DATA_TEST_CASE(RunLarge, NESoftmaxLayerQuantizedFixture, framew // Validate output validate(Accessor(_target), _reference, tolerance_qasymm8); } +TEST_SUITE_END() //QASYMM8 +TEST_SUITE_END() //Quantized -TEST_SUITE_END() -TEST_SUITE_END() - -TEST_SUITE_END() -TEST_SUITE_END() +TEST_SUITE_END() //SoftmaxLayer +TEST_SUITE_END() //NEON } // namespace validation } // namespace test } // namespace arm_compute -- cgit v1.2.1