| // |
| // Copyright © 2020 Arm Ltd and Contributors. All rights reserved. |
| // SPDX-License-Identifier: MIT |
| // |
| |
| #include "ActivationTestHelper.hpp" |
| |
| #include <armnn_delegate.hpp> |
| |
| #include <flatbuffers/flatbuffers.h> |
| #include <tensorflow/lite/interpreter.h> |
| #include <tensorflow/lite/kernels/register.h> |
| #include <tensorflow/lite/model.h> |
| #include <tensorflow/lite/schema/schema_generated.h> |
| #include <tensorflow/lite/version.h> |
| |
| #include <doctest/doctest.h> |
| |
| namespace armnnDelegate |
| { |
| |
| |
| void ActivationReLuTest(std::vector<armnn::BackendId>& backends) |
| { |
| std::vector<float> inputData = { |
| -0.1f, -0.2f, -0.3f, -0.4f, |
| 0.1f, 0.2f, 0.3f, 0.4f, |
| -1.0f, -2.0f, -3.0f, -4.0f, |
| 1.0f, 2.0f, 3.0f, 4.0f |
| }; |
| |
| // Calculate output values for input. |
| auto f = [](float value) |
| { |
| return std::fmax(0.0f, value); |
| }; |
| std::vector<float> outputExpectedData(inputData.size()); |
| std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); |
| |
| ActivationTest(tflite::BuiltinOperator_RELU, |
| backends, |
| inputData, |
| outputExpectedData); |
| } |
| |
| void ActivationBoundedReluTest(std::vector<armnn::BackendId>& backends) |
| { |
| std::vector<float> inputData = { |
| -0.1f, -0.2f, -0.3f, -0.4f, |
| 0.1f, 0.2f, 0.3f, 0.4f, |
| -1.0f, -2.0f, -3.0f, -4.0f, |
| 1.0f, 2.0f, 3.0f, 4.0f |
| }; |
| |
| const float a = 6.0f; |
| const float b = 0.0f; |
| // Calculate output values for input. |
| auto f = [a, b](float value) |
| { |
| return std::min(a, std::max(b, value)); |
| }; |
| std::vector<float> outputExpectedData(inputData.size()); |
| std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); |
| |
| ActivationTest(tflite::BuiltinOperator_RELU6, |
| backends, |
| inputData, |
| outputExpectedData); |
| } |
| |
| void ActivationSigmoidTest(std::vector<armnn::BackendId>& backends) |
| { |
| std::vector<float> inputData = { |
| -0.1f, -0.2f, -0.3f, -0.4f, |
| 0.1f, 0.2f, 0.3f, 0.4f, |
| -1.0f, -2.0f, -3.0f, -4.0f, |
| 1.0f, 2.0f, 3.0f, 4.0f |
| }; |
| |
| // Calculate output values for input. |
| auto f = [](float value) |
| { |
| return 1.0f / (1.0f + std::exp(-value)); |
| }; |
| std::vector<float> outputExpectedData(inputData.size()); |
| std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); |
| |
| ActivationTest(tflite::BuiltinOperator_LOGISTIC, |
| backends, |
| inputData, |
| outputExpectedData); |
| } |
| |
| |
| void ActivationTanHTest(std::vector<armnn::BackendId>& backends) |
| { |
| std::vector<float> inputData = { |
| -0.1f, -0.2f, -0.3f, -0.4f, |
| 0.1f, 0.2f, 0.3f, 0.4f, |
| -1.0f, -2.0f, -3.0f, -4.0f, |
| 1.0f, 2.0f, 3.0f, 4.0f |
| }; |
| |
| // Calculate output values for input. |
| auto f = [](float value) |
| { |
| return tanhf(value); |
| }; |
| std::vector<float> outputExpectedData(inputData.size()); |
| std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); |
| |
| ActivationTest(tflite::BuiltinOperator_TANH, |
| backends, |
| inputData, |
| outputExpectedData); |
| } |
| |
| void ActivationEluTest(std::vector<armnn::BackendId>& backends) |
| { |
| std::vector<float> inputData = { |
| -0.1f, -0.2f, -0.3f, -0.4f, |
| 0.1f, 0.2f, 0.3f, 0.4f, |
| -1.0f, -2.0f, -3.0f, -4.0f, |
| 1.0f, 2.0f, 3.0f, 4.0f |
| }; |
| |
| // Calculate output values for input. |
| auto f = [](float value) |
| { |
| if (value < 0) |
| { |
| // alpha * (exp(x) - 1) |
| return 1 * (std::exp(value) - 1); |
| } |
| return value; |
| }; |
| std::vector<float> outputExpectedData(inputData.size()); |
| std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); |
| |
| ActivationTest(tflite::BuiltinOperator_ELU, |
| backends, |
| inputData, |
| outputExpectedData); |
| } |
| |
| void ActivationHardSwishTest(std::vector<armnn::BackendId>& backends) |
| { |
| std::vector<float> inputData = { |
| -0.1f, -0.2f, -0.3f, -0.4f, |
| 0.1f, 0.2f, 0.3f, 0.4f, |
| -1.0f, -2.0f, -3.0f, -4.0f, |
| 1.0f, 2.0f, 3.0f, 4.0f |
| }; |
| |
| // Calculate output values for input. |
| auto f = [](float x) |
| { |
| // Break down the calculation to help with verification. |
| // hard_swish(x) = x * relu6(x+3) / 6 |
| // relu6(x) = min(max(x,0),6) |
| float reLu6_step1 = std::max((x + 3),0.0f); |
| float reLu6Complete = std::min(reLu6_step1, 6.0f); |
| float hardSwish_step1 = x * reLu6Complete; |
| float result = hardSwish_step1 / 6; |
| return result; |
| }; |
| std::vector<float> outputExpectedData(inputData.size()); |
| std::transform(inputData.begin(), inputData.end(), outputExpectedData.begin(), f); |
| |
| ActivationTest(tflite::BuiltinOperator_HARD_SWISH, |
| backends, |
| inputData, |
| outputExpectedData); |
| } |
| |
| TEST_SUITE("Activation_CpuRefTests") |
| { |
| |
| TEST_CASE ("Activation_ReLu_CpuRef_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef }; |
| ActivationReLuTest(backends); |
| } |
| |
| TEST_CASE ("Activation_Bounded_Relu6_CpuRef_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef }; |
| ActivationBoundedReluTest(backends); |
| } |
| |
| TEST_CASE ("Activation_Sigmoid_CpuRef_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef }; |
| ActivationSigmoidTest(backends); |
| } |
| |
| TEST_CASE ("Activation_TanH_CpuRef_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef }; |
| ActivationTanHTest(backends); |
| } |
| |
| TEST_CASE ("Activation_Elu_CpuRef_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef }; |
| ActivationEluTest(backends); |
| } |
| |
| TEST_CASE ("Activation_HardSwish_CpuRef_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::CpuRef }; |
| ActivationHardSwishTest(backends); |
| } |
| |
| } |
| |
| TEST_SUITE("Activation_CpuAccTests") |
| { |
| |
| TEST_CASE ("Activation_ReLu_CpuAcc_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc }; |
| ActivationReLuTest(backends); |
| } |
| |
| TEST_CASE ("Activation_Bounded_Relu6_CpuAcc_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc }; |
| ActivationBoundedReluTest(backends); |
| } |
| |
| TEST_CASE ("Activation_Sigmoid_CpuAcc_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc }; |
| ActivationSigmoidTest(backends); |
| } |
| |
| TEST_CASE ("Activation_TanH_CpuAcc_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc }; |
| ActivationTanHTest(backends); |
| } |
| |
| TEST_CASE ("Activation_Elu_CpuAcc_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc }; |
| ActivationEluTest(backends); |
| } |
| |
| TEST_CASE ("Activation_HardSwish_CpuAcc_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::CpuAcc }; |
| ActivationHardSwishTest(backends); |
| } |
| |
| } |
| |
| TEST_SUITE("Activation_GpuAccTests") |
| { |
| |
| TEST_CASE ("Activation_ReLu_GpuAcc_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc }; |
| ActivationReLuTest(backends); |
| } |
| |
| TEST_CASE ("Activation_Bounded_Relu6_GpuAcc_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc }; |
| ActivationBoundedReluTest(backends); |
| } |
| |
| TEST_CASE ("Activation_Sigmoid_GpuAcc_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc }; |
| ActivationSigmoidTest(backends); |
| } |
| |
| TEST_CASE ("Activation_TanH_GpuAcc_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc }; |
| ActivationTanHTest(backends); |
| } |
| |
| TEST_CASE ("Activation_Elu_GpuAcc_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc }; |
| ActivationEluTest(backends); |
| } |
| |
| TEST_CASE ("Activation_HardSwish_GpuAcc_Test") |
| { |
| std::vector<armnn::BackendId> backends = { armnn::Compute::GpuAcc }; |
| ActivationHardSwishTest(backends); |
| } |
| |
| } |
| |
| } // namespace armnnDelegate |