1*c217d954SCole Faust /*
2*c217d954SCole Faust * Copyright (c) 2019-2021 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/NEON/functions/NEDetectionPostProcessLayer.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
36*c217d954SCole Faust namespace arm_compute
37*c217d954SCole Faust {
38*c217d954SCole Faust namespace test
39*c217d954SCole Faust {
40*c217d954SCole Faust namespace validation
41*c217d954SCole Faust {
42*c217d954SCole Faust namespace
43*c217d954SCole Faust {
44*c217d954SCole Faust template <typename U, typename T>
fill_tensor(U && tensor,const std::vector<T> & v)45*c217d954SCole Faust inline void fill_tensor(U &&tensor, const std::vector<T> &v)
46*c217d954SCole Faust {
47*c217d954SCole Faust std::memcpy(tensor.data(), v.data(), sizeof(T) * v.size());
48*c217d954SCole Faust }
49*c217d954SCole Faust template <typename U, typename T>
quantize_and_fill_tensor(U && tensor,const std::vector<T> & v)50*c217d954SCole Faust inline void quantize_and_fill_tensor(U &&tensor, const std::vector<T> &v)
51*c217d954SCole Faust {
52*c217d954SCole Faust QuantizationInfo qi = tensor.quantization_info();
53*c217d954SCole Faust std::vector<uint8_t> quantized;
54*c217d954SCole Faust quantized.reserve(v.size());
55*c217d954SCole Faust for(auto elem : v)
56*c217d954SCole Faust {
57*c217d954SCole Faust quantized.emplace_back(quantize_qasymm8(elem, qi));
58*c217d954SCole Faust }
59*c217d954SCole Faust std::memcpy(tensor.data(), quantized.data(), sizeof(uint8_t) * quantized.size());
60*c217d954SCole Faust }
qinfo_scaleoffset_from_minmax(const float min,const float max)61*c217d954SCole Faust inline QuantizationInfo qinfo_scaleoffset_from_minmax(const float min, const float max)
62*c217d954SCole Faust {
63*c217d954SCole Faust int offset = 0;
64*c217d954SCole Faust float scale = 0;
65*c217d954SCole Faust const uint8_t qmin = std::numeric_limits<uint8_t>::min();
66*c217d954SCole Faust const uint8_t qmax = std::numeric_limits<uint8_t>::max();
67*c217d954SCole Faust const float f_qmin = qmin;
68*c217d954SCole Faust const float f_qmax = qmax;
69*c217d954SCole Faust
70*c217d954SCole Faust // Continue only if [min,max] is a valid range and not a point
71*c217d954SCole Faust if(min != max)
72*c217d954SCole Faust {
73*c217d954SCole Faust scale = (max - min) / (f_qmax - f_qmin);
74*c217d954SCole Faust const float offset_from_min = f_qmin - min / scale;
75*c217d954SCole Faust const float offset_from_max = f_qmax - max / scale;
76*c217d954SCole Faust
77*c217d954SCole Faust const float offset_from_min_error = std::abs(f_qmin) + std::abs(min / scale);
78*c217d954SCole Faust const float offset_from_max_error = std::abs(f_qmax) + std::abs(max / scale);
79*c217d954SCole Faust const float f_offset = offset_from_min_error < offset_from_max_error ? offset_from_min : offset_from_max;
80*c217d954SCole Faust
81*c217d954SCole Faust uint8_t uint8_offset = 0;
82*c217d954SCole Faust if(f_offset < f_qmin)
83*c217d954SCole Faust {
84*c217d954SCole Faust uint8_offset = qmin;
85*c217d954SCole Faust }
86*c217d954SCole Faust else if(f_offset > f_qmax)
87*c217d954SCole Faust {
88*c217d954SCole Faust uint8_offset = qmax;
89*c217d954SCole Faust }
90*c217d954SCole Faust else
91*c217d954SCole Faust {
92*c217d954SCole Faust uint8_offset = static_cast<uint8_t>(support::cpp11::round(f_offset));
93*c217d954SCole Faust }
94*c217d954SCole Faust offset = uint8_offset;
95*c217d954SCole Faust }
96*c217d954SCole Faust return QuantizationInfo(scale, offset);
97*c217d954SCole Faust }
98*c217d954SCole Faust
base_test_case(DetectionPostProcessLayerInfo info,DataType data_type,const SimpleTensor<float> & expected_output_boxes,const SimpleTensor<float> & expected_output_classes,const SimpleTensor<float> & expected_output_scores,const SimpleTensor<float> & expected_num_detection,AbsoluteTolerance<float> tolerance_boxes=AbsoluteTolerance<float> (0.1f),AbsoluteTolerance<float> tolerance_others=AbsoluteTolerance<float> (0.1f))99*c217d954SCole Faust inline void base_test_case(DetectionPostProcessLayerInfo info, DataType data_type, const SimpleTensor<float> &expected_output_boxes,
100*c217d954SCole Faust const SimpleTensor<float> &expected_output_classes, const SimpleTensor<float> &expected_output_scores, const SimpleTensor<float> &expected_num_detection,
101*c217d954SCole Faust AbsoluteTolerance<float> tolerance_boxes = AbsoluteTolerance<float>(0.1f), AbsoluteTolerance<float> tolerance_others = AbsoluteTolerance<float>(0.1f))
102*c217d954SCole Faust {
103*c217d954SCole Faust Tensor box_encoding = create_tensor<Tensor>(TensorShape(4U, 6U, 1U), data_type, 1, qinfo_scaleoffset_from_minmax(-1.0f, 1.0f));
104*c217d954SCole Faust Tensor class_prediction = create_tensor<Tensor>(TensorShape(3U, 6U, 1U), data_type, 1, qinfo_scaleoffset_from_minmax(0.0f, 1.0f));
105*c217d954SCole Faust Tensor anchors = create_tensor<Tensor>(TensorShape(4U, 6U), data_type, 1, qinfo_scaleoffset_from_minmax(0.0f, 100.5f));
106*c217d954SCole Faust
107*c217d954SCole Faust box_encoding.allocator()->allocate();
108*c217d954SCole Faust class_prediction.allocator()->allocate();
109*c217d954SCole Faust anchors.allocator()->allocate();
110*c217d954SCole Faust
111*c217d954SCole Faust std::vector<float> box_encoding_vector =
112*c217d954SCole Faust {
113*c217d954SCole Faust 0.0f, 1.0f, 0.0f, 0.0f,
114*c217d954SCole Faust 0.0f, -1.0f, 0.0f, 0.0f,
115*c217d954SCole Faust 0.0f, 0.0f, 0.0f, 0.0f,
116*c217d954SCole Faust 0.0f, 0.0f, 0.0f, 0.0f,
117*c217d954SCole Faust 0.0f, 1.0f, 0.0f, 0.0f,
118*c217d954SCole Faust 0.0f, 0.0f, 0.0f, 0.0f
119*c217d954SCole Faust };
120*c217d954SCole Faust std::vector<float> class_prediction_vector =
121*c217d954SCole Faust {
122*c217d954SCole Faust 0.0f, 0.7f, 0.68f,
123*c217d954SCole Faust 0.0f, 0.6f, 0.5f,
124*c217d954SCole Faust 0.0f, 0.9f, 0.83f,
125*c217d954SCole Faust 0.0f, 0.91f, 0.97f,
126*c217d954SCole Faust 0.0f, 0.5f, 0.4f,
127*c217d954SCole Faust 0.0f, 0.31f, 0.22f
128*c217d954SCole Faust };
129*c217d954SCole Faust std::vector<float> anchors_vector =
130*c217d954SCole Faust {
131*c217d954SCole Faust 0.4f, 0.4f, 1.1f, 1.1f,
132*c217d954SCole Faust 0.4f, 0.4f, 1.1f, 1.1f,
133*c217d954SCole Faust 0.4f, 0.4f, 1.1f, 1.1f,
134*c217d954SCole Faust 0.4f, 10.4f, 1.1f, 1.1f,
135*c217d954SCole Faust 0.4f, 10.4f, 1.1f, 1.1f,
136*c217d954SCole Faust 0.4f, 100.4f, 1.1f, 1.1f
137*c217d954SCole Faust };
138*c217d954SCole Faust
139*c217d954SCole Faust // Fill the tensors with random pre-generated values
140*c217d954SCole Faust if(data_type == DataType::F32)
141*c217d954SCole Faust {
142*c217d954SCole Faust fill_tensor(Accessor(box_encoding), box_encoding_vector);
143*c217d954SCole Faust fill_tensor(Accessor(class_prediction), class_prediction_vector);
144*c217d954SCole Faust fill_tensor(Accessor(anchors), anchors_vector);
145*c217d954SCole Faust }
146*c217d954SCole Faust else
147*c217d954SCole Faust {
148*c217d954SCole Faust quantize_and_fill_tensor(Accessor(box_encoding), box_encoding_vector);
149*c217d954SCole Faust quantize_and_fill_tensor(Accessor(class_prediction), class_prediction_vector);
150*c217d954SCole Faust quantize_and_fill_tensor(Accessor(anchors), anchors_vector);
151*c217d954SCole Faust }
152*c217d954SCole Faust
153*c217d954SCole Faust // Determine the output through the Compute Library operator
154*c217d954SCole Faust Tensor output_boxes;
155*c217d954SCole Faust Tensor output_classes;
156*c217d954SCole Faust Tensor output_scores;
157*c217d954SCole Faust Tensor num_detection;
158*c217d954SCole Faust NEDetectionPostProcessLayer detection;
159*c217d954SCole Faust detection.configure(&box_encoding, &class_prediction, &anchors, &output_boxes, &output_classes, &output_scores, &num_detection, info);
160*c217d954SCole Faust
161*c217d954SCole Faust output_boxes.allocator()->allocate();
162*c217d954SCole Faust output_classes.allocator()->allocate();
163*c217d954SCole Faust output_scores.allocator()->allocate();
164*c217d954SCole Faust num_detection.allocator()->allocate();
165*c217d954SCole Faust
166*c217d954SCole Faust // Run the kernel
167*c217d954SCole Faust detection.run();
168*c217d954SCole Faust
169*c217d954SCole Faust // Validate against the expected output
170*c217d954SCole Faust // Validate output boxes
171*c217d954SCole Faust validate(Accessor(output_boxes), expected_output_boxes, tolerance_boxes);
172*c217d954SCole Faust // Validate detection classes
173*c217d954SCole Faust validate(Accessor(output_classes), expected_output_classes, tolerance_others);
174*c217d954SCole Faust // Validate detection scores
175*c217d954SCole Faust validate(Accessor(output_scores), expected_output_scores, tolerance_others);
176*c217d954SCole Faust // Validate num detections
177*c217d954SCole Faust validate(Accessor(num_detection), expected_num_detection, tolerance_others);
178*c217d954SCole Faust }
179*c217d954SCole Faust } // namespace
180*c217d954SCole Faust
181*c217d954SCole Faust TEST_SUITE(NEON)
TEST_SUITE(DetectionPostProcessLayer)182*c217d954SCole Faust TEST_SUITE(DetectionPostProcessLayer)
183*c217d954SCole Faust
184*c217d954SCole Faust // *INDENT-OFF*
185*c217d954SCole Faust // clang-format off
186*c217d954SCole Faust DATA_TEST_CASE(Validate, framework::DatasetMode::ALL, zip(zip(zip(zip(zip(zip(zip(zip(
187*c217d954SCole Faust framework::dataset::make("BoxEncodingsInfo", { TensorInfo(TensorShape(4U, 10U, 1U), 1, DataType::F32),
188*c217d954SCole Faust TensorInfo(TensorShape(4U, 10U, 3U), 1, DataType::F32), // Mismatching batch_size
189*c217d954SCole Faust TensorInfo(TensorShape(4U, 10U, 1U), 1, DataType::S8), // Unsupported data type
190*c217d954SCole Faust TensorInfo(TensorShape(4U, 10U, 1U), 1, DataType::F32), // Wrong Detection Info
191*c217d954SCole Faust TensorInfo(TensorShape(4U, 10U, 1U), 1, DataType::F32), // Wrong boxes dimensions
192*c217d954SCole Faust TensorInfo(TensorShape(4U, 10U, 1U), 1, DataType::QASYMM8)}), // Wrong score dimension
193*c217d954SCole Faust framework::dataset::make("ClassPredsInfo",{ TensorInfo(TensorShape(3U ,10U), 1, DataType::F32),
194*c217d954SCole Faust TensorInfo(TensorShape(3U ,10U), 1, DataType::F32),
195*c217d954SCole Faust TensorInfo(TensorShape(3U ,10U), 1, DataType::F32),
196*c217d954SCole Faust TensorInfo(TensorShape(3U ,10U), 1, DataType::F32),
197*c217d954SCole Faust TensorInfo(TensorShape(3U ,10U), 1, DataType::F32),
198*c217d954SCole Faust TensorInfo(TensorShape(3U ,10U), 1, DataType::QASYMM8)})),
199*c217d954SCole Faust framework::dataset::make("AnchorsInfo",{ TensorInfo(TensorShape(4U, 10U, 1U), 1, DataType::F32),
200*c217d954SCole Faust TensorInfo(TensorShape(4U, 10U, 1U), 1, DataType::F32),
201*c217d954SCole Faust TensorInfo(TensorShape(4U, 10U, 1U), 1, DataType::F32),
202*c217d954SCole Faust TensorInfo(TensorShape(4U, 10U, 1U), 1, DataType::F32),
203*c217d954SCole Faust TensorInfo(TensorShape(4U, 10U, 1U), 1, DataType::F32),
204*c217d954SCole Faust TensorInfo(TensorShape(4U, 10U, 1U), 1, DataType::QASYMM8)})),
205*c217d954SCole Faust framework::dataset::make("OutputBoxInfo", { TensorInfo(TensorShape(4U, 3U, 1U), 1, DataType::F32),
206*c217d954SCole Faust TensorInfo(TensorShape(4U, 3U, 1U), 1, DataType::F32),
207*c217d954SCole Faust TensorInfo(TensorShape(4U, 3U, 1U), 1, DataType::S8),
208*c217d954SCole Faust TensorInfo(TensorShape(4U, 3U, 1U), 1, DataType::F32),
209*c217d954SCole Faust TensorInfo(TensorShape(1U, 5U, 1U), 1, DataType::F32),
210*c217d954SCole Faust TensorInfo(TensorShape(4U, 3U, 1U), 1, DataType::F32)})),
211*c217d954SCole Faust framework::dataset::make("OuputClassesInfo",{ TensorInfo(TensorShape(3U, 1U), 1, DataType::F32),
212*c217d954SCole Faust TensorInfo(TensorShape(3U, 1U), 1, DataType::F32),
213*c217d954SCole Faust TensorInfo(TensorShape(3U, 1U), 1, DataType::F32),
214*c217d954SCole Faust TensorInfo(TensorShape(3U, 1U), 1, DataType::F32),
215*c217d954SCole Faust TensorInfo(TensorShape(3U, 1U), 1, DataType::F32),
216*c217d954SCole Faust TensorInfo(TensorShape(6U, 1U), 1, DataType::F32)})),
217*c217d954SCole Faust framework::dataset::make("OutputScoresInfo",{ TensorInfo(TensorShape(3U, 1U), 1, DataType::F32),
218*c217d954SCole Faust TensorInfo(TensorShape(3U, 1U), 1, DataType::F32),
219*c217d954SCole Faust TensorInfo(TensorShape(3U, 1U), 1, DataType::F32),
220*c217d954SCole Faust TensorInfo(TensorShape(3U, 1U), 1, DataType::F32),
221*c217d954SCole Faust TensorInfo(TensorShape(3U, 1U), 1, DataType::F32),
222*c217d954SCole Faust TensorInfo(TensorShape(6U, 1U), 1, DataType::F32)})),
223*c217d954SCole Faust framework::dataset::make("NumDetectionsInfo",{ TensorInfo(TensorShape(1U), 1, DataType::F32),
224*c217d954SCole Faust TensorInfo(TensorShape(1U), 1, DataType::F32),
225*c217d954SCole Faust TensorInfo(TensorShape(1U), 1, DataType::F32),
226*c217d954SCole Faust TensorInfo(TensorShape(1U), 1, DataType::F32),
227*c217d954SCole Faust TensorInfo(TensorShape(1U), 1, DataType::F32),
228*c217d954SCole Faust TensorInfo(TensorShape(1U), 1, DataType::F32)})),
229*c217d954SCole Faust framework::dataset::make("DetectionPostProcessLayerInfo",{ DetectionPostProcessLayerInfo(3, 1, 0.0f, 0.5f, 2, {0.1f,0.1f,0.1f,0.1f}),
230*c217d954SCole Faust DetectionPostProcessLayerInfo(3, 1, 0.0f, 0.5f, 2, {0.1f,0.1f,0.1f,0.1f}),
231*c217d954SCole Faust DetectionPostProcessLayerInfo(3, 1, 0.0f, 0.5f, 2, {0.1f,0.1f,0.1f,0.1f}),
232*c217d954SCole Faust DetectionPostProcessLayerInfo(3, 1, 0.0f, 1.5f, 2, {0.0f,0.1f,0.1f,0.1f}),
233*c217d954SCole Faust DetectionPostProcessLayerInfo(3, 1, 0.0f, 0.5f, 2, {0.1f,0.1f,0.1f,0.1f}),
234*c217d954SCole Faust DetectionPostProcessLayerInfo(3, 1, 0.0f, 0.5f, 2, {0.1f,0.1f,0.1f,0.1f})})),
235*c217d954SCole Faust framework::dataset::make("Expected", {true, false, false, false, false, false })),
236*c217d954SCole Faust box_encodings_info, classes_info, anchors_info, output_boxes_info, output_classes_info,output_scores_info, num_detection_info, detect_info, expected)
237*c217d954SCole Faust {
238*c217d954SCole Faust const Status status = NEDetectionPostProcessLayer::validate(&box_encodings_info.clone()->set_is_resizable(false),
239*c217d954SCole Faust &classes_info.clone()->set_is_resizable(false),
240*c217d954SCole Faust &anchors_info.clone()->set_is_resizable(false),
241*c217d954SCole Faust &output_boxes_info.clone()->set_is_resizable(false),
242*c217d954SCole Faust &output_classes_info.clone()->set_is_resizable(false),
243*c217d954SCole Faust &output_scores_info.clone()->set_is_resizable(false), &num_detection_info.clone()->set_is_resizable(false), detect_info);
244*c217d954SCole Faust ARM_COMPUTE_EXPECT(bool(status) == expected, framework::LogLevel::ERRORS);
245*c217d954SCole Faust }
246*c217d954SCole Faust // clang-format on
247*c217d954SCole Faust // *INDENT-ON*
248*c217d954SCole Faust
249*c217d954SCole Faust TEST_SUITE(F32)
TEST_CASE(Float_general,framework::DatasetMode::ALL)250*c217d954SCole Faust TEST_CASE(Float_general, framework::DatasetMode::ALL)
251*c217d954SCole Faust {
252*c217d954SCole Faust DetectionPostProcessLayerInfo info = DetectionPostProcessLayerInfo(3 /*max_detections*/, 1 /*max_classes_per_detection*/, 0.0 /*nms_score_threshold*/,
253*c217d954SCole Faust 0.5 /*nms_iou_threshold*/, 2 /*num_classes*/, { 11.0, 11.0, 6.0, 6.0 } /*scale*/);
254*c217d954SCole Faust // Fill expected detection boxes
255*c217d954SCole Faust SimpleTensor<float> expected_output_boxes(TensorShape(4U, 3U), DataType::F32);
256*c217d954SCole Faust fill_tensor(expected_output_boxes, std::vector<float> { -0.15, 9.85, 0.95, 10.95, -0.15, -0.15, 0.95, 0.95, -0.15, 99.85, 0.95, 100.95 });
257*c217d954SCole Faust // Fill expected detection classes
258*c217d954SCole Faust SimpleTensor<float> expected_output_classes(TensorShape(3U), DataType::F32);
259*c217d954SCole Faust fill_tensor(expected_output_classes, std::vector<float> { 1.0f, 0.0f, 0.0f });
260*c217d954SCole Faust // Fill expected detection scores
261*c217d954SCole Faust SimpleTensor<float> expected_output_scores(TensorShape(3U), DataType::F32);
262*c217d954SCole Faust fill_tensor(expected_output_scores, std::vector<float> { 0.97f, 0.95f, 0.31f });
263*c217d954SCole Faust // Fill expected num detections
264*c217d954SCole Faust SimpleTensor<float> expected_num_detection(TensorShape(1U), DataType::F32);
265*c217d954SCole Faust fill_tensor(expected_num_detection, std::vector<float> { 3.f });
266*c217d954SCole Faust // Run base test
267*c217d954SCole Faust base_test_case(info, DataType::F32, expected_output_boxes, expected_output_classes, expected_output_scores, expected_num_detection);
268*c217d954SCole Faust }
269*c217d954SCole Faust
TEST_CASE(Float_fast,framework::DatasetMode::ALL)270*c217d954SCole Faust TEST_CASE(Float_fast, framework::DatasetMode::ALL)
271*c217d954SCole Faust {
272*c217d954SCole Faust DetectionPostProcessLayerInfo info = DetectionPostProcessLayerInfo(3 /*max_detections*/, 1 /*max_classes_per_detection*/, 0.0 /*nms_score_threshold*/,
273*c217d954SCole Faust 0.5 /*nms_iou_threshold*/, 2 /*num_classes*/, { 11.0, 11.0, 6.0, 6.0 } /*scale*/,
274*c217d954SCole Faust false /*use_regular_nms*/, 1 /*detections_per_class*/);
275*c217d954SCole Faust
276*c217d954SCole Faust // Fill expected detection boxes
277*c217d954SCole Faust SimpleTensor<float> expected_output_boxes(TensorShape(4U, 3U), DataType::F32);
278*c217d954SCole Faust fill_tensor(expected_output_boxes, std::vector<float> { -0.15, 9.85, 0.95, 10.95, -0.15, -0.15, 0.95, 0.95, -0.15, 99.85, 0.95, 100.95 });
279*c217d954SCole Faust // Fill expected detection classes
280*c217d954SCole Faust SimpleTensor<float> expected_output_classes(TensorShape(3U), DataType::F32);
281*c217d954SCole Faust fill_tensor(expected_output_classes, std::vector<float> { 1.0f, 0.0f, 0.0f });
282*c217d954SCole Faust // Fill expected detection scores
283*c217d954SCole Faust SimpleTensor<float> expected_output_scores(TensorShape(3U), DataType::F32);
284*c217d954SCole Faust fill_tensor(expected_output_scores, std::vector<float> { 0.97f, 0.95f, 0.31f });
285*c217d954SCole Faust // Fill expected num detections
286*c217d954SCole Faust SimpleTensor<float> expected_num_detection(TensorShape(1U), DataType::F32);
287*c217d954SCole Faust fill_tensor(expected_num_detection, std::vector<float> { 3.f });
288*c217d954SCole Faust
289*c217d954SCole Faust // Run base test
290*c217d954SCole Faust base_test_case(info, DataType::F32, expected_output_boxes, expected_output_classes, expected_output_scores, expected_num_detection);
291*c217d954SCole Faust }
292*c217d954SCole Faust
TEST_CASE(Float_regular,framework::DatasetMode::ALL)293*c217d954SCole Faust TEST_CASE(Float_regular, framework::DatasetMode::ALL)
294*c217d954SCole Faust {
295*c217d954SCole Faust DetectionPostProcessLayerInfo info = DetectionPostProcessLayerInfo(3 /*max_detections*/, 1 /*max_classes_per_detection*/, 0.0 /*nms_score_threshold*/,
296*c217d954SCole Faust 0.5 /*nms_iou_threshold*/, 2 /*num_classes*/, { 11.0, 11.0, 6.0, 6.0 } /*scale*/,
297*c217d954SCole Faust true /*use_regular_nms*/, 1 /*detections_per_class*/);
298*c217d954SCole Faust
299*c217d954SCole Faust // Fill expected detection boxes
300*c217d954SCole Faust SimpleTensor<float> expected_output_boxes(TensorShape(4U, 3U), DataType::F32);
301*c217d954SCole Faust fill_tensor(expected_output_boxes, std::vector<float> { -0.15, 9.85, 0.95, 10.95, -0.15, 9.85, 0.95, 10.95, 0.0f, 0.0f, 0.0f, 0.0f });
302*c217d954SCole Faust // Fill expected detection classes
303*c217d954SCole Faust SimpleTensor<float> expected_output_classes(TensorShape(3U), DataType::F32);
304*c217d954SCole Faust fill_tensor(expected_output_classes, std::vector<float> { 1.0f, 0.0f, 0.0f });
305*c217d954SCole Faust // Fill expected detection scores
306*c217d954SCole Faust SimpleTensor<float> expected_output_scores(TensorShape(3U), DataType::F32);
307*c217d954SCole Faust fill_tensor(expected_output_scores, std::vector<float> { 0.97f, 0.91f, 0.0f });
308*c217d954SCole Faust // Fill expected num detections
309*c217d954SCole Faust SimpleTensor<float> expected_num_detection(TensorShape(1U), DataType::F32);
310*c217d954SCole Faust fill_tensor(expected_num_detection, std::vector<float> { 2.f });
311*c217d954SCole Faust
312*c217d954SCole Faust // Run test
313*c217d954SCole Faust base_test_case(info, DataType::F32, expected_output_boxes, expected_output_classes, expected_output_scores, expected_num_detection);
314*c217d954SCole Faust }
315*c217d954SCole Faust TEST_SUITE_END() // F32
316*c217d954SCole Faust
TEST_SUITE(QASYMM8)317*c217d954SCole Faust TEST_SUITE(QASYMM8)
318*c217d954SCole Faust TEST_CASE(Quantized_general, framework::DatasetMode::ALL)
319*c217d954SCole Faust {
320*c217d954SCole Faust DetectionPostProcessLayerInfo info = DetectionPostProcessLayerInfo(3 /*max_detections*/, 1 /*max_classes_per_detection*/, 0.0 /*nms_score_threshold*/,
321*c217d954SCole Faust 0.5 /*nms_iou_threshold*/, 2 /*num_classes*/, { 11.0, 11.0, 6.0, 6.0 } /*scale*/);
322*c217d954SCole Faust
323*c217d954SCole Faust // Fill expected detection boxes
324*c217d954SCole Faust SimpleTensor<float> expected_output_boxes(TensorShape(4U, 3U), DataType::F32);
325*c217d954SCole Faust fill_tensor(expected_output_boxes, std::vector<float> { -0.15, 9.85, 0.95, 10.95, -0.15, -0.15, 0.95, 0.95, -0.15, 99.85, 0.95, 100.95 });
326*c217d954SCole Faust // Fill expected detection classes
327*c217d954SCole Faust SimpleTensor<float> expected_output_classes(TensorShape(3U), DataType::F32);
328*c217d954SCole Faust fill_tensor(expected_output_classes, std::vector<float> { 1.0f, 0.0f, 0.0f });
329*c217d954SCole Faust // Fill expected detection scores
330*c217d954SCole Faust SimpleTensor<float> expected_output_scores(TensorShape(3U), DataType::F32);
331*c217d954SCole Faust fill_tensor(expected_output_scores, std::vector<float> { 0.97f, 0.95f, 0.31f });
332*c217d954SCole Faust // Fill expected num detections
333*c217d954SCole Faust SimpleTensor<float> expected_num_detection(TensorShape(1U), DataType::F32);
334*c217d954SCole Faust fill_tensor(expected_num_detection, std::vector<float> { 3.f });
335*c217d954SCole Faust // Run test
336*c217d954SCole Faust base_test_case(info, DataType::QASYMM8, expected_output_boxes, expected_output_classes, expected_output_scores, expected_num_detection, AbsoluteTolerance<float>(0.3f));
337*c217d954SCole Faust }
338*c217d954SCole Faust
TEST_CASE(Quantized_fast,framework::DatasetMode::ALL)339*c217d954SCole Faust TEST_CASE(Quantized_fast, framework::DatasetMode::ALL)
340*c217d954SCole Faust {
341*c217d954SCole Faust DetectionPostProcessLayerInfo info = DetectionPostProcessLayerInfo(3 /*max_detections*/, 1 /*max_classes_per_detection*/, 0.0 /*nms_score_threshold*/,
342*c217d954SCole Faust 0.5 /*nms_iou_threshold*/, 2 /*num_classes*/, { 11.0, 11.0, 6.0, 6.0 } /*scale*/,
343*c217d954SCole Faust false /*use_regular_nms*/, 1 /*detections_per_class*/);
344*c217d954SCole Faust
345*c217d954SCole Faust // Fill expected detection boxes
346*c217d954SCole Faust SimpleTensor<float> expected_output_boxes(TensorShape(4U, 3U), DataType::F32);
347*c217d954SCole Faust fill_tensor(expected_output_boxes, std::vector<float> { -0.15, 9.85, 0.95, 10.95, -0.15, -0.15, 0.95, 0.95, -0.15, 99.85, 0.95, 100.95 });
348*c217d954SCole Faust // Fill expected detection classes
349*c217d954SCole Faust SimpleTensor<float> expected_output_classes(TensorShape(3U), DataType::F32);
350*c217d954SCole Faust fill_tensor(expected_output_classes, std::vector<float> { 1.0f, 0.0f, 0.0f });
351*c217d954SCole Faust // Fill expected detection scores
352*c217d954SCole Faust SimpleTensor<float> expected_output_scores(TensorShape(3U), DataType::F32);
353*c217d954SCole Faust fill_tensor(expected_output_scores, std::vector<float> { 0.97f, 0.95f, 0.31f });
354*c217d954SCole Faust // Fill expected num detections
355*c217d954SCole Faust SimpleTensor<float> expected_num_detection(TensorShape(1U), DataType::F32);
356*c217d954SCole Faust fill_tensor(expected_num_detection, std::vector<float> { 3.f });
357*c217d954SCole Faust
358*c217d954SCole Faust // Run base test
359*c217d954SCole Faust base_test_case(info, DataType::QASYMM8, expected_output_boxes, expected_output_classes, expected_output_scores, expected_num_detection, AbsoluteTolerance<float>(0.3f));
360*c217d954SCole Faust }
361*c217d954SCole Faust
TEST_CASE(Quantized_regular,framework::DatasetMode::ALL)362*c217d954SCole Faust TEST_CASE(Quantized_regular, framework::DatasetMode::ALL)
363*c217d954SCole Faust {
364*c217d954SCole Faust DetectionPostProcessLayerInfo info = DetectionPostProcessLayerInfo(3 /*max_detections*/, 1 /*max_classes_per_detection*/, 0.0 /*nms_score_threshold*/,
365*c217d954SCole Faust 0.5 /*nms_iou_threshold*/, 2 /*num_classes*/, { 11.0, 11.0, 6.0, 6.0 } /*scale*/,
366*c217d954SCole Faust true /*use_regular_nms*/, 1 /*detections_per_class*/);
367*c217d954SCole Faust // Fill expected detection boxes
368*c217d954SCole Faust SimpleTensor<float> expected_output_boxes(TensorShape(4U, 3U), DataType::F32);
369*c217d954SCole Faust fill_tensor(expected_output_boxes, std::vector<float> { -0.15, 9.85, 0.95, 10.95, -0.15, 9.85, 0.95, 10.95, 0.0f, 0.0f, 0.0f, 0.0f });
370*c217d954SCole Faust // Fill expected detection classes
371*c217d954SCole Faust SimpleTensor<float> expected_output_classes(TensorShape(3U), DataType::F32);
372*c217d954SCole Faust fill_tensor(expected_output_classes, std::vector<float> { 1.0f, 0.0f, 0.0f });
373*c217d954SCole Faust // Fill expected detection scores
374*c217d954SCole Faust SimpleTensor<float> expected_output_scores(TensorShape(3U), DataType::F32);
375*c217d954SCole Faust fill_tensor(expected_output_scores, std::vector<float> { 0.95f, 0.91f, 0.0f });
376*c217d954SCole Faust // Fill expected num detections
377*c217d954SCole Faust SimpleTensor<float> expected_num_detection(TensorShape(1U), DataType::F32);
378*c217d954SCole Faust fill_tensor(expected_num_detection, std::vector<float> { 2.f });
379*c217d954SCole Faust
380*c217d954SCole Faust // Run test
381*c217d954SCole Faust base_test_case(info, DataType::QASYMM8, expected_output_boxes, expected_output_classes, expected_output_scores, expected_num_detection, AbsoluteTolerance<float>(0.3f));
382*c217d954SCole Faust }
383*c217d954SCole Faust
384*c217d954SCole Faust TEST_SUITE_END() // QASYMM8
385*c217d954SCole Faust
386*c217d954SCole Faust TEST_SUITE_END() // DetectionPostProcessLayer
387*c217d954SCole Faust TEST_SUITE_END() // Neon
388*c217d954SCole Faust } // namespace validation
389*c217d954SCole Faust } // namespace test
390*c217d954SCole Faust } // namespace arm_compute
391