From 0779fecbf897fe85c5e13da52b129e439c4cc75d Mon Sep 17 00:00:00 2001 From: Sang-Hoon Park Date: Wed, 13 Nov 2019 17:08:12 +0000 Subject: COMPMID-2763 [CL] add support for QASYMM8_SIGNED to SoftmaxLayer Change-Id: I4556bde3aa51eb874a4e674dbbd575fa4491c088 Signed-off-by: Sang-Hoon Park Reviewed-on: https://review.mlplatform.org/c/2375 Comments-Addressed: Arm Jenkins Tested-by: Arm Jenkins Reviewed-by: Michele Di Giorgio Reviewed-by: Georgios Pinitas --- tests/validation/CL/SoftmaxLayer.cpp | 36 +++++++++++++++++++++---- tests/validation/Helpers.h | 2 +- tests/validation/fixtures/SoftmaxLayerFixture.h | 4 +-- tests/validation/reference/LogSoftmaxLayer.cpp | 8 +++--- tests/validation/reference/LogSoftmaxLayer.h | 2 +- tests/validation/reference/SoftmaxLayer.cpp | 8 +++--- tests/validation/reference/SoftmaxLayer.h | 2 +- 7 files changed, 44 insertions(+), 18 deletions(-) (limited to 'tests') diff --git a/tests/validation/CL/SoftmaxLayer.cpp b/tests/validation/CL/SoftmaxLayer.cpp index ae7adec9f2..5ee929f6b9 100644 --- a/tests/validation/CL/SoftmaxLayer.cpp +++ b/tests/validation/CL/SoftmaxLayer.cpp @@ -49,6 +49,15 @@ RelativeTolerance tolerance_f32(0.001f); /** Tolerance for quantized operations */ constexpr AbsoluteTolerance tolerance_qasymm8(1); +constexpr AbsoluteTolerance tolerance_qasymm8_signed(1); + +/* + The following tolerance number is used as a workaround for the mismatches + caused by float computation in reference (and NEON) kernel + and integer computations in OpenCL kernel. + COMPMID-2958 is created to investigate this. +*/ +constexpr float tolerance_number_qasymm8_signed = 0.05f; /** CNN data types */ const auto CNNDataTypes = framework::dataset::make("DataType", @@ -110,6 +119,8 @@ DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip( 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_SIGNED, + QuantizationInfo(1.f/256, 12)) }), framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(27U, 13U), 1, DataType::F16), TensorInfo(TensorShape(27U, 11U), 1, DataType::F32), @@ -120,8 +131,10 @@ DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip( 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_SIGNED, + QuantizationInfo(1.f/256, -128)), })), - framework::dataset::make("Expected", { false, false, false, false, false, true, true })), + framework::dataset::make("Expected", { false, false, false, false, false, true, true, true })), input_info, output_info, expected) { ARM_COMPUTE_EXPECT(bool(CLSoftmaxLayer::validate(&input_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false))) == expected, framework::LogLevel::ERRORS); @@ -221,11 +234,24 @@ FIXTURE_DATA_TEST_CASE(Run4D, CLSoftmaxLayerQuantizedFixture, framework validate(CLAccessor(_target), _reference, tolerance_qasymm8); } -TEST_SUITE_END() -TEST_SUITE_END() +TEST_SUITE_END() // QASYMM8 -TEST_SUITE_END() -TEST_SUITE_END() +TEST_SUITE(QASYMM8_SIGNED) + +FIXTURE_DATA_TEST_CASE(RunSmall, CLSoftmaxLayerQuantizedFixture, framework::DatasetMode::ALL, combine(combine(combine(datasets::SoftmaxLayerSmallShapes(), + framework::dataset::make("DataType", DataType::QASYMM8_SIGNED)), + combine(framework::dataset::make("QuantizationInfo", { QuantizationInfo(0.5f, -10) }), + framework::dataset::make("Beta", { 1.0f, 2.f }))), + framework::dataset::make("Axis", { 1, 2 }))) +{ + // Validate output + validate(CLAccessor(_target), _reference, tolerance_qasymm8_signed, tolerance_number_qasymm8_signed); +} + +TEST_SUITE_END() // QASYMM8_SIGNED +TEST_SUITE_END() // Quantized +TEST_SUITE_END() // SoftmaxLayer +TEST_SUITE_END() // CL } // namespace validation } // namespace test } // namespace arm_compute diff --git a/tests/validation/Helpers.h b/tests/validation/Helpers.h index 100f4f05c1..942b2396bf 100644 --- a/tests/validation/Helpers.h +++ b/tests/validation/Helpers.h @@ -177,7 +177,7 @@ void fill_lookuptable(T &&table) } } -/** Convert a quantized simple tensor into float using tensor quantization information. +/** Convert an asymmetric quantized simple tensor into float using tensor quantization information. * * @param[in] src Quantized tensor. * diff --git a/tests/validation/fixtures/SoftmaxLayerFixture.h b/tests/validation/fixtures/SoftmaxLayerFixture.h index f747ab3574..82daf34f13 100644 --- a/tests/validation/fixtures/SoftmaxLayerFixture.h +++ b/tests/validation/fixtures/SoftmaxLayerFixture.h @@ -65,7 +65,7 @@ protected: std::uniform_real_distribution<> distribution(-1000.f, 1000.f); library->fill(tensor, distribution, 0); } - else // data type is quantized_asymmetric + else // data type is quantized_asymmetric (signed or unsigned) { std::uniform_int_distribution<> distribution(0, 100); library->fill(tensor, distribution, 0); @@ -77,7 +77,7 @@ protected: { // Create tensors TensorType src = create_tensor(shape, data_type, 1, quantization_info); - TensorType dst = create_tensor(shape, data_type, 1, QuantizationInfo(1.f / 256, 0)); + TensorType dst = create_tensor(shape, data_type, 1, get_softmax_output_quantization_info(data_type, IS_LOG)); // Create and configure function FunctionType smx_layer; diff --git a/tests/validation/reference/LogSoftmaxLayer.cpp b/tests/validation/reference/LogSoftmaxLayer.cpp index 3f21d85dd0..e4403956ab 100644 --- a/tests/validation/reference/LogSoftmaxLayer.cpp +++ b/tests/validation/reference/LogSoftmaxLayer.cpp @@ -40,21 +40,21 @@ SimpleTensor log_softmax_layer(const SimpleTensor &src, float beta, size_t return softmax_layer_generic(src, beta, axis, true); } -template ::value, int>::type> +template ::value || std::is_same::value, int>::type> SimpleTensor log_softmax_layer(const SimpleTensor &src, float beta, size_t axis) { - // Note: Output quantization info should always have scale = 1/256 and offset = 0 - const QuantizationInfo output_quantization_info = QuantizationInfo(1.f / 256, 0); + const QuantizationInfo output_quantization_info = arm_compute::get_softmax_output_quantization_info(src.data_type(), true); SimpleTensor src_tmp = convert_from_asymmetric(src); SimpleTensor dst_tmp = log_softmax_layer(src_tmp, beta, axis); - SimpleTensor dst = convert_to_asymmetric(dst_tmp, output_quantization_info); + SimpleTensor dst = convert_to_asymmetric(dst_tmp, output_quantization_info); return dst; } template SimpleTensor log_softmax_layer(const SimpleTensor &src, float beta, size_t axis); template SimpleTensor log_softmax_layer(const SimpleTensor &src, float beta, size_t axis); template SimpleTensor log_softmax_layer(const SimpleTensor &src, float beta, size_t axis); +template SimpleTensor log_softmax_layer(const SimpleTensor &src, float beta, size_t axis); } // namespace reference } // namespace validation } // namespace test diff --git a/tests/validation/reference/LogSoftmaxLayer.h b/tests/validation/reference/LogSoftmaxLayer.h index 065315ff2c..c2e3f5974e 100644 --- a/tests/validation/reference/LogSoftmaxLayer.h +++ b/tests/validation/reference/LogSoftmaxLayer.h @@ -38,7 +38,7 @@ namespace reference template ::value, int>::type = 0> SimpleTensor log_softmax_layer(const SimpleTensor &src, float beta, size_t axis = 1); -template ::value, int>::type = 0> +template ::value || std::is_same::value, int>::type = 0> SimpleTensor log_softmax_layer(const SimpleTensor &src, float beta, size_t axis = 1); } // namespace reference } // namespace validation diff --git a/tests/validation/reference/SoftmaxLayer.cpp b/tests/validation/reference/SoftmaxLayer.cpp index ef2468df59..0e470260a9 100644 --- a/tests/validation/reference/SoftmaxLayer.cpp +++ b/tests/validation/reference/SoftmaxLayer.cpp @@ -107,21 +107,21 @@ SimpleTensor softmax_layer(const SimpleTensor &src, float beta, size_t axi return softmax_layer_generic(src, beta, axis, false); } -template ::value, int>::type> +template ::value || std::is_same::value, int>::type> SimpleTensor softmax_layer(const SimpleTensor &src, float beta, size_t axis) { - // Note: Output quantization info should always have scale = 1/256 and offset = 0 - const QuantizationInfo output_quantization_info = QuantizationInfo(1.f / 256, 0); + const QuantizationInfo output_quantization_info = arm_compute::get_softmax_output_quantization_info(src.data_type(), false); SimpleTensor src_tmp = convert_from_asymmetric(src); SimpleTensor dst_tmp = softmax_layer(src_tmp, beta, axis); - SimpleTensor dst = convert_to_asymmetric(dst_tmp, output_quantization_info); + SimpleTensor dst = convert_to_asymmetric(dst_tmp, output_quantization_info); return dst; } template SimpleTensor softmax_layer(const SimpleTensor &src, float beta, size_t axis); template SimpleTensor softmax_layer(const SimpleTensor &src, float beta, size_t axis); template SimpleTensor softmax_layer(const SimpleTensor &src, float beta, size_t axis); +template SimpleTensor softmax_layer(const SimpleTensor &src, float beta, size_t axis); } // namespace reference } // namespace validation } // namespace test diff --git a/tests/validation/reference/SoftmaxLayer.h b/tests/validation/reference/SoftmaxLayer.h index 2708c807f2..2be575c2af 100644 --- a/tests/validation/reference/SoftmaxLayer.h +++ b/tests/validation/reference/SoftmaxLayer.h @@ -41,7 +41,7 @@ SimpleTensor softmax_layer_generic(const SimpleTensor &src, float beta, si template ::value, int>::type = 0> SimpleTensor softmax_layer(const SimpleTensor &src, float beta, size_t axis = 1); -template ::value, int>::type = 0> +template ::value || std::is_same::value, int>::type = 0> SimpleTensor softmax_layer(const SimpleTensor &src, float beta, size_t axis = 1); } // namespace reference } // namespace validation -- cgit v1.2.1