blob: df68aeea524290d0b852063d75c3640938bd4d23 [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>
Jan Eilers53ef7952021-06-02 12:01:25 +01007
8#include <fmt/format.h>
9
Matthew Sloyan7a00eaa2021-06-20 18:45:05 +010010#include <doctest/doctest.h>
Jan Eilers53ef7952021-06-02 12:01:25 +010011
Matthew Sloyan7a00eaa2021-06-20 18:45:05 +010012TEST_SUITE("RefPerChannelDecoder")
13{
Jan Eilers53ef7952021-06-02 12:01:25 +010014template<typename T>
15void CompareVector(std::vector<T> vec1, std::vector<T> vec2)
16{
Matthew Sloyan7a00eaa2021-06-20 18:45:05 +010017 CHECK(vec1.size() == vec2.size());
Jan Eilers53ef7952021-06-02 12:01:25 +010018
19 bool mismatch = false;
Rob Hughes96fd98c2021-07-28 13:50:12 +010020 for (uint32_t i = 0; i < vec1.size(); ++i)
Jan Eilers53ef7952021-06-02 12:01:25 +010021 {
22 if (vec1[i] != vec2[i])
23 {
Matthew Sloyan7a00eaa2021-06-20 18:45:05 +010024 MESSAGE(fmt::format("Vector value mismatch: index={} {} != {}",
25 i,
26 vec1[i],
27 vec2[i]));
28
Jan Eilers53ef7952021-06-02 12:01:25 +010029 mismatch = true;
30 }
31 }
32
33 if (mismatch)
34 {
Matthew Sloyan7a00eaa2021-06-20 18:45:05 +010035 FAIL("Error in CompareVector. Vectors don't match.");
Jan Eilers53ef7952021-06-02 12:01:25 +010036 }
37}
38
39// Ensure quantization works for none depthwise convolutions
Matthew Sloyan7a00eaa2021-06-20 18:45:05 +010040TEST_CASE("RefPerChannelDecoderTest1")
Jan Eilers53ef7952021-06-02 12:01:25 +010041{
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
Matthew Sloyan7a00eaa2021-06-20 18:45:05 +010063TEST_CASE("RefPerChannelDecoderTest2")
Jan Eilers53ef7952021-06-02 12:01:25 +010064{
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
Matthew Sloyan7a00eaa2021-06-20 18:45:05 +010089TEST_CASE("RefPerChannelDecoderTest3")
Jan Eilers53ef7952021-06-02 12:01:25 +010090{
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
Matthew Sloyan7a00eaa2021-06-20 18:45:05 +0100122TEST_CASE("RefPerChannelDecoderTest4")
Jan Eilers53ef7952021-06-02 12:01:25 +0100123{
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
Matthew Sloyan7a00eaa2021-06-20 18:45:05 +0100154}