diff options
author | morgolock <pablo.tello@arm.com> | 2020-02-27 11:46:28 +0000 |
---|---|---|
committer | Pablo Marquez <pablo.tello@arm.com> | 2020-02-28 11:29:30 +0000 |
commit | 07df3d4b85f42245abf97e1a889e1fb3ef8af359 (patch) | |
tree | 243f111c776d2e19fbdd555ccef28e5369705b41 | |
parent | cd5b4a30d4208f9eadce7e9942526e000f72ee97 (diff) | |
download | ComputeLibrary-07df3d4b85f42245abf97e1a889e1fb3ef8af359.tar.gz |
COMPMID-3079: Implement Hard-Swish in NEON.
Change-Id: I019e36f65b4d821009bada9c6cdebc096d893b54
Signed-off-by: morgolock <pablo.tello@arm.com>
Reviewed-on: https://review.mlplatform.org/c/ml/ComputeLibrary/+/2802
Tested-by: Arm Jenkins <bsgcomp@arm.com>
Comments-Addressed: Arm Jenkins <bsgcomp@arm.com>
Reviewed-by: Michele Di Giorgio <michele.digiorgio@arm.com>
-rw-r--r-- | arm_compute/core/Types.h | 3 | ||||
-rw-r--r-- | src/core/NEON/kernels/NEActivationLayerKernel.cpp | 31 | ||||
-rw-r--r-- | tests/validation/NEON/ActivationLayer.cpp | 6 | ||||
-rw-r--r-- | tests/validation/reference/ActivationLayer.h | 5 | ||||
-rw-r--r-- | utils/TypePrinter.h | 4 |
5 files changed, 36 insertions, 13 deletions
diff --git a/arm_compute/core/Types.h b/arm_compute/core/Types.h index a4e629ce6c..2030b171c6 100644 --- a/arm_compute/core/Types.h +++ b/arm_compute/core/Types.h @@ -1630,7 +1630,8 @@ public: SQUARE, /**< Square ( \f$ f(x)= x^2 \f$ )*/ SQRT, /**< Square root ( \f$ f(x) = \sqrt{x} \f$ )*/ LINEAR, /**< Linear ( \f$ f(x)= ax + b \f$ ) */ - IDENTITY /**< Identity ( \f$ f(x)= x \f$ ) */ + IDENTITY, /**< Identity ( \f$ f(x)= x \f$ ) */ + HARD_SWISH /**< Hard-swish ( \f$ f(x) = (x * relu6(x+3))/6 \f$ ) */ }; ActivationLayerInfo() = default; diff --git a/src/core/NEON/kernels/NEActivationLayerKernel.cpp b/src/core/NEON/kernels/NEActivationLayerKernel.cpp index 44f76f6e22..a0bf9e8010 100644 --- a/src/core/NEON/kernels/NEActivationLayerKernel.cpp +++ b/src/core/NEON/kernels/NEActivationLayerKernel.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 ARM Limited. + * Copyright (c) 2017-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -156,6 +156,8 @@ void NEActivationLayerKernel::configure(ITensor *input, ITensor *output, Activat { ActivationFunction::SQUARE, &NEActivationLayerKernel::activation<ActivationFunction::SQUARE, float> }, { ActivationFunction::TANH, &NEActivationLayerKernel::activation<ActivationFunction::TANH, float> }, { ActivationFunction::IDENTITY, &NEActivationLayerKernel::activation<ActivationFunction::IDENTITY, float> }, + { ActivationFunction::HARD_SWISH, &NEActivationLayerKernel::activation<ActivationFunction::HARD_SWISH, float> }, + }; #ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC @@ -175,6 +177,8 @@ void NEActivationLayerKernel::configure(ITensor *input, ITensor *output, Activat { ActivationFunction::SQUARE, &NEActivationLayerKernel::activation<ActivationFunction::SQUARE, float16_t> }, { ActivationFunction::TANH, &NEActivationLayerKernel::activation<ActivationFunction::TANH, float16_t> }, { ActivationFunction::IDENTITY, &NEActivationLayerKernel::activation<ActivationFunction::IDENTITY, float16_t> }, + { ActivationFunction::HARD_SWISH, &NEActivationLayerKernel::activation<ActivationFunction::HARD_SWISH, float16_t> }, + }; #endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC*/ @@ -254,14 +258,17 @@ NEActivationLayerKernel::activation(const Window &window) Iterator input(_input, win_collapsed); Iterator output(_output, win_collapsed); - const auto epsilon = wrapper::vdup_n(static_cast<T>(1e-24), ExactTagType{}); - const auto const_1 = wrapper::vdup_n(static_cast<T>(1.f), ExactTagType{}); - const auto const_0 = wrapper::vdup_n(static_cast<T>(0.f), ExactTagType{}); - const auto va = wrapper::vdup_n(static_cast<T>(_act_info.a()), ExactTagType{}); - const auto vb = wrapper::vdup_n(static_cast<T>(_act_info.b()), ExactTagType{}); - const auto a = static_cast<T>(_act_info.a()); - const auto b = static_cast<T>(_act_info.b()); - + const auto epsilon = wrapper::vdup_n(static_cast<T>(1e-24), ExactTagType{}); + const auto const_1 = wrapper::vdup_n(static_cast<T>(1.f), ExactTagType{}); + const auto const_0 = wrapper::vdup_n(static_cast<T>(0.f), ExactTagType{}); + const auto const_6 = wrapper::vdup_n(static_cast<T>(6.f), ExactTagType{}); + const auto const_3 = wrapper::vdup_n(static_cast<T>(3.f), ExactTagType{}); + const auto const_inv_6 = wrapper::vdup_n(static_cast<T>(0.166666667f), ExactTagType{}); + + const auto va = wrapper::vdup_n(static_cast<T>(_act_info.a()), ExactTagType{}); + const auto vb = wrapper::vdup_n(static_cast<T>(_act_info.b()), ExactTagType{}); + const auto a = static_cast<T>(_act_info.a()); + const auto b = static_cast<T>(_act_info.b()); execute_window_loop(win_collapsed, [&](const Coordinates &) { const auto input_ptr = reinterpret_cast<const T *>(input.ptr()); @@ -315,6 +322,9 @@ NEActivationLayerKernel::activation(const Window &window) case ActivationFunction::IDENTITY: tmp = vin; break; + case ActivationFunction::HARD_SWISH: + tmp = wrapper::vmul(vin, wrapper::vmul(const_inv_6, wrapper::vmin(const_6, wrapper::vmax(const_0, wrapper::vadd(vin, const_3))))); + break; default: ARM_COMPUTE_ERROR("Unsupported activation function"); } @@ -367,6 +377,9 @@ NEActivationLayerKernel::activation(const Window &window) case ActivationFunction::IDENTITY: tmp = in; break; + case ActivationFunction::HARD_SWISH: + tmp = in * ((std::min(std::max((in + 3), 0.0f), 6.0f)) * 0.166666667f); + break; default: ARM_COMPUTE_ERROR("Unsupported activation function"); } diff --git a/tests/validation/NEON/ActivationLayer.cpp b/tests/validation/NEON/ActivationLayer.cpp index 1b9278988a..e3082cb5dc 100644 --- a/tests/validation/NEON/ActivationLayer.cpp +++ b/tests/validation/NEON/ActivationLayer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 ARM Limited. + * Copyright (c) 2017-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -117,8 +117,10 @@ const auto CNNDataTypes = framework::dataset::make("DataType", DataType::F32, }); +const auto NeonActivationFunctionsDataset = concat(datasets::ActivationFunctions(), framework::dataset::make("ActivationFunction", ActivationLayerInfo::ActivationFunction::HARD_SWISH) ); + /** Input data sets. */ -const auto ActivationDataset = combine(combine(framework::dataset::make("InPlace", { false, true }), datasets::ActivationFunctions()), framework::dataset::make("AlphaBeta", { 0.5f, 1.f })); +const auto ActivationDataset = combine(combine(framework::dataset::make("InPlace", { false, true }), NeonActivationFunctionsDataset), framework::dataset::make("AlphaBeta", { 0.5f, 1.f })); } // namespace TEST_SUITE(NEON) diff --git a/tests/validation/reference/ActivationLayer.h b/tests/validation/reference/ActivationLayer.h index cd861d7715..f41e87123e 100644 --- a/tests/validation/reference/ActivationLayer.h +++ b/tests/validation/reference/ActivationLayer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 ARM Limited. + * Copyright (c) 2017-2020 ARM Limited. * * SPDX-License-Identifier: MIT * @@ -81,6 +81,9 @@ inline T activate_float(T x, T a, T b, ActivationLayerInfo::ActivationFunction a case ActivationLayerInfo::ActivationFunction::IDENTITY: ret = x; break; + case ActivationLayerInfo::ActivationFunction::HARD_SWISH: + ret = x * ((std::min(std::max((x + 3), 0.0f), 6.0f)) * 0.166666667f); + break; default: ARM_COMPUTE_ERROR("Unsupported activation function"); break; diff --git a/utils/TypePrinter.h b/utils/TypePrinter.h index 1831733ec0..50eb4753d1 100644 --- a/utils/TypePrinter.h +++ b/utils/TypePrinter.h @@ -391,6 +391,10 @@ inline ::std::ostream &operator<<(::std::ostream &os, const ActivationLayerInfo: case ActivationLayerInfo::ActivationFunction::IDENTITY: os << "IDENTITY"; break; + case ActivationLayerInfo::ActivationFunction::HARD_SWISH: + os << "HARD_SWISH"; + break; + default: ARM_COMPUTE_ERROR("NOT_SUPPORTED!"); } |