From ea7de7babc319e2fa31c5e1c986e48d6c5370689 Mon Sep 17 00:00:00 2001 From: Giorgio Arena Date: Thu, 10 Dec 2020 16:49:39 +0000 Subject: Enable FFT for FP16 Resolves: COMPMID-4051 Change-Id: I0c0bf97212dd281c19d5081e6247e7dc0c23cd6b Signed-off-by: Giorgio Arena Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/4687 Tested-by: Arm Jenkins Reviewed-by: Gian Marco Iodice Comments-Addressed: Arm Jenkins --- tests/validation/CL/FFT.cpp | 36 +++++++++++++++++++++++++++++----- tests/validation/fixtures/FFTFixture.h | 33 ++++++++++++++++++++++++++----- tests/validation/reference/DFT.cpp | 20 +++++++++++++++---- 3 files changed, 75 insertions(+), 14 deletions(-) (limited to 'tests/validation') diff --git a/tests/validation/CL/FFT.cpp b/tests/validation/CL/FFT.cpp index 1115ddcd8b..fb2f1f53e2 100644 --- a/tests/validation/CL/FFT.cpp +++ b/tests/validation/CL/FFT.cpp @@ -64,8 +64,10 @@ const auto ActivationFunctionsSmallDataset = framework::dataset::make("Activatio ActivationLayerInfo(ActivationLayerInfo::ActivationFunction::LU_BOUNDED_RELU, 0.5f) }); -RelativeTolerance tolerance_f32(0.1f); /**< Relative tolerance value for FP32 */ -constexpr float tolerance_num = 0.07f; /**< Tolerance number */ +RelativeTolerance tolerance_f32(0.1f); /**< Relative tolerance value for FP32 */ +RelativeTolerance tolerance_f16(half(0.1f)); /**< Relative tolerance value for FP16 */ +constexpr float tolerance_num_f32 = 0.07f; /**< Tolerance number for FP32*/ +constexpr float tolerance_num_f16 = 0.15f; /**< Tolerance number for FP32*/ } // namespace TEST_SUITE(CL) @@ -108,9 +110,16 @@ TEST_SUITE(FP32) FIXTURE_DATA_TEST_CASE(RunSmall, CLFFT1DFixture, framework::DatasetMode::ALL, combine(shapes_1d, framework::dataset::make("DataType", DataType::F32))) { // Validate output - validate(CLAccessor(_target), _reference, tolerance_f32, tolerance_num); + validate(CLAccessor(_target), _reference, tolerance_f32, tolerance_num_f32); } TEST_SUITE_END() // FP32 +TEST_SUITE(FP16) +FIXTURE_DATA_TEST_CASE(RunSmall, CLFFT1DFixture, framework::DatasetMode::ALL, combine(shapes_1d, framework::dataset::make("DataType", DataType::F16))) +{ + // Validate output + validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num_f16); +} +TEST_SUITE_END() // FP16 TEST_SUITE_END() // Float TEST_SUITE_END() // FFT1D @@ -149,9 +158,16 @@ TEST_SUITE(FP32) FIXTURE_DATA_TEST_CASE(RunSmall, CLFFT2DFixture, framework::DatasetMode::ALL, combine(shapes_2d, framework::dataset::make("DataType", DataType::F32))) { // Validate output - validate(CLAccessor(_target), _reference, tolerance_f32, tolerance_num); + validate(CLAccessor(_target), _reference, tolerance_f32, tolerance_num_f32); } TEST_SUITE_END() // FP32 +TEST_SUITE(FP16) +FIXTURE_DATA_TEST_CASE(RunSmall, CLFFT2DFixture, framework::DatasetMode::ALL, combine(shapes_2d, framework::dataset::make("DataType", DataType::F16))) +{ + // Validate output + validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num_f16); +} +TEST_SUITE_END() // FP16 TEST_SUITE_END() // Float TEST_SUITE_END() // FFT2D @@ -168,9 +184,19 @@ FIXTURE_DATA_TEST_CASE(RunSmall, CLFFTConvolutionLayerFixture, framework: ActivationFunctionsSmallDataset)) { // Validate output - validate(CLAccessor(_target), _reference, tolerance_f32, tolerance_num); + validate(CLAccessor(_target), _reference, tolerance_f32, tolerance_num_f32); } TEST_SUITE_END() // FP32 +TEST_SUITE(FP16) +FIXTURE_DATA_TEST_CASE(RunSmall, CLFFTConvolutionLayerFixture, framework::DatasetMode::PRECOMMIT, combine(combine(combine(datasets::SmallFFTConvolutionLayerDataset(), + framework::dataset::make("DataType", DataType::F16)), + framework::dataset::make("DataLayout", { DataLayout::NCHW, DataLayout::NHWC })), + ActivationFunctionsSmallDataset)) +{ + // Validate output + validate(CLAccessor(_target), _reference, tolerance_f16, tolerance_num_f16); +} +TEST_SUITE_END() // FP16 TEST_SUITE_END() // Float TEST_SUITE_END() // FFTConvolutionLayer diff --git a/tests/validation/fixtures/FFTFixture.h b/tests/validation/fixtures/FFTFixture.h index dad774ce51..564098497b 100644 --- a/tests/validation/fixtures/FFTFixture.h +++ b/tests/validation/fixtures/FFTFixture.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Arm Limited. + * Copyright (c) 2019-2020 Arm Limited. * * SPDX-License-Identifier: MIT * @@ -35,6 +35,8 @@ #include "tests/validation/reference/ConvolutionLayer.h" #include "tests/validation/reference/DFT.h" +#include "utils/Utils.h" + #include namespace arm_compute @@ -59,8 +61,23 @@ protected: template void fill(U &&tensor) { - std::uniform_real_distribution distribution(-5.f, 5.f); - library->fill(tensor, distribution, 0); + switch(tensor.data_type()) + { + case DataType::F16: + { + arm_compute::utils::uniform_real_distribution_fp16 distribution(half(-5.0f), half(5.0f)); + library->fill(tensor, distribution, 0); + break; + } + case DataType::F32: + { + std::uniform_real_distribution distribution(-5.0f, 5.0f); + library->fill(tensor, distribution, 0); + break; + } + default: + library->fill_tensor_uniform(tensor, 0); + } } TensorType compute_target(const TensorShape &shape, DataType data_type) @@ -134,9 +151,15 @@ protected: { switch(tensor.data_type()) { + case DataType::F16: + { + arm_compute::utils::uniform_real_distribution_fp16 distribution(half(-1.0f), half(1.0f)); + library->fill(tensor, distribution, i); + break; + } case DataType::F32: { - std::uniform_real_distribution<> distribution(-1.0f, 1.0f); + std::uniform_real_distribution distribution(-1.0f, 1.0f); library->fill(tensor, distribution, i); break; } @@ -166,7 +189,7 @@ protected: // Create and configure function FunctionType conv; - conv.configure(&src, &weights, &bias, &dst, info, act_info); + conv.configure(&src, &weights, &bias, &dst, info, act_info, _data_type == DataType::F16); ARM_COMPUTE_EXPECT(src.info()->is_resizable(), framework::LogLevel::ERRORS); ARM_COMPUTE_EXPECT(weights.info()->is_resizable(), framework::LogLevel::ERRORS); diff --git a/tests/validation/reference/DFT.cpp b/tests/validation/reference/DFT.cpp index 1f746eaeb7..b98bc77b1d 100644 --- a/tests/validation/reference/DFT.cpp +++ b/tests/validation/reference/DFT.cpp @@ -318,7 +318,7 @@ SimpleTensor ridft_1d(const SimpleTensor &src, bool is_odd) { auto dst = rdft_1d_core(src, FFTDirection::Inverse, is_odd); - const T scaling_factor = dst.shape()[0]; + const T scaling_factor = T(dst.shape()[0]); scale(dst, scaling_factor); return dst; @@ -330,7 +330,7 @@ SimpleTensor dft_1d(const SimpleTensor &src, FFTDirection direction) auto dst = dft_1d_core(src, direction); if(direction == FFTDirection::Inverse) { - const T scaling_factor = dst.shape()[0]; + const T scaling_factor = T(dst.shape()[0]); scale(dst, scaling_factor); } return dst; @@ -359,7 +359,7 @@ SimpleTensor ridft_2d(const SimpleTensor &src, bool is_odd) auto transposed_2 = permute(first_pass, PermutationVector(1U, 0U)); auto dst = rdft_1d_core(transposed_2, direction, is_odd); - const T scaling_factor = dst.shape()[0] * dst.shape()[1]; + const T scaling_factor = T(dst.shape()[0] * dst.shape()[1]); scale(dst, scaling_factor); return dst; } @@ -383,7 +383,7 @@ SimpleTensor dft_2d(const SimpleTensor &src, FFTDirection direction) auto transposed_2 = permute(first_pass, PermutationVector(1U, 0U)); auto dst = dft_1d_core(transposed_2, direction); - const T scaling_factor = dst.shape()[0] * dst.shape()[1]; + const T scaling_factor = T(dst.shape()[0] * dst.shape()[1]); scale(dst, scaling_factor); return dst; @@ -425,6 +425,7 @@ SimpleTensor conv2d_dft(const SimpleTensor &src, const SimpleTensor &w, return slice(conv_res, Coordinates(start_left, start_top), Coordinates(end_right, end_botton)); } +// FP32 template SimpleTensor rdft_1d(const SimpleTensor &src); template SimpleTensor ridft_1d(const SimpleTensor &src, bool is_odd); template SimpleTensor dft_1d(const SimpleTensor &src, FFTDirection direction); @@ -434,6 +435,17 @@ template SimpleTensor ridft_2d(const SimpleTensor &src, bool is_od template SimpleTensor dft_2d(const SimpleTensor &src, FFTDirection direction); template SimpleTensor conv2d_dft(const SimpleTensor &src, const SimpleTensor &w, const PadStrideInfo &conv_info); + +// FP16 +template SimpleTensor rdft_1d(const SimpleTensor &src); +template SimpleTensor ridft_1d(const SimpleTensor &src, bool is_odd); +template SimpleTensor dft_1d(const SimpleTensor &src, FFTDirection direction); + +template SimpleTensor rdft_2d(const SimpleTensor &src); +template SimpleTensor ridft_2d(const SimpleTensor &src, bool is_odd); +template SimpleTensor dft_2d(const SimpleTensor &src, FFTDirection direction); + +template SimpleTensor conv2d_dft(const SimpleTensor &src, const SimpleTensor &w, const PadStrideInfo &conv_info); } // namespace reference } // namespace validation } // namespace test -- cgit v1.2.1