blob: f53f97ae884632338fe33c0a6387cece5141aac3 [file] [log] [blame]
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +00001//
John Mcloughlinceb44282024-04-23 16:47:04 +01002// Copyright © 2022, 2024 Arm Ltd and Contributors. All rights reserved.
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +00003// SPDX-License-Identifier: MIT
4//
5#pragma once
6
7#include "EndToEndTestImpl.hpp"
8#include <armnnUtils/QuantizeHelper.hpp>
9
10#include <ResolveType.hpp>
11
12#include <CommonTestUtils.hpp>
13#include <armnnTestUtils/DataLayoutUtils.hpp>
14
15#include <map>
16#include <vector>
17
18namespace
19{
20
21armnn::INetworkPtr CreateConstConvolution2dNetwork(const armnn::Convolution2dDescriptor& descriptor,
22 const armnn::TensorInfo& inputInfo,
23 const armnn::TensorInfo& weightsInfo,
24 const armnn::TensorInfo& biasInfo,
25 const armnn::TensorInfo& outputInfo,
26 const armnn::ConstTensor& weights,
27 const armnn::ConstTensor& biases,
28 bool biasEnabled)
29{
30 using namespace armnn;
31
32 INetworkPtr network(INetwork::Create());
33 IConnectableLayer* input = network->AddInputLayer(0, "input");
34 IConnectableLayer* weightsLayer = network->AddConstantLayer(weights, "Weights");
35 IConnectableLayer* convolution2d = network->AddConvolution2dLayer(descriptor, "convolution2d");
36 IConnectableLayer* output = network->AddOutputLayer(0, "output");
37
38 Connect(input, convolution2d, inputInfo, 0, 0);
39 Connect(weightsLayer, convolution2d, weightsInfo, 0, 1);
40
41 if(biasEnabled)
42 {
43 armnn::IConnectableLayer* biasLayer = network->AddConstantLayer(biases, "Bias");
44 Connect(biasLayer, convolution2d, biasInfo, 0, 2);
45 }
46
47 Connect(convolution2d, output, outputInfo, 0, 0);
48
49 return network;
50}
51
John Mcloughlinceb44282024-04-23 16:47:04 +010052template<DataType ArmnnIType, DataType ArmnnWType = ArmnnIType, DataType ArmnnBType = ArmnnIType,
53 DataType ArmnnOType = ArmnnIType>
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +000054void Convolution2dEndToEnd(const std::vector<armnn::BackendId>& backends,
55 armnn::DataLayout dataLayout,
56 bool biasEnabled = true)
57{
58 using namespace armnn;
John Mcloughlinceb44282024-04-23 16:47:04 +010059 using IT = ResolveType<ArmnnIType>;
60 using WT = ResolveType<ArmnnWType>;
61 using BT = ResolveType<ArmnnBType>;
62 using OT = ResolveType<ArmnnOType>;
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +000063
John Mcloughlinceb44282024-04-23 16:47:04 +010064 const float qScale = 1.0f;
65 const int32_t qOffset = IsQuantizedType<IT>() ? 10 : 0; // offset must be zero for non-quantized types
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +000066
John Mcloughlinceb44282024-04-23 16:47:04 +010067 TensorInfo inputInfo( { 1, 5, 5, 1 }, ArmnnIType, qScale, qOffset, true);
68 TensorInfo weightsInfo({ 1, 3, 3, 1 }, ArmnnWType, qScale, qOffset, true);
69 TensorInfo biasesInfo( { 1 }, ArmnnBType, qScale * qScale, 0, true);
70 TensorInfo outputInfo( { 1, 3, 3, 1 }, ArmnnOType, qScale, qOffset);
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +000071
72 std::vector<float> inputData =
John Mcloughlinceb44282024-04-23 16:47:04 +010073 {
74 1, 5, 2, 3, 5,
75 8, 7, 3, 6, 3,
76 3, 3, 9, 1, 9,
77 4, 1, 8, 1, 3,
78 6, 8, 1, 9, 2
79 };
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +000080
81 std::vector<float> weightsData =
John Mcloughlinceb44282024-04-23 16:47:04 +010082 {
83 4, 5, 6,
84 0, 0, 0,
85 3, 2, 1
86 };
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +000087
John Mcloughlinceb44282024-04-23 16:47:04 +010088 std::vector<float> biasesData = { 1 };
89 float bias = biasEnabled ? biasesData[0] : 0;
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +000090
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +000091 std::vector<float> expectedOutputData =
John Mcloughlinceb44282024-04-23 16:47:04 +010092 {
93 65 + bias, 76 + bias, 91 + bias,
94 107 + bias, 99 + bias, 89 + bias,
95 116 + bias, 98 + bias, 118 + bias
96 };
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +000097
98 Convolution2dDescriptor descriptor;
99 descriptor.m_PadLeft = 0;
100 descriptor.m_PadRight = 0;
101 descriptor.m_PadTop = 0;
102 descriptor.m_PadBottom = 0;
103 descriptor.m_StrideX = 1;
104 descriptor.m_StrideY = 1;
105 descriptor.m_BiasEnabled = biasEnabled;
106 descriptor.m_DataLayout = dataLayout;
107
108 if (dataLayout == DataLayout::NCHW)
109 {
John Mcloughlinceb44282024-04-23 16:47:04 +0100110 PermuteTensorNhwcToNchw(inputInfo, inputData);
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +0000111 PermuteTensorNhwcToNchw(weightsInfo, weightsData);
John Mcloughlinceb44282024-04-23 16:47:04 +0100112 PermuteTensorNhwcToNchw(outputInfo, expectedOutputData);
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +0000113 }
114
John Mcloughlinceb44282024-04-23 16:47:04 +0100115 // Convert data
116 std::vector<IT> qInputData = armnnUtils::QuantizedVector<IT>(inputData, qScale, qOffset);
117 std::vector<WT> qWeightsData = armnnUtils::QuantizedVector<WT>(weightsData, qScale, qOffset);
118 std::vector<BT> qBiasesData = armnnUtils::QuantizedVector<BT>(biasesData, qScale * qScale, 0);
119 std::vector<OT> qExpectedOutputData = armnnUtils::QuantizedVector<OT>(expectedOutputData, qScale, qOffset);
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +0000120
121 ConstTensor weights(weightsInfo, qWeightsData);
122 ConstTensor biases(biasesInfo, qBiasesData);
123
124 INetworkPtr network = CreateConstConvolution2dNetwork(descriptor,
125 inputInfo,
126 weightsInfo,
127 biasesInfo,
128 outputInfo,
129 weights,
130 biases,
131 biasEnabled);
132
John Mcloughlinceb44282024-04-23 16:47:04 +0100133 EndToEndLayerTestImpl<ArmnnIType, ArmnnOType>(std::move(network),
134 {{ 0, qInputData }},
135 {{ 0, qExpectedOutputData }},
136 backends);
Matthew Sloyanc5fe6e72022-11-25 16:10:00 +0000137}
138
139} // anonymous namespace