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