blob: c2e3cee7a04d663d30efebda2b9c66598bf5af89 [file] [log] [blame]
Jan Eilers53ef7952021-06-02 12:01:25 +01001//
2// Copyright © 2021 Arm Ltd and Contributors. All rights reserved.
3// SPDX-License-Identifier: MIT
4//
5
6#include <reference/workloads/Decoders.hpp>
7#include <armnn/utility/NumericCast.hpp>
8
9#include <fmt/format.h>
10
11#include <boost/test/unit_test.hpp>
12
13BOOST_AUTO_TEST_SUITE(RefPerChannelDecoder)
14
15template<typename T>
16void CompareVector(std::vector<T> vec1, std::vector<T> vec2)
17{
18 BOOST_TEST(vec1.size() == vec2.size());
19
20 bool mismatch = false;
21 for (uint i = 0; i < vec1.size(); ++i)
22 {
23 if (vec1[i] != vec2[i])
24 {
25 /*std::stringstream ss;
26 ss << "Vector value mismatch: index=" << i << " " << vec1[i] << "!=" << vec2[i];*/
27 BOOST_TEST_MESSAGE(fmt::format("Vector value mismatch: index={} {} != {}",
28 i,
29 vec1[i],
30 vec2[i]));
31 mismatch = true;
32 }
33 }
34
35 if (mismatch)
36 {
37 BOOST_FAIL("Error in CompareVector. Vectors don't match.");
38 }
39}
40
41// Ensure quantization works for none depthwise convolutions
42BOOST_AUTO_TEST_CASE(RefPerChannelDecoderTest1)
43{
44 using namespace armnn;
45 std::vector<int8_t> input =
46 {
47 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
48 };
49
50 std::vector<float> expOutput =
51 {
52 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f,
53 24.0f, 26.0f, 28.0f, 30.0f, 32.0f, 34.0f, 36.0f, 38.0f, 40.0f, 42.0f, 44.0f, 46.0f
54 };
55
56 TensorInfo tensorInfo ({2,2,2,3},DataType::QSymmS8,{1.0f, 2.0f},0);
57 auto decoder = MakeDecoder<float>(tensorInfo, input.data());
58
59 std::vector<float> output = decoder->DecodeTensor(tensorInfo.GetShape());
60
61 CompareVector(output, expOutput);
62}
63
64// Ensure quantization works for depthwise convolutions M=1
65BOOST_AUTO_TEST_CASE(RefPerChannelDecoderTest2)
66{
67 using namespace armnn;
68 std::vector<int8_t> input =
69 {
70 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
71 };
72
73 std::vector<float> expOutput =
74 {
75 0.0f, 1.0f, 2.0f, 3.0f,
76 8.0f, 10.0f, 12.0f, 14.0f,
77 24.0f, 27.0f, 30.0f, 33.0f,
78 48.0f, 52.0f, 56.0f, 60.0f
79 };
80
81 // [O,1,H,W] = [I*M,1,H,W] = [4*1,1,2,2]
82 TensorInfo tensorInfo ({4,1,2,2},DataType::QSymmS8,{1.0f, 2.0f, 3.0f, 4.0f},0);
83 auto decoder = MakeDecoder<float>(tensorInfo, input.data());
84
85 std::vector<float> output = decoder->DecodeTensor(tensorInfo.GetShape(), true);
86
87 CompareVector(output, expOutput);
88}
89
90// Ensure quantization works for depthwise convolutions M=2
91BOOST_AUTO_TEST_CASE(RefPerChannelDecoderTest3)
92{
93 using namespace armnn;
94 std::vector<int8_t> input =
95 {
96 0, 1, 2, 3,
97 4, 5, 6, 7,
98 8, 9, 10, 11,
99 12, 13, 14, 15,
100 16, 17, 18, 19,
101 20, 21, 22, 23
102 };
103
104 std::vector<float> expOutput =
105 {
106 0.0f, 1.0f, 2.0f, 3.0f,
107 8.0f, 10.0f, 12.0f, 14.0f,
108 24.0f, 27.0f, 30.0f, 33.0f,
109 48.0f, 52.0f, 56.0f, 60.0f,
110 80.0f, 85.0f, 90.0f, 95.0f,
111 120.0f, 126.0f, 132.0f, 138.0f
112 };
113
114 // [O,1,H,W] = [I*M,1,H,W] = [3*2,1,2,2]
115 TensorInfo tensorInfo ({6,1,2,2},DataType::QSymmS8,{1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f},0);
116 auto decoder = MakeDecoder<float>(tensorInfo, input.data());
117
118 std::vector<float> output = decoder->DecodeTensor(tensorInfo.GetShape(), true);
119
120 CompareVector(output, expOutput);
121}
122
123// Ensure quantization works for depthwise convolutions M=2 for int32
124BOOST_AUTO_TEST_CASE(RefPerChannelDecoderTest4)
125{
126 using namespace armnn;
127 std::vector<int32_t> input =
128 {
129 0, 1, 2, 3,
130 4, 5, 6, 7,
131 8, 9, 10, 11,
132 12, 13, 14, 15,
133 16, 17, 18, 19,
134 20, 21, 22, 23
135 };
136
137 std::vector<float> expOutput =
138 {
139 0.0f, 1.0f, 2.0f, 3.0f,
140 8.0f, 10.0f, 12.0f, 14.0f,
141 24.0f, 27.0f, 30.0f, 33.0f,
142 48.0f, 52.0f, 56.0f, 60.0f,
143 80.0f, 85.0f, 90.0f, 95.0f,
144 120.0f, 126.0f, 132.0f, 138.0f
145 };
146
147 // [O,1,H,W] = [I*M,1,H,W] = [3*2,1,2,2]
148 TensorInfo tensorInfo ({6,1,2,2},DataType::Signed32,{1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f},0);
149 auto decoder = MakeDecoder<float>(tensorInfo, input.data());
150
151 std::vector<float> output = decoder->DecodeTensor(tensorInfo.GetShape(), true);
152
153 CompareVector(output, expOutput);
154}
155
156BOOST_AUTO_TEST_SUITE_END()