xref: /aosp_15_r20/external/ComputeLibrary/tests/validation/UNIT/TensorInfo.cpp (revision c217d954acce2dbc11938adb493fc0abd69584f3)
1 /*
2  * Copyright (c) 2017-2021 Arm Limited.
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #include "arm_compute/core/TensorInfo.h"
25 #include "arm_compute/core/Types.h"
26 #include "tests/framework/Asserts.h"
27 #include "tests/framework/Macros.h"
28 #include "tests/framework/datasets/Datasets.h"
29 #include "tests/validation/Validation.h"
30 #include "utils/TypePrinter.h"
31 
32 namespace arm_compute
33 {
34 namespace test
35 {
36 namespace validation
37 {
38 TEST_SUITE(UNIT)
TEST_SUITE(TensorInfo)39 TEST_SUITE(TensorInfo)
40 
41 // *INDENT-OFF*
42 // clang-format off
43 /** Validates TensorInfo Autopadding */
44 DATA_TEST_CASE(AutoPadding, framework::DatasetMode::ALL, zip(zip(zip(
45                framework::dataset::make("TensorShape", {
46                TensorShape{},
47                TensorShape{ 10U },
48                TensorShape{ 10U, 10U },
49                TensorShape{ 10U, 10U, 10U },
50                TensorShape{ 10U, 10U, 10U, 10U },
51                TensorShape{ 10U, 10U, 10U, 10U, 10U },
52                TensorShape{ 10U, 10U, 10U, 10U, 10U, 10U }}),
53                framework::dataset::make("PaddingSize", {
54                PaddingSize{ 0, 0, 0, 0 },
55                PaddingSize{ 0, 36, 0, 4 },
56                PaddingSize{ 4, 36, 4, 4 },
57                PaddingSize{ 4, 36, 4, 4 },
58                PaddingSize{ 4, 36, 4, 4 },
59                PaddingSize{ 4, 36, 4, 4 },
60                PaddingSize{ 4, 36, 4, 4 }})),
61                framework::dataset::make("Strides", {
62                Strides{},
63                Strides{ 1U, 50U },
64                Strides{ 1U, 50U },
65                Strides{ 1U, 50U, 900U },
66                Strides{ 1U, 50U, 900U, 9000U },
67                Strides{ 1U, 50U, 900U, 9000U, 90000U },
68                Strides{ 1U, 50U, 900U, 9000U, 90000U, 900000U }})),
69                framework::dataset::make("Offset", { 0U, 4U, 204U, 204U, 204U, 204U, 204U })),
70                shape, auto_padding, strides, offset)
71 {
72     TensorInfo info{ shape, Format::U8 };
73 
74     ARM_COMPUTE_EXPECT(!info.has_padding(), framework::LogLevel::ERRORS);
75 
76     info.auto_padding();
77 
78     validate(info.padding(), auto_padding);
79 
80     ARM_COMPUTE_EXPECT(compare_dimensions(info.strides_in_bytes(), strides), framework::LogLevel::ERRORS);
81     ARM_COMPUTE_EXPECT(info.offset_first_element_in_bytes() == offset, framework::LogLevel::ERRORS);
82 }
83 // clang-format on
84 // *INDENT-ON*
85 
86 /** Validates that TensorInfo is clonable */
TEST_CASE(Clone,framework::DatasetMode::ALL)87 TEST_CASE(Clone, framework::DatasetMode::ALL)
88 {
89     // Create tensor info
90     TensorInfo info(TensorShape(23U, 17U, 3U), // tensor shape
91                     1,                         // number of channels
92                     DataType::F32);            // data type
93 
94     // Get clone of current tensor info
95     std::unique_ptr<ITensorInfo> info_clone = info.clone();
96     ARM_COMPUTE_ASSERT(info_clone != nullptr);
97     ARM_COMPUTE_EXPECT(info_clone->total_size() == info.total_size(), framework::LogLevel::ERRORS);
98     ARM_COMPUTE_EXPECT(info_clone->num_channels() == info.num_channels(), framework::LogLevel::ERRORS);
99     ARM_COMPUTE_EXPECT(info_clone->data_type() == info.data_type(), framework::LogLevel::ERRORS);
100 }
101 
102 /** Validates that TensorInfo can chain multiple set commands */
TEST_CASE(TensorInfoBuild,framework::DatasetMode::ALL)103 TEST_CASE(TensorInfoBuild, framework::DatasetMode::ALL)
104 {
105     // Create tensor info
106     TensorInfo info(TensorShape(23U, 17U, 3U), // tensor shape
107                     1,                         // number of channels
108                     DataType::F32);            // data type
109 
110     // Update data type and number of channels
111     info.set_data_type(DataType::S32).set_num_channels(3);
112     ARM_COMPUTE_EXPECT(info.data_type() == DataType::S32, framework::LogLevel::ERRORS);
113     ARM_COMPUTE_EXPECT(info.num_channels() == 3, framework::LogLevel::ERRORS);
114 
115     // Update data type and set quantization info
116     info.set_data_type(DataType::QASYMM8).set_quantization_info(QuantizationInfo(0.5f, 15));
117     ARM_COMPUTE_EXPECT(info.data_type() == DataType::QASYMM8, framework::LogLevel::ERRORS);
118     ARM_COMPUTE_EXPECT(info.quantization_info() == QuantizationInfo(0.5f, 15), framework::LogLevel::ERRORS);
119 
120     // Update tensor shape
121     info.set_tensor_shape(TensorShape(13U, 15U));
122     ARM_COMPUTE_EXPECT(info.tensor_shape() == TensorShape(13U, 15U), framework::LogLevel::ERRORS);
123 }
124 
125 /** Validates empty quantization info */
TEST_CASE(NoQuantizationInfo,framework::DatasetMode::ALL)126 TEST_CASE(NoQuantizationInfo, framework::DatasetMode::ALL)
127 {
128     // Create tensor info
129     const TensorInfo info(TensorShape(32U, 16U), 1, DataType::F32);
130 
131     // Check quantization information
132     ARM_COMPUTE_EXPECT(info.quantization_info().empty(), framework::LogLevel::ERRORS);
133 }
134 
135 /** Validates symmetric quantization info */
TEST_CASE(SymmQuantizationInfo,framework::DatasetMode::ALL)136 TEST_CASE(SymmQuantizationInfo, framework::DatasetMode::ALL)
137 {
138     // Create tensor info
139     const float      scale = 0.25f;
140     const TensorInfo info(TensorShape(32U, 16U), 1, DataType::QSYMM8, QuantizationInfo(scale));
141 
142     // Check quantization information
143     ARM_COMPUTE_EXPECT(!info.quantization_info().empty(), framework::LogLevel::ERRORS);
144     ARM_COMPUTE_EXPECT(!info.quantization_info().scale().empty(), framework::LogLevel::ERRORS);
145     ARM_COMPUTE_EXPECT(info.quantization_info().scale().size() == 1, framework::LogLevel::ERRORS);
146     ARM_COMPUTE_EXPECT(info.quantization_info().offset().empty(), framework::LogLevel::ERRORS);
147 
148     UniformQuantizationInfo qinfo = info.quantization_info().uniform();
149     ARM_COMPUTE_EXPECT(qinfo.scale == scale, framework::LogLevel::ERRORS);
150     ARM_COMPUTE_EXPECT(qinfo.offset == 0.f, framework::LogLevel::ERRORS);
151 }
152 
153 /** Validates asymmetric quantization info */
TEST_CASE(AsymmQuantizationInfo,framework::DatasetMode::ALL)154 TEST_CASE(AsymmQuantizationInfo, framework::DatasetMode::ALL)
155 {
156     // Create tensor info
157     const float      scale  = 0.25f;
158     const int32_t    offset = 126;
159     const TensorInfo info(TensorShape(32U, 16U), 1, DataType::QSYMM8, QuantizationInfo(scale, offset));
160 
161     // Check quantization information
162     ARM_COMPUTE_EXPECT(!info.quantization_info().empty(), framework::LogLevel::ERRORS);
163     ARM_COMPUTE_EXPECT(!info.quantization_info().scale().empty(), framework::LogLevel::ERRORS);
164     ARM_COMPUTE_EXPECT(info.quantization_info().scale().size() == 1, framework::LogLevel::ERRORS);
165     ARM_COMPUTE_EXPECT(!info.quantization_info().offset().empty(), framework::LogLevel::ERRORS);
166     ARM_COMPUTE_EXPECT(info.quantization_info().offset().size() == 1, framework::LogLevel::ERRORS);
167 
168     UniformQuantizationInfo qinfo = info.quantization_info().uniform();
169     ARM_COMPUTE_EXPECT(qinfo.scale == scale, framework::LogLevel::ERRORS);
170     ARM_COMPUTE_EXPECT(qinfo.offset == offset, framework::LogLevel::ERRORS);
171 }
172 
173 /** Validates symmetric per channel quantization info */
TEST_CASE(SymmPerChannelQuantizationInfo,framework::DatasetMode::ALL)174 TEST_CASE(SymmPerChannelQuantizationInfo, framework::DatasetMode::ALL)
175 {
176     // Create tensor info
177     const std::vector<float> scale = { 0.25f, 1.4f, 3.2f, 2.3f, 4.7f };
178     const TensorInfo         info(TensorShape(32U, 16U), 1, DataType::QSYMM8_PER_CHANNEL, QuantizationInfo(scale));
179 
180     // Check quantization information
181     ARM_COMPUTE_EXPECT(!info.quantization_info().empty(), framework::LogLevel::ERRORS);
182     ARM_COMPUTE_EXPECT(!info.quantization_info().scale().empty(), framework::LogLevel::ERRORS);
183     ARM_COMPUTE_EXPECT(info.quantization_info().scale().size() == scale.size(), framework::LogLevel::ERRORS);
184     ARM_COMPUTE_EXPECT(info.quantization_info().offset().empty(), framework::LogLevel::ERRORS);
185 }
186 
187 /** Validates lock paddings flag*/
TEST_CASE(SubTensorPaddingExpansion,framework::DatasetMode::ALL)188 TEST_CASE(SubTensorPaddingExpansion, framework::DatasetMode::ALL)
189 {
190     TensorInfo    tensor_info(TensorShape(23U, 17U, 3U), 1, DataType::F32);
191     tensor_info.set_lock_paddings(true);
192 
193     // Now lock padding is set to true, therefore the extend padding would fail
194     ARM_COMPUTE_EXPECT_THROW(tensor_info.extend_padding(PaddingSize(2, 1)), framework::LogLevel::ERRORS);
195 }
196 TEST_SUITE_END() // TensorInfo
197 TEST_SUITE_END() // UNIT
198 } // namespace validation
199 } // namespace test
200 } // namespace arm_compute
201