aboutsummaryrefslogtreecommitdiff
path: root/src/backends/backendsCommon/test/layerTests
diff options
context:
space:
mode:
authorTeresa Charlin <teresa.charlinreyes@arm.com>2023-08-17 18:44:58 +0100
committerTeresa Charlin <teresa.charlinreyes@arm.com>2023-08-28 12:37:25 +0100
commit9145e38edf49fa4862008c163c34590141eecb14 (patch)
tree64706ef579f548b804d5b674b33f6b239c638d0f /src/backends/backendsCommon/test/layerTests
parente40cc8359b02a7786908294300c45b672cf6b0e4 (diff)
downloadarmnn-9145e38edf49fa4862008c163c34590141eecb14.tar.gz
IVGCVSW-7505 Create FusedLayer and NeonFusedWorkload for AddMulAdd Neon kernel
Signed-off-by: Teresa Charlin <teresa.charlinreyes@arm.com> Change-Id: Ic778d35b001474b44fb1e433a6fe276e4ec9f565
Diffstat (limited to 'src/backends/backendsCommon/test/layerTests')
-rw-r--r--src/backends/backendsCommon/test/layerTests/AddMulAddTestImpl.hpp182
1 files changed, 182 insertions, 0 deletions
diff --git a/src/backends/backendsCommon/test/layerTests/AddMulAddTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/AddMulAddTestImpl.hpp
new file mode 100644
index 0000000000..9dece9be3b
--- /dev/null
+++ b/src/backends/backendsCommon/test/layerTests/AddMulAddTestImpl.hpp
@@ -0,0 +1,182 @@
+//
+// Copyright © 2023 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include <armnnTestUtils/LayerTestResult.hpp>
+
+#include <armnnUtils/QuantizeHelper.hpp>
+#include <ResolveType.hpp>
+
+#include <armnn/backends/IBackendInternal.hpp>
+#include <armnn/backends/WorkloadFactory.hpp>
+
+#include <armnnTestUtils/TensorCopyUtils.hpp>
+#include <backendsCommon/test/WorkloadFactoryHelper.hpp>
+#include <armnnTestUtils/WorkloadTestUtils.hpp>
+
+#include <armnnTestUtils/TensorHelpers.hpp>
+
+template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
+std::vector<LayerTestResult<T,4>> AddMulAddTest(armnn::IWorkloadFactory& workloadFactory,
+ const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
+ const armnn::ITensorHandleFactory& tensorHandleFactory,
+ bool addOutput)
+{
+ using namespace armnn;
+ IgnoreUnused(memoryManager);
+
+ TensorInfo input0TensorInfo({ 1, 2, 2, 3 }, ArmnnType);
+ TensorInfo input1TensorInfo({ 1, 2, 2, 3 }, ArmnnType);
+ TensorInfo mulInput1TensorInfo({ 3 }, ArmnnType);
+ TensorInfo addInput1TensorInfo({ 3 }, ArmnnType);
+
+ TensorInfo output0TensorInfo({ 1, 2, 2, 3 }, ArmnnType);
+ TensorInfo output1TensorInfo({ 1, 2, 2, 3 }, ArmnnType);
+
+ if (IsQuantizedType<T>())
+ {
+ input0TensorInfo.SetQuantizationScale(0.25f);
+ input0TensorInfo.SetQuantizationOffset(128);
+ input1TensorInfo.SetQuantizationScale(0.25f);
+ input1TensorInfo.SetQuantizationOffset(128);
+ mulInput1TensorInfo.SetQuantizationScale(0.25f);
+ mulInput1TensorInfo.SetQuantizationOffset(128);
+ addInput1TensorInfo.SetQuantizationScale(0.25f);
+ addInput1TensorInfo.SetQuantizationOffset(128);
+
+ output0TensorInfo.SetQuantizationScale(0.5f);
+ output0TensorInfo.SetQuantizationOffset(120);
+ output1TensorInfo.SetQuantizationScale(0.5f);
+ output1TensorInfo.SetQuantizationOffset(120);
+ }
+
+ std::vector<float> input0Data
+ {
+ 0.0f, 0.0f, 0.0f,
+ 1.0f, 1.0f, 1.0f,
+ -1.0f, -1.0f, -1.0f,
+ -2.0f, -2.0f, -2.0f
+ };
+ std::vector<float> input1Data
+ {
+ 0.0f, 0.0f, 0.0f,
+ 1.0f, 1.0f, 1.0f,
+ -1.0f, -1.0f, -1.0f,
+ -2.0f, -2.0f, -2.0f
+ };
+ std::vector<float> mulInput1Data
+ {
+ 2.0f, 1.0f, 1.0f
+ };
+ std::vector<float> addInput1Data
+ {
+ 3.0f, 0.0f, 0.0f
+ };
+ std::vector<float> output0ExpectedData =
+ {
+ 0.0f, 0.0f, 0.0f,
+ 2.0f, 2.0f, 2.0f,
+ -2.0f, -2.0f, -2.0f,
+ -4.0f, -4.0f, -4.0f
+ };
+
+ std::vector<float> output1ExpectedData =
+ {
+ 3.0f, 0.0f, 0.0f,
+ 7.0f, 2.0f, 2.0f,
+ -1.0f, -2.0f, -2.0f,
+ -5.0f, -4.0f, -4.0f
+ };
+
+ std::vector<T> input0 = armnnUtils::QuantizedVector<T>(input0Data,
+ input0TensorInfo.GetQuantizationScale(),
+ input0TensorInfo.GetQuantizationOffset());
+
+ std::vector<T> input1 = armnnUtils::QuantizedVector<T>(input1Data,
+ input1TensorInfo.GetQuantizationScale(),
+ input1TensorInfo.GetQuantizationOffset());
+
+ std::vector<T> mulInput1 = armnnUtils::QuantizedVector<T>(mulInput1Data,
+ mulInput1TensorInfo.GetQuantizationScale(),
+ mulInput1TensorInfo.GetQuantizationOffset());
+
+ std::vector<T> addInput1 = armnnUtils::QuantizedVector<T>(addInput1Data,
+ addInput1TensorInfo.GetQuantizationScale(),
+ addInput1TensorInfo.GetQuantizationOffset());
+
+ std::vector<T> output0Expected = armnnUtils::QuantizedVector<T>(output0ExpectedData,
+ output0TensorInfo.GetQuantizationScale(),
+ output0TensorInfo.GetQuantizationOffset());
+
+ std::vector<T> output1Expected = armnnUtils::QuantizedVector<T>(output1ExpectedData,
+ output1TensorInfo.GetQuantizationScale(),
+ output1TensorInfo.GetQuantizationOffset());
+
+ std::vector<T> output0Actual(output0TensorInfo.GetNumElements());
+ std::vector<T> output1Actual(output1TensorInfo.GetNumElements());
+
+ std::unique_ptr<ITensorHandle> input0Handle = tensorHandleFactory.CreateTensorHandle(input0TensorInfo);
+ std::unique_ptr<ITensorHandle> input1Handle = tensorHandleFactory.CreateTensorHandle(input1TensorInfo);
+ std::unique_ptr<ITensorHandle> mulInput1Handle = tensorHandleFactory.CreateTensorHandle(mulInput1TensorInfo);
+ std::unique_ptr<ITensorHandle> addInput1Handle = tensorHandleFactory.CreateTensorHandle(addInput1TensorInfo);
+ std::unique_ptr<ITensorHandle> output0Handle = tensorHandleFactory.CreateTensorHandle(output0TensorInfo);
+ std::unique_ptr<ITensorHandle> output1Handle = tensorHandleFactory.CreateTensorHandle(output1TensorInfo);
+
+ uint32_t numOutputs = addOutput ? 2 : 1;
+ FusedDescriptor descriptor(4, numOutputs, FusedKernelType::AddMulAdd);
+ FusedQueueDescriptor fusedQueueDescriptor;
+ fusedQueueDescriptor.m_Parameters = descriptor;
+ WorkloadInfo info;
+ AddInputToWorkload (fusedQueueDescriptor, info, input0TensorInfo, input0Handle.get());
+ AddInputToWorkload (fusedQueueDescriptor, info, input1TensorInfo, input1Handle.get());
+ AddInputToWorkload (fusedQueueDescriptor, info, mulInput1TensorInfo, mulInput1Handle.get());
+ AddInputToWorkload (fusedQueueDescriptor, info, addInput1TensorInfo, addInput1Handle.get());
+ if (addOutput)
+ {
+ AddOutputToWorkload(fusedQueueDescriptor, info, output0TensorInfo, output0Handle.get());
+ }
+ AddOutputToWorkload(fusedQueueDescriptor, info, output1TensorInfo, output1Handle.get());
+
+ std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(LayerType::Fused,
+ fusedQueueDescriptor,
+ info);
+
+ input0Handle->Allocate();
+ input1Handle->Allocate();
+ mulInput1Handle->Allocate();
+ addInput1Handle->Allocate();
+ if (addOutput)
+ {
+ output0Handle->Allocate();
+ }
+ output1Handle->Allocate();
+
+ CopyDataToITensorHandle(input0Handle.get(), input0.data());
+ CopyDataToITensorHandle(input1Handle.get(), input1.data());
+ CopyDataToITensorHandle(mulInput1Handle.get(), mulInput1.data());
+ CopyDataToITensorHandle(addInput1Handle.get(), addInput1.data());
+
+ workload->Execute();
+
+ CopyDataFromITensorHandle(output1Actual.data(), output1Handle.get());
+ LayerTestResult<T,4> ret1(output1Actual,
+ output1Expected,
+ output1Handle->GetShape(),
+ output1TensorInfo.GetShape());
+
+ std::vector<LayerTestResult<T,4>> ret = {ret1};
+
+ if (addOutput)
+ {
+ CopyDataFromITensorHandle(output0Actual.data(), output0Handle.get());
+ LayerTestResult<T,4> ret0(output0Actual,
+ output0Expected,
+ output0Handle->GetShape(),
+ output0TensorInfo.GetShape());
+ ret = {ret0, ret1};
+ }
+ return ret;
+}