xref: /aosp_15_r20/external/ComputeLibrary/tests/validation/CPP/TopKV.cpp (revision c217d954acce2dbc11938adb493fc0abd69584f3)
1*c217d954SCole Faust /*
2*c217d954SCole Faust  * Copyright (c) 2019-2020 Arm Limited.
3*c217d954SCole Faust  *
4*c217d954SCole Faust  * SPDX-License-Identifier: MIT
5*c217d954SCole Faust  *
6*c217d954SCole Faust  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*c217d954SCole Faust  * of this software and associated documentation files (the "Software"), to
8*c217d954SCole Faust  * deal in the Software without restriction, including without limitation the
9*c217d954SCole Faust  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*c217d954SCole Faust  * sell copies of the Software, and to permit persons to whom the Software is
11*c217d954SCole Faust  * furnished to do so, subject to the following conditions:
12*c217d954SCole Faust  *
13*c217d954SCole Faust  * The above copyright notice and this permission notice shall be included in all
14*c217d954SCole Faust  * copies or substantial portions of the Software.
15*c217d954SCole Faust  *
16*c217d954SCole Faust  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*c217d954SCole Faust  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*c217d954SCole Faust  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*c217d954SCole Faust  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*c217d954SCole Faust  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21*c217d954SCole Faust  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*c217d954SCole Faust  * SOFTWARE.
23*c217d954SCole Faust  */
24*c217d954SCole Faust #include "arm_compute/core/Types.h"
25*c217d954SCole Faust #include "arm_compute/runtime/CPP/functions/CPPTopKV.h"
26*c217d954SCole Faust #include "arm_compute/runtime/Tensor.h"
27*c217d954SCole Faust #include "arm_compute/runtime/TensorAllocator.h"
28*c217d954SCole Faust #include "tests/NEON/Accessor.h"
29*c217d954SCole Faust #include "tests/PaddingCalculator.h"
30*c217d954SCole Faust #include "tests/datasets/ShapeDatasets.h"
31*c217d954SCole Faust #include "tests/framework/Asserts.h"
32*c217d954SCole Faust #include "tests/framework/Macros.h"
33*c217d954SCole Faust #include "tests/framework/datasets/Datasets.h"
34*c217d954SCole Faust #include "tests/validation/Validation.h"
35*c217d954SCole Faust #include "tests/validation/fixtures/PermuteFixture.h"
36*c217d954SCole Faust 
37*c217d954SCole Faust namespace arm_compute
38*c217d954SCole Faust {
39*c217d954SCole Faust namespace test
40*c217d954SCole Faust {
41*c217d954SCole Faust namespace validation
42*c217d954SCole Faust {
43*c217d954SCole Faust namespace
44*c217d954SCole Faust {
45*c217d954SCole Faust template <typename U, typename T>
fill_tensor(U && tensor,const std::vector<T> & v)46*c217d954SCole Faust inline void fill_tensor(U &&tensor, const std::vector<T> &v)
47*c217d954SCole Faust {
48*c217d954SCole Faust     std::memcpy(tensor.data(), v.data(), sizeof(T) * v.size());
49*c217d954SCole Faust }
50*c217d954SCole Faust } // namespace
51*c217d954SCole Faust 
52*c217d954SCole Faust TEST_SUITE(CPP)
TEST_SUITE(TopKV)53*c217d954SCole Faust TEST_SUITE(TopKV)
54*c217d954SCole Faust 
55*c217d954SCole Faust // *INDENT-OFF*
56*c217d954SCole Faust // clang-format off
57*c217d954SCole Faust DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(
58*c217d954SCole Faust         framework::dataset::make("PredictionsInfo", { TensorInfo(TensorShape(20, 10), 1, DataType::F32),
59*c217d954SCole Faust                                                 TensorInfo(TensorShape(10, 20), 1, DataType::F16),  // Mismatching batch_size
60*c217d954SCole Faust                                                 TensorInfo(TensorShape(20, 10), 1, DataType::S8), // Unsupported data type
61*c217d954SCole Faust                                                 TensorInfo(TensorShape(10, 10, 10), 1, DataType::F32), // Wrong predictions dimensions
62*c217d954SCole Faust                                                 TensorInfo(TensorShape(20, 10), 1, DataType::F32)}), // Wrong output dimension
63*c217d954SCole Faust         framework::dataset::make("TargetsInfo",{ TensorInfo(TensorShape(10), 1, DataType::U32),
64*c217d954SCole Faust                                                 TensorInfo(TensorShape(10), 1, DataType::U32),
65*c217d954SCole Faust                                                 TensorInfo(TensorShape(10), 1, DataType::U32),
66*c217d954SCole Faust                                                 TensorInfo(TensorShape(10), 1, DataType::U32),
67*c217d954SCole Faust                                                 TensorInfo(TensorShape(10), 1, DataType::U32)})),
68*c217d954SCole Faust         framework::dataset::make("OutputInfo",{ TensorInfo(TensorShape(10), 1, DataType::U8),
69*c217d954SCole Faust                                                 TensorInfo(TensorShape(10), 1, DataType::U8),
70*c217d954SCole Faust                                                 TensorInfo(TensorShape(10), 1, DataType::U8),
71*c217d954SCole Faust                                                 TensorInfo(TensorShape(10), 1, DataType::U8),
72*c217d954SCole Faust                                                 TensorInfo(TensorShape(1), 1, DataType::U8)})),
73*c217d954SCole Faust 
74*c217d954SCole Faust         framework::dataset::make("k",{ 0, 1, 2, 3, 4 })),
75*c217d954SCole Faust         framework::dataset::make("Expected", {true, false, false, false, false })),
76*c217d954SCole Faust         prediction_info, targets_info, output_info, k, expected)
77*c217d954SCole Faust {
78*c217d954SCole Faust     const Status status = CPPTopKV::validate(&prediction_info.clone()->set_is_resizable(false),&targets_info.clone()->set_is_resizable(false), &output_info.clone()->set_is_resizable(false), k);
79*c217d954SCole Faust     ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
80*c217d954SCole Faust }
81*c217d954SCole Faust // clang-format on
82*c217d954SCole Faust // *INDENT-ON*
83*c217d954SCole Faust 
TEST_CASE(Float,framework::DatasetMode::ALL)84*c217d954SCole Faust TEST_CASE(Float, framework::DatasetMode::ALL)
85*c217d954SCole Faust {
86*c217d954SCole Faust     const unsigned int k = 5;
87*c217d954SCole Faust 
88*c217d954SCole Faust     Tensor predictions = create_tensor<Tensor>(TensorShape(10, 20), DataType::F32);
89*c217d954SCole Faust     Tensor targets     = create_tensor<Tensor>(TensorShape(20), DataType::U32);
90*c217d954SCole Faust 
91*c217d954SCole Faust     predictions.allocator()->allocate();
92*c217d954SCole Faust     targets.allocator()->allocate();
93*c217d954SCole Faust 
94*c217d954SCole Faust     // Fill the tensors with random pre-generated values
95*c217d954SCole Faust     fill_tensor(Accessor(predictions), std::vector<float>
96*c217d954SCole Faust     {
97*c217d954SCole Faust         0.8147, 0.6557, 0.4387, 0.7513, 0.3517, 0.1622, 0.1067, 0.8530, 0.7803, 0.5470,
98*c217d954SCole Faust         0.9058, 0.0357, 0.3816, 0.2551, 0.8308, 0.7943, 0.9619, 0.6221, 0.3897, 0.2963,
99*c217d954SCole Faust         0.1270, 0.8491, 0.7655, 0.5060, 0.5853, 0.3112, 0.0046, 0.3510, 0.2417, 0.7447,
100*c217d954SCole Faust         0.9134, 0.9340, 0.7952, 0.6991, 0.5497, 0.5285, 0.7749, 0.5132, 0.4039, 0.1890,
101*c217d954SCole Faust         0.6324, 0.6787, 0.1869, 0.8909, 0.9172, 0.1656, 0.8173, 0.4018, 0.0965, 0.6868,
102*c217d954SCole Faust         0.0975, 0.7577, 0.4898, 0.9593, 0.2858, 0.6020, 0.8687, 0.0760, 0.1320, 0.1835,
103*c217d954SCole Faust         0.2785, 0.7431, 0.4456, 0.5472, 0.7572, 0.2630, 0.0844, 0.2399, 0.9421, 0.3685,
104*c217d954SCole Faust         0.5469, 0.3922, 0.6463, 0.1386, 0.7537, 0.6541, 0.3998, 0.1233, 0.9561, 0.6256,
105*c217d954SCole Faust         0.9575, 0.6555, 0.7094, 0.1493, 0.3804, 0.6892, 0.2599, 0.1839, 0.5752, 0.7802,
106*c217d954SCole Faust         0.9649, 0.1712, 0.7547, 0.2575, 0.5678, 0.7482, 0.8001, 0.2400, 0.0598, 0.0811,
107*c217d954SCole Faust         0.1576, 0.7060, 0.2760, 0.8407, 0.0759, 0.4505, 0.4314, 0.4173, 0.2348, 0.9294,
108*c217d954SCole Faust         0.9706, 0.0318, 0.6797, 0.2543, 0.0540, 0.0838, 0.9106, 0.0497, 0.3532, 0.7757,
109*c217d954SCole Faust         0.9572, 0.2769, 0.6551, 0.8143, 0.5308, 0.2290, 0.1818, 0.9027, 0.8212, 0.4868,
110*c217d954SCole Faust         0.4854, 0.0462, 0.1626, 0.2435, 0.7792, 0.9133, 0.2638, 0.9448, 0.0154, 0.4359,
111*c217d954SCole Faust         0.8003, 0.0971, 0.1190, 0.9293, 0.9340, 0.1524, 0.1455, 0.4909, 0.0430, 0.4468,
112*c217d954SCole Faust         0.1419, 0.8235, 0.4984, 0.3500, 0.1299, 0.8258, 0.1361, 0.4893, 0.1690, 0.3063,
113*c217d954SCole Faust         0.4218, 0.6948, 0.9597, 0.1966, 0.5688, 0.5383, 0.8693, 0.3377, 0.6491, 0.5085,
114*c217d954SCole Faust         0.9157, 0.3171, 0.3404, 0.2511, 0.4694, 0.9961, 0.5797, 0.9001, 0.7317, 0.5108,
115*c217d954SCole Faust         0.7922, 0.9502, 0.5853, 0.6160, 0.0119, 0.0782, 0.5499, 0.3692, 0.6477, 0.8176,
116*c217d954SCole Faust         0.9595, 0.0344, 0.2238, 0.4733, 0.3371, 0.4427, 0.1450, 0.1112, 0.4509, 0.7948
117*c217d954SCole Faust     });
118*c217d954SCole Faust 
119*c217d954SCole Faust     fill_tensor(Accessor(targets), std::vector<int> { 1, 5, 7, 2, 8, 1, 2, 1, 2, 4, 3, 9, 4, 1, 9, 9, 4, 1, 2, 4 });
120*c217d954SCole Faust 
121*c217d954SCole Faust     // Determine the output through the CPP kernel
122*c217d954SCole Faust     Tensor   output;
123*c217d954SCole Faust     CPPTopKV topkv;
124*c217d954SCole Faust     topkv.configure(&predictions, &targets, &output, k);
125*c217d954SCole Faust 
126*c217d954SCole Faust     output.allocator()->allocate();
127*c217d954SCole Faust 
128*c217d954SCole Faust     // Run the kernel
129*c217d954SCole Faust     topkv.run();
130*c217d954SCole Faust 
131*c217d954SCole Faust     // Validate against the expected values
132*c217d954SCole Faust     SimpleTensor<uint8_t> expected_output(TensorShape(20), DataType::U8);
133*c217d954SCole Faust     fill_tensor(expected_output, std::vector<uint8_t> { 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0 });
134*c217d954SCole Faust     validate(Accessor(output), expected_output);
135*c217d954SCole Faust }
136*c217d954SCole Faust 
TEST_CASE(QASYMM8,framework::DatasetMode::ALL)137*c217d954SCole Faust TEST_CASE(QASYMM8, framework::DatasetMode::ALL)
138*c217d954SCole Faust {
139*c217d954SCole Faust     const unsigned int k = 5;
140*c217d954SCole Faust 
141*c217d954SCole Faust     Tensor predictions = create_tensor<Tensor>(TensorShape(10, 20), DataType::QASYMM8, 1, QuantizationInfo());
142*c217d954SCole Faust     Tensor targets     = create_tensor<Tensor>(TensorShape(20), DataType::U32);
143*c217d954SCole Faust 
144*c217d954SCole Faust     predictions.allocator()->allocate();
145*c217d954SCole Faust     targets.allocator()->allocate();
146*c217d954SCole Faust 
147*c217d954SCole Faust     // Fill the tensors with random pre-generated values
148*c217d954SCole Faust     fill_tensor(Accessor(predictions), std::vector<uint8_t>
149*c217d954SCole Faust     {
150*c217d954SCole Faust         133, 235, 69, 118, 140, 179, 189, 203, 137, 157,
151*c217d954SCole Faust         242, 1, 196, 170, 166, 25, 102, 244, 24, 254,
152*c217d954SCole Faust         164, 119, 49, 198, 140, 135, 175, 84, 29, 136,
153*c217d954SCole Faust         246, 109, 74, 90, 185, 136, 181, 172, 35, 123,
154*c217d954SCole Faust         62, 118, 24, 170, 134, 221, 114, 113, 174, 206,
155*c217d954SCole Faust         174, 198, 148, 107, 255, 125, 6, 214, 127, 59,
156*c217d954SCole Faust         75, 83, 175, 216, 56, 101, 85, 197, 49, 128,
157*c217d954SCole Faust         172, 201, 140, 214, 28, 172, 109, 43, 127, 231,
158*c217d954SCole Faust         178, 121, 109, 66, 29, 190, 70, 221, 38, 148,
159*c217d954SCole Faust         18, 10, 165, 158, 17, 134, 51, 254, 15, 217,
160*c217d954SCole Faust         66, 46, 166, 150, 104, 90, 211, 132, 218, 190,
161*c217d954SCole Faust         58, 185, 174, 139, 115, 39, 111, 227, 144, 151,
162*c217d954SCole Faust         171, 122, 163, 223, 94, 151, 228, 151, 238, 64,
163*c217d954SCole Faust         217, 40, 242, 68, 196, 68, 101, 40, 179, 171,
164*c217d954SCole Faust         89, 88, 54, 82, 161, 12, 197, 52, 150, 22,
165*c217d954SCole Faust         200, 156, 182, 31, 198, 194, 102, 105, 209, 161,
166*c217d954SCole Faust         173, 50, 61, 241, 239, 63, 207, 192, 226, 170,
167*c217d954SCole Faust         2, 190, 31, 166, 250, 114, 194, 212, 254, 187,
168*c217d954SCole Faust         155, 63, 156, 123, 50, 177, 97, 203, 1, 229,
169*c217d954SCole Faust         100, 235, 116, 164, 36, 92, 56, 82, 222, 252
170*c217d954SCole Faust     });
171*c217d954SCole Faust 
172*c217d954SCole Faust     fill_tensor(Accessor(targets), std::vector<int> { 1, 5, 7, 2, 8, 1, 2, 1, 2, 4, 3, 9, 4, 1, 9, 9, 4, 1, 2, 4 });
173*c217d954SCole Faust 
174*c217d954SCole Faust     // Determine the output through the CPP kernel
175*c217d954SCole Faust     Tensor   output;
176*c217d954SCole Faust     CPPTopKV topkv;
177*c217d954SCole Faust     topkv.configure(&predictions, &targets, &output, k);
178*c217d954SCole Faust 
179*c217d954SCole Faust     output.allocator()->allocate();
180*c217d954SCole Faust 
181*c217d954SCole Faust     // Run the kernel
182*c217d954SCole Faust     topkv.run();
183*c217d954SCole Faust 
184*c217d954SCole Faust     // Validate against the expected values
185*c217d954SCole Faust     SimpleTensor<uint8_t> expected_output(TensorShape(20), DataType::U8);
186*c217d954SCole Faust     fill_tensor(expected_output, std::vector<uint8_t> { 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0 });
187*c217d954SCole Faust     validate(Accessor(output), expected_output);
188*c217d954SCole Faust }
189*c217d954SCole Faust 
TEST_CASE(QASYMM8_SIGNED,framework::DatasetMode::ALL)190*c217d954SCole Faust TEST_CASE(QASYMM8_SIGNED, framework::DatasetMode::ALL)
191*c217d954SCole Faust {
192*c217d954SCole Faust     const unsigned int k = 5;
193*c217d954SCole Faust 
194*c217d954SCole Faust     Tensor predictions = create_tensor<Tensor>(TensorShape(10, 20), DataType::QASYMM8_SIGNED, 1, QuantizationInfo());
195*c217d954SCole Faust     Tensor targets     = create_tensor<Tensor>(TensorShape(20), DataType::U32);
196*c217d954SCole Faust 
197*c217d954SCole Faust     predictions.allocator()->allocate();
198*c217d954SCole Faust     targets.allocator()->allocate();
199*c217d954SCole Faust 
200*c217d954SCole Faust     // Fill the tensors with random pre-generated values
201*c217d954SCole Faust     fill_tensor(Accessor(predictions), std::vector<int8_t>
202*c217d954SCole Faust     {
203*c217d954SCole Faust         123, -34, 69, 118, 20, -45, 99, -98, 127, 117,  //-34
204*c217d954SCole Faust         -99, 1, -128, 90, 60, 25, 102, 76, 24, -110,    //25
205*c217d954SCole Faust         99, 119, 49, 43, -40, 60, 43, 84, 29, 67,       //84
206*c217d954SCole Faust         33, 109, 74, 90, 90, 44, 98, 90, 35, 123,       //74
207*c217d954SCole Faust         62, 118, 24, -32, 34, 21, 114, 113, 124, 20,    //124
208*c217d954SCole Faust         74, 98, 48, 107, 127, 125, 6, -98, 127, 59,     //98
209*c217d954SCole Faust         75, 83, 75, -118, 56, 101, 85, 97, 49, 127,     //75
210*c217d954SCole Faust         72, -20, 40, 14, 28, -30, 109, 43, 127, -31,    //-20
211*c217d954SCole Faust         78, 121, 109, 66, 29, 90, 70, 21, 38, 48,       //109
212*c217d954SCole Faust         18, 10, 115, 124, 17, 123, 51, 54, 15, 17,      //17
213*c217d954SCole Faust         66, 46, -66, 125, 104, 90, 123, 113, -54, -126, //125
214*c217d954SCole Faust         58, -85, 74, 39, 115, 39, 111, -27, 44, 51,     //51
215*c217d954SCole Faust         71, 122, -34, -123, 94, 113, 125, 111, 38, 64,  //94
216*c217d954SCole Faust         -17, 40, 42, 68, 96, 68, 101, 40, 79, 71,       //40
217*c217d954SCole Faust         89, 88, 54, 82, 127, 12, 112, 52, 125, 22,      //22
218*c217d954SCole Faust         -128, 56, 82, 31, 98, 94, 102, 105, 127, 123,   //123
219*c217d954SCole Faust         112, 50, 61, 41, 39, 63, -77, 92, 26, 70,       //39
220*c217d954SCole Faust         2, 90, 31, 99, -34, 114, 112, 126, 127, 87,     //90
221*c217d954SCole Faust         125, 63, 56, 123, 50, -77, 97, -93, 1, 29,      //56
222*c217d954SCole Faust         100, -35, 116, 64, 36, 92, 56, 82, -22, -118    //36
223*c217d954SCole Faust     });
224*c217d954SCole Faust 
225*c217d954SCole Faust     fill_tensor(Accessor(targets), std::vector<int> { 1, 5, 7, 2, 8, 1, 2, 1, 2, 4, 3, 9, 4, 1, 9, 9, 4, 1, 2, 4 });
226*c217d954SCole Faust 
227*c217d954SCole Faust     // Determine the output through the CPP kernel
228*c217d954SCole Faust     Tensor   output;
229*c217d954SCole Faust     CPPTopKV topkv;
230*c217d954SCole Faust     topkv.configure(&predictions, &targets, &output, k);
231*c217d954SCole Faust 
232*c217d954SCole Faust     output.allocator()->allocate();
233*c217d954SCole Faust 
234*c217d954SCole Faust     // Run the kernel
235*c217d954SCole Faust     topkv.run();
236*c217d954SCole Faust 
237*c217d954SCole Faust     // Validate against the expected values
238*c217d954SCole Faust     SimpleTensor<int8_t> expected_output(TensorShape(20), DataType::U8);
239*c217d954SCole Faust     fill_tensor(expected_output, std::vector<int8_t> { 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0 });
240*c217d954SCole Faust     validate(Accessor(output), expected_output);
241*c217d954SCole Faust }
242*c217d954SCole Faust 
243*c217d954SCole Faust TEST_SUITE_END() // TopKV
244*c217d954SCole Faust TEST_SUITE_END() // CPP
245*c217d954SCole Faust } // namespace validation
246*c217d954SCole Faust } // namespace test
247*c217d954SCole Faust } // namespace arm_compute
248