blob: e12813ad911c7b25f40a9062a1505f7258ce40a5 [file] [log] [blame]
Aron Virginas-Tar98180ef2019-06-26 15:02:47 +01001//
2// Copyright © 2017 Arm Ltd. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5#pragma once
6
Matteo Martincighe011d202019-11-28 11:35:47 +00007#include <armnnUtils/Permute.hpp>
8
Colm Donelanc42a9872022-02-02 16:35:09 +00009#include <armnnUtils/QuantizeHelper.hpp>
Aron Virginas-Tar98180ef2019-06-26 15:02:47 +010010#include <ResolveType.hpp>
11
Sadik Armagana097d2a2021-11-24 15:47:28 +000012#include <CommonTestUtils.hpp>
Aron Virginas-Tar98180ef2019-06-26 15:02:47 +010013
Aron Virginas-Tar98180ef2019-06-26 15:02:47 +010014#include <map>
15#include <vector>
16
17namespace
18{
19
20INetworkPtr CreateTransposeConvolution2dNetwork(const armnn::TransposeConvolution2dDescriptor& descriptor,
21 const armnn::TensorInfo& inputInfo,
22 const armnn::TensorInfo& outputInfo,
23 const armnn::ConstTensor& weights,
24 const armnn::Optional<armnn::ConstTensor>& biases)
25{
26 using namespace armnn;
27
28 INetworkPtr network(INetwork::Create());
29 IConnectableLayer* input = network->AddInputLayer(0, "input");
30 IConnectableLayer* transposeConvolution2d =
31 network->AddTransposeConvolution2dLayer(descriptor, weights, biases, "transposeConvolution2d");
32 IConnectableLayer* output = network->AddOutputLayer(0, "output");
33
34 Connect(input, transposeConvolution2d, inputInfo, 0, 0);
35 Connect(transposeConvolution2d, output, outputInfo, 0, 0);
36
37 return network;
38}
39
40} // anonymous namespace
41
42template<armnn::DataType ArmnnType, armnn::DataType ArmnnBType>
43void TransposeConvolution2dEndToEnd(const std::vector<armnn::BackendId>& backends,
44 armnn::DataLayout dataLayout)
45{
46 using namespace armnn;
47 using T = ResolveType<ArmnnType>;
48
49 constexpr unsigned int batches = 1u;
50 constexpr unsigned int channels = 1u;
51
52 constexpr unsigned int wInput = 3u;
53 constexpr unsigned int hInput = wInput;
54
55 constexpr unsigned int wOutput = 5u;
56 constexpr unsigned int hOutput = wOutput;
57
58 constexpr unsigned int wWeights = 3u;
59 constexpr unsigned int hWeights = wWeights;
60
61 TensorShape inputShape = MakeTensorShape(batches, channels, hInput, wInput, dataLayout);
62 TensorShape outputShape = MakeTensorShape(batches, channels, hOutput, wOutput, dataLayout);
63 TensorShape weightsShape = MakeTensorShape(batches, channels, hWeights, wWeights, dataLayout);
64
65 const float qScale = IsQuantizedType<T>() ? 0.25f : 1.0f;
66 const int32_t qOffset = IsQuantizedType<T>() ? 50 : 0;
67
Cathal Corbett5b8093c2021-10-22 11:12:07 +010068 TensorInfo inputInfo(inputShape, ArmnnType, qScale, qOffset, true);
Aron Virginas-Tar98180ef2019-06-26 15:02:47 +010069 TensorInfo outputInfo(outputShape, ArmnnType, qScale, qOffset);
Cathal Corbett5b8093c2021-10-22 11:12:07 +010070 TensorInfo weightsInfo(weightsShape, ArmnnType, qScale, qOffset, true);
71 TensorInfo biasesInfo({ channels }, ArmnnBType, qScale * qScale, 0, true);
Aron Virginas-Tar98180ef2019-06-26 15:02:47 +010072
73 std::vector<float> inputData =
74 {
75 1.f, 1.f, 1.f,
76 1.f, 1.f, 1.f,
77 1.f, 1.f, 1.f
78 };
79
80 std::vector<float> weightsData =
81 {
82 1.f, 2.f, 3.f,
83 4.f, 5.f, 6.f,
84 7.f, 8.f, 9.f
85 };
86
87 std::vector<float> biasesData = { 1.f };
88
89 std::vector<float> expectedOutputData =
90 {
91 6.f, 11.f, 6.f, 11.f, 6.f,
92 11.f, 21.f, 11.f, 21.f, 11.f,
93 6.f, 11.f, 6.f, 11.f, 6.f,
94 11.f, 21.f, 11.f, 21.f, 11.f,
95 6.f, 11.f, 6.f, 11.f, 6.f
96 };
97
98 TransposeConvolution2dDescriptor descriptor;
99 descriptor.m_PadLeft = 1;
100 descriptor.m_PadRight = 1;
101 descriptor.m_PadTop = 1;
102 descriptor.m_PadBottom = 1;
103 descriptor.m_StrideX = 2;
104 descriptor.m_StrideY = 2;
105 descriptor.m_BiasEnabled = true;
106 descriptor.m_DataLayout = dataLayout;
107
108 // swizzle data if needed
109 if (dataLayout == armnn::DataLayout::NHWC)
110 {
111 constexpr size_t dataTypeSize = sizeof(float);
112 const armnn::PermutationVector nchwToNhwc = { 0, 3, 1, 2 };
113
114 std::vector<float> tmp(inputData.size());
115 armnnUtils::Permute(inputInfo.GetShape(), nchwToNhwc, inputData.data(), tmp.data(), dataTypeSize);
116 inputData = tmp;
117
118 tmp.resize(weightsData.size());
119 armnnUtils::Permute(weightsInfo.GetShape(), nchwToNhwc, weightsData.data(), tmp.data(), dataTypeSize);
120 weightsData = tmp;
121
122 tmp.resize(expectedOutputData.size());
123 armnnUtils::Permute(outputInfo.GetShape(), nchwToNhwc, expectedOutputData.data(), tmp.data(), dataTypeSize);
124 expectedOutputData = tmp;
125 }
126
127 // quantize data
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100128 std::vector<T> qInputData = armnnUtils::QuantizedVector<T>(inputData, qScale, qOffset);
129 std::vector<T> qWeightsData = armnnUtils::QuantizedVector<T>(weightsData, qScale, qOffset);
130 std::vector<T> qExpectedOutputData = armnnUtils::QuantizedVector<T>(expectedOutputData, qScale, qOffset);
Aron Virginas-Tar98180ef2019-06-26 15:02:47 +0100131
132 using BT = ResolveType<ArmnnBType>;
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100133 std::vector<BT> qBiasesData = armnnUtils::QuantizedVector<BT>(biasesData, qScale * qScale, 0);
Aron Virginas-Tar98180ef2019-06-26 15:02:47 +0100134
135 ConstTensor weights(weightsInfo, qWeightsData);
136 ConstTensor biases(biasesInfo, qBiasesData);
137
138 INetworkPtr network = CreateTransposeConvolution2dNetwork(descriptor,
139 inputInfo,
140 outputInfo,
141 weights,
142 Optional<ConstTensor>(biases));
143
144
145 EndToEndLayerTestImpl<ArmnnType, ArmnnType>(std::move(network),
146 { { 0, qInputData } },
147 { { 0, qExpectedOutputData } },
148 backends);
Aron Virginas-Tar48623a02019-10-22 10:00:28 +0100149}