aboutsummaryrefslogtreecommitdiff
path: root/src/backends/backendsCommon/test
diff options
context:
space:
mode:
Diffstat (limited to 'src/backends/backendsCommon/test')
-rw-r--r--src/backends/backendsCommon/test/CMakeLists.txt1
-rw-r--r--src/backends/backendsCommon/test/DepthwiseConvolution2dEndToEndTests.hpp183
-rw-r--r--src/backends/backendsCommon/test/OptimizationViewsTests.cpp6
-rw-r--r--src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.cpp143
4 files changed, 303 insertions, 30 deletions
diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt
index 06d230b006..991f37d17e 100644
--- a/src/backends/backendsCommon/test/CMakeLists.txt
+++ b/src/backends/backendsCommon/test/CMakeLists.txt
@@ -21,6 +21,7 @@ list(APPEND armnnBackendsCommonUnitTests_sources
DataTypeUtils.hpp
DefaultAsyncExecuteTest.cpp
DepthToSpaceEndToEndTestImpl.hpp
+ DepthwiseConvolution2dEndToEndTests.hpp
DequantizeEndToEndTestImpl.hpp
DetectionPostProcessEndToEndTestImpl.hpp
DynamicBackendTests.cpp
diff --git a/src/backends/backendsCommon/test/DepthwiseConvolution2dEndToEndTests.hpp b/src/backends/backendsCommon/test/DepthwiseConvolution2dEndToEndTests.hpp
new file mode 100644
index 0000000000..1f9b60a4f2
--- /dev/null
+++ b/src/backends/backendsCommon/test/DepthwiseConvolution2dEndToEndTests.hpp
@@ -0,0 +1,183 @@
+//
+// Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+
+#include "EndToEndTestImpl.hpp"
+#include <armnnUtils/QuantizeHelper.hpp>
+
+#include <ResolveType.hpp>
+
+#include <CommonTestUtils.hpp>
+#include <armnnTestUtils/DataLayoutUtils.hpp>
+
+#include <map>
+#include <vector>
+
+namespace
+{
+
+armnn::INetworkPtr CreateDepthwiseConvolution2dNetwork(const armnn::DepthwiseConvolution2dDescriptor& descriptor,
+ const armnn::TensorInfo& inputInfo,
+ const armnn::TensorInfo& weightsInfo,
+ const armnn::TensorInfo& biasInfo,
+ const armnn::TensorInfo& outputInfo,
+ const armnn::ConstTensor& weights,
+ const armnn::ConstTensor& biases)
+{
+ using namespace armnn;
+
+ INetworkPtr network(INetwork::Create());
+ IConnectableLayer* input = network->AddInputLayer(0, "input");
+ armnn::IConnectableLayer* weightsLayer = network->AddConstantLayer(weights, "Weights");
+ armnn::IConnectableLayer* biasLayer = network->AddConstantLayer(biases, "Bias");
+ IConnectableLayer* convolution2d = network->AddDepthwiseConvolution2dLayer(descriptor, "depthwiseConvolution2d");
+ IConnectableLayer* output = network->AddOutputLayer(0, "output");
+
+ Connect(input, convolution2d, inputInfo, 0, 0);
+ Connect(weightsLayer, convolution2d, weightsInfo, 0, 1);
+ Connect(biasLayer, convolution2d, biasInfo, 0, 2);
+ Connect(convolution2d, output, outputInfo, 0, 0);
+
+ return network;
+}
+
+} // anonymous namespace
+
+template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType>
+void DepthwiseConvolution2dEndToEnd(const std::vector<armnn::BackendId>& backends,
+ armnn::DataLayout dataLayout)
+{
+ using namespace armnn;
+ using T = ResolveType<ArmnnType>;
+ using BT = ResolveType<ArmnnBType>;
+
+ const float qScale = IsQuantizedType<T>() ? 0.25f : 1.0f;
+ const int32_t qOffset = IsQuantizedType<T>() ? 50 : 0;
+
+ unsigned int depthMultiplier = 2;
+
+ unsigned int inputHeight = 8;
+ unsigned int inputWidth = 16;
+ unsigned int inputChannels = 2;
+ unsigned int inputBatchSize = 1;
+
+ unsigned int kernelHeight = 5;
+ unsigned int kernelWidth = 3;
+
+ unsigned int outputHeight = inputHeight - kernelHeight + 1 + 2;
+ unsigned int outputWidth = (inputWidth - kernelWidth + 1)/2;
+ unsigned int outputChannels = inputChannels * depthMultiplier;
+ unsigned int outputBatchSize = inputBatchSize;
+
+ TensorInfo inputInfo({ inputBatchSize, inputChannels, inputHeight, inputWidth }, ArmnnType, qScale, qOffset, true);
+ TensorInfo outputInfo({ outputBatchSize, outputChannels, outputHeight, outputWidth }, ArmnnType, qScale, qOffset);
+ TensorInfo weightsInfo({1, kernelHeight, kernelWidth, outputChannels}, ArmnnType, qScale, qOffset, true);
+ TensorInfo biasesInfo({outputChannels}, ArmnnBType, qScale * qScale, 0, true);
+
+ std::vector<float> inputData =
+ {
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
+ };
+
+ std::vector<float> weightsData =
+ {
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, -1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f,
+ 1.0f, 1.0f, 1.0f,
+
+ 2.0f, 2.0f, 2.0f,
+ 2.0f, 2.0f, 2.0f,
+ 2.0f, 2.0f, 2.0f,
+ 2.0f, 2.0f, 2.0f,
+ 2.0f, 2.0f, 2.0f,
+
+ 0.0f, 0.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f,
+
+ 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f
+ };
+
+ std::vector<float> biasesData = { 0.0f, 2.0f, 1.0f, -1.0f };
+
+ std::vector<float> expectedOutputData =
+ {
+ 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f, 3.0f,
+ 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.5f, 5.5f, 5.5f, 5.5f, 5.5f, 5.5f, 5.5f,
+ 5.5f, 5.5f, 5.5f, 5.5f, 5.5f, 5.5f, 5.5f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f, 5.0f,
+ 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 2.5f, 3.5f, 3.5f, 3.5f, 3.5f, 3.5f, 3.5f, 3.5f,
+ 4.5f, 4.5f, 4.5f, 4.5f, 4.5f, 4.5f, 4.5f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
+ 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f, 6.0f,
+ 1.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, 4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 2.0f, 4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, 4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 2.0f, 4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 2.0f, 4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 2.0f, 4.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 3.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 3.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 3.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ 3.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 3.0f, 5.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
+ };
+
+ DepthwiseConvolution2dDescriptor descriptor;
+ descriptor.m_PadLeft = 0;
+ descriptor.m_PadRight = 0;
+ descriptor.m_PadTop = 1;
+ descriptor.m_PadBottom = 0;
+ descriptor.m_StrideX = 2;
+ descriptor.m_StrideY = 1;
+ descriptor.m_BiasEnabled = true;
+ descriptor.m_DataLayout = dataLayout;
+
+ // Permute input and output if NCDHW.
+ if (dataLayout == DataLayout::NCHW)
+ {
+ PermuteTensorNhwcToNchw(inputInfo, inputData);
+ PermuteTensorNhwcToNchw(outputInfo, expectedOutputData);
+ }
+
+ // Quantize data
+ std::vector<T> qInputData = armnnUtils::QuantizedVector<T>(inputData, qScale, qOffset);
+ std::vector<T> qWeightsData = armnnUtils::QuantizedVector<T>(weightsData, qScale, qOffset);
+ std::vector<T> qExpectedOutputData = armnnUtils::QuantizedVector<T>(expectedOutputData, qScale, qOffset);
+
+ std::vector<BT> qBiasesData = armnnUtils::QuantizedVector<BT>(biasesData, qScale * qScale, 0);
+
+ ConstTensor weights(weightsInfo, qWeightsData);
+ ConstTensor biases(biasesInfo, qBiasesData);
+
+ INetworkPtr network = CreateDepthwiseConvolution2dNetwork(descriptor,
+ inputInfo,
+ weightsInfo,
+ biasesInfo,
+ outputInfo,
+ weights,
+ biases);
+
+ EndToEndLayerTestImpl<ArmnnType, ArmnnType>(std::move(network),
+ { { 0, qInputData } },
+ { { 0, qExpectedOutputData } },
+ backends);
+}
diff --git a/src/backends/backendsCommon/test/OptimizationViewsTests.cpp b/src/backends/backendsCommon/test/OptimizationViewsTests.cpp
index f0f5b632de..1219ac5a33 100644
--- a/src/backends/backendsCommon/test/OptimizationViewsTests.cpp
+++ b/src/backends/backendsCommon/test/OptimizationViewsTests.cpp
@@ -128,20 +128,16 @@ TEST_CASE("OptimizedViewsSubgraphLayerCountUsingGetINetwork")
IConnectableLayer* const inputLayer = view.GetINetwork()->AddInputLayer(0, "input");
DepthwiseConvolution2dDescriptor convDescriptor;
- PreCompiledDescriptor substitutionLayerDescriptor(1, 1);
+ PreCompiledDescriptor substitutionLayerDescriptor(2, 1);
CompiledBlobPtr blobPtr;
BackendId backend = Compute::CpuRef;
Layer* convLayer1 = PolymorphicDowncast<Layer*>(
view.GetINetwork()->AddDepthwiseConvolution2dLayer(convDescriptor,
- ConstTensor(),
- Optional<ConstTensor>(),
"conv1"));
Layer* convLayer2 = PolymorphicDowncast<Layer*>(
view.GetINetwork()->AddDepthwiseConvolution2dLayer(convDescriptor,
- ConstTensor(),
- Optional<ConstTensor>(),
"conv2"));
IConnectableLayer* const outputLayer = view.GetINetwork()->AddOutputLayer(0, "output");
diff --git a/src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.cpp
index bd7cc40f27..4203fed23a 100644
--- a/src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.cpp
+++ b/src/backends/backendsCommon/test/layerTests/Conv2dTestImpl.cpp
@@ -1736,19 +1736,38 @@ LayerTestResult<T, 4> DepthwiseConvolution2dAsymmetricTestImpl(
}
std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
+ std::unique_ptr<armnn::ITensorHandle> weightsHandle = tensorHandleFactory.CreateTensorHandle(kernelDesc);
+ std::unique_ptr<armnn::ITensorHandle> biasHandle = nullptr;
std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
+ armnn::DepthwiseConvolution2dQueueDescriptor data;
+ armnn::WorkloadInfo info;
+
armnn::ScopedTensorHandle weightsTensor(kernelDesc);
+ // AllocateAndCopyDataToITensorHandle() is required twice for the weights AND biases:
+ // 1) ScopedTensorHandle (weightsTensor) required for QueueDescriptor (data.m_Weight).
+ // Needed in Neon and Cl Workload when permuting. Backend TensorHandle in (2) below will not work.
+ // 2) ITensorHandle (converts to Backend TensorHandle) required in RefWorkload for GetTensorInfo() method.
+ // Cannot PolymorphicDowncast from ScopedTensorHandle->RefTensorHandle.
+ // Need to PolymorphicDowncast from ITensorHandle->RefTensorHandle.
AllocateAndCopyDataToITensorHandle(&weightsTensor, kernel.data());
+ AllocateAndCopyDataToITensorHandle(weightsHandle.get(), kernel.data()); // required for ConstantTensor
+
+ AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
+ AddInputToWorkload(data, info, kernelDesc, weightsHandle.get());
+ AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
armnn::ScopedTensorHandle biasTensor(biasDesc);
if (biasEnabled)
{
AllocateAndCopyDataToITensorHandle(&biasTensor, bias.data());
+
+ biasHandle = tensorHandleFactory.CreateTensorHandle(biasDesc);
+ AllocateAndCopyDataToITensorHandle(biasHandle.get(), bias.data());
+ AddInputToWorkload(data, info, biasDesc, biasHandle.get());
}
- armnn::DepthwiseConvolution2dQueueDescriptor data;
data.m_Weight = &weightsTensor;
data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled - it can be a source of bugs.
data.m_Parameters.m_StrideX = strideX;
@@ -1760,12 +1779,9 @@ LayerTestResult<T, 4> DepthwiseConvolution2dAsymmetricTestImpl(
data.m_Parameters.m_BiasEnabled = biasEnabled;
data.m_Parameters.m_DataLayout = layout;
- armnn::WorkloadInfo info;
- AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
- AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
-
std::unique_ptr<armnn::IWorkload> workload
= workloadFactory.CreateWorkload(armnn::LayerType::DepthwiseConvolution2d, data, info);
+
inputHandle->Allocate();
outputHandle->Allocate();
@@ -1890,19 +1906,35 @@ LayerTestResult<T, 4> DepthwiseConvolution2dDepthMul1TestImpl(
std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
+ std::unique_ptr<armnn::ITensorHandle> weightsHandle = tensorHandleFactory.CreateTensorHandle(kernelDesc);
+ std::unique_ptr<armnn::ITensorHandle> biasHandle = nullptr;
std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
armnn::DepthwiseConvolution2dQueueDescriptor data;
armnn::WorkloadInfo info;
- armnn::ScopedTensorHandle weightsTensor(kernelDesc);
- armnn::ScopedTensorHandle biasTensor(biasDesc);
- AllocateAndCopyDataToITensorHandle(&weightsTensor, kernelData.data());
- AllocateAndCopyDataToITensorHandle(&biasTensor, biasV.data());
+ armnn::ScopedTensorHandle weightsTensor(kernelDesc);
+ // AllocateAndCopyDataToITensorHandle() is required twice for the weights AND biases:
+ // See comment in DepthwiseConvolution2dAsymmetricTestImpl() for reasons.
+ // 1) ScopedTensorHandle (weightsTensor) required for QueueDescriptor (data.m_Weight).
+ // 2) ITensorHandle (converts to Backend TensorHandle) required in RefWorkload for GetTensorInfo() method.
+ AllocateAndCopyDataToITensorHandle(&weightsTensor, kernelData.data()); // required for QueueDescriptor
+ AllocateAndCopyDataToITensorHandle(weightsHandle.get(), kernelData.data()); // required for ConstantTensor
AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
+ AddInputToWorkload(data, info, kernelDesc, weightsHandle.get());
AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
+ armnn::ScopedTensorHandle biasTensor(biasDesc);
+ if (biasEnabled)
+ {
+ AllocateAndCopyDataToITensorHandle(&biasTensor, biasV.data());
+
+ biasHandle = tensorHandleFactory.CreateTensorHandle(biasDesc);
+ AllocateAndCopyDataToITensorHandle(biasHandle.get(), biasV.data());
+ AddInputToWorkload(data, info, biasDesc, biasHandle.get());
+ }
+
data.m_Weight = &weightsTensor;
data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled.
data.m_Parameters.m_StrideX = 1;
@@ -1916,6 +1948,7 @@ LayerTestResult<T, 4> DepthwiseConvolution2dDepthMul1TestImpl(
std::unique_ptr<armnn::IWorkload> workload
= workloadFactory.CreateWorkload(armnn::LayerType::DepthwiseConvolution2d, data, info);
+
inputHandle->Allocate();
outputHandle->Allocate();
@@ -2086,19 +2119,35 @@ LayerTestResult<T, 4> DepthwiseConvolution2dTestImpl(
std::vector<T> actualOutput(outputTensorInfo.GetNumElements());
std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
+ std::unique_ptr<armnn::ITensorHandle> weightsHandle = tensorHandleFactory.CreateTensorHandle(kernelDesc);
+ std::unique_ptr<armnn::ITensorHandle> biasHandle = nullptr;
std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
armnn::DepthwiseConvolution2dQueueDescriptor data;
armnn::WorkloadInfo info;
- armnn::ScopedTensorHandle weightsTensor(kernelDesc);
- armnn::ScopedTensorHandle biasTensor(biasDesc);
- AllocateAndCopyDataToITensorHandle(&weightsTensor, kernelData.data());
- AllocateAndCopyDataToITensorHandle(&biasTensor, biasV.data());
+ armnn::ScopedTensorHandle weightsTensor(kernelDesc);
+ // AllocateAndCopyDataToITensorHandle() is required twice for the weights AND biases:
+ // See comment in DepthwiseConvolution2dAsymmetricTestImpl() for reasons.
+ // 1) ScopedTensorHandle (weightsTensor) required for QueueDescriptor (data.m_Weight).
+ // 2) ITensorHandle (converts to Backend TensorHandle) required in RefWorkload for GetTensorInfo() method.
+ AllocateAndCopyDataToITensorHandle(&weightsTensor, kernelData.data()); // required for QueueDescriptor
+ AllocateAndCopyDataToITensorHandle(weightsHandle.get(), kernelData.data()); // required for ConstantTensor
AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
+ AddInputToWorkload(data, info, kernelDesc, weightsHandle.get());
AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
+ armnn::ScopedTensorHandle biasTensor(biasDesc);
+ if (biasEnabled)
+ {
+ AllocateAndCopyDataToITensorHandle(&biasTensor, biasV.data());
+
+ biasHandle = tensorHandleFactory.CreateTensorHandle(biasDesc);
+ AllocateAndCopyDataToITensorHandle(biasHandle.get(), biasV.data());
+ AddInputToWorkload(data, info, biasDesc, biasHandle.get());
+ }
+
data.m_Weight = &weightsTensor;
data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled.
data.m_Parameters.m_StrideX = 2;
@@ -2112,6 +2161,7 @@ LayerTestResult<T, 4> DepthwiseConvolution2dTestImpl(
std::unique_ptr<armnn::IWorkload> workload
= workloadFactory.CreateWorkload(armnn::LayerType::DepthwiseConvolution2d, data, info);
+
inputHandle->Allocate();
outputHandle->Allocate();
@@ -2247,22 +2297,34 @@ LayerTestResult<T, 4> DepthwiseConvolution2dTestImpl(
}
std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
+ std::unique_ptr<armnn::ITensorHandle> weightsHandle = tensorHandleFactory.CreateTensorHandle(kernelDesc);
+ std::unique_ptr<armnn::ITensorHandle> biasHandle = nullptr;
std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
armnn::DepthwiseConvolution2dQueueDescriptor data;
armnn::WorkloadInfo info;
+
armnn::ScopedTensorHandle weightsTensor(kernelDesc);
- armnn::ScopedTensorHandle biasTensor(biasDesc);
+ // AllocateAndCopyDataToITensorHandle() is required twice for the weights AND biases:
+ // See comment in DepthwiseConvolution2dAsymmetricTestImpl() for reasons.
+ // 1) ScopedTensorHandle (weightsTensor) required for QueueDescriptor (data.m_Weight).
+ // 2) ITensorHandle (converts to Backend TensorHandle) required in RefWorkload for GetTensorInfo() method.
+ AllocateAndCopyDataToITensorHandle(&weightsTensor, originalKernel.data()); // required for QueueDescriptor
+ AllocateAndCopyDataToITensorHandle(weightsHandle.get(), originalKernel.data()); // required for ConstantTensor
- AllocateAndCopyDataToITensorHandle(&weightsTensor, originalKernel.data());
+ AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
+ AddInputToWorkload(data, info, kernelDesc, weightsHandle.get());
+ AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
- if(biasEnabled)
+ armnn::ScopedTensorHandle biasTensor(biasDesc);
+ if (biasEnabled)
{
AllocateAndCopyDataToITensorHandle(&biasTensor, bias.data());
- }
- AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
- AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
+ biasHandle = tensorHandleFactory.CreateTensorHandle(biasDesc);
+ AllocateAndCopyDataToITensorHandle(biasHandle.get(), bias.data());
+ AddInputToWorkload(data, info, biasDesc, biasHandle.get());
+ }
data.m_Weight = &weightsTensor;
data.m_Bias = &biasTensor; // Still set this whether or not bias is enabled - can be a source of bugs.
@@ -2279,6 +2341,7 @@ LayerTestResult<T, 4> DepthwiseConvolution2dTestImpl(
std::unique_ptr<armnn::IWorkload> workload
= workloadFactory.CreateWorkload(armnn::LayerType::DepthwiseConvolution2d, data, info);
+
inputHandle->Allocate();
outputHandle->Allocate();
@@ -2970,18 +3033,30 @@ LayerTestResult<T, 4> CompareDepthwiseConvolution2dTestImpl(
std::vector<T> expectedOutput(outputTensorInfo.GetNumElements());
std::unique_ptr<armnn::ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputTensorInfo);
+ std::unique_ptr<armnn::ITensorHandle> weightsHandle = tensorHandleFactory.CreateTensorHandle(kernelDesc);
+ std::unique_ptr<armnn::ITensorHandle> biasHandle = tensorHandleFactory.CreateTensorHandle(biasDesc);
std::unique_ptr<armnn::ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputTensorInfo);
armnn::DepthwiseConvolution2dQueueDescriptor data;
armnn::WorkloadInfo info;
+
armnn::ScopedTensorHandle weightsTensor(kernelDesc);
armnn::ScopedTensorHandle biasTensor(biasDesc);
+ AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
+ AddInputToWorkload(data, info, kernelDesc, weightsHandle.get());
+ AddInputToWorkload(data, info, biasDesc, biasHandle.get());
+ AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
+
+ // AllocateAndCopyDataToITensorHandle() is required twice for the weights AND biases:
+ // See comment in DepthwiseConvolution2dAsymmetricTestImpl() for reasons.
+ // 1) ScopedTensorHandle (weightsTensor) required for QueueDescriptor (data.m_Weight).
+ // 2) ITensorHandle (converts to Backend TensorHandle) required in RefWorkload for GetTensorInfo() method.
+ AllocateAndCopyDataToITensorHandle(weightsHandle.get(), kernel.data());
AllocateAndCopyDataToITensorHandle(&weightsTensor, kernel.data());
+ AllocateAndCopyDataToITensorHandle(biasHandle.get(), bias.data());
AllocateAndCopyDataToITensorHandle(&biasTensor, bias.data());
- AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get());
- AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());
data.m_Weight = &weightsTensor;
data.m_Bias = &biasTensor;
data.m_Parameters.m_StrideX = strideX;
@@ -2994,11 +3069,15 @@ LayerTestResult<T, 4> CompareDepthwiseConvolution2dTestImpl(
data.m_Parameters.m_DataLayout = layout.GetDataLayout();
std::unique_ptr<armnn::ITensorHandle> outputHandleRef = refTensorHandleFactory.CreateTensorHandle(outputTensorInfo);
+ std::unique_ptr<armnn::ITensorHandle> weightsHandleRef = refTensorHandleFactory.CreateTensorHandle(kernelDesc);
+ std::unique_ptr<armnn::ITensorHandle> biasHandleRef = refTensorHandleFactory.CreateTensorHandle(biasDesc);
std::unique_ptr<armnn::ITensorHandle> inputHandleRef = refTensorHandleFactory.CreateTensorHandle(inputTensorInfo);
armnn::DepthwiseConvolution2dQueueDescriptor refData = data;
armnn::WorkloadInfo refInfo = info;
SetWorkloadInput(refData, refInfo, 0, inputTensorInfo, inputHandleRef.get());
+ SetWorkloadInput(refData, refInfo, 1, kernelDesc, weightsHandleRef.get());
+ SetWorkloadInput(refData, refInfo, 2, biasDesc, biasHandleRef.get());
SetWorkloadOutput(refData, refInfo, 0, outputTensorInfo, outputHandleRef.get());
std::unique_ptr<armnn::IWorkload> workload
@@ -3007,6 +3086,8 @@ LayerTestResult<T, 4> CompareDepthwiseConvolution2dTestImpl(
= refWorkloadFactory.CreateWorkload(armnn::LayerType::DepthwiseConvolution2d, refData, refInfo);
outputHandleRef->Allocate();
+ weightsHandleRef->Allocate();
+ biasHandleRef->Allocate();
inputHandleRef->Allocate();
inputHandle->Allocate();
@@ -3014,6 +3095,8 @@ LayerTestResult<T, 4> CompareDepthwiseConvolution2dTestImpl(
CopyDataToITensorHandle(inputHandle.get(), input.data());
CopyDataToITensorHandle(inputHandleRef.get(), input.data());
+ CopyDataToITensorHandle(weightsHandleRef.get(), kernel.data());
+ CopyDataToITensorHandle(biasHandleRef.get(), bias.data());
ExecuteWorkload(*workload, memoryManager);
@@ -3739,23 +3822,33 @@ LayerTestResult<uint8_t, 4> DepthwiseConvolution2dPerAxisQuantTest(
descriptor.m_DataLayout = layout;
std::unique_ptr<ITensorHandle> inputHandle = tensorHandleFactory.CreateTensorHandle(inputInfo);
+ std::unique_ptr<ITensorHandle> weightsHandle = tensorHandleFactory.CreateTensorHandle(kernelInfo);
+ std::unique_ptr<ITensorHandle> biasHandle = tensorHandleFactory.CreateTensorHandle(biasInfo);
std::unique_ptr<ITensorHandle> outputHandle = tensorHandleFactory.CreateTensorHandle(outputInfo);
+ DepthwiseConvolution2dQueueDescriptor queueDescriptor;
WorkloadInfo workloadInfo;
ScopedTensorHandle weightTensor(kernelInfo);
ScopedTensorHandle biasTensor(biasInfo);
+ AddInputToWorkload(queueDescriptor, workloadInfo, inputInfo, inputHandle.get());
+ AddInputToWorkload(queueDescriptor, workloadInfo, kernelInfo, weightsHandle.get());
+ AddOutputToWorkload(queueDescriptor, workloadInfo, outputInfo, outputHandle.get());
+ AddInputToWorkload(queueDescriptor, workloadInfo, biasInfo, biasHandle.get());
+
+ // AllocateAndCopyDataToITensorHandle() is required twice for the weights AND biases:
+ // See comment in DepthwiseConvolution2dAsymmetricTestImpl() for reasons.
+ // 1) ScopedTensorHandle (weightsTensor) required for QueueDescriptor (data.m_Weight).
+ // 2) ITensorHandle (converts to Backend TensorHandle) required in RefWorkload for GetTensorInfo() method.
+ AllocateAndCopyDataToITensorHandle(weightsHandle.get(), kernelData.data());
AllocateAndCopyDataToITensorHandle(&weightTensor, kernelData.data());
+ AllocateAndCopyDataToITensorHandle(biasHandle.get(), biasData.data());
AllocateAndCopyDataToITensorHandle(&biasTensor, biasData.data());
- DepthwiseConvolution2dQueueDescriptor queueDescriptor;
queueDescriptor.m_Parameters = descriptor;
queueDescriptor.m_Weight = &weightTensor;
queueDescriptor.m_Bias = &biasTensor;
- AddInputToWorkload(queueDescriptor, workloadInfo, inputInfo, inputHandle.get());
- AddOutputToWorkload(queueDescriptor, workloadInfo, outputInfo, outputHandle.get());
-
std::unique_ptr<IWorkload> workload = workloadFactory.CreateWorkload(armnn::LayerType::DepthwiseConvolution2d,
queueDescriptor,
workloadInfo);