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