xref: /aosp_15_r20/external/armnn/src/backends/backendsCommon/test/ResizeEndToEndTestImpl.hpp (revision 89c4ff92f2867872bb9e2354d150bf0c8c502810)
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
7 #include <armnnUtils/Permute.hpp>
8 
9 #include <armnnUtils/QuantizeHelper.hpp>
10 #include <ResolveType.hpp>
11 
12 #include <CommonTestUtils.hpp>
13 
14 #include <map>
15 #include <vector>
16 
17 namespace
18 {
19 
CreateResizeNetwork(const armnn::ResizeDescriptor & descriptor,const armnn::TensorInfo & inputInfo,const armnn::TensorInfo & outputInfo)20 armnn::INetworkPtr CreateResizeNetwork(const armnn::ResizeDescriptor& descriptor,
21                                        const armnn::TensorInfo& inputInfo,
22                                        const armnn::TensorInfo& outputInfo)
23 {
24     using namespace armnn;
25 
26     INetworkPtr network(INetwork::Create());
27     IConnectableLayer* input  = network->AddInputLayer(0, "input");
28     IConnectableLayer* resize = network->AddResizeLayer(descriptor, "resize");
29     IConnectableLayer* output = network->AddOutputLayer(0, "output");
30 
31     Connect(input, resize, inputInfo, 0, 0);
32     Connect(resize, output, outputInfo, 0, 0);
33 
34     return network;
35 }
36 
37 template<armnn::DataType ArmnnType>
ResizeEndToEnd(const std::vector<armnn::BackendId> & backends,armnn::DataLayout dataLayout,armnn::ResizeMethod resizeMethod)38 void ResizeEndToEnd(const std::vector<armnn::BackendId>& backends,
39                     armnn::DataLayout dataLayout,
40                     armnn::ResizeMethod resizeMethod)
41 {
42     using namespace armnn;
43     using T = ResolveType<ArmnnType>;
44 
45     constexpr unsigned int inputWidth  = 3u;
46     constexpr unsigned int inputHeight = inputWidth;
47 
48     constexpr unsigned int outputWidth  = 5u;
49     constexpr unsigned int outputHeight = outputWidth;
50 
51     TensorShape inputShape  = MakeTensorShape(1, 1, inputHeight, inputWidth, dataLayout);
52     TensorShape outputShape = MakeTensorShape(1, 1, outputHeight, outputWidth, dataLayout);
53 
54     const float   qScale  = IsQuantizedType<T>() ? 0.25f : 1.0f;
55     const int32_t qOffset = IsQuantizedType<T>() ? 50    : 0;
56 
57     TensorInfo inputInfo(inputShape, ArmnnType, qScale, qOffset, true);
58     TensorInfo outputInfo(outputShape, ArmnnType, qScale, qOffset);
59 
60     std::vector<float> inputData =
61     {
62        1.f, 2.f, 3.f,
63        4.f, 5.f, 6.f,
64        7.f, 8.f, 9.f
65     };
66 
67     std::vector<float> expectedOutputData;
68     switch(resizeMethod)
69     {
70         case ResizeMethod::Bilinear:
71         {
72             expectedOutputData =
73             {
74                 1.0f, 1.6f, 2.2f, 2.8f, 3.0f,
75                 2.8f, 3.4f, 4.0f, 4.6f, 4.8f,
76                 4.6f, 5.2f, 5.8f, 6.4f, 6.6f,
77                 6.4f, 7.0f, 7.6f, 8.2f, 8.4f,
78                 7.0f, 7.6f, 8.2f, 8.8f, 9.0f
79             };
80             break;
81         }
82         case ResizeMethod::NearestNeighbor:
83         {
84             expectedOutputData =
85             {
86                 1.f, 1.f, 2.f, 2.f, 3.f,
87                 1.f, 1.f, 2.f, 2.f, 3.f,
88                 4.f, 4.f, 5.f, 5.f, 6.f,
89                 4.f, 4.f, 5.f, 5.f, 6.f,
90                 7.f, 7.f, 8.f, 8.f, 9.f
91             };
92             break;
93         }
94         default:
95         {
96             throw InvalidArgumentException("Unrecognized resize method");
97         }
98     }
99 
100     ResizeDescriptor descriptor;
101     descriptor.m_TargetWidth  = outputWidth;
102     descriptor.m_TargetHeight = outputHeight;
103     descriptor.m_Method       = resizeMethod;
104     descriptor.m_DataLayout   = dataLayout;
105 
106     // swizzle data if needed
107     if (dataLayout == armnn::DataLayout::NHWC)
108     {
109         constexpr size_t dataTypeSize = sizeof(float);
110         const armnn::PermutationVector nchwToNhwc = { 0, 3, 1, 2 };
111 
112         std::vector<float> tmp(inputData.size());
113         armnnUtils::Permute(inputInfo.GetShape(), nchwToNhwc, inputData.data(), tmp.data(), dataTypeSize);
114         inputData = tmp;
115     }
116 
117     // quantize data
118     std::vector<T> qInputData          = armnnUtils::QuantizedVector<T>(inputData, qScale, qOffset);
119     std::vector<T> qExpectedOutputData = armnnUtils::QuantizedVector<T>(expectedOutputData, qScale, qOffset);
120 
121     INetworkPtr network = CreateResizeNetwork(descriptor, inputInfo, outputInfo);
122 
123     EndToEndLayerTestImpl<ArmnnType, ArmnnType>(std::move(network),
124                                                 { { 0, qInputData } },
125                                                 { { 0, qExpectedOutputData } },
126                                                 backends);
127 }
128 
129 } // anonymous namespace
130 
131 template<armnn::DataType ArmnnType>
ResizeBilinearEndToEnd(const std::vector<armnn::BackendId> & backends,armnn::DataLayout dataLayout)132 void ResizeBilinearEndToEnd(const std::vector<armnn::BackendId>& backends,
133                             armnn::DataLayout dataLayout)
134 {
135     ResizeEndToEnd<ArmnnType>(backends, dataLayout, armnn::ResizeMethod::Bilinear);
136 }
137 
138 template<armnn::DataType ArmnnType>
ResizeNearestNeighborEndToEnd(const std::vector<armnn::BackendId> & backends,armnn::DataLayout dataLayout)139 void ResizeNearestNeighborEndToEnd(const std::vector<armnn::BackendId>& backends,
140                                    armnn::DataLayout dataLayout)
141 {
142     ResizeEndToEnd<ArmnnType>(backends, dataLayout, armnn::ResizeMethod::NearestNeighbor);
143 }
144