aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arm_compute/core/Types.h3
-rw-r--r--src/core/NEON/kernels/NEActivationLayerKernel.cpp31
-rw-r--r--tests/validation/NEON/ActivationLayer.cpp6
-rw-r--r--tests/validation/reference/ActivationLayer.h5
-rw-r--r--utils/TypePrinter.h4
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!");
}