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