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