diff options
author | Sadik Armagan <sadik.armagan@arm.com> | 2021-03-25 07:46:55 +0000 |
---|---|---|
committer | Sadik Armagan <sadik.armagan@arm.com> | 2021-03-25 07:46:55 +0000 |
commit | f0a6dec75832604d5ab18242dc216852821a8279 (patch) | |
tree | ff25e64c62c63975a54abd16a8bff744be70d7c0 /src/backends/backendsCommon/test | |
parent | 16fb1a2d9c1d3d80c0f0b6ab549919fbabd2a0b9 (diff) | |
download | armnn-f0a6dec75832604d5ab18242dc216852821a8279.tar.gz |
IVGCVSW-5736 and IVGCVSW-5743 'NonConstWeights: Update front-end and TfLiteDelegate support for FullyConnected Operator'
* Added front-end support for non-const weights for FULLY_CONNECTED operator
* Added FULLY_CONNECTED end-to-end test
* Updated FULLY_CONNECTED operator support in TfLite Arm NN Delegate for non-const weights
* Updated the version numbers
Signed-off-by: Sadik Armagan <sadik.armagan@arm.com>
Change-Id: Iffa5b9aa9297aca4c02d923cce4636c88ac21faa
Diffstat (limited to 'src/backends/backendsCommon/test')
5 files changed, 209 insertions, 13 deletions
diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt index f92e0745d3..d3857b8357 100644 --- a/src/backends/backendsCommon/test/CMakeLists.txt +++ b/src/backends/backendsCommon/test/CMakeLists.txt @@ -23,6 +23,7 @@ list(APPEND armnnBackendsCommonUnitTests_sources ElementwiseUnaryEndToEndTestImpl.hpp EndToEndTestImpl.hpp FillEndToEndTestImpl.hpp + FullyConnectedEndToEndTestImpl.hpp GatherEndToEndTestImpl.hpp InstanceNormalizationEndToEndTestImpl.cpp InstanceNormalizationEndToEndTestImpl.hpp diff --git a/src/backends/backendsCommon/test/CompatibilityTests.cpp b/src/backends/backendsCommon/test/CompatibilityTests.cpp index b69e11253d..1c4ff709fa 100644 --- a/src/backends/backendsCommon/test/CompatibilityTests.cpp +++ b/src/backends/backendsCommon/test/CompatibilityTests.cpp @@ -7,6 +7,7 @@ #include <cl/ClBackend.hpp> #include <neon/NeonBackend.hpp> +#include <reference/RefBackend.hpp> #include <Network.hpp> @@ -115,3 +116,18 @@ BOOST_AUTO_TEST_CASE(Neon_Cl_DirectCompatibility_Test) } BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(BackendCapability) + +BOOST_AUTO_TEST_CASE(Backends_Capability_Test) +{ + auto neonBackend = std::make_unique<NeonBackend>(); + auto clBackend = std::make_unique<ClBackend>(); + auto refBackend = std::make_unique<RefBackend>(); + + BOOST_CHECK(!neonBackend->HasCapability(armnn::BackendCapability::NonConstWeights)); + BOOST_CHECK(!clBackend->HasCapability(armnn::BackendCapability::NonConstWeights)); + BOOST_CHECK(refBackend->HasCapability(armnn::BackendCapability::NonConstWeights)); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/backends/backendsCommon/test/FullyConnectedEndToEndTestImpl.hpp b/src/backends/backendsCommon/test/FullyConnectedEndToEndTestImpl.hpp new file mode 100644 index 0000000000..5a618c32e1 --- /dev/null +++ b/src/backends/backendsCommon/test/FullyConnectedEndToEndTestImpl.hpp @@ -0,0 +1,97 @@ +// +// Copyright © 2021 Arm Ltd and Contributors. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include "CommonTestUtils.hpp" + +#include <ResolveType.hpp> + +#include <armnn/INetwork.hpp> + +#include <armnn/utility/NumericCast.hpp> + +#include <boost/test/unit_test.hpp> + +#include <vector> + +namespace +{ + +armnn::INetworkPtr CreateFullyConnectedNetworkNonConstWeights(const armnn::TensorInfo& inputTensorInfo, + const armnn::TensorInfo& outputTensorInfo, + const armnn::TensorInfo& weightsTensorInfo, + armnn::FullyConnectedDescriptor descriptor) +{ + armnn::INetworkPtr network(armnn::INetwork::Create()); + + armnn::IConnectableLayer* inputLayer = network->AddInputLayer(0, "Input"); + armnn::IConnectableLayer* weightsInputLayer = network->AddInputLayer(1, "Weights_Input"); + armnn::IConnectableLayer* fullyConnectedLayer = network->AddFullyConnectedLayer(descriptor, + armnn::EmptyOptional(), + armnn::EmptyOptional(), + "Fully_Connected"); + armnn::IConnectableLayer* outputLayer = network->AddOutputLayer(0, "Output"); + + Connect(inputLayer, fullyConnectedLayer, inputTensorInfo, 0, 0); + Connect(weightsInputLayer, fullyConnectedLayer, weightsTensorInfo, 0, 1); + Connect(fullyConnectedLayer, outputLayer, outputTensorInfo, 0, 0); + + return network; +} + +template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>> +void FullyConnectedWithDynamicWeightsEndToEnd(const std::vector<armnn::BackendId>& backends) +{ + using namespace armnn; + + armnn::TensorInfo inputTensorInfo({ 1, 1, 2, 3 }, ArmnnType); + inputTensorInfo.SetQuantizationScale(0.1f); + inputTensorInfo.SetQuantizationOffset(63); + + armnn::TensorInfo outputTensorInfo({ 1, 2 }, ArmnnType); + outputTensorInfo.SetQuantizationScale(5.f); + outputTensorInfo.SetQuantizationOffset(10); + + armnn::TensorInfo weightsTensorInfo({ 2, 6 }, ArmnnType); + weightsTensorInfo.SetQuantizationScale(0.2f); + weightsTensorInfo.SetQuantizationOffset(93); + + FullyConnectedDescriptor descriptor; + descriptor.m_ConstantWeights = false; + descriptor.m_BiasEnabled = false; + descriptor.m_TransposeWeightMatrix = true; + + std::vector<T> inputData { + -1.2f, 6.1f, -3.5f, + 18.8f, -5.5f, 2.9f + }; + + std::vector<T> weightsData { + -8.4f, 20.0f, -10.4f, -8, 16.4f, -11.8f, + 23.4f, 10.4f, -14.0f, -3.8f, -11.8f, 11.4f + }; + + std::vector<T> floatExpectedOutputData { + -107.04f, 110.f + }; + std::vector<T> expectedOutputData = armnnUtils::QuantizedVector<T>(floatExpectedOutputData); + + armnn::INetworkPtr network = CreateFullyConnectedNetworkNonConstWeights(inputTensorInfo, + outputTensorInfo, + weightsTensorInfo, + descriptor); + + BOOST_TEST_CHECKPOINT("create a network"); + + std::map<int, std::vector<T>> inputTensorData = {{ 0, inputData }, {1, weightsData}}; + std::map<int, std::vector<T>> expectedOutputTensorData = {{ 0, expectedOutputData }}; + + EndToEndLayerTestImpl<ArmnnType, ArmnnType>(move(network), + inputTensorData, + expectedOutputTensorData, + backends, + 1.0f); +} +} // anonymous namespace diff --git a/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.cpp index c9e2e1602d..9176094eb2 100644 --- a/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.cpp +++ b/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.cpp @@ -67,12 +67,70 @@ LayerTestResult<T, 2> SimpleFullyConnectedTestImpl( return result; } +template<typename T, typename B> +LayerTestResult<T, 2> SimpleFullyConnectedTestWeightsAsInputsImpl( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + const armnn::ITensorHandleFactory& tensorHandleFactory, + armnn::TensorInfo inputTensorInfo, + armnn::TensorInfo outputTensorInfo, + armnn::TensorInfo weightsTensorInfo, + armnn::TensorInfo biasesTensorInfo, + boost::multi_array<T, 2>& weights, + boost::multi_array<B, 1>& bias, + boost::multi_array<T, 4>& input, + bool biasEnabled, + bool transposeWeights) +{ + std::unique_ptr<armnn::ITensorHandle> input0Handle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo); + std::unique_ptr<armnn::ITensorHandle> input1Handle = tensorHandleFactory.CreateTensorHandle(weightsTensorInfo); + std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo); + + armnn::FullyConnectedQueueDescriptor data; + armnn::WorkloadInfo info; + + AddInputToWorkload(data, info, inputTensorInfo, input0Handle.get()); + AddInputToWorkload(data, info, weightsTensorInfo, input1Handle.get()); + AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get()); + data.m_Parameters.m_BiasEnabled = biasEnabled; + data.m_Parameters.m_TransposeWeightMatrix = transposeWeights; + data.m_Parameters.m_ConstantWeights = false; + + std::unique_ptr<armnn::ITensorHandle> input2Handle = nullptr; + if (biasEnabled) + { + input2Handle = tensorHandleFactory.CreateTensorHandle(biasesTensorInfo); + AddInputToWorkload(data, info, biasesTensorInfo, input2Handle.get()); + } + + std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateFullyConnected(data, info); + LayerTestResult<T, 2> result(outputTensorInfo); + + input0Handle->Allocate(); + input1Handle->Allocate(); + outputHandle->Allocate(); + CopyDataToITensorHandle(input0Handle.get(), &input[0][0][0][0]); + CopyDataToITensorHandle(input1Handle.get(), &weights[0][0]); + if (biasEnabled) + { + input2Handle->Allocate(); + CopyDataToITensorHandle(input2Handle.get(), &bias[0]); + } + + ExecuteWorkload(*workload, memoryManager); + + CopyDataFromITensorHandle(&result.output[0][0], outputHandle.get()); + + return result; +} + template<armnn::DataType ArmnnType, typename T> LayerTestResult<T, 2> FullyConnectedTest( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, - bool biasEnabled) + bool biasEnabled, + bool constantWeights) { constexpr static unsigned int inputWidth = 3u; constexpr static unsigned int inputHeight = 2u; @@ -116,15 +174,36 @@ LayerTestResult<T, 2> FullyConnectedTest( auto bias = MakeTensor<int32_t, 1>(biasesDesc, std::vector<int32_t>{9250, 67500}); - result = SimpleFullyConnectedTestImpl<T>( - workloadFactory, - memoryManager, - tensorHandleFactory, - inputTensorInfo, outputTensorInfo, - weightsDesc, biasesDesc, - weights, bias, input, - biasEnabled, true - ); + if (constantWeights) + { + result = SimpleFullyConnectedTestImpl<T>(workloadFactory, + memoryManager, + tensorHandleFactory, + inputTensorInfo, + outputTensorInfo, + weightsDesc, + biasesDesc, + weights, + bias, + input, + biasEnabled, + true); + } + else + { + result = SimpleFullyConnectedTestWeightsAsInputsImpl<T>(workloadFactory, + memoryManager, + tensorHandleFactory, + inputTensorInfo, + outputTensorInfo, + weightsDesc, + biasesDesc, + weights, + bias, + input, + biasEnabled, + true); + } if (biasEnabled) { @@ -237,14 +316,16 @@ FullyConnectedTest<armnn::DataType::QAsymmU8>( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, - bool biasEnabled); + bool biasEnabled, + bool constWeights); template LayerTestResult<armnn::ResolveType<armnn::DataType::QSymmS16>, 2> FullyConnectedTest<armnn::DataType::QSymmS16>( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, - bool biasEnabled); + bool biasEnabled, + bool constWeights); // // Implementation functions diff --git a/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.hpp index c2d53a5178..ec921f7dd5 100644 --- a/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.hpp +++ b/src/backends/backendsCommon/test/layerTests/FullyConnectedTestImpl.hpp @@ -17,7 +17,8 @@ LayerTestResult<T, 2> FullyConnectedTest( armnn::IWorkloadFactory& workloadFactory, const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, const armnn::ITensorHandleFactory& tensorHandleFactory, - bool biasEnabled); + bool biasEnabled, + bool constantWeights); LayerTestResult<float, 2> FullyConnectedFloat32Test( armnn::IWorkloadFactory& workloadFactory, |